You are not logged in.
Pages: 1
Hello,
I am using Delphi 10.3.3, Synopse is updated from github. I double check that I am using latest version of SynCommons.pas
I have a simple json string (json array) that I fail to find why I cannot de-serialize. I simply fail to find a reason.
I do appreciate any help.
Record definition:
TStVATDetail = packed record
u32VAT: Integer;
u32Amount: Integer;
u16VATPercentage: UInt16;
end;
TStVATDetails = Array of TStVATDetail;
Json array that I cannot de-serialize:
[{"u32VAT":15,"u32Amount":100,"u16VATPercentage":1800},{"u32VAT":0,"u32Amount":0,"u16VATPercentage":0},{"u32VAT":0,"u32Amount":0,"u16VATPercentage":800},{"u32VAT":0,"u32Amount":0,"u16VATPercentage":100},{"u32VAT":0,"u32Amount":0,"u16VATPercentage":2400},{"u32VAT":0,"u32Amount":0,"u16VATPercentage":0},{"u32VAT":0,"u32Amount":0,"u16VATPercentage":0},{"u32VAT":0,"u32Amount":0,"u16VATPercentage":0}]
My code for de-serialization:
const
Json = '[{"u32VAT":15,"u32Amount":100,"u16VATPercentage":1800},{"u32VAT":0,"u32Amount":0,"u16VATPercentage":0},{"u32VAT":0,"u32Amount":0,"u16VATPercentage":800},{"u32VAT":0,"u32Amount":0,"u16VATPercentage":100},' +
'{"u32VAT":0,"u32Amount":0,"u16VATPercentage":2400},{"u32VAT":0,"u32Amount":0,"u16VATPercentage":0},{"u32VAT":0,"u32Amount":0,"u16VATPercentage":0},{"u32VAT":0,"u32Amount":0,"u16VATPercentage":0}]';
procedure TForm3.Button1Click(Sender: TObject);
var
Taxes: TStVATDetails;
begin
if not SynCommons.DynArrayLoadJSON(Taxes, RawUTF8(Json), TypeInfo(TStVATDetails)) then
begin
ShowMessage('Cannot deserialize Json!');
end
else
begin
ShowMessage('Json deserialization OK');
end;
end;
Offline
DynArrayLoadJSON modified JSON-buffer in-place when parsing.
You pass const string and function fails. Try:
var
Taxes: TStVATDetails;
S: RawUTF8;
begin
S:= Json;
if DynArrayLoadJSON(Taxes, UniqueRawUTF8(S), TypeInfo(TStVATDetails)) then...
end;
Offline
There is an overloaded version of DynArrayLoadJSON in SynCommons.pas. My code supposed to use it
function DynArrayLoadJSON(var Value; const JSON: RawUTF8; TypeInfo: pointer): boolean;
var tmp: TSynTempBuffer;
begin
tmp.Init(JSON); // make private copy before in-place decoding
try
result := DynArrayLoadJSON(Value,tmp.buf,TypeInfo)<>nil;
finally
tmp.Done;
end;
end;
Offline
Delphi does not create RTTI information for records without managed fields (like String, Variant, Array, Interface).
So there are 3 option:
1. Add managed field
2. Use text-based definition https://synopse.info/files/html/Synopse … #TITLE_242
3. Use custom serialization
Offline
I do not know details of RTTI. However, below code works for the first one and not for the second one. I do get "json2 OK" displayed on the screen. That is without using any of suggested 3 options above.
const
Json = '[{"u32VAT":15,"u32Amount":100,"u16VATPercentage":1800},{"u32VAT":0,"u32Amount":0,"u16VATPercentage":0},{"u32VAT":0,"u32Amount":0,"u16VATPercentage":800},{"u32VAT":0,"u32Amount":0,"u16VATPercentage":100},' +
'{"u32VAT":0,"u32Amount":0,"u16VATPercentage":2400},{"u32VAT":0,"u32Amount":0,"u16VATPercentage":0},{"u32VAT":0,"u32Amount":0,"u16VATPercentage":0},{"u32VAT":0,"u32Amount":0,"u16VATPercentage":0}]';
Json2 = '{"u32VAT":15,"u32Amount":100,"u16VATPercentage":1800}';
procedure TForm3.Button1Click(Sender: TObject);
var
Taxes: TStVATDetails;
Tax: TStVATDetail;
begin
if SynCommons.RecordLoadJSON(Tax, RawUTF8(Json2), TypeInfo(TStVATDetail)) then
ShowMessage('json2 OK')
else
ShowMessage('json2 failed');
if not SynCommons.DynArrayLoadJSON(Taxes, RawUTF8(Json), TypeInfo(TStVATDetails)) then
begin
ShowMessage('Cannot deserialize Json!');
end
else
begin
ShowMessage('Json deserialization OK');
end;
end;
Offline
Type TStVATDetail has type information, but TStVATDetails does not, because compiler not needed for it - no managed fields in record, so compiler might simply free memory used for array.
Try change your record:
TStVATDetail = packed record
u32VAT: Integer;
u32Amount: Integer;
u16VATPercentage: UInt16;
s: String;
end;
And you will see that code now works.
Offline
That did indeed work.
Offline
Pages: 1