source: code/Website/open-flash-chart/com/adobe/serialization/json/JSON.as

Last change on this file was 7849, checked in by dennisw, 15 years ago
File size: 14.8 KB
Line 
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 Revision: 2008-07-24 DZ - Added allowing numbers with scientific notation
107 Revision: 2008-09-05 DZ - Allow comma before final brace/bracket of objects/arrays
108
109**/
110
111// TODO REFACTORING PLEASE - type and co... !!!!!!
112
113package com.serialization.json
114{
115
116 public class JSON
117 {
118
119 // ----o Public Methods
120
121 static public function deserialize(source:String):* {
122
123 source = new String(source) ; // Speed
124 var at:Number = 0 ;
125 var ch:String = ' ';
126
127 var _isDigit:Function ;
128 var _isHexDigit:Function ;
129 var _white:Function ;
130 var _string:Function ;
131 var _next:Function ;
132 var _array:Function ;
133 var _object:Function ;
134 var _number:Function ;
135 var _word:Function ;
136 var _value:Function ;
137 var _error:Function ;
138
139 _isDigit = function( /*Char*/ c:String ):* {
140 return( ("0" <= c) && (c <= "9") );
141 } ;
142
143 _isHexDigit = function( /*Char*/ c:String ):* {
144 return( _isDigit( c ) || (("A" <= c) && (c <= "F")) || (("a" <= c) && (c <= "f")) );
145 } ;
146
147 _error = function(m:String):void {
148 //throw new JSONError( m, at - 1 , source) ;
149 throw new Error(m, at-1);
150 } ;
151
152 _next = function():* {
153 ch = source.charAt(at);
154 at += 1;
155 return ch;
156 } ;
157
158 _white = function ():void {
159 while (ch) {
160 if (ch <= ' ') {
161 _next();
162 } else if (ch == '/') {
163 switch (_next()) {
164 case '/':
165 while (_next() && ch != '\n' && ch != '\r') {}
166 break;
167 case '*':
168 _next();
169 for (;;) {
170 if (ch) {
171 if (ch == '*') {
172 if (_next() == '/') {
173 _next();
174 break;
175 }
176 } else {
177 _next();
178 }
179 } else {
180 _error("Unterminated Comment");
181 }
182 }
183 break;
184 default:
185 _error("Syntax Error");
186 }
187 } else {
188 break;
189 }
190 }
191 };
192
193 _string = function ():* {
194
195 var i:* = '' ;
196 var s:* = '' ;
197 var t:* ;
198 var u:* ;
199 var outer:Boolean = false;
200
201 if (ch == '"') {
202
203 while (_next()) {
204 if (ch == '"')
205 {
206 _next();
207 return s;
208 }
209 else if (ch == '\\')
210 {
211 switch (_next()) {
212 case 'b':
213 s += '\b';
214 break;
215 case 'f':
216 s += '\f';
217 break;
218 case 'n':
219 s += '\n';
220 break;
221 case 'r':
222 s += '\r';
223 break;
224 case 't':
225 s += '\t';
226 break;
227 case 'u':
228 u = 0;
229 for (i = 0; i < 4; i += 1) {
230 t = parseInt(_next(), 16);
231 if (!isFinite(t)) {
232 outer = true;
233 break;
234 }
235 u = u * 16 + t;
236 }
237 if(outer) {
238 outer = false;
239 break;
240 }
241 s += String.fromCharCode(u);
242 break;
243 default:
244 s += ch;
245 }
246 } else {
247 s += ch;
248 }
249 }
250 }
251 _error("Bad String");
252 return null ;
253 } ;
254
255 _array = function():* {
256 var a:Array = [];
257 if (ch == '[') {
258 _next();
259 _white();
260 if (ch == ']') {
261 _next();
262 return a;
263 }
264 while (ch) {
265 a.push(_value());
266 _white();
267 if (ch == ']') {
268 _next();
269 return a;
270 } else if (ch != ',') {
271 break;
272 }
273 _next();
274 _white();
275 // Allow for an extra comma before ending bracket
276 if (ch == ']') {
277 _next();
278 return a;
279 }
280 }
281 }
282 _error("Bad Array");
283 return null ;
284 };
285
286 _object = function ():* {
287 var k:* = {} ;
288 var o:* = {} ;
289 if (ch == '{') {
290
291 _next();
292
293 _white();
294
295 if (ch == '}')
296 {
297 _next() ;
298 return o ;
299 }
300
301 while (ch)
302 {
303 k = _string();
304 _white();
305 if (ch != ':')
306 {
307 break;
308 }
309 _next();
310 o[k] = _value();
311 _white();
312 if (ch == '}') {
313 _next();
314 return o;
315 } else if (ch != ',') {
316 break;
317 }
318 _next();
319 _white();
320 // Allow for an extra comma before ending brace
321 if (ch == '}') {
322 _next();
323 return o;
324 }
325 }
326 }
327 _error("Bad Object") ;
328 };
329
330 _number = function ():* {
331
332 var n:* = '' ;
333 var e:* = '' ;
334 var v:* ;
335 var exp:* ;
336 var hex:String = '' ;
337 var sign:String = '' ;
338
339 if (ch == '-') {
340 n = '-';
341 sign = n ;
342 _next();
343 }
344
345 if( ch == "0" ) {
346 _next() ;
347 if( ( ch == "x") || ( ch == "X") ) {
348 _next();
349 while( _isHexDigit( ch ) ) {
350 hex += ch ;
351 _next();
352 }
353 if( hex == "" ) {
354 _error("mal formed Hexadecimal") ;
355 } else {
356 return Number( sign + "0x" + hex ) ;
357 }
358 } else {
359 n += "0" ;
360 }
361 }
362
363 while ( _isDigit(ch) ) {
364 n += ch;
365 _next();
366 }
367 if (ch == '.') {
368 n += '.';
369 while (_next() && ch >= '0' && ch <= '9') {
370 n += ch;
371 }
372 }
373 v = 1 * n ;
374 if (!isFinite(v)) {
375 _error("Bad Number");
376 } else {
377 if ((ch == 'e') || (ch == 'E'))
378 {
379 // Continue processing exponent
380 _next();
381 var expSign:int = (ch == '-') ? -1 : 1;
382 // allow for a digit without a + sign
383 if ((ch == '+') || (ch == '-'))
384 {
385 _next();
386 }
387 if (_isDigit(ch))
388 {
389 e += ch;
390 }
391 else
392 {
393 _error("Bad Exponent");
394 }
395 while (_next() && ch >= '0' && ch <= '9')
396 {
397 e += ch;
398 }
399 exp = expSign * e;
400 if (!isFinite(v))
401 {
402 _error("Bad Exponent");
403 }
404 else
405 {
406 v = v * Math.pow(10, exp);
407 //trace("JSON._number - have exponent: n=" + n + " e=" + e + " v=" + v);
408 }
409 }
410 return v;
411 }
412
413 return NaN ;
414
415 };
416
417 _word = function ():* {
418 switch (ch) {
419 case 't':
420 if (_next() == 'r' && _next() == 'u' && _next() == 'e') {
421 _next();
422 return true;
423 }
424 break;
425 case 'f':
426 if (_next() == 'a' && _next() == 'l' && _next() == 's' && _next() == 'e') {
427 _next();
428 return false;
429 }
430 break;
431 case 'n':
432 if (_next() == 'u' && _next() == 'l' && _next() == 'l') {
433 _next();
434 return null;
435 }
436 break;
437 }
438 _error("Syntax Error");
439 return null ;
440 };
441
442 _value = function ():* {
443 _white();
444 switch (ch) {
445 case '{':
446 return _object();
447 case '[':
448 return _array();
449 case '"':
450 return _string();
451 case '-':
452 return _number();
453 default:
454 return ch >= '0' && ch <= '9' ? _number() : _word();
455 }
456 };
457
458 return _value() ;
459
460 }
461
462 static public function serialize(o:*):String {
463
464 var c:String ; // char
465 var i:Number ;
466 var l:Number ;
467 var s:String = '' ;
468 var v:* ;
469
470 switch (typeof o)
471 {
472
473 case 'object' :
474
475 if (o)
476 {
477 if (o is Array)
478 {
479
480 l = o.length ;
481
482 for (i = 0 ; i < l ; ++i)
483 {
484 v = serialize(o[i]);
485 if (s) s += ',' ;
486 s += v ;
487 }
488 return '[' + s + ']';
489
490 }
491 else if (typeof(o.toString) != 'undefined')
492 {
493
494 for (var prop:String in o)
495 {
496 v = o[prop];
497 if ( (typeof(v) != 'undefined') && (typeof(v) != 'function') )
498 {
499 v = serialize(v);
500 if (s) s += ',';
501 s += serialize(prop) + ':' + v ;
502 }
503 }
504 return "{" + s + "}";
505 }
506 }
507 return 'null';
508
509 case 'number':
510
511 return isFinite(o) ? String(o) : 'null' ;
512
513 case 'string' :
514
515 l = o.length ;
516 s = '"';
517 for (i = 0 ; i < l ; i += 1) {
518 c = o.charAt(i);
519 if (c >= ' ') {
520 if (c == '\\' || c == '"')
521 {
522 s += '\\';
523 }
524 s += c;
525 }
526 else
527 {
528 switch (c)
529 {
530
531 case '\b':
532 s += '\\b';
533 break;
534 case '\f':
535 s += '\\f';
536 break;
537 case '\n':
538 s += '\\n';
539 break;
540 case '\r':
541 s += '\\r';
542 break;
543 case '\t':
544 s += '\\t';
545 break;
546 default:
547 var code:Number = c.charCodeAt() ;
548 s += '\\u00' + (Math.floor(code / 16).toString(16)) + ((code % 16).toString(16)) ;
549 }
550 }
551 }
552 return s + '"';
553
554 case 'boolean':
555 return String(o);
556
557 default:
558 return 'null';
559
560 }
561 }
562 }
563}
Note: See TracBrowser for help on using the repository browser.