Mercurial > hg > fulltextSearchServer
comparison lib/org.json_2.0/src/org/json/JSONWriter.java @ 0:db87c1b7eb6d
initial
author | dwinter |
---|---|
date | Wed, 03 Nov 2010 12:18:46 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:db87c1b7eb6d |
---|---|
1 package org.json; | |
2 | |
3 import java.io.IOException; | |
4 import java.io.Writer; | |
5 | |
6 /* | |
7 Copyright (c) 2006 JSON.org | |
8 | |
9 Permission is hereby granted, free of charge, to any person obtaining a copy | |
10 of this software and associated documentation files (the "Software"), to deal | |
11 in the Software without restriction, including without limitation the rights | |
12 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
13 copies of the Software, and to permit persons to whom the Software is | |
14 furnished to do so, subject to the following conditions: | |
15 | |
16 The above copyright notice and this permission notice shall be included in all | |
17 copies or substantial portions of the Software. | |
18 | |
19 The Software shall be used for Good, not Evil. | |
20 | |
21 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
22 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
23 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
24 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
25 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
26 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |
27 SOFTWARE. | |
28 */ | |
29 | |
30 /** | |
31 * JSONWriter provides a quick and convenient way of producing JSON text. | |
32 * The texts produced strictly conform to JSON syntax rules. No whitespace is | |
33 * added, so the results are ready for transmission or storage. Each instance of | |
34 * JSONWriter can produce one JSON text. | |
35 * <p> | |
36 * A JSONWriter instance provides a <code>value</code> method for appending | |
37 * values to the | |
38 * text, and a <code>key</code> | |
39 * method for adding keys before values in objects. There are <code>array</code> | |
40 * and <code>endArray</code> methods that make and bound array values, and | |
41 * <code>object</code> and <code>endObject</code> methods which make and bound | |
42 * object values. All of these methods return the JSONWriter instance, | |
43 * permitting a cascade style. For example, <pre> | |
44 * new JSONWriter(myWriter) | |
45 * .object() | |
46 * .key("JSON") | |
47 * .value("Hello, World!") | |
48 * .endObject();</pre> which writes <pre> | |
49 * {"JSON":"Hello, World!"}</pre> | |
50 * <p> | |
51 * The first method called must be <code>array</code> or <code>object</code>. | |
52 * There are no methods for adding commas or colons. JSONWriter adds them for | |
53 * you. Objects and arrays can be nested up to 20 levels deep. | |
54 * <p> | |
55 * This can sometimes be easier than using a JSONObject to build a string. | |
56 * @author JSON.org | |
57 * @version 2008-09-22 | |
58 */ | |
59 public class JSONWriter { | |
60 private static final int maxdepth = 20; | |
61 | |
62 /** | |
63 * The comma flag determines if a comma should be output before the next | |
64 * value. | |
65 */ | |
66 private boolean comma; | |
67 | |
68 /** | |
69 * The current mode. Values: | |
70 * 'a' (array), | |
71 * 'd' (done), | |
72 * 'i' (initial), | |
73 * 'k' (key), | |
74 * 'o' (object). | |
75 */ | |
76 protected char mode; | |
77 | |
78 /** | |
79 * The object/array stack. | |
80 */ | |
81 private JSONObject stack[]; | |
82 | |
83 /** | |
84 * The stack top index. A value of 0 indicates that the stack is empty. | |
85 */ | |
86 private int top; | |
87 | |
88 /** | |
89 * The writer that will receive the output. | |
90 */ | |
91 protected Writer writer; | |
92 | |
93 /** | |
94 * Make a fresh JSONWriter. It can be used to build one JSON text. | |
95 */ | |
96 public JSONWriter(Writer w) { | |
97 this.comma = false; | |
98 this.mode = 'i'; | |
99 this.stack = new JSONObject[maxdepth]; | |
100 this.top = 0; | |
101 this.writer = w; | |
102 } | |
103 | |
104 /** | |
105 * Append a value. | |
106 * @param s A string value. | |
107 * @return this | |
108 * @throws JSONException If the value is out of sequence. | |
109 */ | |
110 private JSONWriter append(String s) throws JSONException { | |
111 if (s == null) { | |
112 throw new JSONException("Null pointer"); | |
113 } | |
114 if (this.mode == 'o' || this.mode == 'a') { | |
115 try { | |
116 if (this.comma && this.mode == 'a') { | |
117 this.writer.write(','); | |
118 } | |
119 this.writer.write(s); | |
120 } catch (IOException e) { | |
121 throw new JSONException(e); | |
122 } | |
123 if (this.mode == 'o') { | |
124 this.mode = 'k'; | |
125 } | |
126 this.comma = true; | |
127 return this; | |
128 } | |
129 throw new JSONException("Value out of sequence."); | |
130 } | |
131 | |
132 /** | |
133 * Begin appending a new array. All values until the balancing | |
134 * <code>endArray</code> will be appended to this array. The | |
135 * <code>endArray</code> method must be called to mark the array's end. | |
136 * @return this | |
137 * @throws JSONException If the nesting is too deep, or if the object is | |
138 * started in the wrong place (for example as a key or after the end of the | |
139 * outermost array or object). | |
140 */ | |
141 public JSONWriter array() throws JSONException { | |
142 if (this.mode == 'i' || this.mode == 'o' || this.mode == 'a') { | |
143 this.push(null); | |
144 this.append("["); | |
145 this.comma = false; | |
146 return this; | |
147 } | |
148 throw new JSONException("Misplaced array."); | |
149 } | |
150 | |
151 /** | |
152 * End something. | |
153 * @param m Mode | |
154 * @param c Closing character | |
155 * @return this | |
156 * @throws JSONException If unbalanced. | |
157 */ | |
158 private JSONWriter end(char m, char c) throws JSONException { | |
159 if (this.mode != m) { | |
160 throw new JSONException(m == 'o' ? "Misplaced endObject." : | |
161 "Misplaced endArray."); | |
162 } | |
163 this.pop(m); | |
164 try { | |
165 this.writer.write(c); | |
166 } catch (IOException e) { | |
167 throw new JSONException(e); | |
168 } | |
169 this.comma = true; | |
170 return this; | |
171 } | |
172 | |
173 /** | |
174 * End an array. This method most be called to balance calls to | |
175 * <code>array</code>. | |
176 * @return this | |
177 * @throws JSONException If incorrectly nested. | |
178 */ | |
179 public JSONWriter endArray() throws JSONException { | |
180 return this.end('a', ']'); | |
181 } | |
182 | |
183 /** | |
184 * End an object. This method most be called to balance calls to | |
185 * <code>object</code>. | |
186 * @return this | |
187 * @throws JSONException If incorrectly nested. | |
188 */ | |
189 public JSONWriter endObject() throws JSONException { | |
190 return this.end('k', '}'); | |
191 } | |
192 | |
193 /** | |
194 * Append a key. The key will be associated with the next value. In an | |
195 * object, every value must be preceded by a key. | |
196 * @param s A key string. | |
197 * @return this | |
198 * @throws JSONException If the key is out of place. For example, keys | |
199 * do not belong in arrays or if the key is null. | |
200 */ | |
201 public JSONWriter key(String s) throws JSONException { | |
202 if (s == null) { | |
203 throw new JSONException("Null key."); | |
204 } | |
205 if (this.mode == 'k') { | |
206 try { | |
207 stack[top - 1].putOnce(s, Boolean.TRUE); | |
208 if (this.comma) { | |
209 this.writer.write(','); | |
210 } | |
211 this.writer.write(JSONObject.quote(s)); | |
212 this.writer.write(':'); | |
213 this.comma = false; | |
214 this.mode = 'o'; | |
215 return this; | |
216 } catch (IOException e) { | |
217 throw new JSONException(e); | |
218 } | |
219 } | |
220 throw new JSONException("Misplaced key."); | |
221 } | |
222 | |
223 | |
224 /** | |
225 * Begin appending a new object. All keys and values until the balancing | |
226 * <code>endObject</code> will be appended to this object. The | |
227 * <code>endObject</code> method must be called to mark the object's end. | |
228 * @return this | |
229 * @throws JSONException If the nesting is too deep, or if the object is | |
230 * started in the wrong place (for example as a key or after the end of the | |
231 * outermost array or object). | |
232 */ | |
233 public JSONWriter object() throws JSONException { | |
234 if (this.mode == 'i') { | |
235 this.mode = 'o'; | |
236 } | |
237 if (this.mode == 'o' || this.mode == 'a') { | |
238 this.append("{"); | |
239 this.push(new JSONObject()); | |
240 this.comma = false; | |
241 return this; | |
242 } | |
243 throw new JSONException("Misplaced object."); | |
244 | |
245 } | |
246 | |
247 | |
248 /** | |
249 * Pop an array or object scope. | |
250 * @param c The scope to close. | |
251 * @throws JSONException If nesting is wrong. | |
252 */ | |
253 private void pop(char c) throws JSONException { | |
254 if (this.top <= 0) { | |
255 throw new JSONException("Nesting error."); | |
256 } | |
257 char m = this.stack[this.top - 1] == null ? 'a' : 'k'; | |
258 if (m != c) { | |
259 throw new JSONException("Nesting error."); | |
260 } | |
261 this.top -= 1; | |
262 this.mode = this.top == 0 ? 'd' : this.stack[this.top - 1] == null ? 'a' : 'k'; | |
263 } | |
264 | |
265 /** | |
266 * Push an array or object scope. | |
267 * @param c The scope to open. | |
268 * @throws JSONException If nesting is too deep. | |
269 */ | |
270 private void push(JSONObject jo) throws JSONException { | |
271 if (this.top >= maxdepth) { | |
272 throw new JSONException("Nesting too deep."); | |
273 } | |
274 this.stack[this.top] = jo; | |
275 this.mode = jo == null ? 'a' : 'k'; | |
276 this.top += 1; | |
277 } | |
278 | |
279 | |
280 /** | |
281 * Append either the value <code>true</code> or the value | |
282 * <code>false</code>. | |
283 * @param b A boolean. | |
284 * @return this | |
285 * @throws JSONException | |
286 */ | |
287 public JSONWriter value(boolean b) throws JSONException { | |
288 return this.append(b ? "true" : "false"); | |
289 } | |
290 | |
291 /** | |
292 * Append a double value. | |
293 * @param d A double. | |
294 * @return this | |
295 * @throws JSONException If the number is not finite. | |
296 */ | |
297 public JSONWriter value(double d) throws JSONException { | |
298 return this.value(new Double(d)); | |
299 } | |
300 | |
301 /** | |
302 * Append a long value. | |
303 * @param l A long. | |
304 * @return this | |
305 * @throws JSONException | |
306 */ | |
307 public JSONWriter value(long l) throws JSONException { | |
308 return this.append(Long.toString(l)); | |
309 } | |
310 | |
311 | |
312 /** | |
313 * Append an object value. | |
314 * @param o The object to append. It can be null, or a Boolean, Number, | |
315 * String, JSONObject, or JSONArray, or an object with a toJSONString() | |
316 * method. | |
317 * @return this | |
318 * @throws JSONException If the value is out of sequence. | |
319 */ | |
320 public JSONWriter value(Object o) throws JSONException { | |
321 return this.append(JSONObject.valueToString(o)); | |
322 } | |
323 } |