{"id":13514704,"url":"https://github.com/whyisitworking/C-Simple-JSON-Parser","last_synced_at":"2025-03-31T03:31:11.631Z","repository":{"id":25655970,"uuid":"83491344","full_name":"forkachild/C-Simple-JSON-Parser","owner":"forkachild","description":"Extremely lightweight, easy-to-use \u0026 blazing fast JSON parsing library written in pure C","archived":false,"fork":false,"pushed_at":"2024-02-22T08:53:32.000Z","size":123,"stargazers_count":43,"open_issues_count":2,"forks_count":17,"subscribers_count":5,"default_branch":"master","last_synced_at":"2024-08-02T05:11:36.123Z","etag":null,"topics":["c","json","json-parser","library","parser","rfc-8259"],"latest_commit_sha":null,"homepage":"https://forkachild.github.io/C-Simple-JSON-Parser/","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/forkachild.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2017-02-28T23:56:35.000Z","updated_at":"2024-08-01T07:25:39.000Z","dependencies_parsed_at":"2024-02-22T09:51:47.139Z","dependency_job_id":null,"html_url":"https://github.com/forkachild/C-Simple-JSON-Parser","commit_stats":null,"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/forkachild%2FC-Simple-JSON-Parser","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/forkachild%2FC-Simple-JSON-Parser/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/forkachild%2FC-Simple-JSON-Parser/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/forkachild%2FC-Simple-JSON-Parser/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/forkachild","download_url":"https://codeload.github.com/forkachild/C-Simple-JSON-Parser/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":222623218,"owners_count":17013318,"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":["c","json","json-parser","library","parser","rfc-8259"],"created_at":"2024-08-01T05:01:00.653Z","updated_at":"2025-03-31T03:31:10.189Z","avatar_url":"https://github.com/forkachild.png","language":"C","funding_links":["https://www.paypal.me/suhelchakraborty"],"categories":["C"],"sub_categories":[],"readme":"# Simple JSON Parser in C\n\nAn easy to use, very fast JSON parsing implementation written in pure C\n\n## Features\n\n- Fully [RFC-8259](https://datatracker.ietf.org/doc/html/rfc8259) compliant\n- Small 2 file library\n- Support for all data types\n- Simple and efficient hash table implementation to search element by key\n- Rust like `result` type used throughout fallible calls\n- Compile with `-DJSON_SKIP_WHITESPACE` to parse non-minified JSON with whitespace in between\n\n## Setup\n\nCopy the following from this repository in your source\n\n- `json.h`\n- `json.c`\n\nAnd in your code\n\n```C\n#include \"json.h\"\n```\n\n## MACROs\n\n### The `typed` helper\n\nA uniform type system used throughout the API\n`typed(x)` is alias for `x_t`\n\n```C\ntyped(json_element) // json_element_t\n```\n\n### Rust like `result`\n\nA tagged union comprising two variants, either `ok` with the data or `err` with `typed(json_error)` with simplified API to manage variants\n\n```C\nresult(json_element) // json_element_result_t\n```\n\n## API\n\n### Parse JSON:\n\n```C\nresult(json_element) json_parse(typed(json_string) json_str);\n```\n\n### Find an element by key\n\n```C\nresult(json_element) json_object_find(typed(json_object) * object, typed(json_string) key);\n```\n\n### Print JSON with specified indentation\n\n```C\nvoid json_print(typed(json_element) *element, int indent);\n```\n\n### Free JSON from memory\n\n```C\nvoid json_free(typed(json_element) *element);\n```\n\n### Convert error into user friendly error String\n\n```C\ntyped(json_string) json_error_to_string(typed(json_error) error);\n```\n\n## Types\n\n### JSON String\n\nA null-terminated char-sequence\n\n```C\ntyped(json_string) // alias for const char *\n```\n\n### JSON Number\n\nA 64-bit floating point number\n\n```C\ntyped(json_number) // alias for double\n```\n\n### JSON Object\n\nAn array of key-value entries\n\n```C\ntyped(json_object)\n```\n\n#### Fields\n\n| **Name**  | **Type**              | **Description**       |\n| --------- | --------------------- | --------------------- |\n| `count`   | `typed(size)`         | The number of entries |\n| `entries` | `typed(json_entry) *` | The array of entries  |\n\n### JSON Array\n\nA hetergeneous array of elements\n\n```C\ntyped(json_array)\n```\n\n#### Fields\n\n| **Name**   | **Type**                | **Description**        |\n| ---------- | ----------------------- | ---------------------- |\n| `count`    | `typed(size)`           | The number of elements |\n| `elements` | `typed(json_element) *` | The array of elements  |\n\n### JSON Boolean\n\nA boolean value\n\n```C\ntyped(json_boolean)\n```\n\n### Element\n\nA tagged union representing a JSON value with its type\n\n```C\ntyped(json_element)\n```\n\n#### Fields\n\n| **Name** | **Type**                    | **Description**       |\n| -------- | --------------------------- | --------------------- |\n| `type`   | `typed(json_element_type)`  | The type of the value |\n| `value`  | `typed(json_element_value)` | The actual value      |\n\n### Element Type\n\nAn enum which represents a JSON type\n\n```C\ntyped(json_element_type)\n```\n\n#### Variants\n\n| **Variant**                 | **Description** |\n| --------------------------- | --------------- |\n| `JSON_ELEMENT_TYPE_STRING`  | JSON String     |\n| `JSON_ELEMENT_TYPE_NUMBER`  | JSON Number     |\n| `JSON_ELEMENT_TYPE_OBJECT`  | JSON Object     |\n| `JSON_ELEMENT_TYPE_ARRAY`   | JSON Array      |\n| `JSON_ELEMENT_TYPE_BOOLEAN` | JSON Boolean    |\n| `JSON_ELEMENT_TYPE_NULL`    | JSON Null       |\n\n### Element Value\n\nA union for interpreting JSON data\n\n```C\ntyped(json_element_value)\n```\n\n#### Fields\n\n| **Name**     | **Type**               | **Interpret data as** |\n| ------------ | ---------------------- | --------------------- |\n| `as_string`  | `typed(json_string)`   | JSON String           |\n| `as_number`  | `typed(json_number)`   | JSON Number           |\n| `as_object`  | `typed(json_object) *` | JSON Object           |\n| `as_array`   | `typed(json_array) *`  | JSON Array            |\n| `as_boolean` | `typed(json_boolean)`  | JSON Boolean          |\n\n### Error\n\nAn enum which represents an error\n\n```C\ntyped(json_error)\n```\n\n#### Variants\n\n| **Variant**                | **Description**                |\n| -------------------------- | ------------------------------ |\n| `JSON_ERROR_EMPTY`         | Null or empty value            |\n| `JSON_ERROR_INVALID_TYPE`  | Type inference failed          |\n| `JSON_ERROR_INVALID_KEY`   | Key is not a valid string      |\n| `JSON_ERROR_INVALID_VALUE` | Value is not a valid JSON type |\n\n## Usage\n\n### Parse with error checking\n\n```C\n#include \"json.h\"\n\nconst char * some_json_str = \"{\\\"hello\\\":\\\"world\\\",\\\"key\\\":\\\"value\\\"}\";\n\nint main() {\n  result(json_element) element_result = json_parse(some_json_str);\n\n  // Guard if\n  if(result_is_err(json_element)(\u0026element_result)) {\n    typed(json_error) error = result_unwrap_err(json_element)(\u0026element_result);\n    fprintf(stderr, \"Error parsing JSON: %s\\n\", json_error_to_string(error));\n    return -1;\n  }\n\n  // Extract the data\n  typed(json_element) element = result_unwrap(json_element)(\u0026element_result);\n\n  // Fetch the \"hello\" key value\n  result(json_element) hello_element_result = json_object_find(element.value.as_object, \"hello\");\n  if(result_is_err(json_element)(\u0026hello_element_result)) {\n    typed(json_error) error = result_unwrap_err(json_element)(\u0026hello_element_result);\n    fprintf(stderr, \"Error getting element \\\"hello\\\": %s\\n\", json_error_to_string(error));\n    return -1;\n  }\n  typed(json_element) hello_element = result_unwrap(json_element)(\u0026hello_element_result);\n\n  // Use the element\n  printf(\"\\\"hello\\\": \\\"%s\\\"\\n\", hello_element.value.as_string);\n  json_print(\u0026element, 2);\n  json_free(\u0026element);\n\n  return 0;\n}\n```\n\nOutputs\n\n```\n\"hello\": \"world\"\n{\n  \"hello\": \"world\",\n  \"key\": \"value\"\n}\n```\n\n### Example in repository\n\n1.  Clone this repository `git clone https://github.com/forkachild/C-Simple-JSON-Parser`\n2.  Compile the example `clang example.c json.c -o example.out`\n3.  Run the binary `./example.out`\n\n## FAQs\n\n### How to know the type?\n\nAt each Key-Value pair `typed(json_entry_t)`, there is a member `type`\n\n```C\n#include \"json.h\"\n\n...\n\ntyped(json_element) element = ...; // See example above\ntyped(json_entry) entry = element.value.as_object-\u003eentries[0];\n\nswitch(entry.element.type) {\n  case JSON_TYPE_STRING:\n    // `entry.element.value.as_string` is a `json_string_t`\n    break;\n  case JSON_TYPE_NUMBER:\n    // `entry.element.value.as_number` is a `json_number_t`\n    break;\n  case JSON_TYPE_OBJECT:\n    // `entry.element.value.as_object` is a `json_object_t *`\n    break;\n  case JSON_TYPE_ARRAY:\n    // `entry.element.value.as_array` is a `json_array_t *`\n    break;\n  case JSON_TYPE_BOOLEAN:\n    // `entry.element.value.as_boolean` is a `json_boolean_t`\n    break;\n}\n```\n\n### How to get the count of number of Key-Value pairs?\n\nIn each `typed(json_object)`, there is a member `count`\n\n```C\n#include \"json.h\"\n\n...\n\nint i;\n\ntyped(json_element) element = ...; // See example above\ntyped(json_object) *obj = element.value.as_object;\n\nfor(i = 0; i \u003c obj-\u003ecount; i++) {\n  typed(json_entry) entry = obj-\u003eentries[i];\n\n  typed(json_string) key = entry.key;\n  typed(json_element_type) type = entry.element.type;\n  typed(json_element_value) value = entry.element.value;\n  // Do something with `key`, `type` and `value`\n}\n```\n\n### How to get the number of elements in an array?\n\nIn each `typed(json_array)`, there is a member `count`\n\n```C\n#include \"json.h\"\n\n...\n\nint i;\n\ntyped(json_element) element = ...; // See example above\ntyped(json_array) *arr = element.value.as_array;\n\nfor(i = 0; i \u003c arr-\u003ecount; i++) {\n  typed(json_element) element = arr-\u003eelements[i];\n\n  typed(json_element_type) type = element.type;\n  typed(json_element_value) value = element.value;\n  // Do something with `value`\n}\n```\n\n### What if the JSON is poorly formatted with uneven whitespace\n\nCompile using `-DJSON_SKIP_WHITESPACE`\n\n## If this helped you in any way you can [buy me a beer](https://www.paypal.me/suhelchakraborty)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwhyisitworking%2FC-Simple-JSON-Parser","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwhyisitworking%2FC-Simple-JSON-Parser","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwhyisitworking%2FC-Simple-JSON-Parser/lists"}