• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2009 Google Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are
6  * met:
7  *
8  *     * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  *     * Redistributions in binary form must reproduce the above
11  * copyright notice, this list of conditions and the following disclaimer
12  * in the documentation and/or other materials provided with the
13  * distribution.
14  *     * Neither the name of Google Inc. nor the names of its
15  * contributors may be used to endorse or promote products derived from
16  * this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30 
31 #ifndef JSONValues_h
32 #define JSONValues_h
33 
34 #include "platform/PlatformExport.h"
35 #include "wtf/Forward.h"
36 #include "wtf/HashMap.h"
37 #include "wtf/RefCounted.h"
38 #include "wtf/Vector.h"
39 #include "wtf/text/StringHash.h"
40 #include "wtf/text/WTFString.h"
41 
42 namespace WebCore {
43 
44 class JSONArray;
45 class JSONObject;
46 
47 class PLATFORM_EXPORT JSONValue : public RefCounted<JSONValue> {
48 public:
49     static const int maxDepth = 1000;
50 
JSONValue()51     JSONValue() : m_type(TypeNull) { }
~JSONValue()52     virtual ~JSONValue() { }
53 
null()54     static PassRefPtr<JSONValue> null()
55     {
56         return adoptRef(new JSONValue());
57     }
58 
59     typedef enum {
60         TypeNull = 0,
61         TypeBoolean,
62         TypeNumber,
63         TypeString,
64         TypeObject,
65         TypeArray
66     } Type;
67 
type()68     Type type() const { return m_type; }
69 
isNull()70     bool isNull() const { return m_type == TypeNull; }
71 
72     virtual bool asBoolean(bool* output) const;
73     virtual bool asNumber(double* output) const;
74     virtual bool asNumber(long* output) const;
75     virtual bool asNumber(int* output) const;
76     virtual bool asNumber(unsigned long* output) const;
77     virtual bool asNumber(unsigned* output) const;
78     virtual bool asString(String* output) const;
79     virtual bool asValue(RefPtr<JSONValue>* output);
80     virtual bool asObject(RefPtr<JSONObject>* output);
81     virtual bool asArray(RefPtr<JSONArray>* output);
82     virtual PassRefPtr<JSONObject> asObject();
83     virtual PassRefPtr<JSONArray> asArray();
84 
85     String toJSONString() const;
86     virtual void writeJSON(StringBuilder* output) const;
87 
88 protected:
JSONValue(Type type)89     explicit JSONValue(Type type) : m_type(type) { }
90 
91 private:
92     Type m_type;
93 };
94 
95 class PLATFORM_EXPORT JSONBasicValue : public JSONValue {
96 public:
97 
create(bool value)98     static PassRefPtr<JSONBasicValue> create(bool value)
99     {
100         return adoptRef(new JSONBasicValue(value));
101     }
102 
create(int value)103     static PassRefPtr<JSONBasicValue> create(int value)
104     {
105         return adoptRef(new JSONBasicValue(value));
106     }
107 
create(double value)108     static PassRefPtr<JSONBasicValue> create(double value)
109     {
110         return adoptRef(new JSONBasicValue(value));
111     }
112 
113     virtual bool asBoolean(bool* output) const;
114     virtual bool asNumber(double* output) const;
115     virtual bool asNumber(long* output) const;
116     virtual bool asNumber(int* output) const;
117     virtual bool asNumber(unsigned long* output) const;
118     virtual bool asNumber(unsigned* output) const;
119 
120     virtual void writeJSON(StringBuilder* output) const;
121 
122 private:
JSONBasicValue(bool value)123     explicit JSONBasicValue(bool value) : JSONValue(TypeBoolean), m_boolValue(value) { }
JSONBasicValue(int value)124     explicit JSONBasicValue(int value) : JSONValue(TypeNumber), m_doubleValue((double)value) { }
JSONBasicValue(double value)125     explicit JSONBasicValue(double value) : JSONValue(TypeNumber), m_doubleValue(value) { }
126 
127     union {
128         bool m_boolValue;
129         double m_doubleValue;
130     };
131 };
132 
133 class PLATFORM_EXPORT JSONString : public JSONValue {
134 public:
create(const String & value)135     static PassRefPtr<JSONString> create(const String& value)
136     {
137         return adoptRef(new JSONString(value));
138     }
139 
create(const char * value)140     static PassRefPtr<JSONString> create(const char* value)
141     {
142         return adoptRef(new JSONString(value));
143     }
144 
145     virtual bool asString(String* output) const;
146 
147     virtual void writeJSON(StringBuilder* output) const;
148 
149 private:
JSONString(const String & value)150     explicit JSONString(const String& value) : JSONValue(TypeString), m_stringValue(value) { }
JSONString(const char * value)151     explicit JSONString(const char* value) : JSONValue(TypeString), m_stringValue(value) { }
152 
153     String m_stringValue;
154 };
155 
156 class PLATFORM_EXPORT JSONObjectBase : public JSONValue {
157 private:
158     typedef HashMap<String, RefPtr<JSONValue> > Dictionary;
159 
160 public:
161     typedef Dictionary::iterator iterator;
162     typedef Dictionary::const_iterator const_iterator;
163 
164     virtual PassRefPtr<JSONObject> asObject();
165     JSONObject* openAccessors();
166 
167 protected:
168     ~JSONObjectBase();
169 
170     virtual bool asObject(RefPtr<JSONObject>* output);
171 
172     void setBoolean(const String& name, bool);
173     void setNumber(const String& name, double);
174     void setString(const String& name, const String&);
175     void setValue(const String& name, PassRefPtr<JSONValue>);
176     void setObject(const String& name, PassRefPtr<JSONObject>);
177     void setArray(const String& name, PassRefPtr<JSONArray>);
178 
179     iterator find(const String& name);
180     const_iterator find(const String& name) const;
181     bool getBoolean(const String& name, bool* output) const;
getNumber(const String & name,T * output)182     template<class T> bool getNumber(const String& name, T* output) const
183     {
184         RefPtr<JSONValue> value = get(name);
185         if (!value)
186             return false;
187         return value->asNumber(output);
188     }
189     bool getString(const String& name, String* output) const;
190     PassRefPtr<JSONObject> getObject(const String& name) const;
191     PassRefPtr<JSONArray> getArray(const String& name) const;
192     PassRefPtr<JSONValue> get(const String& name) const;
193 
194     void remove(const String& name);
195 
196     virtual void writeJSON(StringBuilder* output) const;
197 
begin()198     iterator begin() { return m_data.begin(); }
end()199     iterator end() { return m_data.end(); }
begin()200     const_iterator begin() const { return m_data.begin(); }
end()201     const_iterator end() const { return m_data.end(); }
202 
size()203     int size() const { return m_data.size(); }
204 
205 protected:
206     JSONObjectBase();
207 
208 private:
209     Dictionary m_data;
210     Vector<String> m_order;
211 };
212 
213 class PLATFORM_EXPORT JSONObject : public JSONObjectBase {
214 public:
create()215     static PassRefPtr<JSONObject> create()
216     {
217         return adoptRef(new JSONObject());
218     }
219 
220     using JSONObjectBase::asObject;
221 
222     using JSONObjectBase::setBoolean;
223     using JSONObjectBase::setNumber;
224     using JSONObjectBase::setString;
225     using JSONObjectBase::setValue;
226     using JSONObjectBase::setObject;
227     using JSONObjectBase::setArray;
228 
229     using JSONObjectBase::find;
230     using JSONObjectBase::getBoolean;
231     using JSONObjectBase::getNumber;
232     using JSONObjectBase::getString;
233     using JSONObjectBase::getObject;
234     using JSONObjectBase::getArray;
235     using JSONObjectBase::get;
236 
237     using JSONObjectBase::remove;
238 
239     using JSONObjectBase::begin;
240     using JSONObjectBase::end;
241 
242     using JSONObjectBase::size;
243 };
244 
245 
246 class PLATFORM_EXPORT JSONArrayBase : public JSONValue {
247 public:
248     typedef Vector<RefPtr<JSONValue> >::iterator iterator;
249     typedef Vector<RefPtr<JSONValue> >::const_iterator const_iterator;
250 
251     virtual PassRefPtr<JSONArray> asArray();
252 
length()253     unsigned length() const { return m_data.size(); }
254 
255 protected:
256     ~JSONArrayBase();
257 
258     virtual bool asArray(RefPtr<JSONArray>* output);
259 
260     void pushBoolean(bool);
261     void pushInt(int);
262     void pushNumber(double);
263     void pushString(const String&);
264     void pushValue(PassRefPtr<JSONValue>);
265     void pushObject(PassRefPtr<JSONObject>);
266     void pushArray(PassRefPtr<JSONArray>);
267 
268     PassRefPtr<JSONValue> get(size_t index);
269 
270     virtual void writeJSON(StringBuilder* output) const;
271 
begin()272     iterator begin() { return m_data.begin(); }
end()273     iterator end() { return m_data.end(); }
begin()274     const_iterator begin() const { return m_data.begin(); }
end()275     const_iterator end() const { return m_data.end(); }
276 
277 protected:
278     JSONArrayBase();
279 
280 private:
281     Vector<RefPtr<JSONValue> > m_data;
282 };
283 
284 class PLATFORM_EXPORT JSONArray : public JSONArrayBase {
285 public:
create()286     static PassRefPtr<JSONArray> create()
287     {
288         return adoptRef(new JSONArray());
289     }
290 
291     using JSONArrayBase::asArray;
292 
293     using JSONArrayBase::pushBoolean;
294     using JSONArrayBase::pushInt;
295     using JSONArrayBase::pushNumber;
296     using JSONArrayBase::pushString;
297     using JSONArrayBase::pushValue;
298     using JSONArrayBase::pushObject;
299     using JSONArrayBase::pushArray;
300 
301     using JSONArrayBase::get;
302 
303     using JSONArrayBase::begin;
304     using JSONArrayBase::end;
305 };
306 
307 
find(const String & name)308 inline JSONObjectBase::iterator JSONObjectBase::find(const String& name)
309 {
310     return m_data.find(name);
311 }
312 
find(const String & name)313 inline JSONObjectBase::const_iterator JSONObjectBase::find(const String& name) const
314 {
315     return m_data.find(name);
316 }
317 
setBoolean(const String & name,bool value)318 inline void JSONObjectBase::setBoolean(const String& name, bool value)
319 {
320     setValue(name, JSONBasicValue::create(value));
321 }
322 
setNumber(const String & name,double value)323 inline void JSONObjectBase::setNumber(const String& name, double value)
324 {
325     setValue(name, JSONBasicValue::create(value));
326 }
327 
setString(const String & name,const String & value)328 inline void JSONObjectBase::setString(const String& name, const String& value)
329 {
330     setValue(name, JSONString::create(value));
331 }
332 
setValue(const String & name,PassRefPtr<JSONValue> value)333 inline void JSONObjectBase::setValue(const String& name, PassRefPtr<JSONValue> value)
334 {
335     ASSERT(value);
336     if (m_data.set(name, value).isNewEntry)
337         m_order.append(name);
338 }
339 
setObject(const String & name,PassRefPtr<JSONObject> value)340 inline void JSONObjectBase::setObject(const String& name, PassRefPtr<JSONObject> value)
341 {
342     ASSERT(value);
343     if (m_data.set(name, value).isNewEntry)
344         m_order.append(name);
345 }
346 
setArray(const String & name,PassRefPtr<JSONArray> value)347 inline void JSONObjectBase::setArray(const String& name, PassRefPtr<JSONArray> value)
348 {
349     ASSERT(value);
350     if (m_data.set(name, value).isNewEntry)
351         m_order.append(name);
352 }
353 
pushBoolean(bool value)354 inline void JSONArrayBase::pushBoolean(bool value)
355 {
356     m_data.append(JSONBasicValue::create(value));
357 }
358 
pushInt(int value)359 inline void JSONArrayBase::pushInt(int value)
360 {
361     m_data.append(JSONBasicValue::create(value));
362 }
363 
pushNumber(double value)364 inline void JSONArrayBase::pushNumber(double value)
365 {
366     m_data.append(JSONBasicValue::create(value));
367 }
368 
pushString(const String & value)369 inline void JSONArrayBase::pushString(const String& value)
370 {
371     m_data.append(JSONString::create(value));
372 }
373 
pushValue(PassRefPtr<JSONValue> value)374 inline void JSONArrayBase::pushValue(PassRefPtr<JSONValue> value)
375 {
376     ASSERT(value);
377     m_data.append(value);
378 }
379 
pushObject(PassRefPtr<JSONObject> value)380 inline void JSONArrayBase::pushObject(PassRefPtr<JSONObject> value)
381 {
382     ASSERT(value);
383     m_data.append(value);
384 }
385 
pushArray(PassRefPtr<JSONArray> value)386 inline void JSONArrayBase::pushArray(PassRefPtr<JSONArray> value)
387 {
388     ASSERT(value);
389     m_data.append(value);
390 }
391 
392 } // namespace WebCore
393 
394 #endif // !defined(JSONValues_h)
395