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 "wtf/Forward.h" 35 #include "wtf/HashMap.h" 36 #include "wtf/RefCounted.h" 37 #include "wtf/Vector.h" 38 #include "wtf/text/StringHash.h" 39 #include "wtf/text/WTFString.h" 40 41 namespace WebCore { 42 43 class JSONArray; 44 class JSONObject; 45 46 class JSONValue : public RefCounted<JSONValue> { 47 public: 48 static const int maxDepth = 1000; 49 50 JSONValue() : m_type(TypeNull) { } 51 virtual ~JSONValue() { } 52 53 static PassRefPtr<JSONValue> null() 54 { 55 return adoptRef(new JSONValue()); 56 } 57 58 typedef enum { 59 TypeNull = 0, 60 TypeBoolean, 61 TypeNumber, 62 TypeString, 63 TypeObject, 64 TypeArray 65 } Type; 66 67 Type type() const { return m_type; } 68 69 bool isNull() const { return m_type == TypeNull; } 70 71 virtual bool asBoolean(bool* output) const; 72 virtual bool asNumber(double* output) const; 73 virtual bool asNumber(long* output) const; 74 virtual bool asNumber(int* output) const; 75 virtual bool asNumber(unsigned long* output) const; 76 virtual bool asNumber(unsigned* output) const; 77 virtual bool asString(String* output) const; 78 virtual bool asValue(RefPtr<JSONValue>* output); 79 virtual bool asObject(RefPtr<JSONObject>* output); 80 virtual bool asArray(RefPtr<JSONArray>* output); 81 virtual PassRefPtr<JSONObject> asObject(); 82 virtual PassRefPtr<JSONArray> asArray(); 83 84 String toJSONString() const; 85 virtual void writeJSON(StringBuilder* output) const; 86 87 protected: 88 explicit JSONValue(Type type) : m_type(type) { } 89 90 private: 91 Type m_type; 92 }; 93 94 class JSONBasicValue : public JSONValue { 95 public: 96 97 static PassRefPtr<JSONBasicValue> create(bool value) 98 { 99 return adoptRef(new JSONBasicValue(value)); 100 } 101 102 static PassRefPtr<JSONBasicValue> create(int value) 103 { 104 return adoptRef(new JSONBasicValue(value)); 105 } 106 107 static PassRefPtr<JSONBasicValue> create(double value) 108 { 109 return adoptRef(new JSONBasicValue(value)); 110 } 111 112 virtual bool asBoolean(bool* output) const; 113 virtual bool asNumber(double* output) const; 114 virtual bool asNumber(long* output) const; 115 virtual bool asNumber(int* output) const; 116 virtual bool asNumber(unsigned long* output) const; 117 virtual bool asNumber(unsigned* output) const; 118 119 virtual void writeJSON(StringBuilder* output) const; 120 121 private: 122 explicit JSONBasicValue(bool value) : JSONValue(TypeBoolean), m_boolValue(value) { } 123 explicit JSONBasicValue(int value) : JSONValue(TypeNumber), m_doubleValue((double)value) { } 124 explicit JSONBasicValue(double value) : JSONValue(TypeNumber), m_doubleValue(value) { } 125 126 union { 127 bool m_boolValue; 128 double m_doubleValue; 129 }; 130 }; 131 132 class JSONString : public JSONValue { 133 public: 134 static PassRefPtr<JSONString> create(const String& value) 135 { 136 return adoptRef(new JSONString(value)); 137 } 138 139 static PassRefPtr<JSONString> create(const char* value) 140 { 141 return adoptRef(new JSONString(value)); 142 } 143 144 virtual bool asString(String* output) const; 145 146 virtual void writeJSON(StringBuilder* output) const; 147 148 private: 149 explicit JSONString(const String& value) : JSONValue(TypeString), m_stringValue(value) { } 150 explicit JSONString(const char* value) : JSONValue(TypeString), m_stringValue(value) { } 151 152 String m_stringValue; 153 }; 154 155 class JSONObjectBase : public JSONValue { 156 private: 157 typedef HashMap<String, RefPtr<JSONValue> > Dictionary; 158 159 public: 160 typedef Dictionary::iterator iterator; 161 typedef Dictionary::const_iterator const_iterator; 162 163 virtual PassRefPtr<JSONObject> asObject(); 164 JSONObject* openAccessors(); 165 166 protected: 167 ~JSONObjectBase(); 168 169 virtual bool asObject(RefPtr<JSONObject>* output); 170 171 void setBoolean(const String& name, bool); 172 void setNumber(const String& name, double); 173 void setString(const String& name, const String&); 174 void setValue(const String& name, PassRefPtr<JSONValue>); 175 void setObject(const String& name, PassRefPtr<JSONObject>); 176 void setArray(const String& name, PassRefPtr<JSONArray>); 177 178 iterator find(const String& name); 179 const_iterator find(const String& name) const; 180 bool getBoolean(const String& name, bool* output) const; 181 template<class T> bool getNumber(const String& name, T* output) const 182 { 183 RefPtr<JSONValue> value = get(name); 184 if (!value) 185 return false; 186 return value->asNumber(output); 187 } 188 bool getString(const String& name, String* output) const; 189 PassRefPtr<JSONObject> getObject(const String& name) const; 190 PassRefPtr<JSONArray> getArray(const String& name) const; 191 PassRefPtr<JSONValue> get(const String& name) const; 192 193 void remove(const String& name); 194 195 virtual void writeJSON(StringBuilder* output) const; 196 197 iterator begin() { return m_data.begin(); } 198 iterator end() { return m_data.end(); } 199 const_iterator begin() const { return m_data.begin(); } 200 const_iterator end() const { return m_data.end(); } 201 202 int size() const { return m_data.size(); } 203 204 protected: 205 JSONObjectBase(); 206 207 private: 208 Dictionary m_data; 209 Vector<String> m_order; 210 }; 211 212 class JSONObject : public JSONObjectBase { 213 public: 214 static PassRefPtr<JSONObject> create() 215 { 216 return adoptRef(new JSONObject()); 217 } 218 219 using JSONObjectBase::asObject; 220 221 using JSONObjectBase::setBoolean; 222 using JSONObjectBase::setNumber; 223 using JSONObjectBase::setString; 224 using JSONObjectBase::setValue; 225 using JSONObjectBase::setObject; 226 using JSONObjectBase::setArray; 227 228 using JSONObjectBase::find; 229 using JSONObjectBase::getBoolean; 230 using JSONObjectBase::getNumber; 231 using JSONObjectBase::getString; 232 using JSONObjectBase::getObject; 233 using JSONObjectBase::getArray; 234 using JSONObjectBase::get; 235 236 using JSONObjectBase::remove; 237 238 using JSONObjectBase::begin; 239 using JSONObjectBase::end; 240 241 using JSONObjectBase::size; 242 }; 243 244 245 class JSONArrayBase : public JSONValue { 246 public: 247 typedef Vector<RefPtr<JSONValue> >::iterator iterator; 248 typedef Vector<RefPtr<JSONValue> >::const_iterator const_iterator; 249 250 virtual PassRefPtr<JSONArray> asArray(); 251 252 unsigned length() const { return m_data.size(); } 253 254 protected: 255 ~JSONArrayBase(); 256 257 virtual bool asArray(RefPtr<JSONArray>* output); 258 259 void pushBoolean(bool); 260 void pushInt(int); 261 void pushNumber(double); 262 void pushString(const String&); 263 void pushValue(PassRefPtr<JSONValue>); 264 void pushObject(PassRefPtr<JSONObject>); 265 void pushArray(PassRefPtr<JSONArray>); 266 267 PassRefPtr<JSONValue> get(size_t index); 268 269 virtual void writeJSON(StringBuilder* output) const; 270 271 iterator begin() { return m_data.begin(); } 272 iterator end() { return m_data.end(); } 273 const_iterator begin() const { return m_data.begin(); } 274 const_iterator end() const { return m_data.end(); } 275 276 protected: 277 JSONArrayBase(); 278 279 private: 280 Vector<RefPtr<JSONValue> > m_data; 281 }; 282 283 class JSONArray : public JSONArrayBase { 284 public: 285 static PassRefPtr<JSONArray> create() 286 { 287 return adoptRef(new JSONArray()); 288 } 289 290 using JSONArrayBase::asArray; 291 292 using JSONArrayBase::pushBoolean; 293 using JSONArrayBase::pushInt; 294 using JSONArrayBase::pushNumber; 295 using JSONArrayBase::pushString; 296 using JSONArrayBase::pushValue; 297 using JSONArrayBase::pushObject; 298 using JSONArrayBase::pushArray; 299 300 using JSONArrayBase::get; 301 302 using JSONArrayBase::begin; 303 using JSONArrayBase::end; 304 }; 305 306 307 inline JSONObjectBase::iterator JSONObjectBase::find(const String& name) 308 { 309 return m_data.find(name); 310 } 311 312 inline JSONObjectBase::const_iterator JSONObjectBase::find(const String& name) const 313 { 314 return m_data.find(name); 315 } 316 317 inline void JSONObjectBase::setBoolean(const String& name, bool value) 318 { 319 setValue(name, JSONBasicValue::create(value)); 320 } 321 322 inline void JSONObjectBase::setNumber(const String& name, double value) 323 { 324 setValue(name, JSONBasicValue::create(value)); 325 } 326 327 inline void JSONObjectBase::setString(const String& name, const String& value) 328 { 329 setValue(name, JSONString::create(value)); 330 } 331 332 inline void JSONObjectBase::setValue(const String& name, PassRefPtr<JSONValue> value) 333 { 334 ASSERT(value); 335 if (m_data.set(name, value).isNewEntry) 336 m_order.append(name); 337 } 338 339 inline void JSONObjectBase::setObject(const String& name, PassRefPtr<JSONObject> value) 340 { 341 ASSERT(value); 342 if (m_data.set(name, value).isNewEntry) 343 m_order.append(name); 344 } 345 346 inline void JSONObjectBase::setArray(const String& name, PassRefPtr<JSONArray> value) 347 { 348 ASSERT(value); 349 if (m_data.set(name, value).isNewEntry) 350 m_order.append(name); 351 } 352 353 inline void JSONArrayBase::pushBoolean(bool value) 354 { 355 m_data.append(JSONBasicValue::create(value)); 356 } 357 358 inline void JSONArrayBase::pushInt(int value) 359 { 360 m_data.append(JSONBasicValue::create(value)); 361 } 362 363 inline void JSONArrayBase::pushNumber(double value) 364 { 365 m_data.append(JSONBasicValue::create(value)); 366 } 367 368 inline void JSONArrayBase::pushString(const String& value) 369 { 370 m_data.append(JSONString::create(value)); 371 } 372 373 inline void JSONArrayBase::pushValue(PassRefPtr<JSONValue> value) 374 { 375 ASSERT(value); 376 m_data.append(value); 377 } 378 379 inline void JSONArrayBase::pushObject(PassRefPtr<JSONObject> value) 380 { 381 ASSERT(value); 382 m_data.append(value); 383 } 384 385 inline void JSONArrayBase::pushArray(PassRefPtr<JSONArray> value) 386 { 387 ASSERT(value); 388 m_data.append(value); 389 } 390 391 } // namespace WebCore 392 393 #endif // !defined(JSONValues_h) 394