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 InspectorValues_h
32#define InspectorValues_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
41namespace Inspector {
42
43class InspectorArray;
44class InspectorObject;
45
46class JS_EXPORT_PRIVATE InspectorValue : public RefCounted<InspectorValue> {
47public:
48    static const int maxDepth = 1000;
49
50    InspectorValue() : m_type(TypeNull) { }
51    virtual ~InspectorValue() { }
52
53    static PassRefPtr<InspectorValue> null();
54
55    typedef enum {
56        TypeNull = 0,
57        TypeBoolean,
58        TypeNumber,
59        TypeString,
60        TypeObject,
61        TypeArray
62    } Type;
63
64    Type type() const { return m_type; }
65
66    bool isNull() const { return m_type == TypeNull; }
67
68    virtual bool asBoolean(bool* output) const;
69    virtual bool asNumber(double* output) const;
70    virtual bool asNumber(float* output) const;
71    virtual bool asNumber(int* output) const;
72    virtual bool asNumber(unsigned* output) const;
73    virtual bool asNumber(long* output) const;
74    virtual bool asNumber(long long* output) const;
75    virtual bool asNumber(unsigned long* output) const;
76    virtual bool asNumber(unsigned long long* output) const;
77    virtual bool asString(String* output) const;
78    virtual bool asValue(RefPtr<InspectorValue>* output);
79    virtual bool asObject(RefPtr<InspectorObject>* output);
80    virtual bool asArray(RefPtr<InspectorArray>* output);
81    virtual PassRefPtr<InspectorObject> asObject();
82    virtual PassRefPtr<InspectorArray> asArray();
83
84    static PassRefPtr<InspectorValue> parseJSON(const String& json);
85
86    String toJSONString() const;
87    virtual void writeJSON(StringBuilder* output) const;
88
89protected:
90    explicit InspectorValue(Type type) : m_type(type) { }
91
92private:
93    Type m_type;
94};
95
96class JS_EXPORT_PRIVATE InspectorBasicValue : public InspectorValue {
97public:
98
99    static PassRefPtr<InspectorBasicValue> create(bool);
100    static PassRefPtr<InspectorBasicValue> create(int);
101    static PassRefPtr<InspectorBasicValue> create(double);
102
103    virtual bool asBoolean(bool* output) const override;
104    virtual bool asNumber(double* output) const override;
105    virtual bool asNumber(float* output) const override;
106    virtual bool asNumber(int* output) const override;
107    virtual bool asNumber(unsigned* output) const override;
108    virtual bool asNumber(long* output) const override;
109    virtual bool asNumber(long long* output) const override;
110    virtual bool asNumber(unsigned long* output) const override;
111    virtual bool asNumber(unsigned long long* output) const override;
112
113    virtual void writeJSON(StringBuilder* output) const override;
114
115private:
116    explicit InspectorBasicValue(bool value) : InspectorValue(TypeBoolean), m_boolValue(value) { }
117    explicit InspectorBasicValue(int value) : InspectorValue(TypeNumber), m_doubleValue((double)value) { }
118    explicit InspectorBasicValue(double value) : InspectorValue(TypeNumber), m_doubleValue(value) { }
119
120    union {
121        bool m_boolValue;
122        double m_doubleValue;
123    };
124};
125
126class JS_EXPORT_PRIVATE InspectorString : public InspectorValue {
127public:
128    static PassRefPtr<InspectorString> create(const String&);
129    static PassRefPtr<InspectorString> create(const char*);
130
131    virtual bool asString(String* output) const override;
132
133    virtual void writeJSON(StringBuilder* output) const override;
134
135private:
136    explicit InspectorString(const String& value) : InspectorValue(TypeString), m_stringValue(value) { }
137    explicit InspectorString(const char* value) : InspectorValue(TypeString), m_stringValue(value) { }
138
139    String m_stringValue;
140};
141
142class JS_EXPORT_PRIVATE InspectorObjectBase : public InspectorValue {
143private:
144    typedef HashMap<String, RefPtr<InspectorValue>> Dictionary;
145
146public:
147    typedef Dictionary::iterator iterator;
148    typedef Dictionary::const_iterator const_iterator;
149
150    virtual PassRefPtr<InspectorObject> asObject() override;
151    InspectorObject* openAccessors();
152
153protected:
154    virtual ~InspectorObjectBase();
155
156    virtual bool asObject(RefPtr<InspectorObject>* output) override;
157
158    void setBoolean(const String& name, bool);
159    void setNumber(const String& name, double);
160    void setString(const String& name, const String&);
161    void setValue(const String& name, PassRefPtr<InspectorValue>);
162    void setObject(const String& name, PassRefPtr<InspectorObject>);
163    void setArray(const String& name, PassRefPtr<InspectorArray>);
164
165    iterator find(const String& name);
166    const_iterator find(const String& name) const;
167    bool getBoolean(const String& name, bool* output) const;
168    template<class T> bool getNumber(const String& name, T* output) const
169    {
170        RefPtr<InspectorValue> value = get(name);
171        if (!value)
172            return false;
173        return value->asNumber(output);
174    }
175    bool getString(const String& name, String* output) const;
176    PassRefPtr<InspectorObject> getObject(const String& name) const;
177    PassRefPtr<InspectorArray> getArray(const String& name) const;
178    PassRefPtr<InspectorValue> get(const String& name) const;
179
180    void remove(const String& name);
181
182    virtual void writeJSON(StringBuilder* output) const override;
183
184    iterator begin() { return m_data.begin(); }
185    iterator end() { return m_data.end(); }
186    const_iterator begin() const { return m_data.begin(); }
187    const_iterator end() const { return m_data.end(); }
188
189    int size() const { return m_data.size(); }
190
191protected:
192    InspectorObjectBase();
193
194private:
195    Dictionary m_data;
196    Vector<String> m_order;
197};
198
199class InspectorObject : public InspectorObjectBase {
200public:
201    static JS_EXPORT_PRIVATE PassRefPtr<InspectorObject> create();
202
203    using InspectorObjectBase::asObject;
204
205    using InspectorObjectBase::setBoolean;
206    using InspectorObjectBase::setNumber;
207    using InspectorObjectBase::setString;
208    using InspectorObjectBase::setValue;
209    using InspectorObjectBase::setObject;
210    using InspectorObjectBase::setArray;
211
212    using InspectorObjectBase::find;
213    using InspectorObjectBase::getBoolean;
214    using InspectorObjectBase::getNumber;
215    using InspectorObjectBase::getString;
216    using InspectorObjectBase::getObject;
217    using InspectorObjectBase::getArray;
218    using InspectorObjectBase::get;
219
220    using InspectorObjectBase::remove;
221
222    using InspectorObjectBase::begin;
223    using InspectorObjectBase::end;
224
225    using InspectorObjectBase::size;
226};
227
228
229class JS_EXPORT_PRIVATE InspectorArrayBase : public InspectorValue {
230public:
231    typedef Vector<RefPtr<InspectorValue>>::iterator iterator;
232    typedef Vector<RefPtr<InspectorValue>>::const_iterator const_iterator;
233
234    virtual PassRefPtr<InspectorArray> asArray() override;
235
236    unsigned length() const { return m_data.size(); }
237
238protected:
239    virtual ~InspectorArrayBase();
240
241    virtual bool asArray(RefPtr<InspectorArray>* output) override;
242
243    void pushBoolean(bool);
244    void pushInt(int);
245    void pushNumber(double);
246    void pushString(const String&);
247    void pushValue(PassRefPtr<InspectorValue>);
248    void pushObject(PassRefPtr<InspectorObject>);
249    void pushArray(PassRefPtr<InspectorArray>);
250
251    PassRefPtr<InspectorValue> get(size_t index);
252
253    virtual void writeJSON(StringBuilder* output) const override;
254
255    iterator begin() { return m_data.begin(); }
256    iterator end() { return m_data.end(); }
257    const_iterator begin() const { return m_data.begin(); }
258    const_iterator end() const { return m_data.end(); }
259
260protected:
261    InspectorArrayBase();
262
263private:
264    Vector<RefPtr<InspectorValue>> m_data;
265};
266
267class InspectorArray : public InspectorArrayBase {
268public:
269    static JS_EXPORT_PRIVATE PassRefPtr<InspectorArray> create();
270
271    using InspectorArrayBase::asArray;
272
273    using InspectorArrayBase::pushBoolean;
274    using InspectorArrayBase::pushInt;
275    using InspectorArrayBase::pushNumber;
276    using InspectorArrayBase::pushString;
277    using InspectorArrayBase::pushValue;
278    using InspectorArrayBase::pushObject;
279    using InspectorArrayBase::pushArray;
280
281    using InspectorArrayBase::get;
282
283    using InspectorArrayBase::begin;
284    using InspectorArrayBase::end;
285};
286
287
288inline InspectorObjectBase::iterator InspectorObjectBase::find(const String& name)
289{
290    return m_data.find(name);
291}
292
293inline InspectorObjectBase::const_iterator InspectorObjectBase::find(const String& name) const
294{
295    return m_data.find(name);
296}
297
298inline void InspectorObjectBase::setBoolean(const String& name, bool value)
299{
300    setValue(name, InspectorBasicValue::create(value));
301}
302
303inline void InspectorObjectBase::setNumber(const String& name, double value)
304{
305    setValue(name, InspectorBasicValue::create(value));
306}
307
308inline void InspectorObjectBase::setString(const String& name, const String& value)
309{
310    setValue(name, InspectorString::create(value));
311}
312
313inline void InspectorObjectBase::setValue(const String& name, PassRefPtr<InspectorValue> value)
314{
315    ASSERT(value);
316    if (m_data.set(name, value).isNewEntry)
317        m_order.append(name);
318}
319
320inline void InspectorObjectBase::setObject(const String& name, PassRefPtr<InspectorObject> value)
321{
322    ASSERT(value);
323    if (m_data.set(name, value).isNewEntry)
324        m_order.append(name);
325}
326
327inline void InspectorObjectBase::setArray(const String& name, PassRefPtr<InspectorArray> value)
328{
329    ASSERT(value);
330    if (m_data.set(name, value).isNewEntry)
331        m_order.append(name);
332}
333
334inline void InspectorArrayBase::pushBoolean(bool value)
335{
336    m_data.append(InspectorBasicValue::create(value));
337}
338
339inline void InspectorArrayBase::pushInt(int value)
340{
341    m_data.append(InspectorBasicValue::create(value));
342}
343
344inline void InspectorArrayBase::pushNumber(double value)
345{
346    m_data.append(InspectorBasicValue::create(value));
347}
348
349inline void InspectorArrayBase::pushString(const String& value)
350{
351    m_data.append(InspectorString::create(value));
352}
353
354inline void InspectorArrayBase::pushValue(PassRefPtr<InspectorValue> value)
355{
356    ASSERT(value);
357    m_data.append(value);
358}
359
360inline void InspectorArrayBase::pushObject(PassRefPtr<InspectorObject> value)
361{
362    ASSERT(value);
363    m_data.append(value);
364}
365
366inline void InspectorArrayBase::pushArray(PassRefPtr<InspectorArray> value)
367{
368    ASSERT(value);
369    m_data.append(value);
370}
371
372} // namespace Inspector
373
374#endif // !defined(InspectorValues_h)
375