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 51 JSONValue() : m_type(TypeNull) { } 52 virtual ~JSONValue() { } 53 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 68 Type type() const { return m_type; } 69 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: 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 98 static PassRefPtr<JSONBasicValue> create(bool value) 99 { 100 return adoptRef(new JSONBasicValue(value)); 101 } 102 103 static PassRefPtr<JSONBasicValue> create(int value) 104 { 105 return adoptRef(new JSONBasicValue(value)); 106 } 107 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: 123 explicit JSONBasicValue(bool value) : JSONValue(TypeBoolean), m_boolValue(value) { } 124 explicit JSONBasicValue(int value) : JSONValue(TypeNumber), m_doubleValue((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: 135 static PassRefPtr<JSONString> create(const String& value) 136 { 137 return adoptRef(new JSONString(value)); 138 } 139 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: 150 explicit JSONString(const String& value) : JSONValue(TypeString), m_stringValue(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; 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 198 iterator begin() { return m_data.begin(); } 199 iterator end() { return m_data.end(); } 200 const_iterator begin() const { return m_data.begin(); } 201 const_iterator end() const { return m_data.end(); } 202 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: 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 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 272 iterator begin() { return m_data.begin(); } 273 iterator end() { return m_data.end(); } 274 const_iterator begin() const { return m_data.begin(); } 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: 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 308 inline JSONObjectBase::iterator JSONObjectBase::find(const String& name) 309 { 310 return m_data.find(name); 311 } 312 313 inline JSONObjectBase::const_iterator JSONObjectBase::find(const String& name) const 314 { 315 return m_data.find(name); 316 } 317 318 inline void JSONObjectBase::setBoolean(const String& name, bool value) 319 { 320 setValue(name, JSONBasicValue::create(value)); 321 } 322 323 inline void JSONObjectBase::setNumber(const String& name, double value) 324 { 325 setValue(name, JSONBasicValue::create(value)); 326 } 327 328 inline void JSONObjectBase::setString(const String& name, const String& value) 329 { 330 setValue(name, JSONString::create(value)); 331 } 332 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 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 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 354 inline void JSONArrayBase::pushBoolean(bool value) 355 { 356 m_data.append(JSONBasicValue::create(value)); 357 } 358 359 inline void JSONArrayBase::pushInt(int value) 360 { 361 m_data.append(JSONBasicValue::create(value)); 362 } 363 364 inline void JSONArrayBase::pushNumber(double value) 365 { 366 m_data.append(JSONBasicValue::create(value)); 367 } 368 369 inline void JSONArrayBase::pushString(const String& value) 370 { 371 m_data.append(JSONString::create(value)); 372 } 373 374 inline void JSONArrayBase::pushValue(PassRefPtr<JSONValue> value) 375 { 376 ASSERT(value); 377 m_data.append(value); 378 } 379 380 inline void JSONArrayBase::pushObject(PassRefPtr<JSONObject> value) 381 { 382 ASSERT(value); 383 m_data.append(value); 384 } 385 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