Icon View Thread

The following is the text of the current message along with any replies.
Messages 1 to 5 of 5 total
Thread TPersistent Array Property Saves
Mon, Jun 12 2017 10:12 AMPermanent Link

Mark Brooks

Slikware

Avatar

Probably one for Tim:

I am familiar with having to override LoadProperty and LoadArrayElement for descendants of TPersistent that contain array properties. I understand this is to do with internal storage allocation for the array elements.

Is the same true for SaveProperty and SaveArrayElement? It would seem so? Can you please provide an example of how to do this e.g. determining which element to save within the SaveArrayElement override? It doesn't seem as simply as merely "inverting" the Load logic.

Thanks
Mark
Mon, Jun 12 2017 10:47 AMPermanent Link

Matthew Jones

Mark Brooks wrote:

> Probably one for Tim:
>
> I am familiar with having to override LoadProperty and LoadArrayElement for descendants of TPersistent that contain array properties. I understand this is to do with internal storage allocation for the array elements.
>
> Is the same true for SaveProperty and SaveArrayElement? It would seem so? Can you please provide an example of how to do this e.g. determining which element to save within the SaveArrayElement override? It doesn't seem as simply as merely "inverting" the Load logic.

I think my code was taken from examples in the library or here, but this is my code to save an object that contains a list.


procedure TJSONList.ObjectListToJSON(xWriter : TWriter);
var
   nWriteLoop : Integer;
   xItem : TPersistent;
begin
   xWriter.BeginObject;
   inherited SaveProperties(xWriter);
   xWriter.PropertyName(JSONArrayName);
   xWriter.BeginArray(m_xList.Count > 0); // hasElements param controls the output of spaces

   for nWriteLoop := 0 to m_xList.Count - 1 do
   begin
       if not m_xList.Objects[nWriteLoop] is TPersistent then
           raise Exception.Create('Object in list is not persistent');
       xItem := TPersistent(m_xList.Objects[nWriteLoop]);
       xItem.Save(xWriter);
       if nWriteLoop < m_xList.Count - 1 then
           xWriter.Separator;
   end;
   xWriter.EndArray(m_xList.Count > 0); // hasElements param controls the output of spaces
   xWriter.EndObject;
end;


procedure TJSONList.GetJSONInternal(xWriter : TWriter); // override this to add any other properties in your list
begin
   ObjectListToJSON(xWriter);
end;



function TJSONList.GetJSON : String;
var               
   xWriter : TWriter;
begin
   xWriter := TWriter.Create(dtfISO8601);
         
   xWriter.Initialize;

   GetJSONInternal(xWriter);

   Result := xWriter.Output;

   xWriter.Free;
end;

--

Matthew Jones
Mon, Jun 12 2017 1:42 PMPermanent Link

Mark Brooks

Slikware

Avatar

Thanks Mathew

My method is slightly different in that my classes inherit from TPersistent. I have used them successfully to consume JSON from a variety of REST APIs. When consuming JSON that contains arrays I have always overridden LoadProperty and LoadArrayElement per Tim's prior instructions. This allows me to control allocation of the array element storage. My question relates to the opposite i.e. sending back a JSON representation of a class that contains array properties, where that class descends from TPersistent and just needs (I believe) to do something a bit special for the array bits. At the moment they appear to be skipped by the inherent TPersistent mechanism.
Mon, Jun 12 2017 2:41 PMPermanent Link

Matthew Jones

<Mark Brooks> wrote:
> Thanks Mathew
>
> My method is slightly different in that my classes inherit from
> TPersistent. I have used them successfully to consume JSON from a variety
> of REST APIs. When consuming JSON that contains arrays I have always
> overridden LoadProperty and LoadArrayElement per Tim's prior
> instructions. This allows me to control allocation of the array element
> storage. My question relates to the opposite i.e. sending back a JSON
> representation of a class that contains array properties, where that
> class descends from TPersistent and just needs (I believe) to do
> something a bit special for the array bits. At the moment they appear to
> be skipped by the inherent TPersistent mechanism.
>
>

Mine are TPersistent too. The code does what you want. If you have a writer
already you can of course skip that bit. Dig into the TPersistent source to
understand it.

--
Matthew Jones
Tue, Jun 13 2017 8:42 AMPermanent Link

Matthew Jones

Matthew Jones wrote:

> Mine are TPersistent too. The code does what you want. If you have a writer
> already you can of course skip that bit. Dig into the TPersistent source to
> understand it.

IIRC, the functions can be overridden - looking again at my desk that isn't one of the "native" overrides. Look at TPersistent, and you can see the function to override. Probably SaveProperties as I call that inherited. The content of the function is right though.

--

Matthew Jones
Image