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 "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