212 return "null";
213 } else if (Boolean.TRUE.equals(value)) {
214 return "true";
215 } else if (Boolean.FALSE.equals(value)) {
216 return "false";
217 }
218
219 if (value instanceof String) {
220 return JSONFunctions.quote((String)value);
221 } else if (value instanceof ConsString) {
222 return JSONFunctions.quote(value.toString());
223 }
224
225 if (value instanceof Number) {
226 return JSType.isFinite(((Number)value).doubleValue()) ? JSType.toString(value) : "null";
227 }
228
229 final JSType type = JSType.of(value);
230 if (type == JSType.OBJECT) {
231 if (isArray(value)) {
232 return JA((NativeArray)value, state);
233 } else if (value instanceof ScriptObject) {
234 return JO((ScriptObject)value, state);
235 }
236 }
237
238 return UNDEFINED;
239 }
240
241 // Spec: The abstract operation JO(value) serializes an object.
242 private static String JO(final ScriptObject value, final StringifyState state) {
243 if (state.stack.containsKey(value)) {
244 throw typeError("JSON.stringify.cyclic");
245 }
246
247 state.stack.put(value, value);
248 final StringBuilder stepback = new StringBuilder(state.indent.toString());
249 state.indent.append(state.gap);
250
251 final StringBuilder finalStr = new StringBuilder();
252 final List<Object> partial = new ArrayList<>();
298 if (index < size - 1) {
299 finalStr.append(",\n");
300 finalStr.append(state.indent);
301 }
302 index++;
303 }
304
305 finalStr.append('\n');
306 finalStr.append(stepback);
307 finalStr.append('}');
308 }
309 }
310
311 state.stack.remove(value);
312 state.indent = stepback;
313
314 return finalStr.toString();
315 }
316
317 // Spec: The abstract operation JA(value) serializes an array.
318 private static Object JA(final NativeArray value, final StringifyState state) {
319 if (state.stack.containsKey(value)) {
320 throw typeError("JSON.stringify.cyclic");
321 }
322
323 state.stack.put(value, value);
324 final StringBuilder stepback = new StringBuilder(state.indent.toString());
325 state.indent.append(state.gap);
326 final List<Object> partial = new ArrayList<>();
327
328 final int length = JSType.toInteger(value.getLength());
329 int index = 0;
330
331 while (index < length) {
332 Object strP = str(index, value, state);
333 if (strP == UNDEFINED) {
334 strP = "null";
335 }
336 partial.add(strP);
337 index++;
338 }
|
212 return "null";
213 } else if (Boolean.TRUE.equals(value)) {
214 return "true";
215 } else if (Boolean.FALSE.equals(value)) {
216 return "false";
217 }
218
219 if (value instanceof String) {
220 return JSONFunctions.quote((String)value);
221 } else if (value instanceof ConsString) {
222 return JSONFunctions.quote(value.toString());
223 }
224
225 if (value instanceof Number) {
226 return JSType.isFinite(((Number)value).doubleValue()) ? JSType.toString(value) : "null";
227 }
228
229 final JSType type = JSType.of(value);
230 if (type == JSType.OBJECT) {
231 if (isArray(value)) {
232 return JA((ScriptObject)value, state);
233 } else if (value instanceof ScriptObject) {
234 return JO((ScriptObject)value, state);
235 }
236 }
237
238 return UNDEFINED;
239 }
240
241 // Spec: The abstract operation JO(value) serializes an object.
242 private static String JO(final ScriptObject value, final StringifyState state) {
243 if (state.stack.containsKey(value)) {
244 throw typeError("JSON.stringify.cyclic");
245 }
246
247 state.stack.put(value, value);
248 final StringBuilder stepback = new StringBuilder(state.indent.toString());
249 state.indent.append(state.gap);
250
251 final StringBuilder finalStr = new StringBuilder();
252 final List<Object> partial = new ArrayList<>();
298 if (index < size - 1) {
299 finalStr.append(",\n");
300 finalStr.append(state.indent);
301 }
302 index++;
303 }
304
305 finalStr.append('\n');
306 finalStr.append(stepback);
307 finalStr.append('}');
308 }
309 }
310
311 state.stack.remove(value);
312 state.indent = stepback;
313
314 return finalStr.toString();
315 }
316
317 // Spec: The abstract operation JA(value) serializes an array.
318 private static Object JA(final ScriptObject value, final StringifyState state) {
319 if (state.stack.containsKey(value)) {
320 throw typeError("JSON.stringify.cyclic");
321 }
322
323 state.stack.put(value, value);
324 final StringBuilder stepback = new StringBuilder(state.indent.toString());
325 state.indent.append(state.gap);
326 final List<Object> partial = new ArrayList<>();
327
328 final int length = JSType.toInteger(value.getLength());
329 int index = 0;
330
331 while (index < length) {
332 Object strP = str(index, value, state);
333 if (strP == UNDEFINED) {
334 strP = "null";
335 }
336 partial.add(strP);
337 index++;
338 }
|