{"id":13420021,"url":"https://github.com/danielaparker/jsoncons","last_synced_at":"2025-05-14T22:07:25.808Z","repository":{"id":1781306,"uuid":"9948347","full_name":"danielaparker/jsoncons","owner":"danielaparker","description":"A C++, header-only library for constructing JSON and JSON-like data formats, with JSON Pointer, JSON Patch, JSON Schema, JSONPath, JMESPath, CSV, MessagePack, CBOR, BSON, UBJSON","archived":false,"fork":false,"pushed_at":"2025-05-09T01:43:25.000Z","size":51679,"stargazers_count":765,"open_issues_count":13,"forks_count":177,"subscribers_count":37,"default_branch":"master","last_synced_at":"2025-05-09T02:41:14.823Z","etag":null,"topics":["bson","cbor","cpp","csv","csv-parser","csv-reader","jmespath","json","json-construction","json-diff","json-parser","json-parsing","json-patch","json-pointer","json-serialization","jsonpath","jsonschema","messagepack","streaming-json-read","ubjson"],"latest_commit_sha":null,"homepage":"https://danielaparker.github.io/jsoncons","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/danielaparker.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":"Roadmap.md","authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null},"funding":{"github":"danielaparker","custom":"https://paypal.me/jsoncons?locale.x=en_US"}},"created_at":"2013-05-08T23:48:08.000Z","updated_at":"2025-05-08T15:24:24.000Z","dependencies_parsed_at":"2023-01-13T11:24:35.168Z","dependency_job_id":"f4afd5f9-f393-4e09-b4a2-68b899e57381","html_url":"https://github.com/danielaparker/jsoncons","commit_stats":{"total_commits":10710,"total_committers":66,"mean_commits":"162.27272727272728","dds":0.01867413632119519,"last_synced_commit":"fffa2501736d1b7501530b3a9475c8b7b423378e"},"previous_names":[],"tags_count":173,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danielaparker%2Fjsoncons","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danielaparker%2Fjsoncons/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danielaparker%2Fjsoncons/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danielaparker%2Fjsoncons/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/danielaparker","download_url":"https://codeload.github.com/danielaparker/jsoncons/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254235695,"owners_count":22036963,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bson","cbor","cpp","csv","csv-parser","csv-reader","jmespath","json","json-construction","json-diff","json-parser","json-parsing","json-patch","json-pointer","json-serialization","jsonpath","jsonschema","messagepack","streaming-json-read","ubjson"],"created_at":"2024-07-30T22:01:24.687Z","updated_at":"2025-05-14T22:07:20.770Z","avatar_url":"https://github.com/danielaparker.png","language":"C++","readme":"# JSONCONS\n\njsoncons is a C++, header-only library for constructing [JSON](http://www.json.org) and JSON-like\ndata formats such as [CBOR](http://cbor.io/). For each supported data format, it enables you\nto work with the data in a number of ways:\n\n- As a variant-like, allocator-aware, data structure, [basic_json](doc/ref/corelib/basic_json.md) \n\n- As a strongly typed C++ data structure that implements [json_type_traits](doc/ref/corelib/json_type_traits.md)\n\n- With cursor-level access to a stream of parse events, somewhat analogous to StAX pull parsing and push serializing\n  in the XML world.\n\nCompared to other JSON libraries, jsoncons has been designed to handle very large JSON texts. At its heart are\nSAX-style parsers and serializers. It supports reading an entire JSON text in memory in a variant-like structure.\nBut it also supports efficient access to the underlying data using StAX-style pull parsing and push serializing.\nAnd it supports incremental parsing into a user's preferred form, using\ninformation about user types provided by specializations of [json_type_traits](doc/ref/corelib/json_type_traits.md).\n\nThe [jsoncons data model](doc/ref/corelib/data-model.md) supports the familiar JSON types - nulls,\nbooleans, numbers, strings, arrays, objects - plus byte strings. In addition, jsoncons \nsupports semantic tagging of datetimes, epoch times, big integers, \nbig decimals, big floats and binary encodings. This allows it to preserve these type semantics when parsing \nJSON-like data formats such as CBOR that have them.\n\njsoncons is distributed under the [Boost Software License](http://www.boost.org/users/license.html). \n\njsoncons is free but welcomes support to sustain its development. If you find this library helpful, please consider making a [one time donation](https://paypal.me/jsoncons?locale.x=en_US)\nor becoming a [:heart: sponsor](https://github.com/sponsors/danielaparker). \n\nAs the `jsoncons` library has evolved, names have sometimes changed. To ease transition, jsoncons deprecates the \nold names but continues to support many of them. The deprecated names can be suppressed by defining the macro \n`JSONCONS_NO_DEPRECATED`, and doing so is recommended for new code.\n\n## Extensions\n\n- [bson](doc/ref/bson/bson.md) implements decode from and encode to the [Binary JSON](http://bsonspec.org/) data format.\n- [cbor](doc/ref/cbor/cbor.md) implements decode from and encode to the IETF standard [Concise Binary Object Representation](http://cbor.io/) data format.\n  In addition it supports tags for [stringref](http://cbor.schmorp.de/stringref) and tags for [typed arrays](https://tools.ietf.org/html/rfc8746). \n- [csv](doc/ref/csv/csv.md) implements decode from and encode to CSV files.\n- [jmespath](doc/ref/jmespath/jmespath.md) implements [JMESPath](https://jmespath.org/), a query language for transforming JSON documents into other JSON documents.  \n- [jsonpatch](doc/ref/jsonpatch/jsonpatch.md) implements the IETF standard [JavaScript Object Notation (JSON) Patch](https://tools.ietf.org/html/rfc6902)\n- [mergepatch](doc/ref/mergepatch/mergepatch.md) implements the IETF standard [JSON Merge Patch](https://datatracker.ietf.org/doc/html/rfc7386)\n- [jsonpath](doc/ref/jsonpath/jsonpath.md) implements [Stefan Goessner's JSONPath](http://goessner.net/articles/JsonPath/).  It also supports search and replace using JSONPath expressions.\n- [jsonpointer](doc/ref/jsonpointer/jsonpointer.md) implements the IETF standard [JavaScript Object Notation (JSON) Pointer](https://tools.ietf.org/html/rfc6901)\n- [jsonschema](doc/ref/jsonschema/jsonschema.md) implements Drafts 4, 6, 7, 2019-9 and 2020-12 of the [JSON Schema Specification](https://json-schema.org/specification) (since 0.174.0)\n- [msgpack](doc/ref/msgpack/msgpack.md) implements decode from and encode to the [MessagePack](http://msgpack.org/index.html) data format.\n- [ubjson](doc/ref/ubjson/ubjson.md) implements decode from and encode to the [Universal Binary JSON Specification](http://ubjson.org/) data format.\n\n## What users say\n\n_\"Apache Kvrocks consistently utilizes jsoncons to offer support for JSON data structures to users. We find the development experience with jsoncons outstanding!\"_\n\n_\"I have been using your library in my native language – R – and have created an R package making it easy for (a) JMESpath and JSONpath queries on JSON strings or R objects and (b) for other R developers to link to your library.\"_\n\n_\"I’m using your library for an external interface to pass data, as well as using the conversions from csv to json, which are really helpful for converting data for use in javascript\"_\n\n_\"Verified that, for my needs in JSON and CBOR, it is working perfectly\"_\n\n_\"the JSONPath feature of this library, it's great\"_\n\n_\"We use JMESPath implementation quite extensively\"_ \n\n_\"We love your JSON Schema validator. We are using it in ER/Studio our data modelling tool to parse JSON Schema files so we can create entity relations models from them.\"_\n\n_\"the serialization lib of choice with its beautiful mappings and ease of use\"_\n\n_\"really good\"_ _\"awesome project\"_ _\"very solid and very dependable\"_ _\"my team loves it\"_ _\"Your repo rocks!!!!!\"_\n\n## Mentions on the web\n\n[Get started with HealthImaging image sets and image frames using an AWS SDK](https://docs.aws.amazon.com/healthimaging/latest/devguide/example_medical-imaging_Scenario_ImageSetsAndFrames_section.html)\n\n[RubyGems.org](https://rubygems.org/gems/jsoncons/versions/0.1.3?locale=en)\u0026nbsp;\u0026nbsp;\u0026nbsp;[rjsoncons](https://mtmorgan.github.io/rjsoncons/)\u0026nbsp;\u0026nbsp;\u0026nbsp;[CoppeliaSim](https://manual.coppeliarobotics.com/en/zmqRemoteApiOverview.htm)\n\n## Get jsoncons\n\nYou can use the [vcpkg](https://github.com/Microsoft/vcpkg) platform library manager to install the [jsoncons package](https://github.com/microsoft/vcpkg/tree/master/ports/jsoncons).\n\nOr, download the [latest release](https://github.com/danielaparker/jsoncons/releases) and unpack the zip file. Copy the directory `include/jsoncons` to your `include` directory. If you wish to use extensions, copy `include/jsoncons_ext` as well. \n\nOr, download the latest code on [main](https://github.com/danielaparker/jsoncons/archive/main.zip).\n\n## How to use it\n\n- [Quick guide](http://danielaparker.github.io/jsoncons)\n- [Examples](doc/Examples.md)\n- [Reference](doc/Reference.md)\n- [Ask questions and suggest ideas for new features](https://github.com/danielaparker/jsoncons/discussions)\n\nThe library requires a C++ Compiler with C++11 support. In addition the library defines `jsoncons::endian`,\n`jsoncons::basic_string_view`, `jsoncons::optional`, and `jsoncons::span`, which will be typedefed to\ntheir standard library equivalents if detected. Otherwise they will be typedefed to internal, C++11 compatible, implementations.\n\nThe library uses exceptions and in some cases [std::error_code](https://en.cppreference.com/w/cpp/error/error_code)'s to report errors. Apart from `jsoncons::assertion_error`,\nall jsoncons exception classes implement the [jsoncons::json_error](doc/ref/corelib/json_error.md) interface.\nIf exceptions are disabled or if the compile time macro `JSONCONS_NO_EXCEPTIONS` is defined, throws become calls to `std::terminate`.\n\n## Benchmarks\n\n[json_benchmarks](https://github.com/danielaparker/json_benchmarks) provides some measurements about how `jsoncons` compares to other `json` libraries.\n\n- [JSONTestSuite and JSON_checker test suites](https://danielaparker.github.io/json_benchmarks/) \n\n- [Performance benchmarks with text and integers](https://github.com/danielaparker/json_benchmarks/blob/master/report/performance.md)\n\n- [Performance benchmarks with text and doubles](https://github.com/danielaparker/json_benchmarks/blob/master/report/performance_fp.md)\n\n[JSONPath Comparison](https://cburgmer.github.io/json-path-comparison/) shows how jsoncons JsonPath compares with other implementations\n\n## Examples\n\n[Working with JSON data](#E1)  \n\n[Working with CBOR data](#E2)  \n\n\u003cdiv id=\"E1\"/\u003e \n\n### Working with JSON data\n\nFor the examples below you need to include some header files and initialize a string of JSON data:\n\n```cpp\n#include \u003cjsoncons/json.hpp\u003e\n#include \u003cjsoncons_ext/jsonpath/jsonpath.hpp\u003e\n#include \u003ciostream\u003e\n\nusing namespace jsoncons; // for convenience\n\nstd::string data = R\"(\n    {\n       \"application\": \"hiking\",\n       \"reputons\": [\n       {\n           \"rater\": \"HikingAsylum\",\n           \"assertion\": \"advanced\",\n           \"rated\": \"Marilyn C\",\n           \"rating\": 0.90,\n           \"generated\": 1514862245\n         }\n       ]\n    }\n)\";\n```\n\njsoncons allows you to work with the data in a number of ways:\n\n- As a variant-like data structure, [basic_json](doc/ref/corelib/basic_json.md) \n\n- As a strongly typed C++ data structure that implements [json_type_traits](doc/ref/corelib/json_type_traits.md)\n\n- With [cursor-level access](doc/ref/corelib/basic_json_cursor.md) to a stream of parse events\n\n#### As a variant-like data structure\n\n```cpp\nint main()\n{\n    // Parse the string of data into a json value\n    json j = json::parse(data);\n\n    // Does object member reputons exist?\n    std::cout \u003c\u003c \"(1) \" \u003c\u003c std::boolalpha \u003c\u003c j.contains(\"reputons\") \u003c\u003c \"\\n\\n\";\n\n    // Get a reference to reputons array \n    const json\u0026 v = j[\"reputons\"]; \n\n    // Iterate over reputons array \n    std::cout \u003c\u003c \"(2)\\n\";\n    for (const auto\u0026 item : v.array_range())\n    {\n        // Access rated as string and rating as double\n        std::cout \u003c\u003c item[\"rated\"].as\u003cstd::string\u003e() \u003c\u003c \", \" \u003c\u003c item[\"rating\"].as\u003cdouble\u003e() \u003c\u003c \"\\n\";\n    }\n    std::cout \u003c\u003c \"\\n\";\n\n    // Select all \"rated\" with JSONPath\n    std::cout \u003c\u003c \"(3)\\n\";\n    json result = jsonpath::json_query(j,\"$..rated\");\n    std::cout \u003c\u003c pretty_print(result) \u003c\u003c \"\\n\\n\";\n\n    // Serialize back to JSON\n    std::cout \u003c\u003c \"(4)\\n\" \u003c\u003c pretty_print(j) \u003c\u003c \"\\n\\n\";\n}\n```\nOutput:\n```\n(1) true\n\n(2)\nMarilyn C, 0.9\n\n(3)\n[\n    \"Marilyn C\"\n]\n\n(4)\n{\n    \"application\": \"hiking\",\n    \"reputons\": [\n        {\n            \"assertion\": \"advanced\",\n            \"generated\": 1514862245,\n            \"rated\": \"Marilyn C\",\n            \"rater\": \"HikingAsylum\",\n            \"rating\": 0.9\n        }\n    ]\n}\n```\n\n#### As a strongly typed C++ data structure\n\njsoncons supports transforming JSON texts into C++ data structures. \nThe functions [decode_json](doc/ref/corelib/decode_json.md) and [encode_json](doc/ref/corelib/encode_json.md) \nconvert strings or streams of JSON data to C++ data structures and back. \nDecode and encode work for all C++ classes that have \n[json_type_traits](doc/ref/corelib/json_type_traits.md) \ndefined. jsoncons already supports many types in the standard library, \nand your own types will be supported too if you specialize `json_type_traits`\nin the `jsoncons` namespace. \n\n```cpp\nnamespace ns {\n    enum class hiking_experience {beginner,intermediate,advanced};\n\n    class hiking_reputon\n    {\n        std::string rater_;\n        hiking_experience assertion_;\n        std::string rated_;\n        double rating_;\n        std::optional\u003cstd::chrono::seconds\u003e generated_; // assumes C++17, if not use jsoncons::optional\n        std::optional\u003cstd::chrono::seconds\u003e expires_;\n    public:\n        hiking_reputon(const std::string\u0026 rater,\n            hiking_experience assertion,\n            const std::string\u0026 rated,\n            double rating,\n            const std::optional\u003cstd::chrono::seconds\u003e\u0026 generated = \n                std::optional\u003cstd::chrono::seconds\u003e(),\n            const std::optional\u003cstd::chrono::seconds\u003e\u0026 expires = \n                std::optional\u003cstd::chrono::seconds\u003e())\n            : rater_(rater), assertion_(assertion), rated_(rated), rating_(rating),\n              generated_(generated), expires_(expires)\n        {\n        }\n\n        const std::string\u0026 rater() const {return rater_;}\n        hiking_experience assertion() const {return assertion_;}\n        const std::string\u0026 rated() const {return rated_;}\n        double rating() const {return rating_;}\n        std::optional\u003cstd::chrono::seconds\u003e generated() const {return generated_;}\n        std::optional\u003cstd::chrono::seconds\u003e expires() const {return expires_;}\n\n        friend bool operator==(const hiking_reputon\u0026 lhs, const hiking_reputon\u0026 rhs)\n        {\n            return lhs.rater_ == rhs.rater_ \u0026\u0026 lhs.assertion_ == rhs.assertion_ \u0026\u0026 \n                   lhs.rated_ == rhs.rated_ \u0026\u0026 lhs.rating_ == rhs.rating_ \u0026\u0026\n                   lhs.confidence_ == rhs.confidence_ \u0026\u0026 lhs.expires_ == rhs.expires_;\n        }\n\n        friend bool operator!=(const hiking_reputon\u0026 lhs, const hiking_reputon\u0026 rhs)\n        {\n            return !(lhs == rhs);\n        };\n    };\n\n    class hiking_reputation\n    {\n        std::string application_;\n        std::vector\u003chiking_reputon\u003e reputons_;\n    public:\n        hiking_reputation(const std::string\u0026 application, \n            const std::vector\u003chiking_reputon\u003e\u0026 reputons)\n            : application_(application), \n              reputons_(reputons)\n        {}\n\n        const std::string\u0026 application() const { return application_;}\n        const std::vector\u003chiking_reputon\u003e\u0026 reputons() const { return reputons_;}\n    };\n\n} // namespace ns\n\n// Declare the traits. Specify which data members need to be serialized.\n\nJSONCONS_ENUM_TRAITS(ns::hiking_experience, beginner, intermediate, advanced)\n// First four members listed are mandatory, generated and expires are optional\nJSONCONS_N_CTOR_GETTER_TRAITS(ns::hiking_reputon, 4, rater, assertion, rated, rating, \n                              generated, expires)\n\n// All members are mandatory\nJSONCONS_ALL_CTOR_GETTER_TRAITS(ns::hiking_reputation, application, reputons)\n\nint main()\n{\n    // Decode the string of data into a c++ structure\n    ns::hiking_reputation v = decode_json\u003cns::hiking_reputation\u003e(data);\n\n    // Iterate over reputons array value\n    std::cout \u003c\u003c \"(1)\\n\";\n    for (const auto\u0026 item : v.reputons())\n    {\n        std::cout \u003c\u003c item.rated() \u003c\u003c \", \" \u003c\u003c item.rating();\n        if (item.generated())\n        {\n            std::cout \u003c\u003c \", \" \u003c\u003c (*item.generated()).count();\n        }\n        std::cout \u003c\u003c \"\\n\";\n    }\n\n    // Encode the c++ structure into a string\n    std::string s;\n    encode_json(v, s, indenting::indent);\n    std::cout \u003c\u003c \"(2)\\n\";\n    std::cout \u003c\u003c s \u003c\u003c \"\\n\";\n}\n```\nOutput:\n```\n(1)\nMarilyn C, 0.9, 1514862245\n(2)\n{\n    \"application\": \"hiking\",\n    \"reputons\": [\n        {\n            \"assertion\": \"advanced\",\n            \"generated\": 1514862245,\n            \"rated\": \"Marilyn C\",\n            \"rater\": \"HikingAsylum\",\n            \"rating\": 0.9\n        }\n    ]\n}\n```\nThis example makes use of the convenience macros `JSONCONS_ENUM_TRAITS`,\n`JSONCONS_N_CTOR_GETTER_TRAITS`, and `JSONCONS_ALL_CTOR_GETTER_TRAITS` to specialize the \n[json_type_traits](doc/ref/corelib/json_type_traits.md) for the enum type\n`ns::hiking_experience`, the class `ns::hiking_reputon` (with some non-mandatory members), and the class\n`ns::hiking_reputation` (with all mandatory members.)\nThe macro `JSONCONS_ENUM_TRAITS` generates the code from\nthe enum identifiers, and the macros `JSONCONS_N_CTOR_GETTER_TRAITS`\nand `JSONCONS_ALL_CTOR_GETTER_TRAITS` \ngenerate the code from the get functions and a constructor. \nThese macro declarations must be placed outside any namespace blocks.\n\nSee [examples](doc/Examples.md#G0) for other ways of specializing `json_type_traits`.\n\n#### With cursor-level access\n\nA typical pull parsing application will repeatedly process the `current()` \nevent and call `next()` to advance to the next event, until `done()` \nreturns `true`.\n\n```cpp\nint main()\n{\n    json_string_cursor cursor(data);\n    for (; !cursor.done(); cursor.next())\n    {\n        const auto\u0026 event = cursor.current();\n        switch (event.event_type())\n        {\n            case staj_event_type::begin_array:\n                std::cout \u003c\u003c event.event_type() \u003c\u003c \" \" \u003c\u003c \"\\n\";\n                break;\n            case staj_event_type::end_array:\n                std::cout \u003c\u003c event.event_type() \u003c\u003c \" \" \u003c\u003c \"\\n\";\n                break;\n            case staj_event_type::begin_object:\n                std::cout \u003c\u003c event.event_type() \u003c\u003c \" \" \u003c\u003c \"\\n\";\n                break;\n            case staj_event_type::end_object:\n                std::cout \u003c\u003c event.event_type() \u003c\u003c \" \" \u003c\u003c \"\\n\";\n                break;\n            case staj_event_type::key:\n                // Or std::string_view, if supported\n                std::cout \u003c\u003c event.event_type() \u003c\u003c \": \" \u003c\u003c event.get\u003cjsoncons::string_view\u003e() \u003c\u003c \"\\n\";\n                break;\n            case staj_event_type::string_value:\n                // Or std::string_view, if supported\n                std::cout \u003c\u003c event.event_type() \u003c\u003c \": \" \u003c\u003c event.get\u003cjsoncons::string_view\u003e() \u003c\u003c \"\\n\";\n                break;\n            case staj_event_type::null_value:\n                std::cout \u003c\u003c event.event_type() \u003c\u003c \"\\n\";\n                break;\n            case staj_event_type::bool_value:\n                std::cout \u003c\u003c event.event_type() \u003c\u003c \": \" \u003c\u003c std::boolalpha \u003c\u003c event.get\u003cbool\u003e() \u003c\u003c \"\\n\";\n                break;\n            case staj_event_type::int64_value:\n                std::cout \u003c\u003c event.event_type() \u003c\u003c \": \" \u003c\u003c event.get\u003cint64_t\u003e() \u003c\u003c \"\\n\";\n                break;\n            case staj_event_type::uint64_value:\n                std::cout \u003c\u003c event.event_type() \u003c\u003c \": \" \u003c\u003c event.get\u003cuint64_t\u003e() \u003c\u003c \"\\n\";\n                break;\n            case staj_event_type::double_value:\n                std::cout \u003c\u003c event.event_type() \u003c\u003c \": \" \u003c\u003c event.get\u003cdouble\u003e() \u003c\u003c \"\\n\";\n                break;\n            default:\n                std::cout \u003c\u003c \"Unhandled event type: \" \u003c\u003c event.event_type() \u003c\u003c \" \" \u003c\u003c \"\\n\";\n                break;\n        }\n    }    \n}\n```\nOutput:\n```\nbegin_object\nkey: application\nstring_value: hiking\nkey: reputons\nbegin_array\nbegin_object\nkey: rater\nstring_value: HikingAsylum\nkey: assertion\nstring_value: advanced\nkey: rated\nstring_value: Marilyn C\nkey: rating\ndouble_value: 0.9\nkey: generated\nuint64_value: 1514862245\nend_object\nend_array\nend_object\n```\n\nYou can apply a filter to a cursor using the pipe syntax (e.g., `cursor | filter1 | filter2 | ...`)\n\n```cpp\nint main()\n{\n    std::string name;\n    auto filter = [\u0026](const staj_event\u0026 ev, const ser_context\u0026) -\u003e bool\n    {\n        if (ev.event_type() == staj_event_type::key)\n        {\n            name = ev.get\u003cstd::string\u003e();\n            return false;\n        }\n        if (name == \"rated\")\n        {\n            name.clear();\n            return true;\n        }\n        return false;\n    };\n\n    json_string_cursor cursor(data);\n    auto filtered_c = cursor | filter;\n\n    for (; !filtered_c.done(); filtered_c.next())\n    {\n        const auto\u0026 event = filtered_c.current();\n        switch (event.event_type())\n        {\n            case staj_event_type::string_value:\n                // Or std::string_view, if C++17\n                std::cout \u003c\u003c event.event_type() \u003c\u003c \": \" \u003c\u003c event.get\u003cjsoncons::string_view\u003e() \u003c\u003c \"\\n\";\n                break;\n            default:\n                std::cout \u003c\u003c \"Unhandled event type\\n\";\n                break;\n        }\n    }\n}    \n```\nOutput:\n```\nMarilyn C\n```\n\n\u003cdiv id=\"E2\"/\u003e \n\n### Working with CBOR data\n\nFor the examples below you need to include some header files and initialize a buffer of CBOR data:\n\n```cpp\n#include \u003ciomanip\u003e\n#include \u003ciostream\u003e\n#include \u003cjsoncons/json.hpp\u003e\n#include \u003cjsoncons_ext/cbor/cbor.hpp\u003e\n#include \u003cjsoncons_ext/jsonpath/jsonpath.hpp\u003e\n\nusing namespace jsoncons; // for convenience\n\nconst std::vector\u003cuint8_t\u003e data = {\n    0x9f, // Start indefinte length array\n      0x83, // Array of length 3\n        0x63, // String value of length 3\n          0x66,0x6f,0x6f, // \"foo\" \n        0x44, // Byte string value of length 4\n          0x50,0x75,0x73,0x73, // 'P''u''s''s'\n        0xc5, // Tag 5 (bigfloat)\n          0x82, // Array of length 2\n            0x20, // -1\n            0x03, // 3   \n      0x83, // Another array of length 3\n        0x63, // String value of length 3\n          0x62,0x61,0x72, // \"bar\"\n        0xd6, // Expected conversion to base64\n        0x44, // Byte string value of length 4\n          0x50,0x75,0x73,0x73, // 'P''u''s''s'\n        0xc4, // Tag 4 (decimal fraction)\n          0x82, // Array of length 2\n            0x38, // Negative integer of length 1\n              0x1c, // -29\n            0xc2, // Tag 2 (positive bignum)\n              0x4d, // Byte string value of length 13\n                0x01,0x8e,0xe9,0x0f,0xf6,0xc3,0x73,0xe0,0xee,0x4e,0x3f,0x0a,0xd2,\n    0xff // \"break\"\n};\n```\n\njsoncons allows you to work with the CBOR data similarly to JSON data:\n\n- As a variant-like data structure, [basic_json](doc/ref/corelib/basic_json.md) \n\n- As a strongly typed C++ data structure that implements [json_type_traits](doc/ref/corelib/json_type_traits.md)\n\n- With [cursor-level access](doc/ref/cbor/basic_cbor_cursor.md) to a stream of parse events\n\n#### As a variant-like data structure\n\n```cpp\nint main()\n{\n    // Parse the CBOR data into a json value\n    json j = cbor::decode_cbor\u003cjson\u003e(data);\n\n    // Pretty print\n    std::cout \u003c\u003c \"(1)\\n\" \u003c\u003c pretty_print(j) \u003c\u003c \"\\n\\n\";\n\n    // Iterate over rows\n    std::cout \u003c\u003c \"(2)\\n\";\n    for (const auto\u0026 row : j.array_range())\n    {\n        std::cout \u003c\u003c row[1].as\u003cjsoncons::byte_string\u003e() \u003c\u003c \" (\" \u003c\u003c row[1].tag() \u003c\u003c \")\\n\";\n    }\n    std::cout \u003c\u003c \"\\n\";\n\n    // Select the third column with JSONPath\n    std::cout \u003c\u003c \"(3)\\n\";\n    json result = jsonpath::json_query(j,\"$[*][2]\");\n    std::cout \u003c\u003c pretty_print(result) \u003c\u003c \"\\n\\n\";\n\n    // Serialize back to CBOR\n    std::vector\u003cuint8_t\u003e buffer;\n    cbor::encode_cbor(j, buffer);\n    std::cout \u003c\u003c \"(4)\\n\" \u003c\u003c byte_string_view(buffer) \u003c\u003c \"\\n\\n\";\n}\n```\nOutput:\n```\n(1)\n[\n    [\"foo\", \"UHVzcw\", \"0x3p-1\"],\n    [\"bar\", \"UHVzcw==\", \"1.23456789012345678901234567890\"]\n]\n\n(2)\n50,75,73,73 (n/a)\n50,75,73,73 (base64)\n\n(3)\n[\n    \"0x3p-1\",\n    \"1.23456789012345678901234567890\"\n]\n\n(4)\n82,83,63,66,6f,6f,44,50,75,73,73,c5,82,20,03,83,63,62,61,72,d6,44,50,75,73,73,c4,82,38,1c,c2,4d,01,8e,e9,0f,f6,c3,73,e0,ee,4e,3f,0a,d2\n```\n\n#### As a strongly typed C++ data structure\n\n```cpp\nint main()\n{\n    // Parse the string of data into a std::vector\u003cstd::tuple\u003cstd::string,jsoncons::byte_string,std::string\u003e\u003e value\n    auto val = cbor::decode_cbor\u003cstd::vector\u003cstd::tuple\u003cstd::string,jsoncons::byte_string,std::string\u003e\u003e\u003e(data);\n\n    std::cout \u003c\u003c \"(1)\\n\";\n    for (const auto\u0026 row : val)\n    {\n        std::cout \u003c\u003c std::get\u003c0\u003e(row) \u003c\u003c \", \" \u003c\u003c std::get\u003c1\u003e(row) \u003c\u003c \", \" \u003c\u003c std::get\u003c2\u003e(row) \u003c\u003c \"\\n\";\n    }\n    std::cout \u003c\u003c \"\\n\";\n\n    // Serialize back to CBOR\n    std::vector\u003cuint8_t\u003e buffer;\n    cbor::encode_cbor(val, buffer);\n    std::cout \u003c\u003c \"(2)\\n\" \u003c\u003c byte_string_view(buffer) \u003c\u003c \"\\n\\n\";\n}\n```\nOutput:\n```\n(1)\nfoo, 50,75,73,73, 0x3p-1\nbar, 50,75,73,73, 1.23456789012345678901234567890\n\n(2)\n82,9f,63,66,6f,6f,44,50,75,73,73,66,30,78,33,70,2d,31,ff,9f,63,62,61,72,44,50,75,73,73,78,1f,31,2e,32,33,34,35,36,37,38,39,30,31,32,33,34,35,36,37,38,39,30,31,32,33,34,35,36,37,38,39,30,ff\n```\n\nNote that when decoding the bigfloat and decimal fraction into a `std::string`, we lose the semantic information\nthat the variant like data structure preserved with a tag, so serializing back to CBOR produces a text string.\n\n#### With cursor-level access\n\nA typical pull parsing application will repeatedly process the `current()` \nevent and call `next()` to advance to the next event, until `done()` \nreturns `true`.\n\n```cpp\nint main()\n{\n    cbor::cbor_bytes_cursor cursor(data);\n    for (; !cursor.done(); cursor.next())\n    {\n        const auto\u0026 event = cursor.current();\n        switch (event.event_type())\n        {\n            case staj_event_type::begin_array:\n                std::cout \u003c\u003c event.event_type() \u003c\u003c \" \" \u003c\u003c \"(\" \u003c\u003c event.tag() \u003c\u003c \")\\n\";\n                break;\n            case staj_event_type::end_array:\n                std::cout \u003c\u003c event.event_type() \u003c\u003c \" \" \u003c\u003c \"(\" \u003c\u003c event.tag() \u003c\u003c \")\\n\";\n                break;\n            case staj_event_type::begin_object:\n                std::cout \u003c\u003c event.event_type() \u003c\u003c \" \" \u003c\u003c \"(\" \u003c\u003c event.tag() \u003c\u003c \")\\n\";\n                break;\n            case staj_event_type::end_object:\n                std::cout \u003c\u003c event.event_type() \u003c\u003c \" \" \u003c\u003c \"(\" \u003c\u003c event.tag() \u003c\u003c \")\\n\";\n                break;\n            case staj_event_type::key:\n                // Or std::string_view, if supported\n                std::cout \u003c\u003c event.event_type() \u003c\u003c \": \" \u003c\u003c event.get\u003cjsoncons::string_view\u003e() \u003c\u003c \" \" \u003c\u003c \"(\" \u003c\u003c event.tag() \u003c\u003c \")\\n\";\n                break;\n            case staj_event_type::string_value:\n                // Or std::string_view, if supported\n                std::cout \u003c\u003c event.event_type() \u003c\u003c \": \" \u003c\u003c event.get\u003cjsoncons::string_view\u003e() \u003c\u003c \" \" \u003c\u003c \"(\" \u003c\u003c event.tag() \u003c\u003c \")\\n\";\n                break;\n            case staj_event_type::byte_string_value:\n                std::cout \u003c\u003c event.event_type() \u003c\u003c \": \" \u003c\u003c event.get\u003cjsoncons::span\u003cconst uint8_t\u003e\u003e() \u003c\u003c \" \" \u003c\u003c \"(\" \u003c\u003c event.tag() \u003c\u003c \")\\n\";\n                break;\n            case staj_event_type::null_value:\n                std::cout \u003c\u003c event.event_type() \u003c\u003c \" \" \u003c\u003c \"(\" \u003c\u003c event.tag() \u003c\u003c \")\\n\";\n                break;\n            case staj_event_type::bool_value:\n                std::cout \u003c\u003c event.event_type() \u003c\u003c \": \" \u003c\u003c std::boolalpha \u003c\u003c event.get\u003cbool\u003e() \u003c\u003c \" \" \u003c\u003c \"(\" \u003c\u003c event.tag() \u003c\u003c \")\\n\";\n                break;\n            case staj_event_type::int64_value:\n                std::cout \u003c\u003c event.event_type() \u003c\u003c \": \" \u003c\u003c event.get\u003cint64_t\u003e() \u003c\u003c \" \" \u003c\u003c \"(\" \u003c\u003c event.tag() \u003c\u003c \")\\n\";\n                break;\n            case staj_event_type::uint64_value:\n                std::cout \u003c\u003c event.event_type() \u003c\u003c \": \" \u003c\u003c event.get\u003cuint64_t\u003e() \u003c\u003c \" \" \u003c\u003c \"(\" \u003c\u003c event.tag() \u003c\u003c \")\\n\";\n                break;\n            case staj_event_type::half_value:\n            case staj_event_type::double_value:\n                std::cout \u003c\u003c event.event_type() \u003c\u003c \": \"  \u003c\u003c event.get\u003cdouble\u003e() \u003c\u003c \" \" \u003c\u003c \"(\" \u003c\u003c event.tag() \u003c\u003c \")\\n\";\n                break;\n            default:\n                std::cout \u003c\u003c \"Unhandled event type \" \u003c\u003c event.event_type() \u003c\u003c \" \" \u003c\u003c \"(\" \u003c\u003c event.tag() \u003c\u003c \")\\n\";\n                break;\n        }\n    }\n}\n```\nOutput:\n```\nbegin_array (n/a)\nbegin_array (n/a)\nstring_value: foo (n/a)\nbyte_string_value: 50,75,73,73 (n/a)\nstring_value: 0x3p-1 (bigfloat)\nend_array (n/a)\nbegin_array (n/a)\nstring_value: bar (n/a)\nbyte_string_value: 50,75,73,73 (base64)\nstring_value: 1.23456789012345678901234567890 (bigdec)\nend_array (n/a)\nend_array (n/a)\n```\n\nYou can apply a filter to a cursor using the pipe syntax, \n\n```cpp\nint main()\n{\n    auto filter = [\u0026](const staj_event\u0026 ev, const ser_context\u0026) -\u003e bool\n    {\n        return (ev.tag() == semantic_tag::bigdec) || (ev.tag() == semantic_tag::bigfloat);  \n    };\n\n    cbor::cbor_bytes_cursor cursor(data);\n    auto filtered_c = cursor | filter;\n\n    for (; !filtered_c.done(); filtered_c.next())\n    {\n        const auto\u0026 event = filtered_c.current();\n        switch (event.event_type())\n        {\n            case staj_event_type::string_value:\n                // Or std::string_view, if supported\n                std::cout \u003c\u003c event.event_type() \u003c\u003c \": \" \u003c\u003c event.get\u003cjsoncons::string_view\u003e() \u003c\u003c \" \" \u003c\u003c \"(\" \u003c\u003c event.tag() \u003c\u003c \")\\n\";\n                break;\n            default:\n                std::cout \u003c\u003c \"Unhandled event type \" \u003c\u003c event.event_type() \u003c\u003c \" \" \u003c\u003c \"(\" \u003c\u003c event.tag() \u003c\u003c \")\\n\";\n                break;\n        }\n    }\n}\n```\nOutput:\n```\nstring_value: 0x3p-1 (bigfloat)\nstring_value: 1.23456789012345678901234567890 (bigdec)\n```\n\n## Supported compilers\n\njsoncons requires a compiler with minimally C++11 support. It is tested in continuous integration on [Github Actions](https://github.com/danielaparker/jsoncons/actions) and [circleci](https://app.circleci.com/pipelines/circleci/EFpnYcrBiZEvYvns3VF4vT).\n[UndefinedBehaviorSanitizer (UBSan)](http://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html) diagnostics are enabled for selected gcc and clang builds.\nSince v0.151.0, it is integrated with [Google OSS-fuzz](https://github.com/google/oss-fuzz), with coverage for all parsers and encoders.\n\n| Compiler                | Version                            | Standard     | Architecture | Operating System | CI Service     |  \n|-------------------------|------------------------------------|--------------|--------------|------------------|----------------|\n| Visual Studio           | vs2019                             | default      | x86, x64     | Windows 11       | GitHub Actions |\n|                         | vs2022                             | default      | x86, x64     | Windows 11       | GitHub Actions |\n| Visual Studio - clang   | vs2019                             | default      | x86, x64     | Windows 11       | GitHub Actions |\n|                         | vs2022                             | default      | x86, x64     | Windows 11       | GitHub Actions |\n| g++                     | 6, 7, 8, 9, 10, 11, 12             | default      | x64          | Ubuntu           | circleci       |\n| g++                     | 12                                 | c++20        | x64          | Ubuntu           | GitHub Actions |\n| clang                   | 3.9, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15     | default      | x64          | Ubuntu           | circleci       |\n| clang                   | 14                                 | c++20        | x64          | Ubuntu           | GitHub Actions |\n| clang xcode             | 11, 12, 13                         | default      | x64          | OSX 11           | GitHub Actions |\n| clang xcode             | 13, 14                             | default      | x64          | OSX 12           | GitHub Actions |\n\n## Building the test suite and examples with CMake\n\n[CMake](https://cmake.org/) is a cross-platform build tool that generates makefiles and solutions for the compiler environment of your choice. On Windows you can download a [Windows Installer package](https://cmake.org/download/). On Linux it is usually available as a package, e.g., on Ubuntu,\n```\nsudo apt-get install cmake\n```\nOnce cmake is installed, you can build and run the unit tests from the jsoncons directory,\n\nOn Windows:\n```\n\u003e mkdir build\n\u003e cd build\n\u003e cmake .. -DJSONCONS_BUILD_TESTS=On\n\u003e cmake --build .\n\u003e ctest -C Debug --output-on-failure\n```\n\nOn UNIX:\n```\n$ mkdir build\n$ cd build\n$ cmake .. -DJSONCONS_BUILD_TESTS=On\n$ cmake --build .\n$ ctest --output-on-failure\n```\n\n## Acknowledgements\n\njsoncons uses the PVS-Studio static analyzer, provided free for open source projects.\n\nA big thanks to the comp.lang.c++ community for help with implementation details. \n\nThe jsoncons platform dependent binary configuration draws on to the excellent MIT licensed [tinycbor](https://github.com/intel/tinycbor).\n\nThanks to Milo Yip, author of [RapidJSON](http://rapidjson.org/), for raising the quality of JSON libraries across the board, by publishing [the benchmarks](https://github.com/miloyip/nativejson-benchmark), and contacting this project (among others) to share the results.\n\nThe jsoncons implementation of the Grisu3 algorithm for printing floating-point numbers follows Florian Loitsch's MIT licensed [grisu3_59_56 implementation](http://florian.loitsch.com/publications), with minor modifications. \n\nThe macro `JSONCONS_ALL_MEMBER_TRAITS` follows the approach taken by Martin York's [ThorsSerializer](https://github.com/Loki-Astari/ThorsSerializer)\n\nThe jsoncons implementations of BSON decimal128 to and from string,\nand ObjectId to and from string, are based on the Apache 2 licensed [libbson](https://github.com/mongodb/mongo-c-driver/tree/master/src/libbson).\n\nSpecial thanks to our [contributors](https://github.com/danielaparker/jsoncons/blob/master/acknowledgements.md)\n \n","funding_links":["https://github.com/sponsors/danielaparker","https://paypal.me/jsoncons?locale.x=en_US"],"categories":["TODO scan for Android support in followings","JSON","C++","Objects","进程间通信","Data Formats"],"sub_categories":["Saving/Loading Objects, Compositing Packets","Json"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdanielaparker%2Fjsoncons","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdanielaparker%2Fjsoncons","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdanielaparker%2Fjsoncons/lists"}