{"id":31925041,"url":"https://github.com/stringepsilon/fbjson","last_synced_at":"2025-10-14T00:26:43.721Z","repository":{"id":2678289,"uuid":"47147779","full_name":"StringEpsilon/fbJson","owner":"StringEpsilon","description":"JSON Parser written in FreeBASIC","archived":false,"fork":false,"pushed_at":"2022-06-13T10:00:21.000Z","size":184,"stargazers_count":11,"open_issues_count":0,"forks_count":4,"subscribers_count":5,"default_branch":"master","last_synced_at":"2023-04-09T10:07:15.220Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"FreeBasic","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/StringEpsilon.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"COPYING","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-11-30T21:42:00.000Z","updated_at":"2023-02-10T21:27:59.000Z","dependencies_parsed_at":"2022-08-17T22:25:27.677Z","dependency_job_id":null,"html_url":"https://github.com/StringEpsilon/fbJson","commit_stats":null,"previous_names":[],"tags_count":22,"template":null,"template_full_name":null,"purl":"pkg:github/StringEpsilon/fbJson","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/StringEpsilon%2FfbJson","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/StringEpsilon%2FfbJson/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/StringEpsilon%2FfbJson/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/StringEpsilon%2FfbJson/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/StringEpsilon","download_url":"https://codeload.github.com/StringEpsilon/fbJson/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/StringEpsilon%2FfbJson/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279017364,"owners_count":26086052,"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","status":"online","status_checked_at":"2025-10-13T02:00:06.723Z","response_time":61,"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":[],"created_at":"2025-10-14T00:26:42.253Z","updated_at":"2025-10-14T00:26:43.713Z","avatar_url":"https://github.com/StringEpsilon.png","language":"FreeBasic","readme":"# fbJson\n\nA small JSON library written in FreeBASIC.\n\nLatest stable is 1.0.1\n\n## License\n\nfbJson is licensed under the [MPL 2.0](https://www.mozilla.org/en-US/MPL/2.0/) from version 0.14.1 onwards.\n\n## Roadmap\n\nPast 1.0 / nice to have:\n\n* [ ] More quality of life functionality\n\t* [ ] Datatype specific properties\n* [ ] Write properly escaped json on toString() call.\n* [ ] Make toString() fast(er)\n\n## fbJson specifics\n\nUnfortunately, the JSON spec (RFC 8259) leaves some aspects up for interpretation. You have to watch for the following:\n\n* **UTF-8 forgiveness**: The RFC says that all valid JSON must be UTF-8. fbJSON will reject all input that's not UTF-8 or contains\n bytesquences that are not valid in UTF. Further, fbJSON will reject certain inputs that are valid in principle, but not (currently) valid\n unicode. This includes escaped values in the \\uXXXX notation.\n* **Nesting**: The RFC says: \"An implementation may set limits on the maximum depth ofnesting\". fbJSON doesn't. It will happily\n parse nested elements until it runs out of memory. **Beware.**\n* **String length**: Same situation. In theory, the upper limit is whatever FreeBasics limit is, minus 2 byte.\n* **Duplicate keys**: Parse() will use the newer value for any key. Meaning ```{\"a\": 1, \"a\": 2}``` is treated like ```{\"a\": 2}```.\n\nNote: jsonItem.AddItem() will not override existing keys, since I think the programmer should have more control when\nmanipulating the JSON this way.\n\n## Usage\n\nFor hassle free use as-is, I suggest simply throwing the entire fbJson/ folder and the fbJson.bi file into your\nrepository to include the code at compile time. \n\nIf you don't want to litter your repository with my source code, you can also compile fbJson.bas with the \"-lib\" or \"-dll\" \nflag. Then you only need the fbJsonBase.bi and fbJsonItem.bi along with the DLL.\n\n\n## Parsing stuff\n\nYou can either give the JSON input via the constructor:\n\n```\ndim item as jsonItem = JsonItem(\"{}\")\n```\n\nOr you can create the instance first and then use .Parse().\n\n```\ndim item as jsonItem\n' some code ...\nitem.Parse(\"{}\")\n```\n\nYou could also overwrite instances with the constructor like below, but that comes with some overhead.\n\n```\ndim item as jsonItem\n' some code ...\nitem = JsonItem(\"{}\")\n```\n\n## Accessing elements\n\nYou can access any child-element via the square brackets, either by using the index of the element,\nor in case of json-Objects, using the key.\n\n`jsonItem[string]` \nReturns the child element with the corresponding key. \n\nKeys are case senstive.\n\n`jsonItem[integer]` \nReturns the nTh child of the item.\n\nKeep in mind that the index starts at 0.\n\n## Other properties and methods\n\n#### JsonItem\n\n`jsonItem.Count` \nGets the total number of children.\n\n`jsonItem.DataType` \nGets the datatype of the item.\n\n`jsonItem.Key`\nGets or sets the key of the item. Setting the key will _silently_ fail when the new key is already in use. \n\n`jsonItem.Value as string` \nGets or sets the value of the item (as string). Also sets the datatype. Returns an emptry string on objects and arrays.\n\n`jsonItem.AddItem(string, jsonItem) as boolean` \nAdds an item with a key (only on jsonObjects).\nIf the item is of type null, it's converted into an object.\n\n`jsonItem.AddItem(string, string) as boolean` \nAdds a value with a key (only on jsonObjects).\nIf the item is of type null, it's converted into an object.\n\n`jsonItem.AddItem(string) as boolean` \nAdds an item (only on jsonArrays). Returns true if successful.\nIf the item is of type null, it's converted into an array.\n\n`jsonItem.AddItem(string) as boolean` \nAdds a value (only on jsonArrays). Returns true if successful.\nIf the item is of type null, it's converted into an array.\n\n\n`jsonItem.RemoveItem(string) as boolean` \nRemoves the child with the given key. Returns true if successful.\n\n`jsonItem.RemoveItem(integer) as boolean` \nRemoves the Nth child. Returns true if successful.\n\n`jsonItem.ContainsKey(string) as boolean` \nReturns true if the item is an object that contains the given key.\n\n`jsonItem.ToString() as string` \nCreates a string representation of the Item and all it's children.\n\n## Performance and compiler options\n\nI unscientifically tested how fast fbJson parses through this monstrosity of a JSON file:\n\nhttps://github.com/zemirco/sf-city-lots-json/blob/master/citylots.json (181 mb)\n\nOn my desktop machine (AMD Ryzen 7 1700X), I get the following results:\n\n| Compiler options  | parsing time (s) |\n| ------------- | ------------- |\n| fbc \"%f\"  | 6.33  |\n| fbc \"%f\" -gen GCC -Wc -O1 | ~4.01  |\n\nTest-setup is just loading the file with open and get# and this loop:\n\n```\ndim as double start = timer\nfor i as uinteger = 1 to 30\n\tdim item as jsonItem = jsonItem(jsonFile)\nnext\nprint (timer - start) / 30\n```\n\nSetup:\n\n* AMD Ryzen 7 1700X \n* FreeBASIC Compiler - Version 1.06.0 (11-18-2017) (64bit)\n* glibc 2.28\n* Linux 4.20.4 (64bit)\n* fbJson commit 6ef899d296\n\n## Design\n\nThe basic principle behind fbJson is to handle all parsing of JSON in one go. There is no AST, no tokenization, etc. \nJsonBase.Parse() will do all the heavy lifting while iterating over the input byte for byte. Ideally, fbJson would not\ndo a single string comparison and only ever look at each byte of the input once. Didn't quite get there ;-)\n\nfbJson is not the fastest parser in the world, but I tried my best to optimize it. As a result, a lot of the code\nis rather ugly and convuluted. isValidDouble() is the most prominent example. Keep that in mind when exploring the codebase.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstringepsilon%2Ffbjson","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fstringepsilon%2Ffbjson","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstringepsilon%2Ffbjson/lists"}