Skip to content

Request: binary serialization/deserialization #358

Closed

Description

@CyberBrainX

Wouldn’t it be useful to have the possibility to serialize the json object to a more compact form?
This would make sense for storing the container or sending it over an internet connection.

The MessagePack (http://msgpack.org/) format or some proprietary format directly derived from your internal representation would be fine.
Or could you probably just provide some generic interface for the binary serialization/deserialization?

I think this approach could be more useable than just gzipping the whole JSON data.

As an example this library did implement some alternative representations of a json container: http://greatpanic.com/progdocs/UniversalContainer.html
(But this library doesn’t work properly and doesn’t use C++ 11)

Activity

  1. nlohmann commented on Nov 9, 2016

    @nlohmann
    Owner

    I also had a look at MessagePack, and it seems to be a reasonable approach. As it can express more than JSON, I hope that users would understand that the library would not be able to parse arbitrary MessagePack input.

  2. self-assigned this
    on Nov 11, 2016
  3. nlohmann commented on Nov 11, 2016

    @nlohmann
    Owner

    I started to implement MessagePack. Commit 543745a contains a basic serializer/deserializer for JSON values as static functions. It works with a std::vector<uint8_t> and currently has no diagnosis information in case of a parse error.

    Feedback would be greatly appreciated:

    • naming of the functions
    • static function vs. member function vs. free function
    • move implementation outside the main header?
    • organization of the functions (I am thinking of reorganizing the large if in the parser, maybe using re2c)
    • improvements of the low-level shifting/conversion stuff
    • byte vector vs. containers vs. ???
  4. CyberBrainX commented on Nov 14, 2016

    @CyberBrainX
    Author

    Wow, I couldn’t believe how fast you did implement a first version. And it seems to be working!
    I think it’s a great benefit being able to exchange data with the MessagePack world. Except binary data, but binary data and JSON is a bad match anyway (base 64 encoding).

    I did test the space savings in some of my use cases and got the following results.
    In simple cases (small data set) with almost no numeric data the saving was 12% over the compacted JSON file. Zipping alone showed a 15% reduction. First converting to msgpack and zipping the result gave a 19% reduction. As expected, with more numeric data the compression rate did grow constantly. Nice!

    1. The naming to_msgpack and from_msgpack makes sense and is future save if you like to add more serializers/deserializers.
    2. I prefer the static function. It’s the right context and can be still used in a flexible way.
    3. At the moment it doesn’t hurt to have just one header. It’s just more convenient.
    4. I’am not sure if re2c would be necessary in the parsing part. A hand crafted parser could be faster (the same is true for the json part - rapid json). Using a switch statement (for the fixed values) or a jump table could possibly speed up parsing of the MessagePack data(needs some tests to be verified).
    5. The low-level shifting/conversion stuff could be improved but the code will get more complicated (dealing with endianness).
    6. A byte vector is fine. It has some nice properties. A lot of frameworks have chosen byte vectors for handling serialized data.

    Thank you for your great JSON implementation!

  5. added this to the Release 2.0.8 milestone on Nov 15, 2016
  6. user1095108 commented on Nov 17, 2016

    @user1095108

    I beg to differ. MsgPack is not standardized, whereas CBOR, for example, is. There are a myriad of binary data formats out there, but, for better or worse, CBOR is standardized in RFC 7049, whereas MsgPack is not.

  7. marton78 commented on Nov 21, 2016

    @marton78

    +1 for CBOR!

  8. nlohmann commented on Nov 23, 2016

    @nlohmann
    Owner

    I shall have a look at CBOR.

  9. removed this from the Release 2.0.8 milestone on Nov 23, 2016
  10. CyberBrainX commented on Nov 25, 2016

    @CyberBrainX
    Author

    Ok, standards are great, I like them. CBOR is a PROPOSED standard and could still get changed. The proposal has some nice properties and it seems to be an improved MessagePack protocol. Unfortunately it’s not widely adopted and there are a lot of poor implementations. There’s no modern C++ 11 implementation and the old style C++ implementation is looking more like C code.

  11. 20 remaining items

  12. TurpentineDistillery commented on Dec 2, 2016

    @TurpentineDistillery

    A big benefit of having one file with declarations and one-or-many files with definitions is that it would allow for explicit template instantiation, so that the compilation overhead related to json.hpp can be factored out into a separate translation unit.

  13. added this to the Release 2.0.9 milestone on Dec 2, 2016
  14. nlohmann commented on Dec 10, 2016

    @nlohmann
    Owner

    I am currently cleaning up and bringing the test coverage to 100%. I hope to release CBOR/MessagePack by next week.

  15. nlohmann commented on Dec 11, 2016

    @nlohmann
    Owner

    Merged e906933.

  16. marton78 commented on Dec 11, 2016

    @marton78

    Hi @nlohmann, great job! I have looked at your code, some remarks:

    • When converting single / double, you have reimplemented memcpy. Why don't you just use it? (or std::copy, would be actually even nicer).
    • you could #define all those magic numbers (or put them in an enum)
    • msgpack / cbor are so similar that a lot of code is duplicated. probably you could template those conversions based on serialization format (so, two structs: msgpack and cbor, both of which contain all magic numbers, limits for the integers to fit in the first byte and the conversion functions from small integer to one byte)

    All in all very nice job, thanks!

  17. nlohmann commented on Dec 11, 2016

    @nlohmann
    Owner

    @marton78 Thanks for the feedback.

    • Regarding memcpy: I need to have another look.
    • Regarding the magic numbers / reduce code duplication: There are in fact a lot of similarities between CBOR and MessagePack, but I doubt that creating a configurable super type from which both formats inherit makes the code much more readable. I may play around with it, but right now I'd rather focus on writing down the limitations of the implementations (i.e., which types are not supported).
  18. nlohmann commented on Dec 14, 2016

    @nlohmann
    Owner

    @marton78 Sorry, but I can't find the spot where I can use memcpy/std::copy.

  19. TurpentineDistillery commented on Dec 15, 2016

    @TurpentineDistillery

    Maybe it's this part?

                case value_t::number_float:
                {
                    // Double-Precision Float
                    v.push_back(0xfb);
                    const uint8_t* helper = reinterpret_cast<const uint8_t*>(&(j.m_value.number_float));
                    for (size_t i = 0; i < 8; ++i)
                    {
                        v.push_back(helper[7 - i]);
                    }
                    break;
                }

    Also, if this part of code expects the number_float_t to be double, a static_assert would be appropriate?

  20. marton78 commented on Dec 15, 2016

    @marton78

    Yes, it's this part, std::copy_backward could be used here instead of memcpy though, since copying is done in reverse.

  21. TurpentineDistillery commented on Dec 15, 2016

    @TurpentineDistillery

    This looks like the endianness handling business?
    If so, it can't be assumed that the host platform is little-endian. The ntoh and hton family functions are there to take the host endianness into account and reverse the bytes efficiently as appropriate, but these are not portable. It looks like boost endian library also does this and compiles to efficient byte-swapping instructions too (not saying we should add boost dependency).

  22. user1095108 commented on Dec 15, 2016

    @user1095108

    Lol definetly not, look at my swap file to get some ideas:

    https://github.com/user1095108/generic/blob/master/swap.hpp

  23. nlohmann commented on Dec 16, 2016

    @nlohmann
    Owner

    FYI: I asked to advertize the latest release on the CBOR (cbor/cbor.github.io#25) and MessagePack (msgpack/msgpack#221) website.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Projects

No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions