{"id":20355124,"url":"https://github.com/risc-os-community/libcjson","last_synced_at":"2026-04-20T10:33:28.299Z","repository":{"id":60222915,"uuid":"367954157","full_name":"RISC-OS-Community/LibCJSON","owner":"RISC-OS-Community","description":"RISC OS port of an ultra-lightweight JSON parser in ANSI C","archived":false,"fork":false,"pushed_at":"2023-07-17T19:45:33.000Z","size":509,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-10-24T06:17:23.502Z","etag":null,"topics":["a7000","ansi-c","arm","beagleboard","c","imx6","iyonix","json","library","omap4","omap5","pandaboard","parser","raspberry-pi","risc-os","riscos","riscpc","titanium","wandboard"],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/RISC-OS-Community.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-05-16T18:13:17.000Z","updated_at":"2023-04-22T21:01:59.000Z","dependencies_parsed_at":"2025-03-04T17:33:48.472Z","dependency_job_id":null,"html_url":"https://github.com/RISC-OS-Community/LibCJSON","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":"RISC-OS-Community/StandardRepoTemplate","purl":"pkg:github/RISC-OS-Community/LibCJSON","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RISC-OS-Community%2FLibCJSON","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RISC-OS-Community%2FLibCJSON/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RISC-OS-Community%2FLibCJSON/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RISC-OS-Community%2FLibCJSON/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/RISC-OS-Community","download_url":"https://codeload.github.com/RISC-OS-Community/LibCJSON/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RISC-OS-Community%2FLibCJSON/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32043083,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-20T00:18:06.643Z","status":"online","status_checked_at":"2026-04-20T02:00:06.527Z","response_time":94,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["a7000","ansi-c","arm","beagleboard","c","imx6","iyonix","json","library","omap4","omap5","pandaboard","parser","raspberry-pi","risc-os","riscos","riscpc","titanium","wandboard"],"created_at":"2024-11-14T23:11:20.671Z","updated_at":"2026-04-20T10:33:28.273Z","avatar_url":"https://github.com/RISC-OS-Community.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"# cJSON\n\nThis is a port of the Ultra lightweight JSON parser in ANSI C to RISC OS Operating System.\n\nThis port builds on both GNU GCC and Acorn/ROOL DDE C compilers and come with easy-to-build scripts for both.\n\n**Please Note:** This is not the cJSON original repository, this repository is ONLY for the RISC OS port.\n\n## Building\n\n### GNU GCC\n\nTo build with GNU GCC, simply run the `MkGCC` script in `src`. This will build the library and the test program.\n\n### Acorn ROOL DDE C\n\nTo build with Acorn/ROOL DDE C, simply run the `MkDDE` script in `src`. This will build the library and the test program.\n\n### Packaging\n\nWhichever build method you use, the relative produced binary files will be automatically added to the `!LibCJSON` directory in their appropriate subdirectories.\n\nSo, for example, if you build with GNU GCC, the static `cJSON` library will be placed in `!LibCJSON.a` and the DLL in `!LibCJSON.so`. If you build with Acorn/ROOL DDE C, the static `cJSON` library will be placed in `!LibCJSON.o`.\n\nTo use the DLL you should probably copy them into your !SharedLibs in your !Boot directory. I'll leave that up to you and also, if you use the DLL version, you should probably make sure that you distribute the DLL with your application. If you use the static version, you don't need to worry about that.\n\n## Table of contents\n\n* [License](#license)\n* [Usage](#usage)\n  * [Welcome to cJSON](#welcome-to-cjson)\n  * [Building](#building)\n    * [GNU GCC](#gnu-gcc)\n    * [Acorn/ROOL DDE C](#acorn-rool-dde-c)\n    * [Packaging](#packaging)\n  * [Including cJSON](#including-cjson)\n  * [Data Structure](#data-structure)\n  * [Working with the data structure](#working-with-the-data-structure)\n    * [Basic types](#basic-types)\n    * [Arrays](#arrays)\n    * [Objects](#objects)\n  * [Parsing JSON](#parsing-json)\n  * [Printing JSON](#printing-json)\n  * [Example](#example)\n    * [Printing](#printing)\n    * [Parsing](#parsing)\n  * [Caveats](#caveats)\n    * [Zero Character](#zero-character)\n    * [Character Encoding](#character-encoding)\n    * [C Standard](#c-standard)\n    * [Floating Point Numbers](#floating-point-numbers)\n    * [Deep Nesting Of Arrays And Objects](#deep-nesting-of-arrays-and-objects)\n    * [Thread Safety](#thread-safety)\n    * [Case Sensitivity](#case-sensitivity)\n    * [Duplicate Object Members](#duplicate-object-members)\n  * [Enjoy cJSON!](#enjoy-cjson)\n\n## License\n\nMIT License\n\n\u003e Copyright (c) 2009-2017 Dave Gamble and cJSON contributors\n\u003e\n\u003e Permission is hereby granted, free of charge, to any person obtaining a copy\n\u003e of this software and associated documentation files (the \"Software\"), to deal\n\u003e in the Software without restriction, including without limitation the rights\n\u003e to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n\u003e copies of the Software, and to permit persons to whom the Software is\n\u003e furnished to do so, subject to the following conditions:\n\u003e\n\u003e The above copyright notice and this permission notice shall be included in\n\u003e all copies or substantial portions of the Software.\n\u003e\n\u003e THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n\u003e IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n\u003e FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n\u003e AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n\u003e LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n\u003e OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n\u003e THE SOFTWARE.\n\n## Usage\n\n### Welcome to cJSON\n\ncJSON aims to be the dumbest possible parser that you can get your job done with.\nIt's a single file of C, and a single header file.\n\nJSON is described best [here](http://www.json.org/).\nIt's like XML, but fat-free. You use it to move data around, store things, or just\ngenerally represent your program's state.\n\nAs a library, cJSON exists to take away as much legwork as it can, but not get in your way.\nAs a point of pragmatism (i.e. ignoring the truth), I'm going to say that you can use it\nin one of two modes: Auto and Manual. Let's have a quick run-through.\n\nI lifted some JSON from this [page](http://www.json.org/fatfree.html).\nThat page inspired me to write cJSON, which is a parser that tries to share the same\nphilosophy as JSON itself. Simple, dumb, out of the way.\n\n## Including cJSON\n\nIf you have made your RISC OS Filer see !LibCJSON, you can include cJSON like this:\n\n```c\n#include \"LibCJSON:cJSON.h\"\n```\n\nThen depending on the compiler and the build type, you can link against the static or dynamic library. For example, if you built with GNU GCC, you can link against the static library like this:\n\n```Makefile\ngcc -o myapp myapp.c -L LibCJSON:LibCJSON.a\n```\n\nIf instead you are using DDE C, you can link against the static library like this:\n\n```Makefile\nlink -o myapp o.myapp LibCJSON:o.CJSONlib\n```\n\nSame goes for the cJSON_Utils library.\n\n### Data Structure\n\ncJSON represents JSON data using the `cJSON` struct data type:\n\n```c\n/* The cJSON structure: */\ntypedef struct cJSON\n{\n    struct cJSON *next;\n    struct cJSON *prev;\n    struct cJSON *child;\n    int type;\n    char *valuestring;\n    /* writing to valueint is DEPRECATED, use cJSON_SetNumberValue instead */\n    int valueint;\n    double valuedouble;\n    char *string;\n} cJSON;\n```\n\nAn item of this type represents a JSON value. The type is stored in `type` as a bit-flag (**this means that you cannot find out the type by just comparing the value of `type`**).\n\nTo check the type of an item, use the corresponding `cJSON_Is...` function. It does a `NULL` check followed by a type check and returns a boolean value if the item is of this type.\n\nThe type can be one of the following:\n\n* `cJSON_Invalid` (check with `cJSON_IsInvalid`): Represents an invalid item that doesn't contain any value. You automatically have this type if you set the item to all zero bytes.\n* `cJSON_False` (check with `cJSON_IsFalse`): Represents a `false` boolean value. You can also check for boolean values in general with `cJSON_IsBool`.\n* `cJSON_True` (check with `cJSON_IsTrue`): Represents a `true` boolean value. You can also check for boolean values in general with `cJSON_IsBool`.\n* `cJSON_NULL` (check with `cJSON_IsNull`): Represents a `null` value.\n* `cJSON_Number` (check with `cJSON_IsNumber`): Represents a number value. The value is stored as a double in `valuedouble` and also in `valueint`. If the number is outside of the range of an integer, `INT_MAX` or `INT_MIN` are used for `valueint`.\n* `cJSON_String` (check with `cJSON_IsString`): Represents a string value. It is stored in the form of a zero terminated string in `valuestring`.\n* `cJSON_Array` (check with `cJSON_IsArray`): Represent an array value. This is implemented by pointing `child` to a linked list of `cJSON` items that represent the values in the array. The elements are linked together using `next` and `prev`, where the first element has `prev.next == NULL` and the last element `next == NULL`.\n* `cJSON_Object` (check with `cJSON_IsObject`): Represents an object value. Objects are stored same way as an array, the only difference is that the items in the object store their keys in `string`.\n* `cJSON_Raw` (check with `cJSON_IsRaw`): Represents any kind of JSON that is stored as a zero terminated array of characters in `valuestring`. This can be used, for example, to avoid printing the same static JSON over and over again to save performance. cJSON will never create this type when parsing. Also note that cJSON doesn't check if it is valid JSON.\n\nAdditionally there are the following two flags:\n\n* `cJSON_IsReference`: Specifies that the item that `child` points to and/or `valuestring` is not owned by this item, it is only a reference. So `cJSON_Delete` and other functions will only deallocate this item, not its `child`/`valuestring`.\n* `cJSON_StringIsConst`: This means that `string` points to a constant string. This means that `cJSON_Delete` and other functions will not try to deallocate `string`.\n\n### Working with the data structure\n\nFor every value type there is a `cJSON_Create...` function that can be used to create an item of that type.\nAll of these will allocate a `cJSON` struct that can later be deleted with `cJSON_Delete`.\nNote that you have to delete them at some point, otherwise you will get a memory leak.  \n**Important**: If you have added an item to an array or an object already, you **mustn't** delete it with `cJSON_Delete`. Adding it to an array or object transfers its ownership so that when that array or object is deleted,\nit gets deleted as well. You also could use `cJSON_SetValuestring` to change a `cJSON_String`'s `valuestring`, and you needn't to free the previous `valuestring` manually.\n\n#### Basic types\n\n* **null** is created with `cJSON_CreateNull`\n* **booleans** are created with `cJSON_CreateTrue`, `cJSON_CreateFalse` or `cJSON_CreateBool`\n* **numbers** are created with `cJSON_CreateNumber`. This will set both `valuedouble` and `valueint`. If the number is outside of the range of an integer, `INT_MAX` or `INT_MIN` are used for `valueint`\n* **strings** are created with `cJSON_CreateString` (copies the string) or with `cJSON_CreateStringReference` (directly points to the string. This means that `valuestring` won't be deleted by `cJSON_Delete` and you are responsible for its lifetime, useful for constants)\n\n#### Arrays\n\nYou can create an empty array with `cJSON_CreateArray`. `cJSON_CreateArrayReference` can be used to create an array that doesn't \"own\" its content, so its content doesn't get deleted by `cJSON_Delete`.\n\nTo add items to an array, use `cJSON_AddItemToArray` to append items to the end.\nUsing `cJSON_AddItemReferenceToArray` an element can be added as a reference to another item, array or string. This means that `cJSON_Delete` will not delete that items `child` or `valuestring` properties, so no double frees are occurring if they are already used elsewhere.\nTo insert items in the middle, use `cJSON_InsertItemInArray`. It will insert an item at the given 0 based index and shift all the existing items to the right.\n\nIf you want to take an item out of an array at a given index and continue using it, use `cJSON_DetachItemFromArray`, it will return the detached item, so be sure to assign it to a pointer, otherwise you will have a memory leak.\n\nDeleting items is done with `cJSON_DeleteItemFromArray`. It works like `cJSON_DetachItemFromArray`, but deletes the detached item via `cJSON_Delete`.\n\nYou can also replace an item in an array in place. Either with `cJSON_ReplaceItemInArray` using an index or with `cJSON_ReplaceItemViaPointer` given a pointer to an element. `cJSON_ReplaceItemViaPointer` will return `0` if it fails. What this does internally is to detach the old item, delete it and insert the new item in its place.\n\nTo get the size of an array, use `cJSON_GetArraySize`. Use `cJSON_GetArrayItem` to get an element at a given index.\n\nBecause an array is stored as a linked list, iterating it via index is inefficient (`O(n²)`), so you can iterate over an array using the `cJSON_ArrayForEach` macro in `O(n)` time complexity.\n\n#### Objects\n\nYou can create an empty object with `cJSON_CreateObject`. `cJSON_CreateObjectReference` can be used to create an object that doesn't \"own\" its content, so its content doesn't get deleted by `cJSON_Delete`.\n\nTo add items to an object, use `cJSON_AddItemToObject`. Use `cJSON_AddItemToObjectCS` to add an item to an object with a name that is a constant or reference (key of the item, `string` in the `cJSON` struct), so that it doesn't get freed by `cJSON_Delete`.\nUsing `cJSON_AddItemReferenceToArray` an element can be added as a reference to another object, array or string. This means that `cJSON_Delete` will not delete that items `child` or `valuestring` properties, so no double frees are occurring if they are already used elsewhere.\n\nIf you want to take an item out of an object, use `cJSON_DetachItemFromObjectCaseSensitive`, it will return the detached item, so be sure to assign it to a pointer, otherwise you will have a memory leak.\n\nDeleting items is done with `cJSON_DeleteItemFromObjectCaseSensitive`. It works like `cJSON_DetachItemFromObjectCaseSensitive` followed by `cJSON_Delete`.\n\nYou can also replace an item in an object in place. Either with `cJSON_ReplaceItemInObjectCaseSensitive` using a key or with `cJSON_ReplaceItemViaPointer` given a pointer to an element. `cJSON_ReplaceItemViaPointer` will return `0` if it fails. What this does internally is to detach the old item, delete it and insert the new item in its place.\n\nTo get the size of an object, you can use `cJSON_GetArraySize`, this works because internally objects are stored as arrays.\n\nIf you want to access an item in an object, use `cJSON_GetObjectItemCaseSensitive`.\n\nTo iterate over an object, you can use the `cJSON_ArrayForEach` macro the same way as for arrays.\n\ncJSON also provides convenient helper functions for quickly creating a new item and adding it to an object, like `cJSON_AddNullToObject`. They return a pointer to the new item or `NULL` if they failed.\n\n### Parsing JSON\n\nGiven some JSON in a zero terminated string, you can parse it with `cJSON_Parse`.\n\n```c\ncJSON *json = cJSON_Parse(string);\n```\n\nGiven some JSON in a string (whether zero terminated or not), you can parse it with `cJSON_ParseWithLength`.\n\n```c\ncJSON *json = cJSON_ParseWithLength(string, buffer_length);\n```\n\nIt will parse the JSON and allocate a tree of `cJSON` items that represents it. Once it returns, you are fully responsible for deallocating it after use with `cJSON_Delete`.\n\nThe allocator used by `cJSON_Parse` is `malloc` and `free` by default but can be changed (globally) with `cJSON_InitHooks`.\n\nIf an error occurs a pointer to the position of the error in the input string can be accessed using `cJSON_GetErrorPtr`. Note though that this can produce race conditions in multithreading scenarios, in that case it is better to use `cJSON_ParseWithOpts` with `return_parse_end`.\nBy default, characters in the input string that follow the parsed JSON will not be considered as an error.\n\nIf you want more options, use `cJSON_ParseWithOpts(const char *value, const char **return_parse_end, cJSON_bool require_null_terminated)`.\n`return_parse_end` returns a pointer to the end of the JSON in the input string or the position that an error occurs at (thereby replacing `cJSON_GetErrorPtr` in a thread safe way). `require_null_terminated`, if set to `1` will make it an error if the input string contains data after the JSON.\n\nIf you want more options giving buffer length, use `cJSON_ParseWithLengthOpts(const char *value, size_t buffer_length, const char **return_parse_end, cJSON_bool require_null_terminated)`.\n\n### Printing JSON\n\nGiven a tree of `cJSON` items, you can print them as a string using `cJSON_Print`.\n\n```c\nchar *string = cJSON_Print(json);\n```\n\nIt will allocate a string and print a JSON representation of the tree into it. Once it returns, you are fully responsible for deallocating it after use with your allocator. (usually `free`, depends on what has been set with `cJSON_InitHooks`).\n\n`cJSON_Print` will print with whitespace for formatting. If you want to print without formatting, use `cJSON_PrintUnformatted`.\n\nIf you have a rough idea of how big your resulting string will be, you can use `cJSON_PrintBuffered(const cJSON *item, int prebuffer, cJSON_bool fmt)`. `fmt` is a boolean to turn formatting with whitespace on and off. `prebuffer` specifies the first buffer size to use for printing. `cJSON_Print` currently uses 256 bytes for its first buffer size. Once printing runs out of space, a new buffer is allocated and the old gets copied over before printing is continued.\n\nThese dynamic buffer allocations can be completely avoided by using `cJSON_PrintPreallocated(cJSON *item, char *buffer, const int length, const cJSON_bool format)`. It takes a buffer to a pointer to print to and its length. If the length is reached, printing will fail and it returns `0`. In case of success, `1` is returned. Note that you should provide 5 bytes more than is actually needed, because cJSON is not 100% accurate in estimating if the provided memory is enough.\n\n### Example\n\nIn this example we want to build and parse the following JSON:\n\n```json\n{\n    \"name\": \"Awesome 4K\",\n    \"resolutions\": [\n        {\n            \"width\": 1280,\n            \"height\": 720\n        },\n        {\n            \"width\": 1920,\n            \"height\": 1080\n        },\n        {\n            \"width\": 3840,\n            \"height\": 2160\n        }\n    ]\n}\n```\n\n#### Printing\n\nLet's build the above JSON and print it to a string:\n\n```c\n//create a monitor with a list of supported resolutions\n//NOTE: Returns a heap allocated string, you are required to free it after use.\nchar *create_monitor(void)\n{\n    const unsigned int resolution_numbers[3][2] = {\n        {1280, 720},\n        {1920, 1080},\n        {3840, 2160}\n    };\n    char *string = NULL;\n    cJSON *name = NULL;\n    cJSON *resolutions = NULL;\n    cJSON *resolution = NULL;\n    cJSON *width = NULL;\n    cJSON *height = NULL;\n    size_t index = 0;\n\n    cJSON *monitor = cJSON_CreateObject();\n    if (monitor == NULL)\n    {\n        goto end;\n    }\n\n    name = cJSON_CreateString(\"Awesome 4K\");\n    if (name == NULL)\n    {\n        goto end;\n    }\n    /* after creation was successful, immediately add it to the monitor,\n     * thereby transferring ownership of the pointer to it */\n    cJSON_AddItemToObject(monitor, \"name\", name);\n\n    resolutions = cJSON_CreateArray();\n    if (resolutions == NULL)\n    {\n        goto end;\n    }\n    cJSON_AddItemToObject(monitor, \"resolutions\", resolutions);\n\n    for (index = 0; index \u003c (sizeof(resolution_numbers) / (2 * sizeof(int))); ++index)\n    {\n        resolution = cJSON_CreateObject();\n        if (resolution == NULL)\n        {\n            goto end;\n        }\n        cJSON_AddItemToArray(resolutions, resolution);\n\n        width = cJSON_CreateNumber(resolution_numbers[index][0]);\n        if (width == NULL)\n        {\n            goto end;\n        }\n        cJSON_AddItemToObject(resolution, \"width\", width);\n\n        height = cJSON_CreateNumber(resolution_numbers[index][1]);\n        if (height == NULL)\n        {\n            goto end;\n        }\n        cJSON_AddItemToObject(resolution, \"height\", height);\n    }\n\n    string = cJSON_Print(monitor);\n    if (string == NULL)\n    {\n        fprintf(stderr, \"Failed to print monitor.\\n\");\n    }\n\nend:\n    cJSON_Delete(monitor);\n    return string;\n}\n```\n\nAlternatively we can use the `cJSON_Add...ToObject` helper functions to make our lifes a little easier:\n\n```c\n//NOTE: Returns a heap allocated string, you are required to free it after use.\nchar *create_monitor_with_helpers(void)\n{\n    const unsigned int resolution_numbers[3][2] = {\n        {1280, 720},\n        {1920, 1080},\n        {3840, 2160}\n    };\n    char *string = NULL;\n    cJSON *resolutions = NULL;\n    size_t index = 0;\n\n    cJSON *monitor = cJSON_CreateObject();\n\n    if (cJSON_AddStringToObject(monitor, \"name\", \"Awesome 4K\") == NULL)\n    {\n        goto end;\n    }\n\n    resolutions = cJSON_AddArrayToObject(monitor, \"resolutions\");\n    if (resolutions == NULL)\n    {\n        goto end;\n    }\n\n    for (index = 0; index \u003c (sizeof(resolution_numbers) / (2 * sizeof(int))); ++index)\n    {\n        cJSON *resolution = cJSON_CreateObject();\n\n        if (cJSON_AddNumberToObject(resolution, \"width\", resolution_numbers[index][0]) == NULL)\n        {\n            goto end;\n        }\n\n        if (cJSON_AddNumberToObject(resolution, \"height\", resolution_numbers[index][1]) == NULL)\n        {\n            goto end;\n        }\n\n        cJSON_AddItemToArray(resolutions, resolution);\n    }\n\n    string = cJSON_Print(monitor);\n    if (string == NULL)\n    {\n        fprintf(stderr, \"Failed to print monitor.\\n\");\n    }\n\nend:\n    cJSON_Delete(monitor);\n    return string;\n}\n```\n\n#### Parsing\n\nIn this example we will parse a JSON in the above format and check if the monitor supports a Full HD resolution while printing some diagnostic output:\n\n```c\n/* return 1 if the monitor supports full hd, 0 otherwise */\nint supports_full_hd(const char * const monitor)\n{\n    const cJSON *resolution = NULL;\n    const cJSON *resolutions = NULL;\n    const cJSON *name = NULL;\n    int status = 0;\n    cJSON *monitor_json = cJSON_Parse(monitor);\n    if (monitor_json == NULL)\n    {\n        const char *error_ptr = cJSON_GetErrorPtr();\n        if (error_ptr != NULL)\n        {\n            fprintf(stderr, \"Error before: %s\\n\", error_ptr);\n        }\n        status = 0;\n        goto end;\n    }\n\n    name = cJSON_GetObjectItemCaseSensitive(monitor_json, \"name\");\n    if (cJSON_IsString(name) \u0026\u0026 (name-\u003evaluestring != NULL))\n    {\n        printf(\"Checking monitor \\\"%s\\\"\\n\", name-\u003evaluestring);\n    }\n\n    resolutions = cJSON_GetObjectItemCaseSensitive(monitor_json, \"resolutions\");\n    cJSON_ArrayForEach(resolution, resolutions)\n    {\n        cJSON *width = cJSON_GetObjectItemCaseSensitive(resolution, \"width\");\n        cJSON *height = cJSON_GetObjectItemCaseSensitive(resolution, \"height\");\n\n        if (!cJSON_IsNumber(width) || !cJSON_IsNumber(height))\n        {\n            status = 0;\n            goto end;\n        }\n\n        if ((width-\u003evaluedouble == 1920) \u0026\u0026 (height-\u003evaluedouble == 1080))\n        {\n            status = 1;\n            goto end;\n        }\n    }\n\nend:\n    cJSON_Delete(monitor_json);\n    return status;\n}\n```\n\nNote that there are no NULL checks except for the result of `cJSON_Parse` because `cJSON_GetObjectItemCaseSensitive` checks for `NULL` inputs already, so a `NULL` value is just propagated and `cJSON_IsNumber` and `cJSON_IsString` return `0` if the input is `NULL`.\n\n### Caveats\n\n#### Zero Character\n\ncJSON doesn't support strings that contain the zero character `'\\0'` or `\\u0000`. This is impossible with the current API because strings are zero terminated.\n\n#### Character Encoding\n\ncJSON only supports UTF-8 encoded input. In most cases it doesn't reject invalid UTF-8 as input though, it just propagates it through as is. As long as the input doesn't contain invalid UTF-8, the output will always be valid UTF-8.\n\n#### C Standard\n\ncJSON is written in ANSI C (or C89, C90). If your compiler or C library doesn't follow this standard, correct behavior is not guaranteed.\n\nNOTE: ANSI C is not C++ therefore it shouldn't be compiled with a C++ compiler. You can compile it with a C compiler and link it with your C++ code however. Although compiling with a C++ compiler might work, correct behavior is not guaranteed.\n\n#### Floating Point Numbers\n\ncJSON does not officially support any `double` implementations other than IEEE754 double precision floating point numbers. It might still work with other implementations but bugs with these will be considered invalid.\n\nThe maximum length of a floating point literal that cJSON supports is currently 63 characters.\n\n#### Deep Nesting Of Arrays And Objects\n\ncJSON doesn't support arrays and objects that are nested too deeply because this would result in a stack overflow. To prevent this cJSON limits the depth to `CJSON_NESTING_LIMIT` which is 1000 by default but can be changed at compile time.\n\n#### Thread Safety\n\nIn general cJSON is **not thread safe**.\n\nHowever it is thread safe under the following conditions:\n\n* `cJSON_GetErrorPtr` is never used (the `return_parse_end` parameter of `cJSON_ParseWithOpts` can be used instead)\n* `cJSON_InitHooks` is only ever called before using cJSON in any threads.\n* `setlocale` is never called before all calls to cJSON functions have returned.\n\n#### Case Sensitivity\n\nWhen cJSON was originally created, it didn't follow the JSON standard and didn't make a distinction between uppercase and lowercase letters. If you want the correct, standard compliant, behavior, you need to use the `CaseSensitive` functions where available.\n\n#### Duplicate Object Members\n\ncJSON supports parsing and printing JSON that contains objects that have multiple members with the same name. `cJSON_GetObjectItemCaseSensitive` however will always only return the first one.\n\n## Enjoy cJSON\n\n* Dave Gamble (original author)\n* Max Bruckner and Alan Wang (current maintainers of the original cJSON repository)\n* and the other [cJSON contributors](CONTRIBUTORS.md)\n* RISC OS Port by Paolo Fabio Zaino\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frisc-os-community%2Flibcjson","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frisc-os-community%2Flibcjson","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frisc-os-community%2Flibcjson/lists"}