The data contained in this repository can be downloaded to your computer using one of several clients.
Please see the documentation of your version control software client for more information.

Please select the desired protocol below to get the URL.

This URL has Read-Only access.

Statistics
| Branch: | Revision:

main_repo / deps / v8 / src / json.js @ f230a1cf

History | View | Annotate | Download (7.41 KB)

1
// Copyright 2009 the V8 project authors. All rights reserved.
2
// Redistribution and use in source and binary forms, with or without
3
// modification, are permitted provided that the following conditions are
4
// met:
5
//
6
//     * Redistributions of source code must retain the above copyright
7
//       notice, this list of conditions and the following disclaimer.
8
//     * Redistributions in binary form must reproduce the above
9
//       copyright notice, this list of conditions and the following
10
//       disclaimer in the documentation and/or other materials provided
11
//       with the distribution.
12
//     * Neither the name of Google Inc. nor the names of its
13
//       contributors may be used to endorse or promote products derived
14
//       from this software without specific prior written permission.
15
//
16
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27

    
28
// This file relies on the fact that the following declarations have been made
29
// in runtime.js:
30
// var $Array = global.Array;
31
// var $String = global.String;
32

    
33
var $JSON = global.JSON;
34

    
35
// -------------------------------------------------------------------
36

    
37
function Revive(holder, name, reviver) {
38
  var val = holder[name];
39
  if (IS_OBJECT(val)) {
40
    if (IS_ARRAY(val)) {
41
      var length = val.length;
42
      for (var i = 0; i < length; i++) {
43
        var newElement = Revive(val, $String(i), reviver);
44
        val[i] = newElement;
45
      }
46
    } else {
47
      for (var p in val) {
48
        if (%_CallFunction(val, p, ObjectHasOwnProperty)) {
49
          var newElement = Revive(val, p, reviver);
50
          if (IS_UNDEFINED(newElement)) {
51
            delete val[p];
52
          } else {
53
            val[p] = newElement;
54
          }
55
        }
56
      }
57
    }
58
  }
59
  return %_CallFunction(holder, name, val, reviver);
60
}
61

    
62
function JSONParse(text, reviver) {
63
  var unfiltered = %ParseJson(TO_STRING_INLINE(text));
64
  if (IS_SPEC_FUNCTION(reviver)) {
65
    return Revive({'': unfiltered}, '', reviver);
66
  } else {
67
    return unfiltered;
68
  }
69
}
70

    
71
function SerializeArray(value, replacer, stack, indent, gap) {
72
  if (!%PushIfAbsent(stack, value)) {
73
    throw MakeTypeError('circular_structure', $Array());
74
  }
75
  var stepback = indent;
76
  indent += gap;
77
  var partial = new InternalArray();
78
  var len = value.length;
79
  for (var i = 0; i < len; i++) {
80
    var strP = JSONSerialize($String(i), value, replacer, stack,
81
                             indent, gap);
82
    if (IS_UNDEFINED(strP)) {
83
      strP = "null";
84
    }
85
    partial.push(strP);
86
  }
87
  var final;
88
  if (gap == "") {
89
    final = "[" + partial.join(",") + "]";
90
  } else if (partial.length > 0) {
91
    var separator = ",\n" + indent;
92
    final = "[\n" + indent + partial.join(separator) + "\n" +
93
        stepback + "]";
94
  } else {
95
    final = "[]";
96
  }
97
  stack.pop();
98
  return final;
99
}
100

    
101
function SerializeObject(value, replacer, stack, indent, gap) {
102
  if (!%PushIfAbsent(stack, value)) {
103
    throw MakeTypeError('circular_structure', $Array());
104
  }
105
  var stepback = indent;
106
  indent += gap;
107
  var partial = new InternalArray();
108
  if (IS_ARRAY(replacer)) {
109
    var length = replacer.length;
110
    for (var i = 0; i < length; i++) {
111
      if (%_CallFunction(replacer, i, ObjectHasOwnProperty)) {
112
        var p = replacer[i];
113
        var strP = JSONSerialize(p, value, replacer, stack, indent, gap);
114
        if (!IS_UNDEFINED(strP)) {
115
          var member = %QuoteJSONString(p) + ":";
116
          if (gap != "") member += " ";
117
          member += strP;
118
          partial.push(member);
119
        }
120
      }
121
    }
122
  } else {
123
    for (var p in value) {
124
      if (%_CallFunction(value, p, ObjectHasOwnProperty)) {
125
        var strP = JSONSerialize(p, value, replacer, stack, indent, gap);
126
        if (!IS_UNDEFINED(strP)) {
127
          var member = %QuoteJSONString(p) + ":";
128
          if (gap != "") member += " ";
129
          member += strP;
130
          partial.push(member);
131
        }
132
      }
133
    }
134
  }
135
  var final;
136
  if (gap == "") {
137
    final = "{" + partial.join(",") + "}";
138
  } else if (partial.length > 0) {
139
    var separator = ",\n" + indent;
140
    final = "{\n" + indent + partial.join(separator) + "\n" +
141
        stepback + "}";
142
  } else {
143
    final = "{}";
144
  }
145
  stack.pop();
146
  return final;
147
}
148

    
149
function JSONSerialize(key, holder, replacer, stack, indent, gap) {
150
  var value = holder[key];
151
  if (IS_SPEC_OBJECT(value)) {
152
    var toJSON = value.toJSON;
153
    if (IS_SPEC_FUNCTION(toJSON)) {
154
      value = %_CallFunction(value, key, toJSON);
155
    }
156
  }
157
  if (IS_SPEC_FUNCTION(replacer)) {
158
    value = %_CallFunction(holder, key, value, replacer);
159
  }
160
  if (IS_STRING(value)) {
161
    return %QuoteJSONString(value);
162
  } else if (IS_NUMBER(value)) {
163
    return JSON_NUMBER_TO_STRING(value);
164
  } else if (IS_BOOLEAN(value)) {
165
    return value ? "true" : "false";
166
  } else if (IS_NULL(value)) {
167
    return "null";
168
  } else if (IS_SPEC_OBJECT(value) && !(typeof value == "function")) {
169
    // Non-callable object. If it's a primitive wrapper, it must be unwrapped.
170
    if (IS_ARRAY(value)) {
171
      return SerializeArray(value, replacer, stack, indent, gap);
172
    } else if (IS_NUMBER_WRAPPER(value)) {
173
      value = ToNumber(value);
174
      return JSON_NUMBER_TO_STRING(value);
175
    } else if (IS_STRING_WRAPPER(value)) {
176
      return %QuoteJSONString(ToString(value));
177
    } else if (IS_BOOLEAN_WRAPPER(value)) {
178
      return %_ValueOf(value) ? "true" : "false";
179
    } else {
180
      return SerializeObject(value, replacer, stack, indent, gap);
181
    }
182
  }
183
  // Undefined or a callable object.
184
  return UNDEFINED;
185
}
186

    
187

    
188
function JSONStringify(value, replacer, space) {
189
  if (%_ArgumentsLength() == 1) {
190
    return %BasicJSONStringify(value);
191
  }
192
  if (IS_OBJECT(space)) {
193
    // Unwrap 'space' if it is wrapped
194
    if (IS_NUMBER_WRAPPER(space)) {
195
      space = ToNumber(space);
196
    } else if (IS_STRING_WRAPPER(space)) {
197
      space = ToString(space);
198
    }
199
  }
200
  var gap;
201
  if (IS_NUMBER(space)) {
202
    space = MathMax(0, MathMin(ToInteger(space), 10));
203
    gap = %_SubString("          ", 0, space);
204
  } else if (IS_STRING(space)) {
205
    if (space.length > 10) {
206
      gap = %_SubString(space, 0, 10);
207
    } else {
208
      gap = space;
209
    }
210
  } else {
211
    gap = "";
212
  }
213
  return JSONSerialize('', {'': value}, replacer, new InternalArray(), "", gap);
214
}
215

    
216

    
217
// -------------------------------------------------------------------
218

    
219
function SetUpJSON() {
220
  %CheckIsBootstrapping();
221

    
222
  // Set up non-enumerable properties of the JSON object.
223
  InstallFunctions($JSON, DONT_ENUM, $Array(
224
    "parse", JSONParse,
225
    "stringify", JSONStringify
226
  ));
227
}
228

    
229
SetUpJSON();
230

    
231

    
232
// -------------------------------------------------------------------
233
// JSON Builtins
234

    
235
function JSONSerializeAdapter(key, object) {
236
  var holder = {};
237
  holder[key] = object;
238
  // No need to pass the actual holder since there is no replacer function.
239
  return JSONSerialize(key, holder, UNDEFINED, new InternalArray(), "", "");
240
}