You are not logged in.
Hi, W10pro, Rio10.3.3ent
We have a problem when we have nested object in published properties.
We can't use j2oSetterNoCreate in interfaced service, so we propose this code: lines with // <==
function TPropInfo.ClassFromJSON(Instance: TObject; From: PUTF8Char;
var Valid: boolean; Options: TJSONToObjectOptions): PUTF8Char;
var Field: ^TObject;
{$ifndef FPC}tmp: TObject;UserCreatedObj: Boolean;{$endif} ; // <==
begin
valid := false;
UserCreatedObj := False; // <==
result := nil;
if (@self=nil) or (PropType^.Kind<>tkClass) or (Instance=nil) then
exit;
if SetterIsField then
// setter to field -> direct in-memory access
Field := SetterAddr(Instance) else
{$ifndef FPC}
if WriteIsDefined and not (j2oSetterNoCreate in Options) then begin
// it is a setter method -> create a temporary object
tmp := GetObjProp(Instance); // <==
UserCreatedObj := tmp<>nil; // <==
if tmp=nil then tmp := PropType^.ClassCreate; // <==
// tmp := PropType^.ClassCreate;
try
result := JSONToObject(tmp,From,Valid,nil,Options);
if (not Valid) and (not UserCreatedObj) then // <==
FreeAndNil(tmp) else begin
SetOrdProp(Instance,PtrInt(tmp)); // PtrInt(tmp) is OK for CPU64
if j2oSetterExpectsToFreeTempInstance in Options then
FreeAndNil(tmp);
end;
except
on Exception do
if (not UserCreatedObj) then tmp.Free; // <==
end;
exit;
end else
{$endif FPC}
if GetterIsField then
// no setter -> use direct in-memory access from getter (if available)
Field := GetterAddr(Instance) else
// no setter, nor direct field offset -> impossible to set the instance
exit;
result := JSONToObject(Field^,From,Valid,nil,Options);
end;
The code checks whether object is already present and just updates properties and leaves creation/destruction.
Hope the code is not too long.
Thank you,
Vojko Cendak
Offline