nlohmann/json

repository·master·Indexed 20 days ago

https://github.com/shinyquagsire23/openjkdf2

A JSON library for modern C++ (C++11) distributed as a single header file (json.hpp). It features intuitive syntax using operator overloading, STL-like container methods, and support for serialization/deserialization to strings, streams, and binary formats including BSON, CBOR, MessagePack, and UBJSON. The library supports JSON Pointer (RFC 6901) and JSON Patch (RFC 6902), and provides a SAX interface for high-performance parsing.

Tokens
114.4K
Snippets
371
Records
551
Agent score
70%

What's inside nlohmann_json

  1. Overview of JSON for Modern C++ API

    master

    JSON for Modern C++ is a C++11 header-only library. The primary interface is the nlohmann::json class, which is a specialization of the nlohmann::basic_json template.

    Key functional areas include:

    • Object Inspection: Checking types (e.g., is_number(), is_array()) and serializing values.
    • Value Access: Retrieving values via get<T>(), value(), or implicit conversions.
    • Serialization/Deserialization: Parsing from strings or streams using parse() and serializing to strings via dump().
    • Binary Formats: Support for CBOR, MessagePack, UBJSON, and BSON.
    • JSON Standards: Support for JSON Pointer (RFC 6901), JSON Patch (RFC 6902), and JSON Merge Patch (RFC 7396).
  2. Understand the design goals of JSON for Modern C++

    master

    The library focuses on three primary goals:

    1. Intuitive syntax: Uses C++ operator overloading to make JSON feel like a first-class data type, similar to Python.
    2. Trivial integration: Distributed as a single header file (json.hpp) with no dependencies.
    3. Serious testing: Features 100% code coverage, memory leak checks via Valgrind/Clang Sanitizers, and continuous fuzz testing via Google OSS-Fuzz.

    Note on performance: While there are faster libraries available, this library prioritizes development speed and ease of use. It uses standard C++ types by default (std::string for strings, int64_t/uint64_t/double for numbers, std::map for objects, std::vector for arrays, and bool for Booleans), though these can be customized by templating the basic_json class.

  3. View OpenJKDF2 current progress and decompiled functions

    master

    The project tracks its progress by the percentage of decompiled functions within various subsystems. The progress is measured both by text weight and by the count of functions successfully decompiled.

    Key subsystems include:

    • sith: Core logic/engine components.
    • std: Standard library/utility components.
    • jkGui: Graphical User Interface components.
    • rd: Rendering/math components.
    • jk: Core game components.
    • Raster: The rasterizer subsystem (which accounts for a significant portion of the remaining work).

    Note: Filenames in the progress report may be inaccurate or incomplete. For a complete listing of function names, refer to ida_copypaste_funclist_nostdlib.txt.

  4. Understand the JSON library design goals

    master

    The library prioritizes developer experience and reliability over raw performance metrics. Key design principles include:

    • Intuitive syntax: Uses C++ operator overloading to make JSON manipulation feel like a first-class data type (similar to Python).
    • Trivial integration: Single-header distribution (json.hpp) with no dependencies.
    • Serious testing: High test coverage (100%), memory leak verification via Valgrind/Clang Sanitizers, and continuous fuzz testing via Google OSS-Fuzz.

    Note on performance: While not optimized for maximum memory efficiency or absolute parsing speed compared to specialized libraries, it is optimized for development speed and ease of use. You can customize the underlying data types by templating the basic_json class.

  5. Supported Binary JSON Formats

    master

    To improve data exchange efficiency over networks, the library provides support for several binary formats that encode JSON values into byte vectors. You can choose between the following formats depending on your requirements for completeness, binary data support, and payload size:

    • BJData (Binary JData)
    • BSON (Binary JSON)
    • CBOR (Concise Binary Object Representation)
    • MessagePack
    • UBJSON (Universal Binary JSON)
  6. Related Projects and Sister Repositories

    master

    OpenJKDF2 is part of a broader ecosystem of engine decompilation and open-source projects for the Dark Forces II engine family:

    • OpenJones3D: A sister project focused on decompiling Indiana Jones and the Infernal Machine. It is based on the same engine and internal libraries as OpenJKDF2.
    • OpenJK: A community-maintained open-source engine for Jedi Outcast (SP) and Jedi Academy (SP & MP), which are the sequels to Dark Forces II.
  7. What is the BJData format?

    master

    BJData is a binary-JSON-like format derived from the Universal Binary JSON (UBJSON) specification. It is designed to be both compact and quasi-human-readable, as its semantic elements (type markers and names) are directly readable.

    Key features include:

    • Optimized ND-arrays: Efficient storage for N-dimensional packed arrays.
    • Expanded Type Markers: Adds [u] (uint16), [m] (uint32), [M] (uint64), and [h] (float16) to map common numeric types unambiguously.
    • Little-Endian (LE): Uses little-endian for all numerics to avoid byte-swapping on most modern platforms (unlike UBJSON's big-endian approach).
    • Searchability: The format allows for direct searching or simple processing due to its human-readable markers.
  8. Overview of JSON container functions and type compatibility

    master

    The nlohmann::basic_json library extends standard STL container functions to support various JSON value types (object, array, string, number, boolean, and null).

    Key Behaviors:

    • Signature Variations: The signature of a function may change based on the JSON type. For example, at() accepts a string key for object types but an integer index for array types.
    • Exception Handling: Functions may throw exceptions if called on incompatible types.
      • json::type_error is thrown when a function is called on a type that does not support it (e.g., calling at() on a string).
      • json::out_of_range may be thrown by at() on an array if the index is invalid.
      • json::invalid_iterator is thrown by front() or back() on null types.
  9. Iterate Over Multiple File Selections (PathSets)

    master

    When using a file open dialog with multiple selection enabled, the library returns a PathSet. There are two ways to iterate over the results:

    1. Index-based access: Uses array-like access. This is the easiest method but can be $O(N^2)$ on certain platforms (like Linux or Windows) if the underlying implementation uses a linked list.
    2. Enumerator (Experimental): Uses an enumerator object to iterate. This is guaranteed to be $O(N)$ but is subject to change.

    Refer to test/test_opendialogmultiple.c and test/test_opendialogmultiple_enum.c for implementation details.

  10. Use the SAX interface for custom parsing

    master

    For high-performance or specialized parsing, you can implement a SAX (Simple API for XML) interface. This avoids building a full DOM tree in memory.

    1. Implement a class that provides the required callback functions (e.g., null(), boolean(bool val), start_object(size_t elements), etc.). You can inherit from nlohmann::json_sax<json>.
    2. Use json::sax_parse(input, &your_sax_handler) to begin parsing.

    The sax_parse function returns a bool indicating if the last event was successful. It does not return a json object; you must manage the data within your handler.

  11. Use nlohmann::json_pointer to identify JSON values

    master

    A nlohmann::json_pointer defines a string syntax (based on RFC 6901) for identifying specific values within a JSON document. You can use JSON pointers with the at() method and operator[] on a JSON object to access nested data. JSON pointers also serve as the foundation for JSON patches.

    // Example conceptual usage with a JSON object
    // json_pointer can be used with at() or operator[]
    // auto value = j.at("/foo/bar/0/baz"_json_pointer);