5 * (C) 2006 by Derrell Lipman
9 * LGPL 2.1: http://creativecommons.org/licenses/LGPL/2.1/
13 * This module provides a JSON encoder.
17 /* escape a string as required by json */
21 var arr = new Array();
23 for (i = 0; i < strlen(s); i++)
25 var c = substr(s, i, 1);
30 if (Json._internal.convert[c] != undefined)
32 arr[i] = Json._internal.convert[c];
48 /* encode an arbitrary object. called recursively, for object and array */
51 var type = nativeTypeOf(o);
53 if (type == "undefined")
55 return "null"; /* you really shouldn't count on this! */
57 else if (type == "null")
61 else if (type == "boolean")
72 else if (type == "c_function" ||
73 type == "js_function" ||
74 type == "string_c_function")
78 else if (type == "float" ||
84 else if (type == "pointer")
87 return '"' + substr(x, 16, strlen(x) - 16 - 1) + '"';
89 else if (type == "object")
93 /* Is this an array or an ordinary object? */
94 if (o["length"] != undefined)
98 /* Assume it's an array if there's a length field */
100 for (i = 0; i < o.length; i++)
103 * NOTE: We don't support sparse arrays nor associative
104 * arrays. Should we later want to do either, we're supposed
105 * to send it as an object rather than as an array.
111 buf = buf + this.encode(o[i]);
115 else if (o["__type"] == "_JSON_Date")
117 buf = "" + o.encoding();
121 /* No length field, so it must be an ordinary object */
132 buf = buf + '"' + key + '":' + this.encode(o[key]);
140 else if (type == "string")
142 return '"' + this._internal.escape(o) + '"';
146 return '{ "unknown_object":"' + type + '"}';
150 /* Allocate the public Json access object */
153 /* Json.encode(): encode an arbitrary object */
154 Json.encode = _encode;
157 /* Json.decode(): decode a string into its object form */
158 Json.decode = literal_to_var;
160 /* Internal stuff, not for external access */
161 Json._internal = new Object();
163 Json._internal.escape = _escape;
166 Json._internal.convert = new Object();
167 Json._internal.convert['\b'] = '\\b';
168 Json._internal.convert['\t'] = '\\t';
169 Json._internal.convert['\n'] = '\\n';
170 Json._internal.convert['\f'] = '\\f';
171 Json._internal.convert['\r'] = '\\r';
172 Json._internal.convert['"'] = '\\"';
173 Json._internal.convert['\\'] = '\\\\';
174 Json._internal.convert['\x01'] = '\\u0001';
175 Json._internal.convert['\x02'] = '\\u0002';
176 Json._internal.convert['\x03'] = '\\u0003';
177 Json._internal.convert['\x04'] = '\\u0004';
178 Json._internal.convert['\x05'] = '\\u0005';
179 Json._internal.convert['\x06'] = '\\u0006';
180 Json._internal.convert['\x07'] = '\\u0007';
181 Json._internal.convert['\x08'] = '\\u0008';
182 Json._internal.convert['\x09'] = '\\u0009';
183 Json._internal.convert['\x0a'] = '\\u000a';
184 Json._internal.convert['\x0b'] = '\\u000b';
185 Json._internal.convert['\x0c'] = '\\u000c';
186 Json._internal.convert['\x0d'] = '\\u000d';
187 Json._internal.convert['\x0e'] = '\\u000e';
188 Json._internal.convert['\x0f'] = '\\u000f';
189 Json._internal.convert['\x10'] = '\\u0010';
190 Json._internal.convert['\x11'] = '\\u0011';
191 Json._internal.convert['\x12'] = '\\u0012';
192 Json._internal.convert['\x13'] = '\\u0013';
193 Json._internal.convert['\x14'] = '\\u0014';
194 Json._internal.convert['\x15'] = '\\u0015';
195 Json._internal.convert['\x16'] = '\\u0016';
196 Json._internal.convert['\x17'] = '\\u0017';
197 Json._internal.convert['\x18'] = '\\u0018';
198 Json._internal.convert['\x19'] = '\\u0019';
199 Json._internal.convert['\x1a'] = '\\u001a';
200 Json._internal.convert['\x1b'] = '\\u001b';
201 Json._internal.convert['\x1c'] = '\\u001c';
202 Json._internal.convert['\x1d'] = '\\u001d';
203 Json._internal.convert['\x1e'] = '\\u001e';
204 Json._internal.convert['\x1f'] = '\\u001f';
206 * At some point, we probably want to add \x80-\xff as well, and it's then
207 * probably more efficient to generate these strings dynamically. (Even now
208 * it may be, but this was the the way I started, and so it remains.)
214 libinclude("base.js");
215 function testFormat()
217 var test = new Object();
219 test.str = "hello world";
222 test.array = new Array();
223 test.array[0] = "hello";
224 test.array[1] = "world";
225 test.obj = new Object();
227 test.obj.array = new Array();
228 test.obj.array[0] = 42;
229 test.obj.array[1] = 223;
230 printf("%s\n", Json.encode(test));
236 libinclude("base.js");
242 obj = Json.decode(s);
243 printf("Decode/encode of\n\t%s\nyielded\n\t%s\n\n", s, Json.encode(obj));
245 s = '{ "x" : [ 23, 42] }';
246 obj = Json.decode(s);
247 printf("Decode/encode of\n\t%s\nyielded\n\t%s\n\n", s, Json.encode(obj));
249 s = '[ 13, 19, { "x" : [ 23, 42] }, 223 ]';
250 obj = Json.decode(s);
251 printf("Decode/encode of\n\t%s\nyielded\n\t%s\n\n", s, Json.encode(obj));
253 s = '{ "x" : [ "hi" ] }';
254 obj = Json.decode(s);
255 printf("Decode/encode of\n\t%s\nyielded\n\t%s\n\n", s, Json.encode(obj));
257 s = '[ 13, 19, { "x" : [ 23, 42, { "y":{"a":"hello", "b":"world", "c":[1,2,3]}}] }, 223 ]';
258 obj = Json.decode(s);
259 printf("Decode/encode of\n\t%s\nyielded\n\t%s\n\n", s, Json.encode(obj));