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

Comments

  1. New release with some bug fix and a new syntax for non-object types:

    old syntax

    d := Now();
    s :=toJSON(@d, TypeInfo(TDateTime));
    fromJSON(@d, TypeInfo(TDateTime), s);

    new syntax

    s := JSON.toJSON(Now());
    JSON.fromJSON(d, s);

    ReplyDelete
  2. Your GPL license make it only suitable for GPL projects, so it is a non go for most companies, good luck.

    ReplyDelete
  3. Cesar 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.

    ReplyDelete
  4. Imo the syntax should be:

    s := JSON.toJSON(Now());
    JSON.fromJSON(d, s);

    then you can omit the generic type parameter because of type inference:

    s := JSON.toJSON(Now);

    ReplyDelete
  5. Stefan Glienke great ! I didn't know about that ! 
    Code updated ;)

    ReplyDelete
  6. Execute.JSON in XE4: looks good!

    1) 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'

    ReplyDelete
  7. StrtToUInt64(Str) just use Val(Str, Result, E) :)

    about the 3rd point I don't know why type inference do not works...
    Stefan Glienke any idea ?

    ReplyDelete
  8. 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
  9. //in XE4 (FMX)

    a) 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.

    ReplyDelete
  10. Paul TOTH Please correct the typo in my name in your source code (also its with an f and not ph) ;)

    Also with a few modifications your code also works on XE.

    ReplyDelete
  11. Gustav Schubert this works just fine in XE5, don't have XE4 to test:

    program 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.

    ReplyDelete
  12. Stefan Glienke Yes, this works in XE4 as well, problem solved.


    (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.)

    ReplyDelete
  13. Stefan Glienke sorry for your name, I've mixed it with my brother Stephan and a bad keystroke ;)

    ReplyDelete
  14. Gustav Schubert Base64 was just a quick way to show how to change the encoding, it's not suitable for password protection anyway ;)

    ReplyDelete
  15. Paul TOTH  I know, but had to deal with things that are not "available" (in XE4).
    //  System.NetEncoding,
    //  REST.JSONReflect,
    The demo should hide these things in the "advanced" area. ;)

    ReplyDelete
  16. now that 8bit string question again :)

    I'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 ?

    ReplyDelete

Post a Comment