#1 2019-07-16 21:30:19

Vitaly
Member
From: UAE
Registered: 2017-01-31
Posts: 168
Website

JSONToObject for object with dynamic array of double

I've faced some problem with deserialization JSON, which has a dynamic array of floating-point values inside one of the json-objects.
My JSON has a very complicated structure, but I'll provide here a simple example, showing my trouble.

  TJSONArrayOfFloat = array of double;

  TJSONObjectWithArray = class(TSynPersistent)
  private
    FArrayOfFloat: TJSONArrayOfFloat;
  published
    property ArrayOfFloat: TJSONArrayOfFloat read FArrayOfFloat;
  end;

...

procedure TForm1.FormShow(Sender: TObject);
var
  i: integer;
  LJSON: RawUTF8;
  LObject: TJSONObjectWithArray;
  LDeserResult: boolean;
  LResult: string;
begin
  LJSON := StringToUTF8
    ('{"arrayoffloat": [10.387747, 59.377930, 11.388159, 69.377976, 12.388261, 79.377988]}');
  LObject := TJSONObjectWithArray.Create;
  JSONToObject(LObject, pointer(LJSON), LDeserResult);
  if LDeserResult then
  begin
    LResult := 'Array: ';
    for i := 0 to High(LObject.ArrayOfFloat) do
      LResult := LResult + '   ' + FloatToStr(LObject.ArrayOfFloat[i]);
  end
  else
    LResult := 'Deserialization error!';
  FreeAndNil(LObject);
  Memo1.Text := LResult;
end;

The result values are nearby 0:

Array:    4,94065645841247E-323   2,91498731046335E-322   5,43472210425371E-323   3,4090529563046E-322   5,92878775009496E-323   3,90311860214585E-322

The same result I get with type single (with lower precision).

But if I use integer dynamic array JSONToObject works fine:

  TJSONArrayOfFloat = array of integer;
Array:    10   59   11   69   12   79

Delphi 10.3.1 64. Also checked this code with FPC but no luck.

Offline

#2 2019-07-17 13:41:21

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

Re: JSONToObject for object with dynamic array of double

What is the LObject content?

Offline

#3 2019-07-17 14:14:00

Vitaly
Member
From: UAE
Registered: 2017-01-31
Posts: 168
Website

Re: JSONToObject for object with dynamic array of double

ab wrote:

What is the LObject content?

LObject is just:

LObject := TJSONObjectWithArray.Create;

The class is:

  TJSONObjectWithArray = class(TSynPersistent)
  private
    FArrayOfFloat: TJSONArrayOfFloat;
  published
    property ArrayOfFloat: TJSONArrayOfFloat read FArrayOfFloat;
  end;

Or maybe I misunderstood your question... Can you specify, please, what do you mean?

Offline

#4 2019-07-17 15:36:12

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

Re: JSONToObject for object with dynamic array of double

What is LObject content, i.e. what is LObject.ArrayOfFloat content after JSONToObject() deserialization - use the debugger.

Offline

#5 2019-07-17 15:45:21

Vitaly
Member
From: UAE
Registered: 2017-01-31
Posts: 168
Website

Re: JSONToObject for object with dynamic array of double

ah, thanks, it is pretty much the same as printed in LResult:

((4,94065645841247e-323, 2,91498731046335e-322, 5,43472210425371e-323, 3,4090529563046e-322, 5,92878775009496e-323, 3,90311860214585e-322))

couldn't find ability to post a screen - the value of LObject is copied from local variables watch list

Last edited by Vitaly (2019-07-17 15:48:02)

Offline

#6 2019-07-17 16:52:16

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

Re: JSONToObject for object with dynamic array of double

OK the problem is in TDynArray.ToKnownType.
It recognizes only exact types, like TDoubleDynArray.
So your TJSONArrayOfFloat is not recognized, then the value is handled as an array of integers (djInt64), resulting in the wrong values.

In order to have proper serialization, you need to use a TDoubleDynArray published property...

I can't find something more versatile, since the RTTI doesn't store any type information within TypeInfo(TJSONArrayOfFloat) for its elements. sad

Offline

#7 2019-07-17 17:04:47

Vitaly
Member
From: UAE
Registered: 2017-01-31
Posts: 168
Website

Re: JSONToObject for object with dynamic array of double

Oh, that's fine! TDoubleDynArray works totally good for me, thank you! smile

Offline

Board footer

Powered by FluxBB