#1 2023-02-22 20:01:36

mdbs99
Member
From: Rio de Janeiro, Brazil
Registered: 2018-01-20
Posts: 139
Website

How split a TDocVariantData object into others but sharing data?

From a TDocVariantData object, I would like to split its properties into new instances.

For example, initiate a DocVariantData (dv for short) using this JSON:

{"obj:"{"id:1,"text":"blabla"}}

name = "obj"
value = {"id":1,"text":"blabla"}

I can iterate the dv using its enumerator:

var
  dv: TDocVariantData;
  pair: TDocVariantFields;
begin
  if dv.InitJson('{"obj:"{"id":1,"text":"blabla"}}', JSON_FAST_FLOAT) then
  begin
    for pair in dv do
    begin
      // here pair.Value^ will contain {"id:1,"text":"blabla"}
      // now, how can I create two new PDocVariantData objects...
      // 1 = {"id":1}
      // 2 = {"text":"blabla"}
      // ...but both sharing the same data from dv ?
    end;
  end;
end;

I haven't found any _Obj* function or TDocVariantData.Method to do that.

Maybe a new _ObjFast(PRawUtf8, PValue) or so could be create?

Thanks.

Last edited by mdbs99 (2023-02-22 20:03:33)

Offline

#2 2023-02-23 07:12:41

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

Re: How split a TDocVariantData object into others but sharing data?

I am not sure what "sharing the same data" means exactly.

You could use a new TDocVariantData with values as vtPointer, pointing to the variant values of the main dv.
But it may quickly be error prone (random GPF if the user does not take care of the instances lifetime), or un-shared for some kind of values (numbers are likely to be copied by value not by reference during copy).
And it would be one-way: only reflecting the changes in the main dv, not any change from the flattened objects.

Offline

#3 2023-02-23 10:31:11

mdbs99
Member
From: Rio de Janeiro, Brazil
Registered: 2018-01-20
Posts: 139
Website

Re: How split a TDocVariantData object into others but sharing data?

"sharing the same data" means that all (sub)objects will point to the same data of the main object.

Currently, I can do that using arrays, creating new objets for each index and those objects points to the main data.

For example, we can split an array of objects, creating new objects for each item, then changing any value on those subobjects it will change the main array data:

var
  vDoc: TDocVariantData;
  vIndex1: PDocVariantData;
begin
  vDoc.Clear;
  if vDoc.InitJson('[{"id":1,"text":"blabla"},{"id":2,"text":"toto"}]', JSON_FAST_FLOAT) then
  begin
    ShowMessage(vDoc.ToJson);
    vIndex1 := _Safe(vDoc.Value[1]);
    vIndex1^.S['text'] := 'new value'; // shared data; it will change both object
    ShowMessage(vDoc.ToJson);
    ShowMessage(vIndex1^.ToJson);
  end
  else
    ShowMessage('invalid json');
end;

Following the same idea, it would be nice if we could split an object, creating new objects for each property of the main one — but sharing the data, of course.

Offline

#4 2023-02-23 11:10:27

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

Re: How split a TDocVariantData object into others but sharing data?

vIndex1 points to vDoc.Value[1] as a direct pointer.
It does not share the data, it is just the same data.

If you want to create another TDocVariantData to hold the values, it won't be a direct pointer.
At most, it could be a vtPointer kind of variant.
Which is not the same: if you change the value in the 2nd TDocVariantData, it won't be reflected on the first/main TDocVariantData.

Offline

#5 2023-02-23 11:26:43

mdbs99
Member
From: Rio de Janeiro, Brazil
Registered: 2018-01-20
Posts: 139
Website

Re: How split a TDocVariantData object into others but sharing data?

ab wrote:

vIndex1 points to vDoc.Value[1] as a direct pointer.
It does not share the data, it is just the same data.

In this case, same data or sharing the data is the same to me. But, Ok, we're at the same page.

ab wrote:

If you want to create another TDocVariantData to hold the values, it won't be a direct pointer.
At most, it could be a vtPointer kind of variant.
Which is not the same: if you change the value in the 2nd TDocVariantData, it won't be reflected on the first/main TDocVariantData.

What doesn't work for me sad

Offline

Board footer

Powered by FluxBB