Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Avoid constructing the JSON tree #1

Open
briot opened this issue Oct 27, 2017 · 0 comments
Open

Avoid constructing the JSON tree #1

briot opened this issue Oct 27, 2017 · 0 comments

Comments

@briot
Copy link

briot commented Oct 27, 2017

Hi Per,
I feel bad because I never had time to integrate your proposal in GNATCOLL... At my new job, we also had a need to build JSON strings on the fly. But I found that having to build a full tree in memory (via GNATCOLL.JSON) and then write it to a string is slow. It is much more efficient to build the string on the fly (in particular in the context of a web server we could directly start returning the string as it is built, reducing the memory usage of the server). Here's an example of usage of our package

 procedure Encode (Bytes : in out XString; C : Char_Type) is
 begin
    Bytes.Append (Character'Val (Char_Type'Pos (C)));
 end Encode;

 --  This package configures what kind of strings can be encoded to JSON.
 --  We can decide whether to support wide character sets or not,...
 package Basic_Streams is new JSON_Streams (GNATCOLL.Strings);

 --  base package to output a JSON object, array and simple type to our
 --  output type (a string, in our case, as per the profile of Encode).
 package Strings is new Basic_Streams.String_Encoders (Encode);

 --  higher-level package to create objects,... using the low-level package.
 --  This is always the same whether we output to a string, a stream, a tree,...
 package Stream_To_String is new Basic_Streams.Streams (Strings.Traits);

 declare
    S   : aliased Strings.Encoder := Strings.Create;
 begin
    declare
       use Stream_To_String;
       JS  : aliased JSON_Stream (S'Access);

       --  An object is declared on the stack. When it is finalized, it automatically
       --  closes itself in the output stream
       Obj : JSON_Object := Create (JS);
    begin
       Obj.Add ("Key", "Value");
       Obj.Add ("Key2", True);

       declare
          A : JSON_Object := Obj.Add ("Key3");
       begin
          A.Add (2);
       end;
    end;

    --  JS has been finalized, so S is now well formed
    --  You can also call Close explicitly instead.
    Strings.Encode (S, Ada.Text_IO.Put_Line'Access);
 end;

Let me know if you are interested, we could maybe make a pull request for GNATCOLL. Your packages could easily be built on top of this package.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant