{"id":39179578,"url":"https://github.com/codewitch-honey-crisis/htcw_json","last_synced_at":"2026-01-17T22:32:32.700Z","repository":{"id":230571806,"uuid":"779563661","full_name":"codewitch-honey-crisis/htcw_json","owner":"codewitch-honey-crisis","description":"a small pull parser for JSON","archived":false,"fork":false,"pushed_at":"2025-11-10T00:31:59.000Z","size":56,"stargazers_count":4,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-11-10T02:26:04.677Z","etag":null,"topics":["bulk","json","streaming"],"latest_commit_sha":null,"homepage":"https://www.codeproject.com/Articles/5379857/htcw-json-A-tiny-streaming-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/codewitch-honey-crisis.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,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2024-03-30T06:45:34.000Z","updated_at":"2025-11-10T00:32:03.000Z","dependencies_parsed_at":"2024-05-10T10:28:41.526Z","dependency_job_id":"341515be-cb43-4f3d-bc8c-1e01851f0838","html_url":"https://github.com/codewitch-honey-crisis/htcw_json","commit_stats":null,"previous_names":["codewitch-honey-crisis/htcw_json"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/codewitch-honey-crisis/htcw_json","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/codewitch-honey-crisis%2Fhtcw_json","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/codewitch-honey-crisis%2Fhtcw_json/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/codewitch-honey-crisis%2Fhtcw_json/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/codewitch-honey-crisis%2Fhtcw_json/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/codewitch-honey-crisis","download_url":"https://codeload.github.com/codewitch-honey-crisis/htcw_json/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/codewitch-honey-crisis%2Fhtcw_json/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28520836,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-17T22:11:28.393Z","status":"ssl_error","status_checked_at":"2026-01-17T22:11:27.841Z","response_time":85,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["bulk","json","streaming"],"created_at":"2026-01-17T22:32:31.940Z","updated_at":"2026-01-17T22:32:32.687Z","avatar_url":"https://github.com/codewitch-honey-crisis.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# JSON\n\nA minimalist JSON parser with streaming support\n\n```\n[env:node32s]\nplatform = espressif32\nboard = node32s\nframework = arduino\nlib_deps = \n\tcodewitch-honey-crisis/htcw_json\n```\n\nSee [IP Geolocation with an ESP32 and Arduino at CodeProject](https://www.codeproject.com/articles/IP-Geolocation-with-an-ESP32-and-Arduino) for a simple real world example\n\n```cpp\n#include \u003cstdio.h\u003e\n#include \u003cstddef.h\u003e\n#include \u003cstdint.h\u003e\n#include \u003cmemory.h\u003e\n#include \u003cstring.h\u003e\n#include \u003cjson.hpp\u003e\nusing namespace io;\nusing namespace json;\nvoid indent(int spaces, FILE* file) {\n    while(spaces--) fprintf(file,\"    \");\n}\n// accept any reader regardless of capture size\nvoid dump(json_reader_base\u0026 reader, FILE* file) {\n    // don't de-escape and dequote field names or string values:\n    //reader.raw_strings(true);\n    \n    bool first_part=true; // first value part in series\n    int tabs = 0; // number of \"tabs\" to indent by\n    bool skip_read = false; // don't call read() the next iteration\n    while(skip_read || reader.read()) {\n        skip_read = false;\n        switch(reader.node_type()) {\n            case json_node_type::array:\n                indent(tabs++,file);\n                fputs(\"[\",file);\n                break;\n            case json_node_type::end_array:\n                indent(--tabs,file);\n                fputs(\"]\",file);\n                break;\n            case json_node_type::object:\n                indent(tabs++,file);\n                fputs(\"{\",file);\n                break;\n            case json_node_type::end_object:\n                indent(--tabs,file);\n                fputs(\"}\",file);\n                break;\n            case json_node_type::field:\n                indent(tabs,file);\n                fprintf(file, \"%s: \",reader.value());\n                // we want to spit the value here, so \n                // we basically hijack the reader and \n                // read the value subtree here.\n                while(reader.read() \u0026\u0026 reader.is_value()) {\n                    fprintf(file,\"%s\",reader.value());\n                }\n                fputs(\"\",file);\n                skip_read = true;\n                break;\n            case json_node_type::value:\n                indent(tabs,file);\n                fprintf(file,\"%s\\r\\n\",reader.value());\n                //fwrite(reader.value(),1,strlen(reader.value()),file);\n                fputs(\"\",file);\n                break;\n            case json_node_type::value_part:\n                // the first value part needs to be indented\n                if(first_part) {\n                    indent(tabs,file);\n                    first_part = false; // reset the flag\n                }\n                fprintf(file,\"%s\",reader.value());\n                break;\n            case json_node_type::end_value_part:\n                fprintf(file,\"%s,\\r\\n\",reader.value());               \n                // set the first flag\n                first_part = true;\n                break;      \n        }\n    }\n}\nchar name[2048];\nchar overview[8192];\nvoid read_episodes(json_reader_base\u0026 reader, FILE* file) {\n    int episodes_array_depth = 0;\n    if(reader.read() \u0026\u0026 reader.node_type()==json_node_type::array) {\n        episodes_array_depth = reader.depth();\n        while(true) {\n            if(reader.depth()==episodes_array_depth \u0026\u0026 reader.node_type()==json_node_type::end_array) {\n                break;\n            }\n            if(reader.read()\u0026\u0026reader.node_type()==json_node_type::object) {\n                \n                int episode_object_depth = reader.depth();\n                int season_number = -1;\n                int episode_number = -1;\n                while(reader.read() \u0026\u0026 reader.depth()\u003e=episode_object_depth) {\n                    if(reader.depth()==episode_object_depth \u0026\u0026 reader.node_type()==json_node_type::field) {\n                        if(0==strcmp(\"episode_number\",reader.value()) \u0026\u0026 reader.read() \u0026\u0026 reader.node_type()==json_node_type::value) {\n                            episode_number = reader.value_int();\n                        }\n                        if(0==strcmp(\"season_number\",reader.value()) \u0026\u0026 reader.read() \u0026\u0026 reader.node_type()==json_node_type::value) {\n                            season_number = reader.value_int();\n                        }\n                        if(0==strcmp(\"name\",reader.value())) {\n                            name[0]=0;\n                            while(reader.read() \u0026\u0026 reader.is_value()) {\n                                strcat(name,reader.value());\n                            }\n                        }\n                        if(0==strcmp(\"overview\",reader.value())) {\n                            overview[0]=0;\n                            while(reader.read() \u0026\u0026 reader.is_value()) {\n                                strcat(overview,reader.value());\n                            }\n                        }\n                    }\n                }\n                if(season_number\u003e-1 \u0026\u0026 episode_number\u003e-1 \u0026\u0026 name[0]) {\n                    fprintf(file,\"S%02dE%02d %s\\r\\n\",season_number,episode_number,name);\n                    if(overview[0]) {\n                        fprintf(file,\"\\t%s\\r\\n\",overview);\n                    }\n                    fputs(\"\",file);\n                }\n            }\n        }\n    }\n}\nvoid read_series(json_reader_base\u0026 reader,FILE* file) {\n    while(reader.read()) {\n        switch(reader.node_type()) {\n            case json_node_type::field:\n                if(0==strcmp(\"episodes\",reader.value())) {\n                    read_episodes(reader,file);\n                }\n                break;\n            default:\n                break;      \n        }\n    }\n}\nint main() {\n    file_stream stm(\"C:\\\\Users\\\\gazto\\\\Documents\\\\json_test\\\\data.json\",io::file_mode::read);\n    json_reader reader(stm);\n    read_series(reader,stdout);\n    return 0;\n}\n```\n\nThis will parse JSON of the following format\n\n```js\n{\n  \"backdrop_path\": \"/lgTB0XOd4UFixecZgwWrsR69AxY.jpg\",\n  \"created_by\": [\n      {\n        \"id\": 1233032,\n        \"credit_id\": \"525749f819c29531db09b231\",\n        \"name\": \"Matt Nix\",\n        \"profile_path\": \"/qvfbD7kc7nU3RklhFZDx9owIyrY.jpg\"\n      }\n    ],\n  \"episode_run_time\": [\n      45\n    ],\n  \"first_air_date\": \"2007-06-28\",\n  \"genres\": [\n      {\n        \"id\": 10759,\n        \"name\": \"Action \u0026 Adventure\"\n      },\n      {\n        \"id\": 18,\n        \"name\": \"Drama\"\n      }\n    ],\n  \"homepage\": \"http://usanetwork.com/burnnotice\",\n  \"id\": 2919,\n  \"in_production\": false,\n  \"languages\": [\n      \"en\"\n    ],\n  \"last_air_date\": \"2013-09-12\",\n  \"last_episode_to_air\": {\n      \"air_date\": \"2013-09-12\",\n      \"episode_number\": 13,\n      \"id\": 224759,\n      \"name\": \"Reckoning\",\n      \"overview\": \"Series Finale. Michael must regain the trust of those closest to him in order to finish what he started.\",\n      \"production_code\": null,\n      \"season_number\": 7,\n      \"show_id\": 2919,\n      \"still_path\": \"/lGdhFXEi29e2HeXMzgA9bvvIIJU.jpg\",\n      \"vote_average\": 0,\n      \"vote_count\": 0\n    },\n  \"name\": \"Burn Notice\",\n  \"next_episode_to_air\": null,\n  \"networks\": [\n      {\n        \"name\": \"USA Network\",\n        \"id\": 30,\n        \"logo_path\": \"/g1e0H0Ka97IG5SyInMXdJkHGKiH.png\",\n        \"origin_country\": \"US\"\n      }\n    ],\n  \"number_of_episodes\": 111,\n  \"number_of_seasons\": 7,\n  \"origin_country\": [\n      \"US\"\n    ],\n  \"original_language\": \"en\",\n  \"original_name\": \"Burn Notice\",\n  \"overview\": \"A formerly blacklisted spy uses his unique skills and training to help people in desperate situations.\",\n  \"popularity\": 12.174,\n  \"poster_path\": \"/A9EmzNtwfEnXYdMTgGKcL4kiZm2.jpg\",\n  \"production_companies\": [\n      {\n        \"id\": 6981,\n        \"logo_path\": null,\n        \"name\": \"Fuse Entertainment\",\n        \"origin_country\": \"\"\n      },\n      {\n        \"id\": 6529,\n        \"logo_path\": null,\n        \"name\": \"Fox Television Studios\",\n        \"origin_country\": \"\"\n      }\n    ],\n  \"seasons\": [\n      {\n        \"_id\": \"525749cc19c29531db0988cc\",\n        \"air_date\": \"2011-04-17\",\n        \"episodes\": [\n            {\n              \"air_date\": \"2011-04-17\",\n              \"episode_number\": 1,\n              \"id\": 224659,\n              \"name\": \"The Fall of Sam Axe\",\n              \"overview\": \"The Fall of Sam Axe is a 2011 American television film based on the USA Network television series Burn Notice. It was the first official Burn Notice spin-off, and was directed by Jeffrey Donovan. The show was broadcast in the United States on April 17, 2011, on the U.S. television network USA Network. The film, while not an episode of the show, introduced plot elements for the show's fifth season.\",\n              \"production_code\": null,\n              \"season_number\": 0,\n              \"show_id\": 2919,\n              \"still_path\": \"/dchZWB1GoBuk1l4HFtmbVdIfE6w.jpg\",\n              \"vote_average\": 0,\n              \"vote_count\": 0,\n              \"crew\": [\n                  {\n                    \"id\": 52886,\n                    \"credit_id\": \"525749ee19c29531db09a624\",\n                    \"name\": \"Jeffrey Donovan\",\n                    \"department\": \"Directing\",\n                    \"job\": \"Director\",\n                    \"profile_path\": \"/5i47zZDpnAjLBtQdlqhg5AIYCuT.jpg\"\n                  },\n                  {\n                    \"id\": 1233032,\n                    \"credit_id\": \"525749d019c29531db098a46\",\n                    \"name\": \"Matt Nix\",\n                    \"department\": \"Writing\",\n                    \"job\": \"Writer\",\n                    \"profile_path\": null\n                  }\n                ],\n              \"guest_stars\": []\n            }\n          ],\n        \"name\": \"Specials\",\n        \"overview\": \"\",\n        \"poster_path\": \"/AoMKrA2j56SrQMBc3hp5jVmLv3B.jpg\",\n        \"season_number\": 0\n      },\n...\n```\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcodewitch-honey-crisis%2Fhtcw_json","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcodewitch-honey-crisis%2Fhtcw_json","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcodewitch-honey-crisis%2Fhtcw_json/lists"}