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 42namespace WebCore { 43 44class JSONArray; 45class JSONObject; 46 47class PLATFORM_EXPORT JSONValue : public RefCounted<JSONValue> { 48public: 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 88protected: 89 explicit JSONValue(Type type) : m_type(type) { } 90 91private: 92 Type m_type; 93}; 94 95class PLATFORM_EXPORT JSONBasicValue : public JSONValue { 96public: 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 122private: 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 133class PLATFORM_EXPORT JSONString : public JSONValue { 134public: 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 149private: 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 156class PLATFORM_EXPORT JSONObjectBase : public JSONValue { 157private: 158 typedef HashMap<String, RefPtr<JSONValue> > Dictionary; 159 160public: 161 typedef Dictionary::iterator iterator; 162 typedef Dictionary::const_iterator const_iterator; 163 164 virtual PassRefPtr<JSONObject> asObject(); 165 JSONObject* openAccessors(); 166 167protected: 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 205protected: 206 JSONObjectBase(); 207 208private: 209 Dictionary m_data; 210 Vector<String> m_order; 211}; 212 213class PLATFORM_EXPORT JSONObject : public JSONObjectBase { 214public: 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 246class PLATFORM_EXPORT JSONArrayBase : public JSONValue { 247public: 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 255protected: 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 277protected: 278 JSONArrayBase(); 279 280private: 281 Vector<RefPtr<JSONValue> > m_data; 282}; 283 284class PLATFORM_EXPORT JSONArray : public JSONArrayBase { 285public: 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 308inline JSONObjectBase::iterator JSONObjectBase::find(const String& name) 309{ 310 return m_data.find(name); 311} 312 313inline JSONObjectBase::const_iterator JSONObjectBase::find(const String& name) const 314{ 315 return m_data.find(name); 316} 317 318inline void JSONObjectBase::setBoolean(const String& name, bool value) 319{ 320 setValue(name, JSONBasicValue::create(value)); 321} 322 323inline void JSONObjectBase::setNumber(const String& name, double value) 324{ 325 setValue(name, JSONBasicValue::create(value)); 326} 327 328inline void JSONObjectBase::setString(const String& name, const String& value) 329{ 330 setValue(name, JSONString::create(value)); 331} 332 333inline 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 340inline 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 347inline 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 354inline void JSONArrayBase::pushBoolean(bool value) 355{ 356 m_data.append(JSONBasicValue::create(value)); 357} 358 359inline void JSONArrayBase::pushInt(int value) 360{ 361 m_data.append(JSONBasicValue::create(value)); 362} 363 364inline void JSONArrayBase::pushNumber(double value) 365{ 366 m_data.append(JSONBasicValue::create(value)); 367} 368 369inline void JSONArrayBase::pushString(const String& value) 370{ 371 m_data.append(JSONString::create(value)); 372} 373 374inline void JSONArrayBase::pushValue(PassRefPtr<JSONValue> value) 375{ 376 ASSERT(value); 377 m_data.append(value); 378} 379 380inline void JSONArrayBase::pushObject(PassRefPtr<JSONObject> value) 381{ 382 ASSERT(value); 383 m_data.append(value); 384} 385 386inline 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