{"id":13662371,"url":"https://github.com/mtschoen/JSONObject","last_synced_at":"2025-04-25T10:31:02.803Z","repository":{"id":19476651,"uuid":"22722087","full_name":"mtschoen/JSONObject","owner":"mtschoen","description":"The JSONObject class/library for Unity","archived":false,"fork":false,"pushed_at":"2022-12-27T06:53:23.000Z","size":204,"stargazers_count":281,"open_issues_count":5,"forks_count":70,"subscribers_count":18,"default_branch":"master","last_synced_at":"2024-08-02T05:13:52.769Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"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/mtschoen.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-08-07T13:24:21.000Z","updated_at":"2024-07-29T10:07:22.000Z","dependencies_parsed_at":"2023-01-11T20:28:38.698Z","dependency_job_id":null,"html_url":"https://github.com/mtschoen/JSONObject","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mtschoen%2FJSONObject","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mtschoen%2FJSONObject/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mtschoen%2FJSONObject/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mtschoen%2FJSONObject/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mtschoen","download_url":"https://codeload.github.com/mtschoen/JSONObject/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":223996553,"owners_count":17238327,"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":[],"created_at":"2024-08-02T05:01:56.855Z","updated_at":"2024-11-10T18:30:16.313Z","avatar_url":"https://github.com/mtschoen.png","language":"C#","funding_links":[],"categories":["C\\#","Game Development"],"sub_categories":["Unity Engine: Resources"],"readme":"# Author\n\n Matt Schoen \u003cschoen@defectivestudios.com\u003e of [Defective Studios](http://www.defectivestudios.com)\n\n\n# Intro\n\nI came across the need to send structured data to and from a server on one of my projects, and figured it would be worth my while to use JSON.  When I looked into the issue, I tried a few of the C# implementations listed on http://json.org, but found them to be too complicated to work with and expand upon.  So, I've written a very simple JSONObject class, which can be generically used to encode/decode data into a simple container.  This page assumes that you know what JSON is, and how it works.  It's rather simple, just go to json.org for a visual description of the encoding format.\n\n# Usage\n\nUsers should not have to modify the JSONObject class themselves, and must follow the very simple procedures outlined below:\n\nSample data (in JSON format):\n```JSON\n{\n    \"TestObject\": {\n        \"SomeText\": \"Blah\",\n        \"SomeObject\": {\n            \"SomeNumber\": 42,\n            \"SomeBool\": true,\n            \"SomeNull\": null\n        },\n        \n        \"SomeEmptyObject\": { },\n        \"SomeEmptyArray\": [ ],\n        \"EmbeddedObject\": \"{\\\"field\\\":\\\"Value with \\\\\\\"escaped quotes\\\\\\\"\\\"}\"\n    }\n}\n```\n\nThe test classes provide the best examples for how the API is intended to be used.\n\n## Features\n\n* Decode JSON-formatted strings into a usable data structure\n* Encode structured data into a JSON-formatted string\n* Interoperable with `Dictionary` and `WWWForm`\n* Optimized `parse`/`stringify` functions -- minimal (unavoidable) garbage creation\n* Asynchronous `stringify` function for serializing lots of data without frame drops\n* `MaxDepth` parsing will skip over nested data that you don't need\n* Special (non-compliant) `Baked` object type can store stringified data within parsed objects\n* Copy to new `JSONObject`\n* Merge with another `JSONObject` (experimental)\n* Random access (with `int` or `string`)\n* `ToString()` returns JSON data with optional \"pretty\" flag to include newlines and tabs\n* Switch between double and float for numeric storage depending on level of precision needed (and to ensure that numbers are parsed/stringified correctly)\n* Supports `Infinity` and `NaN` values\n* `JSONTemplates` static class provides serialization functions for common classes like `Vector3`, `Matrix4x4` \n* Object pool implementation (experimental)\n* Handy `JSONChecker` window to test parsing on sample data\n\nIt should be pretty obvious what this parser can and cannot do.  If anyone reading this is a JSON buff (is there such a thing?) please feel free to expand and modify the parser to be more compliant.  Currently I am using the .NET `System.Convert` namespace functions for parsing the data itself.  It parses strings and numbers, which was all that I needed of it, but unless the formatting is supported by `System.Convert`, it may not incorporate all proper JSON strings.  Also, having never written a JSON parser before, I don't doubt that I could improve the efficiency or correctness of the parser.  It serves my purpose, and hopefully will help you with your project!  Let me know if you make any improvements :)\n\nAlso, you JSON buffs (really, who would admit to being a JSON buff...) might also notice from my feature list that this thing isn't exactly to specifications. Here is where it differs:\n* \"a string\" is considered valid JSON.  There is an optional \"strict\" parameter to the parser which will bomb out on such input, in case that matters to you.\n* The `Baked` mode is totally made up.\n* The `MaxDepth` parsing is totally made up.\n* `NaN` and `Infinity` were introduced in a later version of the standard, and some linters will report them as errors\n\n\n## Encoding\n\nEncoding is something of a hard-coded process.  This is because I have no idea what your data is!  It would be great if this were some sort of interface for taking an entire class and encoding it's number/string fields, but it's not.  I've come up with a few clever ways of using loops and/or recursive methods to cut down of the amount of code I have to write when I use this tool, but they're pretty project-specific.\n\nThe constructor, Add, and AddField functions now support a nested delegate structure.  This is useful if you need to create a nested JSONObject in a single line.  For example:\n\n\n```C#\nvoid DoRequest(string url, string jsonString) {\n\t// Web Request logic\n}\n\nvoid Test(string url) {\n\tDoRequest(url, new JSONObject(request =\u003e {\n\t\trequest.AddField(\"sort\", sort =\u003e sort.AddField(\"_timestamp\", \"desc\"));\n\t\trequest.AddField(\"query\", new JSONObject(query =\u003e query.AddField(\"match_all\", JSONObject.emptyObject)));\n\t\trequest.AddField(\"fields\", fields =\u003e fields.Add(\"_timestamp\"));\n\t}).ToString());\n}\n```\n\n\n## Decoding\n\nDecoding is much simpler on the input end, and again, what you do with the `JSONObject` will vary on a per-project basis.  One of the more complicated way to extract the data is with a recursive function, as drafted below.  Calling the constructor with a properly formatted JSON string will return the root object (or array) containing all of its children, in one neat reference!  The data is in a public `ArrayList` called `list`, with a matching key list (called `keys`!) if the root is an `Object`.  If that's confusing, take a glance over the following code and the `print()` method in the `JSONObject` class.  If there is an error in the JSON formatting (or if there's an error with my code!) the debug console will read \"improper JSON formatting\".\n\n```C#\nvoid Test() {\n\tvar encodedString = \"{\\\"field1\\\": 0.5,\\\"field2\\\": \\\"sampletext\\\",\\\"field3\\\": [1,2,3]}\";\n\tvar jsonObject = new JSONObject(encodedString);\n\tAccessData(jsonObject);\n}\n\nvoid AccessData(JSONObject jsonObject) {\n\tswitch (jsonObject.type) {\n\t\tcase JSONObject.Type.Object:\n\t\t\tfor (var i = 0; i \u003c jsonObject.list.Count; i++) {\n\t\t\t\tvar key = jsonObject.keys[i];\n\t\t\t\tvar value = jsonObject.list[i];\n\t\t\t\tDebug.Log(key);\n\t\t\t\tAccessData(value);\n\t\t\t}\n\t\t\tbreak;\n\t\tcase JSONObject.Type.Array:\n\t\t\tforeach (JSONObject element in jsonObject.list) {\n\t\t\t\tAccessData(element);\n\t\t\t}\n\t\t\tbreak;\n\t\tcase JSONObject.Type.String:\n\t\t\tDebug.Log(jsonObject.stringValue);\n\t\t\tbreak;\n\t\tcase JSONObject.Type.Number:\n\t\t\tDebug.Log(jsonObject.floatValue);\n\t\t\tbreak;\n\t\tcase JSONObject.Type.Bool:\n\t\t\tDebug.Log(jsonObject.boolValue);\n\t\t\tbreak;\n\t\tcase JSONObject.Type.Null:\n\t\t\tDebug.Log(\"Null\");\n\t\t\tbreak;\n\t\tcase JSONObject.Type.Baked:\n\t\t\tDebug.Log(jsonObject.stringValue);\n\t\t\tbreak;\n\t}\n}\n```\n\nDecoding also supports a delegate format which will automatically check if a field exists before processing the data, providing an optional parameter for an OnFieldNotFound response.  For example:\n\n```C#\nvoid Test(string jsonString) {\n\tvar list = new JSONObject(jsonString);\n\tlist.GetField(\"users\", users =\u003e {\n\t\tforeach (var user in users.list) {\n\t\t\tvar thisUser = user;\n\t\t\tusers.GetField(\"sessions\", sessions =\u003e {\n\t\t\t\tforeach (JSONObject gameSession in sessions.list) {\n\t\t\t\t\tDebug.Log(gameSession);\n\t\t\t\t}\n\t\t\t}, name =\u003e Debug.LogWarning(string.Format(\"No sessions for user {0}\", thisUser[\"name\"].stringValue)));\n\t\t}\n\t\t\n\t});\n}\n```\n\n## `(O(n))` Random access\n\nI've added a string and int [] index to the class, so you can now retrieve data as such (from above):\n\n```C#\nvoid Test() {\n\tvar jsonObject = new JSONObject(\"{\\\"field\\\":[0,1,2]\");\n\tvar array = jsonObject[\"field\"];\n\tDebug.Log(array[2].intValue); //Should output \"2\"\n}\n```\n\n## Change Log\n\n### v2.1.3\n* Fix exception where input is just an empty array or object\n* Pool and null out list and keys field when clearing JSONObject for consistency with a fresh object;\nThis was causing the MaxDepthWithExcessLevels test to fail randomly when checking results because some pooled objects had list but not keys\n* Update JSONChecker with information about pools and a note about not validating standard JSON\n\n### v2.1.2\n* Fix issue parsing json strings with whitespace after colon characters\n\n### v2.1.1\n* Fix issue parsing nested arrays with multiple elements\n* Refactor MaxDepth tests\n* Fix issues with MaxDepth\n\n### v2.1\n* Add async parsing method\n* Rewrite and optimize parser\n* Fix parsing errors\n* Refactor VectorTemplates to use extension methods\n* Add more tests\n\n### v2.0\n* Add JSONObject to Defective.JSON namespace\n* Update APIs to be more descriptive\n* Fix parsing errors\n* Add tests\n\n### v1.4\nBig update!\n\n* Better GC performance.  Enough of that garbage!\n\t* Remaining culprits are internal garbage from `StringBuilder.Append`/`AppendFormat`, `String.Substring`, `List.Add`/`GrowIfNeeded`, `Single.ToString`\n* Added asynchronous `Stringify` function for serializing large amounts of data at runtime without frame drops\n* Added `Baked` type\n* Added `MaxDepth` to parsing function\n* Various cleanup refactors recommended by ReSharper\n\n### v1.3.2\n* Added support for `NaN`\n* Added strict mode to fail on purpose for improper formatting.  Right now this just means that if the parse string doesn't start with `[` or `{`, it will print a warning and return a `null` `JSONObject`.\n* Changed `infinity` and `NaN` implementation to use `float` and `double` instead of `Mathf`\n* Handles empty objects/arrays better\n* Added a flag to print and `ToString` to turn on/off pretty print.  The define on top is now an override to system-wide disable\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmtschoen%2FJSONObject","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmtschoen%2FJSONObject","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmtschoen%2FJSONObject/lists"}