1 /* |
1 /* |
2 json.js |
2 json.js |
3 2007-03-20 |
3 2007-03-20 |
4 |
4 |
5 All of the code contained within this file is released into |
5 All of the code contained within this file is released into |
6 the public domain. Optionally, you may distribute this code |
6 the public domain. Optionally, you may distribute this code |
7 under the terms of the GNU General Public License as well |
7 under the terms of the GNU General Public License as well |
8 (public domain licensing allows this). |
8 (public domain licensing allows this). |
9 |
9 |
10 */ |
10 */ |
11 |
11 |
12 function toJSONString(input) |
12 function toJSONString(input) |
13 { |
13 { |
14 if ( window.JSON ) |
14 if ( window.JSON ) |
15 { |
15 { |
16 return window.JSON.stringify(input); |
16 return window.JSON.stringify(input); |
17 } |
17 } |
18 var m = { |
18 var m = { |
19 '\b': '\\b', |
19 '\b': '\\b', |
20 '\t': '\\t', |
20 '\t': '\\t', |
21 '\n': '\\n', |
21 '\n': '\\n', |
22 '\f': '\\f', |
22 '\f': '\\f', |
23 '\r': '\\r', |
23 '\r': '\\r', |
24 '"' : '\\"', |
24 '"' : '\\"', |
25 '\\': '\\\\' |
25 '\\': '\\\\' |
26 }; |
26 }; |
27 var t = typeof(input); |
27 var t = typeof(input); |
28 switch(t) |
28 switch(t) |
29 { |
29 { |
30 case 'string': |
30 case 'string': |
31 if (/["\\\x00-\x1f]/.test(input)) |
31 if (/["\\\x00-\x1f]/.test(input)) |
32 { |
32 { |
33 return '"' + input.replace(/([\x00-\x1f\\"])/g, function(a, b) |
33 return '"' + input.replace(/([\x00-\x1f\\"])/g, function(a, b) |
34 { |
34 { |
35 var c = m[b]; |
35 var c = m[b]; |
36 if (c) { |
36 if (c) { |
37 return c; |
37 return c; |
38 } |
38 } |
39 c = b.charCodeAt(); |
39 c = b.charCodeAt(); |
40 return '\\u00' + |
40 return '\\u00' + |
41 Math.floor(c / 16).toString(16) + |
41 Math.floor(c / 16).toString(16) + |
42 (c % 16).toString(16); |
42 (c % 16).toString(16); |
43 }) + '"'; |
43 }) + '"'; |
44 } |
44 } |
45 return '"' + input + '"'; |
45 return '"' + input + '"'; |
46 break; |
46 break; |
47 case 'array': |
47 case 'array': |
48 var a = ['['], |
48 var a = ['['], |
49 b, |
49 b, |
50 i, |
50 i, |
51 l = input.length, |
51 l = input.length, |
52 v; |
52 v; |
53 |
53 |
54 var p = function (s) { |
54 var p = function (s) { |
55 |
55 |
56 if (b) { |
56 if (b) { |
57 a.push(','); |
57 a.push(','); |
58 } |
58 } |
59 a.push(s); |
59 a.push(s); |
60 b = true; |
60 b = true; |
61 } |
61 } |
62 |
62 |
63 for (i = 0; i < l; i += 1) { |
63 for (i = 0; i < l; i += 1) { |
64 v = input[i]; |
64 v = input[i]; |
65 switch (typeof v) { |
65 switch (typeof v) { |
66 case 'object': |
66 case 'object': |
67 if (v) { |
67 if (v) { |
68 p(toJSONString(v)); |
68 p(toJSONString(v)); |
69 } else { |
69 } else { |
70 p("null"); |
70 p("null"); |
71 } |
71 } |
72 break; |
72 break; |
73 case 'array': |
73 case 'array': |
74 case 'string': |
74 case 'string': |
75 case 'number': |
75 case 'number': |
76 case 'boolean': |
76 case 'boolean': |
77 p(toJSONString(v)); |
77 p(toJSONString(v)); |
78 } |
78 } |
79 } |
79 } |
80 |
80 |
81 a.push(']'); |
81 a.push(']'); |
82 return a.join(''); |
82 return a.join(''); |
83 break; |
83 break; |
84 case 'date': |
84 case 'date': |
85 var f = function (n) |
85 var f = function (n) |
86 { |
86 { |
87 return n < 10 ? '0' + n : n; |
87 return n < 10 ? '0' + n : n; |
88 } |
88 } |
89 return '"' + input.getFullYear() + '-' + |
89 return '"' + input.getFullYear() + '-' + |
90 f(input.getMonth() + 1) + '-' + |
90 f(input.getMonth() + 1) + '-' + |
91 f(input.getDate()) + 'T' + |
91 f(input.getDate()) + 'T' + |
92 f(input.getHours()) + ':' + |
92 f(input.getHours()) + ':' + |
93 f(input.getMinutes()) + ':' + |
93 f(input.getMinutes()) + ':' + |
94 f(input.getSeconds()) + '"'; |
94 f(input.getSeconds()) + '"'; |
95 |
95 |
96 case 'boolean': |
96 case 'boolean': |
97 return String(input); |
97 return String(input); |
98 break; |
98 break; |
99 case 'number': |
99 case 'number': |
100 return isFinite(input) ? String(input) : "null"; |
100 return isFinite(input) ? String(input) : "null"; |
101 break; |
101 break; |
102 case 'object': |
102 case 'object': |
103 var a = ['{'], |
103 var a = ['{'], |
104 b, |
104 b, |
105 k, |
105 k, |
106 v; |
106 v; |
107 |
107 |
108 var p = function (s) |
108 var p = function (s) |
109 { |
109 { |
110 if (b) |
110 if (b) |
111 { |
111 { |
112 a.push(','); |
112 a.push(','); |
113 } |
113 } |
114 a.push(toJSONString(k), ':', s); |
114 a.push(toJSONString(k), ':', s); |
115 b = true; |
115 b = true; |
116 } |
116 } |
117 |
117 |
118 for (k in input) |
118 for (k in input) |
119 { |
119 { |
120 if (input.hasOwnProperty(k)) |
120 if (input.hasOwnProperty(k)) |
121 { |
121 { |
122 v = input[k]; |
122 v = input[k]; |
123 switch (typeof v) { |
123 switch (typeof v) { |
124 |
124 |
125 case 'object': |
125 case 'object': |
126 if (v) { |
126 if (v) { |
127 p(toJSONString(v)); |
127 p(toJSONString(v)); |
128 } else { |
128 } else { |
129 p("null"); |
129 p("null"); |
130 } |
130 } |
131 break; |
131 break; |
132 case 'string': |
132 case 'string': |
133 case 'number': |
133 case 'number': |
134 case 'boolean': |
134 case 'boolean': |
135 p(toJSONString(v)); |
135 p(toJSONString(v)); |
136 break; |
136 break; |
137 } |
137 } |
138 } |
138 } |
139 } |
139 } |
140 |
140 |
141 a.push('}'); |
141 a.push('}'); |
142 return a.join(''); |
142 return a.join(''); |
143 break; |
143 break; |
144 } |
144 } |
145 } |
145 } |
146 |
146 |
147 function parseJSON(string, filter) |
147 function parseJSON(string, filter) |
148 { |
148 { |
149 if ( window.JSON ) |
149 if ( window.JSON ) |
150 { |
150 { |
151 return window.JSON.parse(string); |
151 return window.JSON.parse(string); |
152 } |
152 } |
153 |
153 |
154 try { |
154 try { |
155 if (/^("(\\.|[^"\\\n\r])*?"|[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t])+?$/. |
155 if (/^("(\\.|[^"\\\n\r])*?"|[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t])+?$/. |
156 test(string)) |
156 test(string)) |
157 { |
157 { |
158 |
158 |
159 var j = eval('(' + string + ')'); |
159 var j = eval('(' + string + ')'); |
160 if (typeof filter === 'function') { |
160 if (typeof filter === 'function') { |
161 |
161 |
162 function walk(k, v) |
162 function walk(k, v) |
163 { |
163 { |
164 if (v && typeof v === 'object') { |
164 if (v && typeof v === 'object') { |
165 for (var i in v) { |
165 for (var i in v) { |
166 if (v.hasOwnProperty(i)) { |
166 if (v.hasOwnProperty(i)) { |
167 v[i] = walk(i, v[i]); |
167 v[i] = walk(i, v[i]); |
168 } |
168 } |
169 } |
169 } |
170 } |
170 } |
171 return filter(k, v); |
171 return filter(k, v); |
172 } |
172 } |
173 |
173 |
174 j = walk('', j); |
174 j = walk('', j); |
175 } |
175 } |
176 return j; |
176 return j; |
177 } |
177 } |
178 } catch (e) { |
178 } catch (e) { |
179 |
179 |
180 } |
180 } |
181 throw new SyntaxError("parseJSON"); |
181 throw new SyntaxError("parseJSON"); |
182 } |
182 } |