You are not logged in.
Pages: 1
There is a code:
type
TLatLon = packed record
Lat, Lon: Double;
end;
TLatLonArr = array of TLatLon;
TLatLon1 = packed record
Lat, Lon: Double;
s: RawUTF8;
end;
TLatLonArr1 = array of TLatLon1;
...
procedure TForm1.Button1Click(Sender: TObject);
var
a: TLatLonArr;
a1: TLatLonArr1;
i: Integer;
begin
SetLength(a, 5);
SetLength(a1, 5);
for i := 0 to 4 do
begin
a[i].Lat := i;
a[i].Lon := i;
a1[i].Lat := i;
a1[i].Lon := i;
end;
Memo1.Lines.Add(SaveJSON(a, TypeInfo(TLatLonArr)));
Memo1.Lines.Add(SaveJSON(a1, TypeInfo(TLatLonArr1)));
end;
Tell me why
SaveJSON(a, TypeInfo(TLatLonArr)) returns something like ["EAAFAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADwPwAAAAAAAPA/AAAAAAAAAEAAAAAAAAAAQAAAAAAAAAhAAAAAAAAACEAAAAAAAAAQQAAAAAAAABBA"]
But
SaveJSON(a1, TypeInfo(TLatLonArr1)) returns [{"Lat":0,"Lon":0,"s":""},{"Lat":1,"Lon":1,"s":""},{"Lat":2,"Lon":2,"s":""},{"Lat":3,"Lon":3,"s":""},{"Lat":4,"Lon":4,"s":""}]
The difference is
s: RawUTF8;
Tested in Delphi XE2
By the way custom serialization doesn't work too:
TTLatLonArrSerializer = class
class function ShortReader(P: PUTF8Char; var aValue; out aValid: Boolean): PUTF8Char;
class procedure ShortWriter(const aWriter: TTextWriter; const aValue);
end;
implementation
{ TTLatLonArrSerializer }
class function TTLatLonArrSerializer.ShortReader(P: PUTF8Char; var aValue; out aValid: Boolean): PUTF8Char;
var
V: TLatLon absolute aValue;
begin
aValid := false;
result := nil;
if (P=nil) or (P^<>'[') then
exit;
inc(P);
V.Lat := GetNextItemDouble(P);
V.Lon := GetNextItemDouble(P);
if P=nil then
exit;
aValid := true;
result := P;
end;
class procedure TTLatLonArrSerializer.ShortWriter(const aWriter: TTextWriter; const aValue);
var
V: TLatLon absolute aValue;
begin
aWriter.Add('["%","%"]', [V.Lat, V.Lon], twJSONEscape);
end;
initialization
TTextWriter.RegisterCustomJSONSerializer(TypeInfo(TLatLon),
TTLatLonArrSerializer.ShortReader, TTLatLonArrSerializer.ShortWriter);
end.
Offline
OK.
Good explanation, but why SaveJSON(a[0], TypeInfo(TLatLon)) returns {"Lat":0,"Lon":0} ?
And why does not custom serialization work?
I apologize for boring, but is it the final diagnosis? It is tempting to use the arrays of records without string fields.
Just curious.
Offline
Thanks for answer, but I tried to dig by myself and found something interesting:
SynCommons (line:41326)
fElemType := PTypeInfo(aTypeInfo)^.elType;
I inspected PTypeInfo(aTypeInfo)^ , it has properties
elType = nil
and
elType2 = $62CA90
When I modified
fElemType := PTypeInfo(aTypeInfo)^.elType2;
I have got the result = [{"Lat":0,"Lon":0},{"Lat":1,"Lon":1},{"Lat":2,"Lon":2},{"Lat":3,"Lon":3},{"Lat":4,"Lon":4}]
SynCommons (line:18870)
// also unmanaged field
elType2: PTypeInfoStored;
May be should be used elType2 for unmanaged fields, or at least in the case when elType = nil. Will it be correct?
Offline
This was as designed, to have the same serialization behavior with compilers prior to Delphi 2010, and with FPC.
Your modification would change the behavior, and break other features (like T*ObjArray support).
Offline
Ok. It seems like I have to follow your proposition to use text definition.
Thanks a lot.
Offline
Pages: 1