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

Last change on this file was 7849, checked in by dennisw, 15 years ago
File size: 13.5 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
107// TODO REFACTORING PLEASE - type and co... !!!!!!
108
109package 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}
Note: See TracBrowser for help on using the repository browser.