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 blink {
     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     String toPrettyJSONString() const;
     87     virtual void writeJSON(StringBuilder* output) const;
     88     virtual void prettyWriteJSON(StringBuilder* output) const;
     89 
     90 protected:
     91     explicit JSONValue(Type type) : m_type(type) { }
     92     virtual void prettyWriteJSONInternal(StringBuilder* output, int depth) const;
     93 
     94 private:
     95     friend class JSONObjectBase;
     96     friend class JSONArrayBase;
     97 
     98     Type m_type;
     99 };
    100 
    101 class PLATFORM_EXPORT JSONBasicValue : public JSONValue {
    102 public:
    103 
    104     static PassRefPtr<JSONBasicValue> create(bool value)
    105     {
    106         return adoptRef(new JSONBasicValue(value));
    107     }
    108 
    109     static PassRefPtr<JSONBasicValue> create(int value)
    110     {
    111         return adoptRef(new JSONBasicValue(value));
    112     }
    113 
    114     static PassRefPtr<JSONBasicValue> create(double value)
    115     {
    116         return adoptRef(new JSONBasicValue(value));
    117     }
    118 
    119     virtual bool asBoolean(bool* output) const OVERRIDE;
    120     virtual bool asNumber(double* output) const OVERRIDE;
    121     virtual bool asNumber(long* output) const OVERRIDE;
    122     virtual bool asNumber(int* output) const OVERRIDE;
    123     virtual bool asNumber(unsigned long* output) const OVERRIDE;
    124     virtual bool asNumber(unsigned* output) const OVERRIDE;
    125 
    126     virtual void writeJSON(StringBuilder* output) const OVERRIDE;
    127 
    128 private:
    129     explicit JSONBasicValue(bool value) : JSONValue(TypeBoolean), m_boolValue(value) { }
    130     explicit JSONBasicValue(int value) : JSONValue(TypeNumber), m_doubleValue((double)value) { }
    131     explicit JSONBasicValue(double value) : JSONValue(TypeNumber), m_doubleValue(value) { }
    132 
    133     union {
    134         bool m_boolValue;
    135         double m_doubleValue;
    136     };
    137 };
    138 
    139 class PLATFORM_EXPORT JSONString : public JSONValue {
    140 public:
    141     static PassRefPtr<JSONString> create(const String& value)
    142     {
    143         return adoptRef(new JSONString(value));
    144     }
    145 
    146     static PassRefPtr<JSONString> create(const char* value)
    147     {
    148         return adoptRef(new JSONString(value));
    149     }
    150 
    151     virtual bool asString(String* output) const OVERRIDE;
    152 
    153     virtual void writeJSON(StringBuilder* output) const OVERRIDE;
    154 
    155 private:
    156     explicit JSONString(const String& value) : JSONValue(TypeString), m_stringValue(value) { }
    157     explicit JSONString(const char* value) : JSONValue(TypeString), m_stringValue(value) { }
    158 
    159     String m_stringValue;
    160 };
    161 
    162 class PLATFORM_EXPORT JSONObjectBase : public JSONValue {
    163 private:
    164     typedef HashMap<String, RefPtr<JSONValue> > Dictionary;
    165 
    166 public:
    167     typedef Dictionary::iterator iterator;
    168     typedef Dictionary::const_iterator const_iterator;
    169 
    170     virtual PassRefPtr<JSONObject> asObject() OVERRIDE;
    171     JSONObject* openAccessors();
    172 
    173     virtual void writeJSON(StringBuilder* output) const OVERRIDE;
    174 
    175 protected:
    176     virtual ~JSONObjectBase();
    177 
    178     virtual bool asObject(RefPtr<JSONObject>* output) OVERRIDE;
    179 
    180     void setBoolean(const String& name, bool);
    181     void setNumber(const String& name, double);
    182     void setString(const String& name, const String&);
    183     void setValue(const String& name, PassRefPtr<JSONValue>);
    184     void setObject(const String& name, PassRefPtr<JSONObject>);
    185     void setArray(const String& name, PassRefPtr<JSONArray>);
    186 
    187     iterator find(const String& name);
    188     const_iterator find(const String& name) const;
    189     bool getBoolean(const String& name, bool* output) const;
    190     template<class T> bool getNumber(const String& name, T* output) const
    191     {
    192         RefPtr<JSONValue> value = get(name);
    193         if (!value)
    194             return false;
    195         return value->asNumber(output);
    196     }
    197     bool getString(const String& name, String* output) const;
    198     PassRefPtr<JSONObject> getObject(const String& name) const;
    199     PassRefPtr<JSONArray> getArray(const String& name) const;
    200     PassRefPtr<JSONValue> get(const String& name) const;
    201 
    202     void remove(const String& name);
    203 
    204     virtual void prettyWriteJSONInternal(StringBuilder* output, int depth) const OVERRIDE;
    205 
    206     iterator begin() { return m_data.begin(); }
    207     iterator end() { return m_data.end(); }
    208     const_iterator begin() const { return m_data.begin(); }
    209     const_iterator end() const { return m_data.end(); }
    210 
    211     int size() const { return m_data.size(); }
    212 
    213 protected:
    214     JSONObjectBase();
    215 
    216 private:
    217     Dictionary m_data;
    218     Vector<String> m_order;
    219 };
    220 
    221 class PLATFORM_EXPORT JSONObject : public JSONObjectBase {
    222 public:
    223     static PassRefPtr<JSONObject> create()
    224     {
    225         return adoptRef(new JSONObject());
    226     }
    227 
    228     using JSONObjectBase::asObject;
    229 
    230     using JSONObjectBase::setBoolean;
    231     using JSONObjectBase::setNumber;
    232     using JSONObjectBase::setString;
    233     using JSONObjectBase::setValue;
    234     using JSONObjectBase::setObject;
    235     using JSONObjectBase::setArray;
    236 
    237     using JSONObjectBase::find;
    238     using JSONObjectBase::getBoolean;
    239     using JSONObjectBase::getNumber;
    240     using JSONObjectBase::getString;
    241     using JSONObjectBase::getObject;
    242     using JSONObjectBase::getArray;
    243     using JSONObjectBase::get;
    244 
    245     using JSONObjectBase::remove;
    246 
    247     using JSONObjectBase::begin;
    248     using JSONObjectBase::end;
    249 
    250     using JSONObjectBase::size;
    251 };
    252 
    253 
    254 class PLATFORM_EXPORT JSONArrayBase : public JSONValue {
    255 public:
    256     typedef Vector<RefPtr<JSONValue> >::iterator iterator;
    257     typedef Vector<RefPtr<JSONValue> >::const_iterator const_iterator;
    258 
    259     virtual PassRefPtr<JSONArray> asArray() OVERRIDE;
    260 
    261     unsigned length() const { return m_data.size(); }
    262 
    263     virtual void writeJSON(StringBuilder* output) const OVERRIDE;
    264 
    265 protected:
    266     virtual ~JSONArrayBase();
    267 
    268     virtual bool asArray(RefPtr<JSONArray>* output) OVERRIDE;
    269 
    270     void pushBoolean(bool);
    271     void pushInt(int);
    272     void pushNumber(double);
    273     void pushString(const String&);
    274     void pushValue(PassRefPtr<JSONValue>);
    275     void pushObject(PassRefPtr<JSONObject>);
    276     void pushArray(PassRefPtr<JSONArray>);
    277 
    278     PassRefPtr<JSONValue> get(size_t index);
    279 
    280     virtual void prettyWriteJSONInternal(StringBuilder* output, int depth) const OVERRIDE;
    281 
    282     iterator begin() { return m_data.begin(); }
    283     iterator end() { return m_data.end(); }
    284     const_iterator begin() const { return m_data.begin(); }
    285     const_iterator end() const { return m_data.end(); }
    286 
    287 protected:
    288     JSONArrayBase();
    289 
    290 private:
    291     Vector<RefPtr<JSONValue> > m_data;
    292 };
    293 
    294 class PLATFORM_EXPORT JSONArray : public JSONArrayBase {
    295 public:
    296     static PassRefPtr<JSONArray> create()
    297     {
    298         return adoptRef(new JSONArray());
    299     }
    300 
    301     using JSONArrayBase::asArray;
    302 
    303     using JSONArrayBase::pushBoolean;
    304     using JSONArrayBase::pushInt;
    305     using JSONArrayBase::pushNumber;
    306     using JSONArrayBase::pushString;
    307     using JSONArrayBase::pushValue;
    308     using JSONArrayBase::pushObject;
    309     using JSONArrayBase::pushArray;
    310 
    311     using JSONArrayBase::get;
    312 
    313     using JSONArrayBase::begin;
    314     using JSONArrayBase::end;
    315 };
    316 
    317 } // namespace blink
    318 
    319 #endif // !defined(JSONValues_h)
    320