Home | History | Annotate | Download | only in platform
      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