JSONObject

From Unify Community Wiki
Revision as of 05:40, 24 August 2010 by Scone (Talk | contribs)

Jump to: navigation, search

Contents

Intro

I 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 [json.org], but found them to be too complicated, or used part of the .NET framework not accessible from Unity scripts. 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.

Usage

Users should not have to modify the JSONObject class themselves, and must follow the very simple proceedures outlined below:

Sample data (in JSON format): {"field1":0.5,"field2":"sampletext","field3":[1,2,3]}


Encoding

Note: your data can only be numbers and strings. This is not a solution for object serialization or anything like that.

<csharp> JSONObject j = new JSONObject(JSONObject.Type.OBJECT); //number j.keys.Add("field1"); j.list.Add(0.5); //string j.keys.Add("field2"); j.list.Add("sampletext"); //array j.keys.Add("field3");

JSONObject arr = new JSONObject(JSONObject.Type.ARRAY); arr.list.Add(1); arr.list.Add(2); arr.list.Add(3);

j.list.Add(arr);

string encodedString = j.print(); </csharp>

Decoding

<csharp> string encodedString = "{"field1":0.5,"field2":"sampletext","field3":[1,2,3]}"; JSONObject j = new JSONObject(encodedString); accessData(j); //access data (and print it) void accessData(JSONObject obj){ switch(obj.type){ case JSONObject.Type.OBJECT: for(int i = 0; i < obj.list.Count; i++){ string key = (string)obj.keys[i]; JSONObject j = (JSONObject)obj.list[i]; Debug.Log(key); accessData(j); } break; case JSONObject.Type.ARRAY: foreach(JSONObject j in obj.list){ accessData(j); } break; case JSONObject.Type.STRING: Debug.Log(obj.str); break; case JSONObject.Type.NUMBER: Debug.Log(obj.n); break; case JSONObject.Type.BOOL: Debug.Log(obj.n); break; case JSONObject.Type.NULL: Debug.Log(obj.n); break;

} } </csharp>


The JSONObject class

<csharp> using UnityEngine; using System.Collections;

public class JSONObject { public ArrayList keys; public enum Type { STRING, NUMBER, OBJECT, ARRAY, BOOL, NULL } public JSONObject parent; public Type type; public ArrayList list; public string str; public double n; public bool b;

public JSONObject() { } public JSONObject(JSONObject.Type t) { type = t; switch(t) { case Type.ARRAY: list = new ArrayList(); break; case Type.OBJECT: list = new ArrayList(); keys = new ArrayList(); break; } } public JSONObject(bool b){ type = Type.BOOL; this.b = b; } public JSONObject(float f){ type = Type.NUMBER; this.n = f; } public JSONObject() { type = Type.NULL; } public JSONObject(string str) { //create a new JSONObject from a string (this will also create any children, and parse the whole string) if(str.Length > 0) { if(str == "true") { type = Type.BOOL; b = true; } else if(str == "false") { type = Type.BOOL; b = false; } else if(str == "null") { type = Type.NULL; } else if(str[0] == '"') { type = Type.STRING; this.str = str.Substring(1, str.Length - 2); } else { try { n = System.Convert.ToDouble(str); type = Type.NUMBER; } catch(System.FormatException) { int token_tmp = 0; /* * Checking for the following formatting (www.json.org) * object - {"field1":value,"field2":value} * array - [value,value,value] * value - string - "string" * - number - 0.0 * - bool - true -or- false * - null - null */ switch(str[0]) { case '{': type = Type.OBJECT; keys = new ArrayList(); list = new ArrayList(); break; case '[': type = JSONObject.Type.ARRAY; list = new ArrayList(); break; default: type = Type.NULL; Debug.Log("improper JSON formatting"); return; } int depth = 0; bool openquote = false; for(int i = 1; i < str.Length; i++) { if(str[i] == '"') openquote = !openquote; if(str[i] == '[' || str[i] == '{') depth++; if(depth == 0 && !openquote) { if(str[i] == ':') { keys.Add(str.Substring(token_tmp + 2, i - token_tmp - 3)); token_tmp = i; } if(str[i] == ',') { list.Add(new JSONObject(str.Substring(token_tmp + 1, i - token_tmp - 1))); token_tmp = i; } if(str[i] == ']' || str[i] == '}') list.Add(new JSONObject(str.Substring(token_tmp + 1, i - token_tmp - 1))); } if(str[i] == ']' || str[i] == '}') depth--; } } } } else { type = Type.NULL; } } public string print() { //Convert the JSONObject into a stiring string str = ""; switch(type) { case Type.STRING: str = "\"" + this.str + "\""; break; case Type.NUMBER: str += n; break; case JSONObject.Type.OBJECT: str = "{"; for(int i = 0; i < list.Count; i++) { string key = (string)keys[i]; str += "\"" + key + "\":"; JSONObject obj = (JSONObject)list[i]; str += obj.print() +","; } str = str.Substring(0, str.Length - 1); str += "}"; break; case JSONObject.Type.ARRAY: str = "["; foreach(JSONObject obj in list) { str += obj.print() + ","; } str = str.Substring(0, str.Length - 1); str += "]"; break; case Type.BOOL: str += b; break; case Type.NULL: str = "null"; break; } return str; } public static implicit operator bool(JSONObject j) { return j != null; } } </csharp>

Personal tools
Namespaces

Variants
Actions
Navigation
Extras
Toolbox