1 | /*
|
---|
2 |
|
---|
3 | Licence
|
---|
4 |
|
---|
5 | Copyright (c) 2005 JSON.org
|
---|
6 |
|
---|
7 | Permission is hereby granted, free of charge, to any person obtaining a copy
|
---|
8 | of this software and associated documentation files (the "Software"), to deal
|
---|
9 | in the Software without restriction, including without limitation the rights
|
---|
10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
---|
11 | copies of the Software, and to permit persons to whom the Software is
|
---|
12 | furnished to do so, subject to the following conditions:
|
---|
13 |
|
---|
14 | The Software shall be used for Good, not Evil.
|
---|
15 |
|
---|
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
---|
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
---|
18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
---|
19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
---|
20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
---|
21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
---|
22 | SOFTWARE.
|
---|
23 |
|
---|
24 | Contributor(s) :
|
---|
25 |
|
---|
26 | - Ported to Actionscript May 2005 by Trannie Carter <tranniec@designvox.com>, wwww.designvox.com
|
---|
27 |
|
---|
28 | - Alcaraz Marc (aka eKameleon) 2006-01-24 <vegas@ekameleon.net>
|
---|
29 |
|
---|
30 | - Refactoring AS2 and MTASC Compatibilty
|
---|
31 |
|
---|
32 | - Add Hexa Digits in 'deserialize' method -
|
---|
33 |
|
---|
34 | NOTE : EDEN Hexa digits code inspiration -> http://www.burrrn.com/projects/eden.html
|
---|
35 |
|
---|
36 | */
|
---|
37 |
|
---|
38 | /* JSON
|
---|
39 |
|
---|
40 | AUTHOR
|
---|
41 |
|
---|
42 | Name : JSON
|
---|
43 | Package : vegas.string
|
---|
44 | Version : 1.0.0.0
|
---|
45 | Date : 2006-07-09
|
---|
46 | Author : ekameleon
|
---|
47 | URL : http://www.ekameleon.net
|
---|
48 | Mail : vegas@ekameleon.net
|
---|
49 |
|
---|
50 | DESCRIPTION
|
---|
51 |
|
---|
52 | JSON (JavaScript object Notation) is a lightweight data-interchange format.
|
---|
53 |
|
---|
54 | Serializer & deserializer in AS2.
|
---|
55 |
|
---|
56 | MORE INFORMATION IN : http://www.json.org/
|
---|
57 |
|
---|
58 | ADD HEXA DIGITS in deserialize method - EDEN inspiration : http://www.burrrn.com/projects/eden.html
|
---|
59 |
|
---|
60 | METHOD SUMMARY
|
---|
61 |
|
---|
62 | - static deserialize(source:String):*
|
---|
63 |
|
---|
64 | - static serialize(o:*):String
|
---|
65 |
|
---|
66 | EXAMPLE
|
---|
67 |
|
---|
68 | import vegas.string.JSON ;
|
---|
69 |
|
---|
70 | // --- Init
|
---|
71 | var a:Array = [2, true, "hello"] ;
|
---|
72 | var o:Object = { prop1 : 1 , prop2 : 2 } ;
|
---|
73 | var s:String = "hello world" ;
|
---|
74 | var n:Number = 4 ;
|
---|
75 | var b:Boolean = true ;
|
---|
76 |
|
---|
77 | trace ("*** Serialize") ;
|
---|
78 | trace("* a : " + JSON.serialize( a ) ) ;
|
---|
79 | trace("* o : " + JSON.serialize( o ) ) ;
|
---|
80 | trace("* s : " + JSON.serialize( s ) ) ;
|
---|
81 | trace("* n : " + JSON.serialize( n ) ) ;
|
---|
82 | trace("* b : " + JSON.serialize( b ) ) ;
|
---|
83 |
|
---|
84 | trace ("*** Deserialize") ;
|
---|
85 |
|
---|
86 | var source:String = '[ {"prop1":0xFF0000, "prop2":2, "prop3":"hello", "prop4":true} , 2, true, 3, [3, 2] ]' ;
|
---|
87 |
|
---|
88 | import vegas.util.ClassUtil ;
|
---|
89 |
|
---|
90 | var result:* = JSON.deserialize(source) ;
|
---|
91 | for (var prop:String in result)
|
---|
92 | {
|
---|
93 | trace(prop + " : " + result[prop] + " -> " + ClassUtil.getPath(result[prop])) ;
|
---|
94 | }
|
---|
95 |
|
---|
96 | trace ("*** JSONError") ;
|
---|
97 |
|
---|
98 | var source:String = "[3, 2," ; // test1
|
---|
99 | //var source:String = '{"prop1":coucou"}' ; // test2
|
---|
100 | var o = JSON.deserialize(source) ;
|
---|
101 | for (var prop:String in o) {
|
---|
102 | trace(prop + " : " + o[prop]) ;
|
---|
103 | }
|
---|
104 |
|
---|
105 | **/
|
---|
106 |
|
---|
107 | // TODO REFACTORING PLEASE - type and co... !!!!!!
|
---|
108 |
|
---|
109 | package com.serialization.json
|
---|
110 | {
|
---|
111 |
|
---|
112 | public class JSON
|
---|
113 | {
|
---|
114 |
|
---|
115 | // ----o Public Methods
|
---|
116 |
|
---|
117 | static public function deserialize(source:String):* {
|
---|
118 |
|
---|
119 | source = new String(source) ; // Speed
|
---|
120 | var at:Number = 0 ;
|
---|
121 | var ch:String = ' ';
|
---|
122 |
|
---|
123 | var _isDigit:Function ;
|
---|
124 | var _isHexDigit:Function ;
|
---|
125 | var _white:Function ;
|
---|
126 | var _string:Function ;
|
---|
127 | var _next:Function ;
|
---|
128 | var _array:Function ;
|
---|
129 | var _object:Function ;
|
---|
130 | var _number:Function ;
|
---|
131 | var _word:Function ;
|
---|
132 | var _value:Function ;
|
---|
133 | var _error:Function ;
|
---|
134 |
|
---|
135 | _isDigit = function( /*Char*/ c:String ):* {
|
---|
136 | return( ("0" <= c) && (c <= "9") );
|
---|
137 | } ;
|
---|
138 |
|
---|
139 | _isHexDigit = function( /*Char*/ c:String ):* {
|
---|
140 | return( _isDigit( c ) || (("A" <= c) && (c <= "F")) || (("a" <= c) && (c <= "f")) );
|
---|
141 | } ;
|
---|
142 |
|
---|
143 | _error = function(m:String):void {
|
---|
144 | //throw new JSONError( m, at - 1 , source) ;
|
---|
145 | throw new Error(m, at-1);
|
---|
146 | } ;
|
---|
147 |
|
---|
148 | _next = function():* {
|
---|
149 | ch = source.charAt(at);
|
---|
150 | at += 1;
|
---|
151 | return ch;
|
---|
152 | } ;
|
---|
153 |
|
---|
154 | _white = function ():void {
|
---|
155 | while (ch) {
|
---|
156 | if (ch <= ' ') {
|
---|
157 | _next();
|
---|
158 | } else if (ch == '/') {
|
---|
159 | switch (_next()) {
|
---|
160 | case '/':
|
---|
161 | while (_next() && ch != '\n' && ch != '\r') {}
|
---|
162 | break;
|
---|
163 | case '*':
|
---|
164 | _next();
|
---|
165 | for (;;) {
|
---|
166 | if (ch) {
|
---|
167 | if (ch == '*') {
|
---|
168 | if (_next() == '/') {
|
---|
169 | _next();
|
---|
170 | break;
|
---|
171 | }
|
---|
172 | } else {
|
---|
173 | _next();
|
---|
174 | }
|
---|
175 | } else {
|
---|
176 | _error("Unterminated Comment");
|
---|
177 | }
|
---|
178 | }
|
---|
179 | break;
|
---|
180 | default:
|
---|
181 | _error("Syntax Error");
|
---|
182 | }
|
---|
183 | } else {
|
---|
184 | break;
|
---|
185 | }
|
---|
186 | }
|
---|
187 | };
|
---|
188 |
|
---|
189 | _string = function ():* {
|
---|
190 |
|
---|
191 | var i:* = '' ;
|
---|
192 | var s:* = '' ;
|
---|
193 | var t:* ;
|
---|
194 | var u:* ;
|
---|
195 | var outer:Boolean = false;
|
---|
196 |
|
---|
197 | if (ch == '"') {
|
---|
198 |
|
---|
199 | while (_next()) {
|
---|
200 | if (ch == '"')
|
---|
201 | {
|
---|
202 | _next();
|
---|
203 | return s;
|
---|
204 | }
|
---|
205 | else if (ch == '\\')
|
---|
206 | {
|
---|
207 | switch (_next()) {
|
---|
208 | case 'b':
|
---|
209 | s += '\b';
|
---|
210 | break;
|
---|
211 | case 'f':
|
---|
212 | s += '\f';
|
---|
213 | break;
|
---|
214 | case 'n':
|
---|
215 | s += '\n';
|
---|
216 | break;
|
---|
217 | case 'r':
|
---|
218 | s += '\r';
|
---|
219 | break;
|
---|
220 | case 't':
|
---|
221 | s += '\t';
|
---|
222 | break;
|
---|
223 | case 'u':
|
---|
224 | u = 0;
|
---|
225 | for (i = 0; i < 4; i += 1) {
|
---|
226 | t = parseInt(_next(), 16);
|
---|
227 | if (!isFinite(t)) {
|
---|
228 | outer = true;
|
---|
229 | break;
|
---|
230 | }
|
---|
231 | u = u * 16 + t;
|
---|
232 | }
|
---|
233 | if(outer) {
|
---|
234 | outer = false;
|
---|
235 | break;
|
---|
236 | }
|
---|
237 | s += String.fromCharCode(u);
|
---|
238 | break;
|
---|
239 | default:
|
---|
240 | s += ch;
|
---|
241 | }
|
---|
242 | } else {
|
---|
243 | s += ch;
|
---|
244 | }
|
---|
245 | }
|
---|
246 | }
|
---|
247 | _error("Bad String");
|
---|
248 | return null ;
|
---|
249 | } ;
|
---|
250 |
|
---|
251 | _array = function():* {
|
---|
252 | var a:Array = [];
|
---|
253 | if (ch == '[') {
|
---|
254 | _next();
|
---|
255 | _white();
|
---|
256 | if (ch == ']') {
|
---|
257 | _next();
|
---|
258 | return a;
|
---|
259 | }
|
---|
260 | while (ch) {
|
---|
261 | a.push(_value());
|
---|
262 | _white();
|
---|
263 | if (ch == ']') {
|
---|
264 | _next();
|
---|
265 | return a;
|
---|
266 | } else if (ch != ',') {
|
---|
267 | break;
|
---|
268 | }
|
---|
269 | _next();
|
---|
270 | _white();
|
---|
271 | }
|
---|
272 | }
|
---|
273 | _error("Bad Array");
|
---|
274 | return null ;
|
---|
275 | };
|
---|
276 |
|
---|
277 | _object = function ():* {
|
---|
278 | var k:* = {} ;
|
---|
279 | var o:* = {} ;
|
---|
280 | if (ch == '{') {
|
---|
281 |
|
---|
282 | _next();
|
---|
283 |
|
---|
284 | _white();
|
---|
285 |
|
---|
286 | if (ch == '}')
|
---|
287 | {
|
---|
288 | _next() ;
|
---|
289 | return o ;
|
---|
290 | }
|
---|
291 |
|
---|
292 | while (ch)
|
---|
293 | {
|
---|
294 | k = _string();
|
---|
295 | _white();
|
---|
296 | if (ch != ':')
|
---|
297 | {
|
---|
298 | break;
|
---|
299 | }
|
---|
300 | _next();
|
---|
301 | o[k] = _value();
|
---|
302 | _white();
|
---|
303 | if (ch == '}') {
|
---|
304 | _next();
|
---|
305 | return o;
|
---|
306 | } else if (ch != ',') {
|
---|
307 | break;
|
---|
308 | }
|
---|
309 | _next();
|
---|
310 | _white();
|
---|
311 | }
|
---|
312 | }
|
---|
313 | _error("Bad Object") ;
|
---|
314 | };
|
---|
315 |
|
---|
316 | _number = function ():* {
|
---|
317 |
|
---|
318 | var n:* = '' ;
|
---|
319 | var v:* ;
|
---|
320 | var hex:String = '' ;
|
---|
321 | var sign:String = '' ;
|
---|
322 |
|
---|
323 | if (ch == '-') {
|
---|
324 | n = '-';
|
---|
325 | sign = n ;
|
---|
326 | _next();
|
---|
327 | }
|
---|
328 |
|
---|
329 | if( ch == "0" ) {
|
---|
330 | _next() ;
|
---|
331 | if( ( ch == "x") || ( ch == "X") ) {
|
---|
332 | _next();
|
---|
333 | while( _isHexDigit( ch ) ) {
|
---|
334 | hex += ch ;
|
---|
335 | _next();
|
---|
336 | }
|
---|
337 | if( hex == "" ) {
|
---|
338 | _error("mal formed Hexadecimal") ;
|
---|
339 | } else {
|
---|
340 | return Number( sign + "0x" + hex ) ;
|
---|
341 | }
|
---|
342 | } else {
|
---|
343 | n += "0" ;
|
---|
344 | }
|
---|
345 | }
|
---|
346 |
|
---|
347 | while ( _isDigit(ch) ) {
|
---|
348 | n += ch;
|
---|
349 | _next();
|
---|
350 | }
|
---|
351 | if (ch == '.') {
|
---|
352 | n += '.';
|
---|
353 | while (_next() && ch >= '0' && ch <= '9') {
|
---|
354 | n += ch;
|
---|
355 | }
|
---|
356 | }
|
---|
357 | v = 1 * n ;
|
---|
358 | if (!isFinite(v)) {
|
---|
359 | _error("Bad Number");
|
---|
360 | } else {
|
---|
361 | return v;
|
---|
362 | }
|
---|
363 |
|
---|
364 | return NaN ;
|
---|
365 |
|
---|
366 | };
|
---|
367 |
|
---|
368 | _word = function ():* {
|
---|
369 | switch (ch) {
|
---|
370 | case 't':
|
---|
371 | if (_next() == 'r' && _next() == 'u' && _next() == 'e') {
|
---|
372 | _next();
|
---|
373 | return true;
|
---|
374 | }
|
---|
375 | break;
|
---|
376 | case 'f':
|
---|
377 | if (_next() == 'a' && _next() == 'l' && _next() == 's' && _next() == 'e') {
|
---|
378 | _next();
|
---|
379 | return false;
|
---|
380 | }
|
---|
381 | break;
|
---|
382 | case 'n':
|
---|
383 | if (_next() == 'u' && _next() == 'l' && _next() == 'l') {
|
---|
384 | _next();
|
---|
385 | return null;
|
---|
386 | }
|
---|
387 | break;
|
---|
388 | }
|
---|
389 | _error("Syntax Error");
|
---|
390 | return null ;
|
---|
391 | };
|
---|
392 |
|
---|
393 | _value = function ():* {
|
---|
394 | _white();
|
---|
395 | switch (ch) {
|
---|
396 | case '{':
|
---|
397 | return _object();
|
---|
398 | case '[':
|
---|
399 | return _array();
|
---|
400 | case '"':
|
---|
401 | return _string();
|
---|
402 | case '-':
|
---|
403 | return _number();
|
---|
404 | default:
|
---|
405 | return ch >= '0' && ch <= '9' ? _number() : _word();
|
---|
406 | }
|
---|
407 | };
|
---|
408 |
|
---|
409 | return _value() ;
|
---|
410 |
|
---|
411 | }
|
---|
412 |
|
---|
413 | static public function serialize(o:*):String {
|
---|
414 |
|
---|
415 | var c:String ; // char
|
---|
416 | var i:Number ;
|
---|
417 | var l:Number ;
|
---|
418 | var s:String = '' ;
|
---|
419 | var v:* ;
|
---|
420 |
|
---|
421 | switch (typeof o)
|
---|
422 | {
|
---|
423 |
|
---|
424 | case 'object' :
|
---|
425 |
|
---|
426 | if (o)
|
---|
427 | {
|
---|
428 | if (o is Array)
|
---|
429 | {
|
---|
430 |
|
---|
431 | l = o.length ;
|
---|
432 |
|
---|
433 | for (i = 0 ; i < l ; ++i)
|
---|
434 | {
|
---|
435 | v = serialize(o[i]);
|
---|
436 | if (s) s += ',' ;
|
---|
437 | s += v ;
|
---|
438 | }
|
---|
439 | return '[' + s + ']';
|
---|
440 |
|
---|
441 | }
|
---|
442 | else if (typeof(o.toString) != 'undefined')
|
---|
443 | {
|
---|
444 |
|
---|
445 | for (var prop:String in o)
|
---|
446 | {
|
---|
447 | v = o[prop];
|
---|
448 | if ( (typeof(v) != 'undefined') && (typeof(v) != 'function') )
|
---|
449 | {
|
---|
450 | v = serialize(v);
|
---|
451 | if (s) s += ',';
|
---|
452 | s += serialize(prop) + ':' + v ;
|
---|
453 | }
|
---|
454 | }
|
---|
455 | return "{" + s + "}";
|
---|
456 | }
|
---|
457 | }
|
---|
458 | return 'null';
|
---|
459 |
|
---|
460 | case 'number':
|
---|
461 |
|
---|
462 | return isFinite(o) ? String(o) : 'null' ;
|
---|
463 |
|
---|
464 | case 'string' :
|
---|
465 |
|
---|
466 | l = o.length ;
|
---|
467 | s = '"';
|
---|
468 | for (i = 0 ; i < l ; i += 1) {
|
---|
469 | c = o.charAt(i);
|
---|
470 | if (c >= ' ') {
|
---|
471 | if (c == '\\' || c == '"')
|
---|
472 | {
|
---|
473 | s += '\\';
|
---|
474 | }
|
---|
475 | s += c;
|
---|
476 | }
|
---|
477 | else
|
---|
478 | {
|
---|
479 | switch (c)
|
---|
480 | {
|
---|
481 |
|
---|
482 | case '\b':
|
---|
483 | s += '\\b';
|
---|
484 | break;
|
---|
485 | case '\f':
|
---|
486 | s += '\\f';
|
---|
487 | break;
|
---|
488 | case '\n':
|
---|
489 | s += '\\n';
|
---|
490 | break;
|
---|
491 | case '\r':
|
---|
492 | s += '\\r';
|
---|
493 | break;
|
---|
494 | case '\t':
|
---|
495 | s += '\\t';
|
---|
496 | break;
|
---|
497 | default:
|
---|
498 | var code:Number = c.charCodeAt() ;
|
---|
499 | s += '\\u00' + (Math.floor(code / 16).toString(16)) + ((code % 16).toString(16)) ;
|
---|
500 | }
|
---|
501 | }
|
---|
502 | }
|
---|
503 | return s + '"';
|
---|
504 |
|
---|
505 | case 'boolean':
|
---|
506 | return String(o);
|
---|
507 |
|
---|
508 | default:
|
---|
509 | return 'null';
|
---|
510 |
|
---|
511 | }
|
---|
512 | }
|
---|
513 | }
|
---|
514 | }
|
---|