@@ -2275,8 +2275,9 @@ TRttiCustom = class
2275
2275
// - if rcfObjArray is defined in Flags, will release all nested TObject
2276
2276
procedure ValueFinalizeAndClear (Data: pointer);
2277
2277
{ $ifdef HASINLINE} inline;{ $endif}
2278
- // / efficiently copy a stored value of this type
2279
- function ValueCopy (Dest, Source: pointer): PtrInt;
2278
+ // / efficiently copy of a stored value of this type
2279
+ // - same behavior as Dest := Source for all types
2280
+ procedure ValueCopy (Dest, Source: pointer);
2280
2281
{ $ifdef HASINLINE} inline;{ $endif}
2281
2282
// / return TRUE if the Value is 0 / nil / '' / null
2282
2283
function ValueIsVoid (Data: PAnsiChar): boolean;
@@ -5794,6 +5795,42 @@ function _VariantCopy(Dest, Source: PVarData; Info: PRttiInfo): PtrInt;
5794
5795
result := SizeOf(Source^);
5795
5796
end ;
5796
5797
5798
+ function _Per1Copy (Dest, Source: PByte; Info: PRttiInfo): PtrInt;
5799
+ begin
5800
+ Dest^ := Source^;
5801
+ result := 0 ; // called from TRttiCustom.ValueCopy which ignore this
5802
+ end ;
5803
+
5804
+ function _Per2Copy (Dest, Source: PWord; Info: PRttiInfo): PtrInt;
5805
+ begin
5806
+ Dest^ := Source^;
5807
+ result := 0 ; // ignored
5808
+ end ;
5809
+
5810
+ function _Per4Copy (Dest, Source: PInteger; Info: PRttiInfo): PtrInt;
5811
+ begin
5812
+ Dest^ := Source^;
5813
+ result := 0 ; // ignored
5814
+ end ;
5815
+
5816
+ function _Per8Copy (Dest, Source: PInt64; Info: PRttiInfo): PtrInt;
5817
+ begin
5818
+ Dest^ := Source^;
5819
+ result := 0 ; // ignored
5820
+ end ;
5821
+
5822
+ function _Per16Copy (Dest, Source: PHash128; Info: PRttiInfo): PtrInt;
5823
+ begin
5824
+ Dest^ := Source^;
5825
+ result := 0 ; // ignored
5826
+ end ;
5827
+
5828
+ function _Per32Copy (Dest, Source: PHash256; Info: PRttiInfo): PtrInt;
5829
+ begin
5830
+ Dest^ := Source^;
5831
+ result := 0 ; // ignored
5832
+ end ;
5833
+
5797
5834
function _InterfaceCopy (Dest, Source: PInterface; Info: PRttiInfo): PtrInt;
5798
5835
begin
5799
5836
Dest^ := Source^;
@@ -7027,21 +7064,12 @@ procedure TRttiCustomProps.FinalizeAndClearPublishedProperties(Instance: TObject
7027
7064
end ;
7028
7065
7029
7066
// TRttiCustom method defined here for proper inlining
7030
- function TRttiCustom.ValueCopy (Dest, Source: pointer): PtrInt ;
7067
+ procedure TRttiCustom.ValueCopy (Dest, Source: pointer);
7031
7068
begin
7032
- if not Assigned(fCopy) then
7033
- begin
7034
- if rcfHasNestedProperties in fFlags then
7035
- if fCache.Kind = rkClass then
7036
- fProps.CopyProperties(Dest, Source)
7037
- else
7038
- fProps.CopyRecord(Dest, Source)
7039
- else
7040
- MoveFast(Source^, Dest^, fCache.Size);
7041
- result := fCache.Size;
7042
- end
7069
+ if Assigned(fCopy) then
7070
+ fCopy(Dest, Source, fCache.Info)
7043
7071
else
7044
- result := fCopy(Dest, Source , fCache.Info );
7072
+ MoveFast(Source^, Dest^ , fCache.Size );
7045
7073
end ;
7046
7074
7047
7075
procedure TRttiCustomProps.CopyRecord (Dest, Source: PAnsiChar);
@@ -7063,7 +7091,8 @@ procedure TRttiCustomProps.CopyRecord(Dest, Source: PAnsiChar);
7063
7091
inc(Source, offset);
7064
7092
inc(Dest, offset);
7065
7093
end ;
7066
- offset := pp^.Value .ValueCopy(Dest, Source); // copy managed field
7094
+ pp^.Value .ValueCopy(Dest, Source); // copy managed field
7095
+ offset := pp^.Value .Size;
7067
7096
inc(Source, offset);
7068
7097
inc(Dest, offset);
7069
7098
inc(offset, pp^.OffsetGet);
@@ -7095,6 +7124,9 @@ procedure TRttiCustomProps.CopyProperties(Dest, Source: PAnsiChar);
7095
7124
GetValue(Source, v);
7096
7125
SetValue(Dest, v, { andclear=} true);
7097
7126
end
7127
+ else if Value .Kind = rkClass then
7128
+ // explicit copy of nested instances properties
7129
+ Value .Props.CopyProperties(Dest + OffsetSet, Source + OffsetGet)
7098
7130
else
7099
7131
// direct content copy from the fields memory buffers
7100
7132
Value .ValueCopy(Dest + OffsetSet, Source + OffsetGet);
@@ -7220,6 +7252,21 @@ constructor TRttiCustom.Create(aInfo: PRttiInfo);
7220
7252
// initialize processing callbacks
7221
7253
fFinalize := RTTI_FINALIZE[fCache.Kind];
7222
7254
fCopy := RTTI_MANAGEDCOPY[fCache.Kind];
7255
+ if not Assigned(fCopy) then
7256
+ case fCache.Size of // direct copy of most sizes, including class/pointer
7257
+ 1 :
7258
+ fCopy := @_Per1Copy;
7259
+ 2 :
7260
+ fCopy := @_Per2Copy;
7261
+ 4 :
7262
+ fCopy := @_Per4Copy;
7263
+ 8 :
7264
+ fCopy := @_Per8Copy;
7265
+ 16 :
7266
+ fCopy := @_Per16Copy;
7267
+ 32 :
7268
+ fCopy := @_Per32Copy;
7269
+ end ; // ItemCopy() will fallback to MoveFast() otherwise
7223
7270
pt := TypeInfoToStandardParserType(aInfo, { byname=} true, @pct);
7224
7271
SetParserType(pt, pct);
7225
7272
end ;
0 commit comments