#1 2016-11-29 20:56:47

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

JSONtoObject disable creation of published objects

Hi,

We have an published property  that is actually TCollectionItem and internally created. In delphi's object inspector it is normally visible
and streamable ...

1. problem with code in :   

function TPropInfo.ClassFromJSON
...
if SetProc<>0  then begin
    // it is a setter method -> create a temporary object
    tmp := PropType^.ClassCreate;  // it doesn't create TCollectionItem class

2. Is it possible to just set properties  without creating published objects ?

Thank you and all the best,
Vojko Cenda

Offline

#2 2016-11-30 08:19:20

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,182
Website

Re: JSONtoObject disable creation of published objects

It is not clear to me how it may be possible "to just set properties  without creating published objects", by the way...
I've added a new j2oSetterNoCreate option for JSONToObject() process. Is it what you expected?
See http://synopse.info/fossil/info/4bf51eadac

Offline

#3 2016-12-02 14:58:22

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

Re: JSONtoObject disable creation of published objects

I've change the function so that the streamer checks whether the property has object. If it does it just write properties
and it doesn't free the object even if j2oSetterExpectsToFreeTempInstance is present.

function TPropInfo.ClassFromJSON(Instance: TObject; From: PUTF8Char;
  var Valid: boolean; Options: TJSONToObjectOptions): PUTF8Char;
var Field: ^TObject;
    tmp: TObject;
    origobj: Boolean;  // internal object
begin
  valid := false;
  origobj := False; // assume nil
  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 (SetProc<>0) and not (j2oSetterNoCreate in Options)  then begin
    // it is a setter method -> create a temporary object
    tmp := GetObjProp(Instance);  // get property object
    if tmp=nil then // nil
      tmp := PropType^.ClassCreate
    else            
      origobj := True; // flag it is already present
    try
      result := JSONToObject(tmp,From,Valid,nil,Options);
      if not Valid then
        if not origobj then FreeAndNil(tmp) else begin     // free only if not internal
        SetOrdProp(Instance,PtrInt(tmp)); // PtrInt(tmp) is OK for CPU64
        if (not origobj) and (j2oSetterExpectsToFreeTempInstance in Options) then  // free only if not internal
          FreeAndNil(tmp);
      end;
    except
      on e:Exception do
        if (not origobj) then tmp.Free;  // free only if not internal
    end;
    exit;
  end else
  {$endif}
  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;

thank you

Offline

Board footer

Powered by FluxBB