| OLD | NEW |
| 1 // Copyright 2009 the V8 project authors. All rights reserved. | 1 // Copyright 2009 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 59 | 59 |
| 60 function JSONParse(text, reviver) { | 60 function JSONParse(text, reviver) { |
| 61 var unfiltered = ParseJSONUnfiltered(text); | 61 var unfiltered = ParseJSONUnfiltered(text); |
| 62 if (IS_FUNCTION(reviver)) { | 62 if (IS_FUNCTION(reviver)) { |
| 63 return Revive({'': unfiltered}, '', reviver); | 63 return Revive({'': unfiltered}, '', reviver); |
| 64 } else { | 64 } else { |
| 65 return unfiltered; | 65 return unfiltered; |
| 66 } | 66 } |
| 67 } | 67 } |
| 68 | 68 |
| 69 function QuoteJSONString(str) { | |
| 70 var quoted_str = %QuoteJSONString(str); | |
| 71 if (IS_STRING(quoted_str)) return quoted_str; | |
| 72 return '"' + str + '"'; | |
| 73 } | |
| 74 | |
| 75 function StackContains(stack, val) { | 69 function StackContains(stack, val) { |
| 76 var length = stack.length; | 70 var length = stack.length; |
| 77 for (var i = 0; i < length; i++) { | 71 for (var i = 0; i < length; i++) { |
| 78 if (stack[i] === val) { | 72 if (stack[i] === val) { |
| 79 return true; | 73 return true; |
| 80 } | 74 } |
| 81 } | 75 } |
| 82 return false; | 76 return false; |
| 83 } | 77 } |
| 84 | 78 |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 121 var stepback = indent; | 115 var stepback = indent; |
| 122 indent += gap; | 116 indent += gap; |
| 123 var partial = []; | 117 var partial = []; |
| 124 if (IS_ARRAY(replacer)) { | 118 if (IS_ARRAY(replacer)) { |
| 125 var length = replacer.length; | 119 var length = replacer.length; |
| 126 for (var i = 0; i < length; i++) { | 120 for (var i = 0; i < length; i++) { |
| 127 if (ObjectHasOwnProperty.call(replacer, i)) { | 121 if (ObjectHasOwnProperty.call(replacer, i)) { |
| 128 var p = replacer[i]; | 122 var p = replacer[i]; |
| 129 var strP = JSONSerialize(p, value, replacer, stack, indent, gap); | 123 var strP = JSONSerialize(p, value, replacer, stack, indent, gap); |
| 130 if (!IS_UNDEFINED(strP)) { | 124 if (!IS_UNDEFINED(strP)) { |
| 131 var member = QuoteJSONString(p) + ":"; | 125 var member = %QuoteJSONString(p) + ":"; |
| 132 if (gap != "") member += " "; | 126 if (gap != "") member += " "; |
| 133 member += strP; | 127 member += strP; |
| 134 partial.push(member); | 128 partial.push(member); |
| 135 } | 129 } |
| 136 } | 130 } |
| 137 } | 131 } |
| 138 } else { | 132 } else { |
| 139 for (var p in value) { | 133 for (var p in value) { |
| 140 if (ObjectHasOwnProperty.call(value, p)) { | 134 if (ObjectHasOwnProperty.call(value, p)) { |
| 141 var strP = JSONSerialize(p, value, replacer, stack, indent, gap); | 135 var strP = JSONSerialize(p, value, replacer, stack, indent, gap); |
| 142 if (!IS_UNDEFINED(strP)) { | 136 if (!IS_UNDEFINED(strP)) { |
| 143 var member = QuoteJSONString(p) + ":"; | 137 var member = %QuoteJSONString(p) + ":"; |
| 144 if (gap != "") member += " "; | 138 if (gap != "") member += " "; |
| 145 member += strP; | 139 member += strP; |
| 146 partial.push(member); | 140 partial.push(member); |
| 147 } | 141 } |
| 148 } | 142 } |
| 149 } | 143 } |
| 150 } | 144 } |
| 151 var final; | 145 var final; |
| 152 if (gap == "") { | 146 if (gap == "") { |
| 153 final = "{" + partial.join(",") + "}"; | 147 final = "{" + partial.join(",") + "}"; |
| (...skipping 24 matching lines...) Expand all Loading... |
| 178 if (IS_NUMBER_WRAPPER(value)) { | 172 if (IS_NUMBER_WRAPPER(value)) { |
| 179 value = $Number(value); | 173 value = $Number(value); |
| 180 } else if (IS_STRING_WRAPPER(value)) { | 174 } else if (IS_STRING_WRAPPER(value)) { |
| 181 value = $String(value); | 175 value = $String(value); |
| 182 } else if (IS_BOOLEAN_WRAPPER(value)) { | 176 } else if (IS_BOOLEAN_WRAPPER(value)) { |
| 183 value = %_ValueOf(value); | 177 value = %_ValueOf(value); |
| 184 } | 178 } |
| 185 } | 179 } |
| 186 switch (typeof value) { | 180 switch (typeof value) { |
| 187 case "string": | 181 case "string": |
| 188 return QuoteJSONString(value); | 182 return %QuoteJSONString(value); |
| 189 case "object": | 183 case "object": |
| 190 if (!value) { | 184 if (!value) { |
| 191 return "null"; | 185 return "null"; |
| 192 } else if (IS_ARRAY(value)) { | 186 } else if (IS_ARRAY(value)) { |
| 193 return SerializeArray(value, replacer, stack, indent, gap); | 187 return SerializeArray(value, replacer, stack, indent, gap); |
| 194 } else { | 188 } else { |
| 195 return SerializeObject(value, replacer, stack, indent, gap); | 189 return SerializeObject(value, replacer, stack, indent, gap); |
| 196 } | 190 } |
| 197 case "number": | 191 case "number": |
| 198 return $isFinite(value) ? $String(value) : "null"; | 192 return $isFinite(value) ? $String(value) : "null"; |
| 199 case "boolean": | 193 case "boolean": |
| 200 return value ? "true" : "false"; | 194 return value ? "true" : "false"; |
| 201 } | 195 } |
| 202 } | 196 } |
| 203 | 197 |
| 198 function BasicSerializeArray(value, stack) { |
| 199 if (StackContains(stack, value)) { |
| 200 throw MakeTypeError('circular_structure', []); |
| 201 } |
| 202 stack.push(value); |
| 203 var partial = []; |
| 204 var len = value.length; |
| 205 for (var i = 0; i < len; i++) { |
| 206 var strP = BasicJSONSerialize($String(i), value, stack); |
| 207 if (IS_UNDEFINED(strP)) strP = "null"; |
| 208 partial.push(strP); |
| 209 } |
| 210 stack.pop(); |
| 211 return "[" + partial.join() + "]"; |
| 212 } |
| 213 |
| 214 function BasicSerializeObject(value, stack) { |
| 215 if (StackContains(stack, value)) { |
| 216 throw MakeTypeError('circular_structure', []); |
| 217 } |
| 218 stack.push(value); |
| 219 var partial = []; |
| 220 for (var p in value) { |
| 221 if (ObjectHasOwnProperty.call(value, p)) { |
| 222 var strP = BasicJSONSerialize(p, value, stack); |
| 223 if (!IS_UNDEFINED(strP)) partial.push(%QuoteJSONString(p) + ":" + strP); |
| 224 } |
| 225 } |
| 226 stack.pop(); |
| 227 return "{" + partial.join() + "}"; |
| 228 } |
| 229 |
| 230 function BasicJSONSerialize(key, holder, stack) { |
| 231 var value = holder[key]; |
| 232 if (IS_OBJECT(value) && value) { |
| 233 var toJSON = value.toJSON; |
| 234 if (IS_FUNCTION(toJSON)) value = toJSON.call(value, key); |
| 235 } |
| 236 // Unwrap value if necessary |
| 237 if (IS_OBJECT(value)) { |
| 238 if (IS_NUMBER_WRAPPER(value)) { |
| 239 value = $Number(value); |
| 240 } else if (IS_STRING_WRAPPER(value)) { |
| 241 value = $String(value); |
| 242 } else if (IS_BOOLEAN_WRAPPER(value)) { |
| 243 value = %_ValueOf(value); |
| 244 } |
| 245 } |
| 246 switch (typeof value) { |
| 247 case "string": |
| 248 return %QuoteJSONString(value); |
| 249 case "object": |
| 250 if (!value) { |
| 251 return "null"; |
| 252 } else if (IS_ARRAY(value)) { |
| 253 return BasicSerializeArray(value, stack); |
| 254 } else { |
| 255 return BasicSerializeObject(value, stack); |
| 256 } |
| 257 case "number": |
| 258 return $isFinite(value) ? $String(value) : "null"; |
| 259 case "boolean": |
| 260 return value ? "true" : "false"; |
| 261 } |
| 262 } |
| 263 |
| 204 function JSONStringify(value, replacer, space) { | 264 function JSONStringify(value, replacer, space) { |
| 205 var stack = []; | 265 if (IS_UNDEFINED(replacer) && IS_UNDEFINED(space)) { |
| 206 var indent = ""; | 266 return BasicJSONSerialize('', {'': value}, []); |
| 267 } |
| 207 if (IS_OBJECT(space)) { | 268 if (IS_OBJECT(space)) { |
| 208 // Unwrap 'space' if it is wrapped | 269 // Unwrap 'space' if it is wrapped |
| 209 if (IS_NUMBER_WRAPPER(space)) { | 270 if (IS_NUMBER_WRAPPER(space)) { |
| 210 space = $Number(space); | 271 space = $Number(space); |
| 211 } else if (IS_STRING_WRAPPER(space)) { | 272 } else if (IS_STRING_WRAPPER(space)) { |
| 212 space = $String(space); | 273 space = $String(space); |
| 213 } | 274 } |
| 214 } | 275 } |
| 215 var gap; | 276 var gap; |
| 216 if (IS_NUMBER(space)) { | 277 if (IS_NUMBER(space)) { |
| 217 space = $Math.min(ToInteger(space), 10); | 278 space = $Math.min(ToInteger(space), 10); |
| 218 gap = ""; | 279 gap = ""; |
| 219 for (var i = 0; i < space; i++) { | 280 for (var i = 0; i < space; i++) { |
| 220 gap += " "; | 281 gap += " "; |
| 221 } | 282 } |
| 222 } else if (IS_STRING(space)) { | 283 } else if (IS_STRING(space)) { |
| 223 if (space.length > 10) { | 284 if (space.length > 10) { |
| 224 gap = space.substring(0, 10); | 285 gap = space.substring(0, 10); |
| 225 } else { | 286 } else { |
| 226 gap = space; | 287 gap = space; |
| 227 } | 288 } |
| 228 } else { | 289 } else { |
| 229 gap = ""; | 290 gap = ""; |
| 230 } | 291 } |
| 231 return JSONSerialize('', {'': value}, replacer, stack, indent, gap); | 292 return JSONSerialize('', {'': value}, replacer, [], "", gap); |
| 232 } | 293 } |
| 233 | 294 |
| 234 function SetupJSON() { | 295 function SetupJSON() { |
| 235 InstallFunctions($JSON, DONT_ENUM, $Array( | 296 InstallFunctions($JSON, DONT_ENUM, $Array( |
| 236 "parse", JSONParse, | 297 "parse", JSONParse, |
| 237 "stringify", JSONStringify | 298 "stringify", JSONStringify |
| 238 )); | 299 )); |
| 239 } | 300 } |
| 240 | 301 |
| 241 SetupJSON(); | 302 SetupJSON(); |
| OLD | NEW |