~ubuntu-branches/ubuntu/vivid/phabricator/vivid-proposed

« back to all changes in this revision

Viewing changes to phabricator/externals/vegas/src/vegas/strings/json/JSONSerializer.as

  • Committer: Package Import Robot
  • Author(s): Richard Sellam
  • Date: 2015-01-29 00:15:58 UTC
  • mfrom: (0.16.1) (0.15.1) (0.12.2) (2.1.4 sid)
  • Revision ID: package-import@ubuntu.com-20150129001558-na84707j70qqla7z
Tags: 0~git20150129-1
* New snapshot release
* restricted access to local config file (closes: #775479)
* moved local config file to /var/lib/phabricator (closes: #775478)
* switched mysql-server dependency to recommends (closes: #773536)
* use /run instead of /var/run (closes: #775803)
* prevent package reinstall from overwritting local changes (closes: #776288)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 
3
 
  Version: MPL 1.1/GPL 2.0/LGPL 2.1
4
 
 
5
 
  The contents of this file are subject to the Mozilla Public License Version
6
 
  1.1 (the "License"); you may not use this file except in compliance with
7
 
  the License. You may obtain a copy of the License at 
8
 
  
9
 
           http://www.mozilla.org/MPL/ 
10
 
  
11
 
  Software distributed under the License is distributed on an "AS IS" basis,
12
 
  WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13
 
  for the specific language governing rights and limitations under the License. 
14
 
  
15
 
  The Original Code is VEGAS Framework.
16
 
  
17
 
  The Initial Developer of the Original Code is
18
 
  ALCARAZ Marc (aka eKameleon)  <ekameleon@gmail.com>.
19
 
  Portions created by the Initial Developer are Copyright (C) 2004-2011
20
 
  the Initial Developer. All Rights Reserved.
21
 
  
22
 
  Contributor(s) :
23
 
  
24
 
  Alternatively, the contents of this file may be used under the terms of
25
 
  either the GNU General Public License Version 2 or later (the "GPL"), or
26
 
  the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27
 
  in which case the provisions of the GPL or the LGPL are applicable instead
28
 
  of those above. If you wish to allow use of your version of this file only
29
 
  under the terms of either the GPL or the LGPL, and not to allow others to
30
 
  use your version of this file under the terms of the MPL, indicate your
31
 
  decision by deleting the provisions above and replace them with the notice
32
 
  and other provisions required by the LGPL or the GPL. If you do not delete
33
 
  the provisions above, a recipient may use your version of this file under
34
 
  the terms of any one of the MPL, the GPL or the LGPL.
35
 
  
36
 
*/
37
 
 
38
 
package vegas.strings.json 
39
 
{
40
 
    import system.Serializer;
41
 
    
42
 
    /**
43
 
     * This class is the concrete class of the JSON singleton.
44
 
     * <code class="prettyprint">JSON</code> (JavaScript object Notation) is a lightweight data-interchange format.
45
 
     * <p>More information in the official site : <a href="http://www.JSON.org/">http://www.JSON.org</a></p>
46
 
     * <p>Add Hexa Digits tool in deserialize method - <a href="http://code.google.com/p/edenrr/">eden inspiration</a></p>
47
 
     * <p><b>Example :</b></p>
48
 
     * <pre class="prettyprint">
49
 
     * import core.getClassName ;
50
 
     * 
51
 
     * import vegas.strings.JSON;
52
 
     * import vegas.strings.JSONError;
53
 
     * 
54
 
     * // --- Init
55
 
     * 
56
 
     * var a:Array   = [2, true, "hello"] ;
57
 
     * var o:Object  = { prop1 : 1 , prop2 : 2 } ;
58
 
     * var s:String  = "hello world" ;
59
 
     * var n:Number  = 4 ;
60
 
     * var b:Boolean = true ;
61
 
     * 
62
 
     * trace("Serialize") ;
63
 
     * 
64
 
     * trace("- a : " + JSON.serialize( a ) )  ;
65
 
     * trace("- o : " + JSON.serialize( o ) )  ;
66
 
     * trace("- s : " + JSON.serialize( s ) )  ;
67
 
     * trace("- n : " + JSON.serialize( n ) )  ;
68
 
     * trace("- b : " + JSON.serialize( b ) )  ;
69
 
     * 
70
 
     * trace ("Deserialize") ;
71
 
     * 
72
 
     * var source:String = '[ { "prop1" : 0xFF0000 , prop2:2, prop3:"hello", prop4:true} , 2, true, 3, [3, 2] ]' ;
73
 
     * 
74
 
     * o = JSON.deserialize(source) ;
75
 
     * 
76
 
     * var l:uint = o.length ;
77
 
     * for (var i:uint = 0 ; i &lt; l ; i++)
78
 
     * {
79
 
     *     trace("- " + i + " : " + o[i] + " , typeof :: " + typeof(o[i])) ;
80
 
     *     if (typeof(o[i]) == "object")
81
 
     *     {
82
 
     *         for (var each:String in o[i])
83
 
     *         {
84
 
     *             trace("    + " + each + " : " + o[i][each] + " :: " + getClassName(o[i][each]) ) ;
85
 
     *         }
86
 
     *     }
87
 
     * }
88
 
     * 
89
 
     * trace ("JSONError") ;
90
 
     * 
91
 
     * source = "[3, 2," ; // test1
92
 
     * 
93
 
     * // var source:String = '{"prop1":coucou"}' ; // test2
94
 
     * 
95
 
     * try
96
 
     * {
97
 
     *    var errorObj:Object = JSON.deserialize(source) ;
98
 
     * }
99
 
     * catch( e:JSONError )
100
 
     * {
101
 
     *     trace( e.toString() ) ;
102
 
     * }
103
 
     * </pre>
104
 
     */
105
 
    public class JSONSerializer implements Serializer 
106
 
    {
107
 
        /**
108
 
         * Creates a new JSONSerializer instance.
109
 
         */
110
 
        public function JSONSerializer()
111
 
        {
112
 
            //
113
 
        }
114
 
        
115
 
        /**
116
 
         * The source to evaluate.
117
 
         */
118
 
        public var source:String ;
119
 
        
120
 
        /**
121
 
         * Indicates the indentor string representation.
122
 
         */
123
 
        public function get indentor():String
124
 
        {
125
 
            return _indentor;
126
 
        }
127
 
        
128
 
        /**
129
 
         * @private
130
 
         */
131
 
        public function set indentor(value:String):void
132
 
        {
133
 
            _indentor = value;
134
 
        }
135
 
        
136
 
        /**
137
 
         * Indicates the pretty indent value.
138
 
         */   
139
 
        public function get prettyIndent():int
140
 
        {
141
 
            return _prettyIndent;
142
 
        }
143
 
        
144
 
        /**
145
 
         * @private
146
 
         */
147
 
        public function set prettyIndent(value:int):void
148
 
        {
149
 
             _prettyIndent = value ;
150
 
        }
151
 
        
152
 
        /**
153
 
         * Indicates the pretty printing flag value.
154
 
         */        
155
 
        public function get prettyPrinting():Boolean
156
 
        {
157
 
            return _prettyPrinting ;
158
 
        }        
159
 
        
160
 
        /**
161
 
         * @private
162
 
         */
163
 
        public function set prettyPrinting(value:Boolean):void
164
 
        {
165
 
            _prettyPrinting = value;
166
 
        }
167
 
        
168
 
        /**
169
 
         * Parse a string and interpret the source code to the correct object construct.
170
 
         * <p><b>Example :</b></p>
171
 
         * <pre class="prettyprint">
172
 
         * "hello world" --> "hello world"
173
 
         * "0xFF"        --> 255
174
 
         * "{a:1,"b":2}" --> {a:1,b:2}
175
 
         * </pre>
176
 
         * @return a string representing the data.
177
 
         */ 
178
 
        public function deserialize( source:String ):*
179
 
        {
180
 
            this.source = source ;
181
 
            at = 0 ;
182
 
            ch = ' ' ;
183
 
            return value() ;
184
 
        }
185
 
        
186
 
        /**
187
 
         * Serialize the specified value object passed-in argument.
188
 
         */
189
 
        public function serialize( value:* ):String
190
 
        {
191
 
            var c:String ; // char
192
 
            var i:int ;
193
 
            var l:int ;
194
 
            var s:String = '' ;
195
 
            var v:* ;
196
 
            var tof:String = typeof(value) ;
197
 
            switch (tof) 
198
 
            {
199
 
                case 'object' :
200
 
                {
201
 
                    if (value)
202
 
                    {
203
 
                        if (value is Array) 
204
 
                        {
205
 
                            l = (value as Array).length ;
206
 
                            for (i = 0 ; i < l ; ++i) 
207
 
                            {
208
 
                                v = serialize(value[i]);
209
 
                                if (s) s += ',' ;
210
 
                                s += v ;
211
 
                            }
212
 
                            return '[' + s + ']';
213
 
                        }
214
 
                        else if ( typeof( value.toString ) != 'undefined') 
215
 
                        {
216
 
                            for (var prop:String in value) 
217
 
                            {
218
 
                                v = value[prop];
219
 
                                if ( (typeof(v) != 'undefined') && (typeof(v) != 'function') ) 
220
 
                                {
221
 
                                    v = serialize(v);
222
 
                                    if (s) 
223
 
                                    {
224
 
                                        s += ',' ;
225
 
                                    }
226
 
                                    s += serialize(prop) + ':' + v ;
227
 
                                }
228
 
                            }
229
 
                            return "{" + s + "}";
230
 
                        }
231
 
                    }
232
 
                    return 'null';
233
 
                }
234
 
                case 'number':
235
 
                {
236
 
                    return isFinite(value) ? String(value) : 'null' ;
237
 
                }
238
 
                case 'string' :
239
 
                {
240
 
                    l = (value as String).length ;
241
 
                    s = '"' ;
242
 
                    for (i = 0 ; i < l ; i += 1) 
243
 
                    {
244
 
                        c = (value as String).charAt(i) ;
245
 
                        if (c >= ' ') 
246
 
                        {
247
 
                            if (c == '\\' || c == '"') 
248
 
                            {
249
 
                                s += '\\';
250
 
                            }
251
 
                            s += c;
252
 
                        } 
253
 
                        else 
254
 
                        {
255
 
                            switch (c) 
256
 
                            {
257
 
                                case '\b':
258
 
                                {
259
 
                                    s += '\\b';
260
 
                                    break ;
261
 
                                }
262
 
                                case '\f' :
263
 
                                {
264
 
                                    s += '\\f' ;
265
 
                                    break ;
266
 
                                }
267
 
                                case '\n' :
268
 
                                {
269
 
                                    s += '\\n' ;
270
 
                                    break ;
271
 
                                }
272
 
                                case '\r':
273
 
                                {
274
 
                                    s += '\\r' ;
275
 
                                    break ;
276
 
                                }
277
 
                                case '\t':
278
 
                                {
279
 
                                    s += '\\t' ;
280
 
                                    break ;
281
 
                                }
282
 
                                default:
283
 
                                {
284
 
                                    var code:Number = c.charCodeAt() ;
285
 
                                    s += '\\u00' + String(Math.floor(code / 16).toString(16)) + ((code % 16).toString(16)) ;
286
 
                                }
287
 
                            }
288
 
                        }
289
 
                    }
290
 
                    return s + '"' ;
291
 
                }
292
 
                case 'boolean' :
293
 
                {
294
 
                    return String(value);
295
 
                }
296
 
                default :
297
 
                {
298
 
                    return 'null';
299
 
                }
300
 
            }
301
 
        }
302
 
       
303
 
        /**
304
 
         * The current position of the iterator in the source.
305
 
         */
306
 
        protected var at:Number = 0 ;
307
 
 
308
 
        /**
309
 
         * The current character of the iterator in the source.
310
 
         */
311
 
        protected var ch:String = ' ' ;
312
 
        
313
 
        /**
314
 
         * Check the Array objects in the source expression.
315
 
         */
316
 
        protected function array():Array 
317
 
        {
318
 
            var a:Array = [];
319
 
            if ( ch == '[' ) 
320
 
            {
321
 
                next()  ;
322
 
                white() ;
323
 
                if (ch == ']') 
324
 
                {
325
 
                    next();
326
 
                    return a;
327
 
                }
328
 
                while (ch) 
329
 
                {
330
 
                    a.push( value() ) ;
331
 
                    white();
332
 
                    if (ch == ']') 
333
 
                    {
334
 
                        next();
335
 
                        return a;
336
 
                    }
337
 
                    else if (ch != ',') 
338
 
                    {
339
 
                       break;
340
 
                    }
341
 
                    next();
342
 
                    white();
343
 
                }
344
 
            }
345
 
            error( JSONStrings.badArray );
346
 
            return null ;
347
 
        }        
348
 
        
349
 
        /**
350
 
         * Throws a JSONError with the passed-in message.
351
 
         */
352
 
        protected function error( m:String ):void 
353
 
        {
354
 
            throw new JSONError( m, at - 1 , source) ;
355
 
        }
356
 
        
357
 
        /**
358
 
         * Indicates if the passed-in character is a digit.
359
 
         */
360
 
        protected function isDigit( c:String ):Boolean
361
 
        {
362
 
            return( ("0" <= c) && (c <= "9") );
363
 
        }
364
 
        
365
 
        /**
366
 
         * Indicates if the passed-in character is a hexadecimal digit.
367
 
         */
368
 
        protected function isHexDigit( c:String ):Boolean 
369
 
        {
370
 
            return( isDigit( c ) || (("A" <= c) && (c <= "F")) || (("a" <= c) && (c <= "f")) );
371
 
        }
372
 
        
373
 
        /**
374
 
         * Indicates if the current character is a key.
375
 
         */
376
 
        protected function key():*
377
 
        {
378
 
            var s:String        = ch ;
379
 
            var semiColon:int   = source.indexOf( ':' , at ) ;
380
 
            var quoteIndex:int  = source.indexOf( '"' , at ) ;
381
 
            var squoteIndex:int = source.indexOf( "'" , at ) ;
382
 
            if( (quoteIndex <= semiColon && quoteIndex > -1) || (squoteIndex <= semiColon && squoteIndex > -1))
383
 
            {
384
 
                s = string() ;
385
 
                white() ;
386
 
                if(ch == ':')
387
 
                {
388
 
                    return s;
389
 
                }
390
 
                else
391
 
                {
392
 
                    error(JSONStrings.badKey);
393
 
                }
394
 
            }
395
 
            while ( next() ) // Use key handling 
396
 
            {
397
 
                if (ch == ':') 
398
 
                {
399
 
                    return s;
400
 
                } 
401
 
                if(ch <= ' ')
402
 
                {
403
 
                    //
404
 
                }
405
 
                else
406
 
                {
407
 
                    s += ch;
408
 
                }
409
 
            }
410
 
            error( JSONStrings.badKey ) ;
411
 
        }
412
 
        
413
 
        /**
414
 
         * Returns the next character in the source String representation.
415
 
         * @return the next character in the source String representation.
416
 
         */
417
 
        protected function next():String
418
 
        {
419
 
           ch = source.charAt(at);
420
 
           at += 1;
421
 
           return ch;
422
 
        }
423
 
        
424
 
        /**
425
 
         * Check the Number values in the source expression.
426
 
         */    
427
 
        protected function number():* 
428
 
        {
429
 
            
430
 
            var n:* = '' ;
431
 
            var v:* ;
432
 
            var hex:String = '' ;
433
 
            var sign:String = '' ;
434
 
            if (ch == '-') 
435
 
            {
436
 
                n = '-';
437
 
                sign = n ;
438
 
                next();
439
 
            }
440
 
            if( ch == "0" ) 
441
 
            {
442
 
                next() ;
443
 
                if( ( ch == "x") || ( ch == "X") ) 
444
 
                {
445
 
                    next();
446
 
                    while( isHexDigit( ch ) ) 
447
 
                    {
448
 
                        hex += ch ;
449
 
                        next();
450
 
                    }
451
 
                    if( hex == "" ) 
452
 
                    {
453
 
                        error(JSONStrings.malFormedHexadecimal) ;
454
 
                    }
455
 
                    else 
456
 
                    {
457
 
                        return Number( sign + "0x" + hex ) ;
458
 
                    }
459
 
                } 
460
 
                else 
461
 
                {
462
 
                    n += "0" ;
463
 
                }
464
 
            }
465
 
            while ( isDigit(ch) ) 
466
 
            {
467
 
                n += ch ;
468
 
                next() ;
469
 
            }
470
 
            if (ch == '.') 
471
 
            {
472
 
                n += '.';
473
 
                while (next() && ch >= '0' && ch <= '9') 
474
 
                {
475
 
                    n += ch ;
476
 
                }
477
 
            }
478
 
            v = 1 * n ;
479
 
            if (!isFinite(v)) 
480
 
            {
481
 
                error( JSONStrings.badNumber );
482
 
            }
483
 
            else 
484
 
            {
485
 
                return v ;
486
 
            }
487
 
            return NaN ;
488
 
        }        
489
 
        
490
 
        /**
491
 
         * Check the Object values in the source expression.
492
 
         */       
493
 
        protected function object():* 
494
 
        {
495
 
            var k:* = {} ;
496
 
            var o:* = {} ;
497
 
            if (ch == '{') 
498
 
            {
499
 
                next();
500
 
                white();
501
 
                if (ch == '}') 
502
 
                {
503
 
                    next() ;
504
 
                    return o ;
505
 
                }
506
 
                while (ch) 
507
 
                {
508
 
                    k = key() ;
509
 
                    white();
510
 
                    if (ch != ':') 
511
 
                    {
512
 
                        break;
513
 
                    }
514
 
                    next();
515
 
                    o[k] = value() ;
516
 
                    white();
517
 
                    if (ch == '}') 
518
 
                    {
519
 
                        next();
520
 
                        return o;
521
 
                    } 
522
 
                    else if (ch != ',') 
523
 
                    {
524
 
                        break;
525
 
                    }
526
 
                    next();
527
 
                    white();
528
 
                }
529
 
            }
530
 
            error( JSONStrings.badObject ) ;
531
 
        }
532
 
        
533
 
        /**
534
 
         * Check the string objects in the source expression.
535
 
         */
536
 
        protected function string():* 
537
 
        {
538
 
           var i:* = '' ;
539
 
           var s:* = '' ; 
540
 
           var t:* ;
541
 
           var u:* ;
542
 
           var outer:Boolean ;
543
 
           if (ch == '"' || ch == "'" ) 
544
 
           {
545
 
               var outerChar:String = ch ;
546
 
               while ( next() ) 
547
 
               {
548
 
                   if (ch == outerChar) 
549
 
                   {
550
 
                        next() ;
551
 
                        return s ;
552
 
                   }
553
 
                   else if (ch == '\\') 
554
 
                   {
555
 
                        switch ( next() ) 
556
 
                        {
557
 
                            case 'b':
558
 
                            {
559
 
                                s += '\b' ;
560
 
                                break ;
561
 
                            }
562
 
                            case 'f' :
563
 
                            {
564
 
                                s += '\f';
565
 
                                break ;
566
 
                            }
567
 
                            case 'n':
568
 
                            {
569
 
                                s += '\n';
570
 
                                break ;
571
 
                            }
572
 
                            case 'r' :
573
 
                            {
574
 
                                s += '\r';
575
 
                                break ;
576
 
                            }
577
 
                            case 't' :
578
 
                            {
579
 
                                s += '\t' ;
580
 
                                break ;
581
 
                            }
582
 
                            case 'u' :
583
 
                            {
584
 
                                u = 0;
585
 
                                for (i = 0; i < 4; i += 1) 
586
 
                                {
587
 
                                    t = parseInt( next() , 16 ) ;
588
 
                                    if (!isFinite(t)) 
589
 
                                    {
590
 
                                        outer = true;
591
 
                                        break;
592
 
                                    }
593
 
                                    u = u * 16 + t;
594
 
                                }
595
 
                                if(outer) 
596
 
                                {
597
 
                                    outer = false;
598
 
                                    break;
599
 
                                }
600
 
                                s += String.fromCharCode(u);
601
 
                                break;
602
 
                            }
603
 
                            default :
604
 
                            {
605
 
                                s += ch;
606
 
                            }
607
 
                        }
608
 
                    } 
609
 
                    else 
610
 
                    {
611
 
                        s += ch;
612
 
                    }
613
 
                }
614
 
            }
615
 
            error( JSONStrings.badString );
616
 
            return null ;
617
 
        }
618
 
        
619
 
        /**
620
 
         * Evaluates the values in the source expression.
621
 
         */
622
 
        protected function value():* 
623
 
        {
624
 
            white() ;
625
 
            if (ch == '{' ) 
626
 
            {
627
 
                return object();
628
 
            }
629
 
            else if ( ch == '[' )
630
 
            {
631
 
                return array();
632
 
            }
633
 
            else if ( ch == '"' || ch == "'" )
634
 
            {
635
 
                return string();
636
 
            }
637
 
            else if ( ch == '-' ) 
638
 
            {
639
 
                return number();
640
 
            }
641
 
            else 
642
 
            {
643
 
                return ( ch >= '0' && ch <= '9' ) ? number() : word() ;
644
 
            }
645
 
        }        
646
 
        
647
 
        /**
648
 
         * Check all white spaces.
649
 
         */
650
 
        protected function white():void 
651
 
        {
652
 
            while (ch) 
653
 
            {
654
 
                if (ch <= ' ') 
655
 
                {
656
 
                    next();
657
 
                } 
658
 
                else if (ch == '/') 
659
 
                {
660
 
                    switch ( next() ) 
661
 
                    {
662
 
                        case '/' :
663
 
                        {
664
 
                            while ( next() && ch != '\n' && ch != '\r') 
665
 
                            {
666
 
                            }
667
 
                            break;
668
 
                        }
669
 
                        case '*' :
670
 
                        {
671
 
                            next();
672
 
                            for (;;) 
673
 
                            {
674
 
                                if (ch) 
675
 
                                {
676
 
                                    if (ch == '*') 
677
 
                                    {
678
 
                                        if ( next() == '/' ) 
679
 
                                        {
680
 
                                            next();
681
 
                                            break;
682
 
                                        }
683
 
                                    } 
684
 
                                    else 
685
 
                                    {
686
 
                                        next();
687
 
                                    }
688
 
                                }
689
 
                                else 
690
 
                                {
691
 
                                    error( JSONStrings.unterminatedComment );
692
 
                                }
693
 
                            }
694
 
                            break ;
695
 
                        }
696
 
                        default :
697
 
                        {
698
 
                            error( JSONStrings.syntaxError );
699
 
                        }
700
 
                    }
701
 
                } 
702
 
                else 
703
 
                {
704
 
                    break ;
705
 
                }
706
 
            }
707
 
        }
708
 
        
709
 
        /**
710
 
         * Check all special words in the source to evaluate.
711
 
         */
712
 
        protected function word():* 
713
 
        {
714
 
            if (ch == 't') 
715
 
            {
716
 
                if (next() == 'r' && next() == 'u' && next() == 'e') 
717
 
                {
718
 
                    next() ;
719
 
                    return true ;
720
 
                }
721
 
            }
722
 
            else if ( ch == 'f' )
723
 
            {
724
 
                if (next() == 'a' && next() == 'l' && next() == 's' && next() == 'e') 
725
 
                {
726
 
                    next() ;
727
 
                    return false ;
728
 
                }
729
 
            }
730
 
            else if ( ch == 'n' )
731
 
            {
732
 
                if (next() == 'u' && next() == 'l' && next() == 'l') 
733
 
                {
734
 
                    next() ;
735
 
                    return null ;
736
 
                }
737
 
            }
738
 
            error( JSONStrings.syntaxError );
739
 
            return null ;
740
 
        }
741
 
        
742
 
        /**
743
 
         * @private
744
 
         */
745
 
        private var _prettyIndent:int = 0 ;
746
 
        
747
 
        /**
748
 
         * @private
749
 
         */
750
 
        private var _prettyPrinting:Boolean ;
751
 
        
752
 
        /**
753
 
         * @private
754
 
         */
755
 
        private var _indentor:String = "    " ;
756
 
    }
757
 
}