Project

General

Profile

Statistics
| Branch: | Revision:

colonymech / docs / www / colonyscout / internal / includes / uploadify / com / adobe / serialization / json / JSONDecoder.as @ f59acf11

History | View | Annotate | Download (6.41 KB)

1 f59acf11 Dan Shope
/*
2
  Copyright (c) 2008, Adobe Systems Incorporated
3
  All rights reserved.
4
5
  Redistribution and use in source and binary forms, with or without 
6
  modification, are permitted provided that the following conditions are
7
  met:
8
9
  * Redistributions of source code must retain the above copyright notice, 
10
    this list of conditions and the following disclaimer.
11
  
12
  * Redistributions in binary form must reproduce the above copyright
13
    notice, this list of conditions and the following disclaimer in the 
14
    documentation and/or other materials provided with the distribution.
15
  
16
  * Neither the name of Adobe Systems Incorporated nor the names of its 
17
    contributors may be used to endorse or promote products derived from 
18
    this software without specific prior written permission.
19
20
  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
21
  IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22
  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23
  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 
24
  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25
  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26
  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27
  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28
  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29
  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30
  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
*/
32
33
package com.adobe.serialization.json {
34
35
	public class JSONDecoder {
36
		
37
		/** The value that will get parsed from the JSON string */
38
		private var value:*;
39
		
40
		/** The tokenizer designated to read the JSON string */
41
		private var tokenizer:JSONTokenizer;
42
		
43
		/** The current token from the tokenizer */
44
		private var token:JSONToken;
45
		
46
		/**
47
		 * Constructs a new JSONDecoder to parse a JSON string 
48
		 * into a native object.
49
		 *
50
		 * @param s The JSON string to be converted
51
		 *		into a native object
52
		 * @langversion ActionScript 3.0
53
		 * @playerversion Flash 9.0
54
		 * @tiptext
55
		 */
56
		public function JSONDecoder( s:String ) {
57
			
58
			tokenizer = new JSONTokenizer( s );
59
			
60
			nextToken();
61
			value = parseValue();
62
		}
63
		
64
		/**
65
		 * Gets the internal object that was created by parsing
66
		 * the JSON string passed to the constructor.
67
		 *
68
		 * @return The internal object representation of the JSON
69
		 * 		string that was passed to the constructor
70
		 * @langversion ActionScript 3.0
71
		 * @playerversion Flash 9.0
72
		 * @tiptext
73
		 */
74
		public function getValue():* {
75
			return value;
76
		}
77
		
78
		/**
79
		 * Returns the next token from the tokenzier reading
80
		 * the JSON string
81
		 */
82
		private function nextToken():JSONToken {
83
			return token = tokenizer.getNextToken();
84
		}
85
		
86
		/**
87
		 * Attempt to parse an array
88
		 */
89
		private function parseArray():Array {
90
			// create an array internally that we're going to attempt
91
			// to parse from the tokenizer
92
			var a:Array = new Array();
93
			
94
			// grab the next token from the tokenizer to move
95
			// past the opening [
96
			nextToken();
97
			
98
			// check to see if we have an empty array
99
			if ( token.type == JSONTokenType.RIGHT_BRACKET ) {
100
				// we're done reading the array, so return it
101
				return a;
102
			}
103
			
104
			// deal with elements of the array, and use an "infinite"
105
			// loop because we could have any amount of elements
106
			while ( true ) {
107
				// read in the value and add it to the array
108
				a.push ( parseValue() );
109
			
110
				// after the value there should be a ] or a ,
111
				nextToken();
112
				
113
				if ( token.type == JSONTokenType.RIGHT_BRACKET ) {
114
					// we're done reading the array, so return it
115
					return a;
116
				} else if ( token.type == JSONTokenType.COMMA ) {
117
					// move past the comma and read another value
118
					nextToken();
119
				} else {
120
					tokenizer.parseError( "Expecting ] or , but found " + token.value );
121
				}
122
			}
123
            return null;
124
		}
125
		
126
		/**
127
		 * Attempt to parse an object
128
		 */
129
		private function parseObject():Object {
130
			// create the object internally that we're going to
131
			// attempt to parse from the tokenizer
132
			var o:Object = new Object();
133
						
134
			// store the string part of an object member so
135
			// that we can assign it a value in the object
136
			var key:String
137
			
138
			// grab the next token from the tokenizer
139
			nextToken();
140
			
141
			// check to see if we have an empty object
142
			if ( token.type == JSONTokenType.RIGHT_BRACE ) {
143
				// we're done reading the object, so return it
144
				return o;
145
			}
146
			
147
			// deal with members of the object, and use an "infinite"
148
			// loop because we could have any amount of members
149
			while ( true ) {
150
			
151
				if ( token.type == JSONTokenType.STRING ) {
152
					// the string value we read is the key for the object
153
					key = String( token.value );
154
					
155
					// move past the string to see what's next
156
					nextToken();
157
					
158
					// after the string there should be a :
159
					if ( token.type == JSONTokenType.COLON ) {
160
						
161
						// move past the : and read/assign a value for the key
162
						nextToken();
163
						o[key] = parseValue();	
164
						
165
						// move past the value to see what's next
166
						nextToken();
167
						
168
						// after the value there's either a } or a ,
169
						if ( token.type == JSONTokenType.RIGHT_BRACE ) {
170
							// // we're done reading the object, so return it
171
							return o;
172
							
173
						} else if ( token.type == JSONTokenType.COMMA ) {
174
							// skip past the comma and read another member
175
							nextToken();
176
						} else {
177
							tokenizer.parseError( "Expecting } or , but found " + token.value );
178
						}
179
					} else {
180
						tokenizer.parseError( "Expecting : but found " + token.value );
181
					}
182
				} else {
183
					tokenizer.parseError( "Expecting string but found " + token.value );
184
				}
185
			}
186
            return null;
187
		}
188
		
189
		/**
190
		 * Attempt to parse a value
191
		 */
192
		private function parseValue():Object
193
		{
194
			// Catch errors when the input stream ends abruptly
195
			if ( token == null )
196
			{
197
				tokenizer.parseError( "Unexpected end of input" );
198
			}
199
					
200
			switch ( token.type ) {
201
				case JSONTokenType.LEFT_BRACE:
202
					return parseObject();
203
					
204
				case JSONTokenType.LEFT_BRACKET:
205
					return parseArray();
206
					
207
				case JSONTokenType.STRING:
208
				case JSONTokenType.NUMBER:
209
				case JSONTokenType.TRUE:
210
				case JSONTokenType.FALSE:
211
				case JSONTokenType.NULL:
212
					return token.value;
213
214
				default:
215
					tokenizer.parseError( "Unexpected " + token.value );
216
					
217
			}
218
            return null;
219
		}
220
	}
221
}