#1 2020-01-04 16:48:58

VojkoCendak
Member
From: Celje Slovenia
Registered: 2012-09-02
Posts: 88

neste object auto creation problem in interfaced service

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

Board footer

Powered by FluxBB