I've just released a JSON unit for Delphi XE8. It's based only on TypeInfo and let you convert any TypeInfo to a JSON notation or assign a JSON string to any TypeInfo:
I've just released a JSON unit for Delphi XE8. It's based only on TypeInfo and let you convert any TypeInfo to a JSON notation or assign a JSON string to any TypeInfo:
s := MyObject.toJSON();
MyObject.fromJSON(s);
s := ToJSON(@MaVar, TypeInfo(TMyType));
d := Now();
s := ToJSON(@d, TypeInfo(TDateTime)); // '2015-08-09T02:51:32'
FromJSON(@s, TypeInfo(string), '"JSON String"');
Source code is released under GPL
It's time to learn french ... or to download the english demo at the bottom of the page ;)
http://lookinside.free.fr/delphi.php?Delphi+XE8+et+JSON
http://lookinside.free.fr/delphi.php?Delphi+XE8+et+JSON
s := MyObject.toJSON();
MyObject.fromJSON(s);
s := ToJSON(@MaVar, TypeInfo(TMyType));
d := Now();
s := ToJSON(@d, TypeInfo(TDateTime)); // '2015-08-09T02:51:32'
FromJSON(@s, TypeInfo(string), '"JSON String"');
Source code is released under GPL
It's time to learn french ... or to download the english demo at the bottom of the page ;)
http://lookinside.free.fr/delphi.php?Delphi+XE8+et+JSON
http://lookinside.free.fr/delphi.php?Delphi+XE8+et+JSON
New release with some bug fix and a new syntax for non-object types:
ReplyDeleteold syntax
d := Now();
s :=toJSON(@d, TypeInfo(TDateTime));
fromJSON(@d, TypeInfo(TDateTime), s);
new syntax
s := JSON.toJSON(Now());
JSON.fromJSON(d, s);
Your GPL license make it only suitable for GPL projects, so it is a non go for most companies, good luck.
ReplyDeleteCesar Romero the code is protected by GPL, you can read and try it as you wish... and as the author of the code I can sell a private usage licence if required.
ReplyDeleteImo the syntax should be:
ReplyDeletes := JSON.toJSON(Now());
JSON.fromJSON(d, s);
then you can omit the generic type parameter because of type inference:
s := JSON.toJSON(Now);
Stefan Glienke great ! I didn't know about that !
ReplyDeleteCode updated ;)
Execute.JSON in XE4: looks good!
ReplyDelete1) TFormatSettings.Invariant not available
initialization
//JSONFormat := TFormatSettings.Invariant;
JSONFormat.DecimalSeparator := '.';
2) StrToUInt64 not available
//if TypeData.MinInt64Value = 0 then
// UInt64(Instance^) := StrToUInt64(Parser.GetNumber)
//else
Int64(Instance^) := StrToInt64(Parser.GetNumber);
Any better "substitution"?
3) keep syntax version 1 for XE4?
s := toJSON(@r, TypeInfo(TSimpleRecord)); //ok
s := JSON.toJSON(r); //fails with
E2010 Inkompatible Typen: 'TSimpleRecord' und 'Pointer'
StrtToUInt64(Str) just use Val(Str, Result, E) :)
ReplyDeleteabout the 3rd point I don't know why type inference do not works...
Stefan Glienke any idea ?
There is no type inference in 3) as you explicitly defined the type. So r should be of type TSimpleRecord and it should work. There is another error in that code - post the complete code.
ReplyDelete//in XE4 (FMX)
ReplyDeletea) If I do not reference unit System.TypInfo I get a hint:
[dcc32 Hinweis] uDemo9.pas(49): H2443 Inline-Funktion 'JSON.toJSON' wurde nicht expandiert, weil Unit 'System.TypInfo' in der USES-Liste nicht angegeben ist
b) If I add System.TypInfo to the uses clause the I get the Error:
[dcc32 Fehler] uDemo9.pas(47): E2010 Inkompatible Typen: 'TSimpleRecord' und 'Pointer'
c) But no Error if TSimpleRecord has only one field.
(The test code is very similar to Paul's Demo2, and I have kept old and new call style in Execute.JSON.)
unit uDemo9;
Interface
type
TSimpleObject = class
Name : string;
Bonus: string;
end;
TSimpleRecord = record
Name : string;
Bonus: string;
end;
procedure Demo9;
implementation
uses
System.TypInfo,
Execute.Json;
procedure Demo9;
var
o: TSimpleObject;
r: TSimpleRecord;
s: string;
begin
o := TSimpleObject.Create;
try
o.Name := 'Name';
// o.Bonus := 'Bonus';
s := o.toJSON(); //old ok
s := JSON.toJSON(o); //new ok
finally
o.Free;
end;
JSON.fromJSON(r, s);
s := toJSON(@r, TypeInfo(TSimpleRecord)); //old ok
s := JSON.toJSON(r);//new Error E2010
end;
end.
Paul TOTH Please correct the typo in my name in your source code (also its with an f and not ph) ;)
ReplyDeleteAlso with a few modifications your code also works on XE.
Gustav Schubert this works just fine in XE5, don't have XE4 to test:
ReplyDeleteprogram Project1;
{$APPTYPE CONSOLE}
uses
TypInfo,
Execute.JSON;
type
TSimpleRecord = record
Name : string;
Bonus: string;
end;
procedure Main;
var
r: TSimpleRecord;
s: string;
begin
r.Name := 'nametext';
r.Bonus := 'bonustext';
s := JSON.toJSON(r);
Writeln(s);
end;
begin
Main;
Readln;
end.
Stefan Glienke Yes, this works in XE4 as well, problem solved.
ReplyDelete(So far I have found that Execute.JSON can be used in XE4. The demo could be streamlined. I have put all "demo sections" into their own unit. And my main form only has some buttons and one TMemo. Base64 needs to be done differently in XE4, and should be more easy to skip in older versions.)
Stefan Glienke sorry for your name, I've mixed it with my brother Stephan and a bad keystroke ;)
ReplyDeleteGustav Schubert Base64 was just a quick way to show how to change the encoding, it's not suitable for password protection anyway ;)
ReplyDeletePaul TOTH I know, but had to deal with things that are not "available" (in XE4).
ReplyDelete// System.NetEncoding,
// REST.JSONReflect,
The demo should hide these things in the "advanced" area. ;)
now that 8bit string question again :)
ReplyDeleteI'm happy with my JSON unit, but I save the JSON data with Encoding.UTF8.GetBytes(toJSON)...so I guess, shouldn't I make the UTF8 encoding while building the JSON Data, or still using a StringBuilder with a conversion at the very last moment (wasting a lot of memory) ?
for Desktop application I could use UTF8String, but to be mobile compliant I have to fall down on TBytes, and I don't like that.
Any suggestion ?