source: code/Website/open-flash-chart/com/adobe/serialization/json/JSONDecoder.as@ 7849

Last change on this file since 7849 was 7849, checked in by dennisw, 16 years ago
File size: 6.7 KB
Line 
1/*
2Adobe Systems Incorporated(r) Source Code License Agreement
3Copyright(c) 2005 Adobe Systems Incorporated. All rights reserved.
4
5Please read this Source Code License Agreement carefully before using
6the source code.
7
8Adobe Systems Incorporated grants to you a perpetual, worldwide, non-exclusive,
9no-charge, royalty-free, irrevocable copyright license, to reproduce,
10prepare derivative works of, publicly display, publicly perform, and
11distribute this source code and such derivative works in source or
12object code form without any attribution requirements.
13
14The name "Adobe Systems Incorporated" must not be used to endorse or promote products
15derived from the source code without prior written permission.
16
17You agree to indemnify, hold harmless and defend Adobe Systems Incorporated from and
18against any loss, damage, claims or lawsuits, including attorney's
19fees that arise or result from your use or distribution of the source
20code.
21
22THIS SOURCE CODE IS PROVIDED "AS IS" AND "WITH ALL FAULTS", WITHOUT
23ANY TECHNICAL SUPPORT OR ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING,
24BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ALSO, THERE IS NO WARRANTY OF
26NON-INFRINGEMENT, TITLE OR QUIET ENJOYMENT. IN NO EVENT SHALL MACROMEDIA
27OR ITS SUPPLIERS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
28EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
29PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
30OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
31WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
32OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOURCE CODE, EVEN IF
33ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34*/
35
36package com.adobe.serialization.json {
37
38 public class JSONDecoder {
39
40 /** The value that will get parsed from the JSON string */
41 private var value:*;
42
43 /** The tokenizer designated to read the JSON string */
44 private var tokenizer:JSONTokenizer;
45
46 /** The current token from the tokenizer */
47 private var token:JSONToken;
48
49 /**
50 * Constructs a new JSONDecoder to parse a JSON string
51 * into a native object.
52 *
53 * @param s The JSON string to be converted
54 * into a native object
55 * @langversion ActionScript 3.0
56 * @playerversion Flash 9.0
57 * @tiptext
58 */
59 public function JSONDecoder( s:String ) {
60
61 tokenizer = new JSONTokenizer( s );
62
63 nextToken();
64 value = parseValue();
65 }
66
67 /**
68 * Gets the internal object that was created by parsing
69 * the JSON string passed to the constructor.
70 *
71 * @return The internal object representation of the JSON
72 * string that was passed to the constructor
73 * @langversion ActionScript 3.0
74 * @playerversion Flash 9.0
75 * @tiptext
76 */
77 public function getValue():* {
78 return value;
79 }
80
81 /**
82 * Returns the next token from the tokenzier reading
83 * the JSON string
84 */
85 private function nextToken():JSONToken {
86 return token = tokenizer.getNextToken();
87 }
88
89 /**
90 * Attempt to parse an array
91 */
92 private function parseArray():Array {
93 // create an array internally that we're going to attempt
94 // to parse from the tokenizer
95 var a:Array = new Array();
96
97 // grab the next token from the tokenizer to move
98 // past the opening [
99 nextToken();
100
101 // check to see if we have an empty array
102 if ( token.type == JSONTokenType.RIGHT_BRACKET ) {
103 // we're done reading the array, so return it
104 return a;
105 }
106
107 // deal with elements of the array, and use an "infinite"
108 // loop because we could have any amount of elements
109 while ( true ) {
110 // read in the value and add it to the array
111 a.push ( parseValue() );
112
113 // after the value there should be a ] or a ,
114 nextToken();
115
116 if ( token.type == JSONTokenType.RIGHT_BRACKET ) {
117 // we're done reading the array, so return it
118 return a;
119 } else if ( token.type == JSONTokenType.COMMA ) {
120 // move past the comma and read another value
121 nextToken();
122 } else {
123 tokenizer.parseError( "Expecting ] or , but found " + token.value );
124 }
125 }
126 return null;
127 }
128
129 /**
130 * Attempt to parse an object
131 */
132 private function parseObject():Object {
133 // create the object internally that we're going to
134 // attempt to parse from the tokenizer
135 var o:Object = new Object();
136
137 // store the string part of an object member so
138 // that we can assign it a value in the object
139 var key:String
140
141 // grab the next token from the tokenizer
142 nextToken();
143
144 // check to see if we have an empty object
145 if ( token.type == JSONTokenType.RIGHT_BRACE ) {
146 // we're done reading the object, so return it
147 return o;
148 }
149
150 // deal with members of the object, and use an "infinite"
151 // loop because we could have any amount of members
152 while ( true ) {
153
154 if ( token.type == JSONTokenType.STRING ) {
155 // the string value we read is the key for the object
156 key = String( token.value );
157
158 // move past the string to see what's next
159 nextToken();
160
161 // after the string there should be a :
162 if ( token.type == JSONTokenType.COLON ) {
163
164 // move past the : and read/assign a value for the key
165 nextToken();
166 o[key] = parseValue();
167
168 // move past the value to see what's next
169 nextToken();
170
171 // after the value there's either a } or a ,
172 if ( token.type == JSONTokenType.RIGHT_BRACE ) {
173 // // we're done reading the object, so return it
174 return o;
175
176 } else if ( token.type == JSONTokenType.COMMA ) {
177 // skip past the comma and read another member
178 nextToken();
179 } else {
180 tokenizer.parseError( "Expecting } or , but found " + token.value );
181 }
182 } else {
183 tokenizer.parseError( "Expecting : but found " + token.value );
184 }
185 } else {
186 tokenizer.parseError( "Expecting string but found " + token.value );
187 }
188 }
189 return null;
190 }
191
192 /**
193 * Attempt to parse a value
194 */
195 private function parseValue():Object {
196
197 switch ( token.type ) {
198 case JSONTokenType.LEFT_BRACE:
199 return parseObject();
200
201 case JSONTokenType.LEFT_BRACKET:
202 return parseArray();
203
204 case JSONTokenType.STRING:
205 case JSONTokenType.NUMBER:
206 case JSONTokenType.TRUE:
207 case JSONTokenType.FALSE:
208 case JSONTokenType.NULL:
209 return token.value;
210
211 default:
212 tokenizer.parseError( "Unexpected " + token.value );
213
214 }
215 return null;
216 }
217 }
218}
Note: See TracBrowser for help on using the repository browser.