SkJSON.h revision 80bacfeb4bda06541e8695bd502229727bccfeab
1/*
2 * Copyright 2011 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#ifndef SkJSON_DEFINED
9#define SkJSON_DEFINED
10
11#include "SkTypes.h"
12
13class SkStream;
14class SkString;
15
16class SkJSON {
17public:
18    enum Type {
19        kObject,
20        kArray,
21        kString,
22        kInt,
23        kFloat,
24        kBool,
25    };
26
27    class Array;
28
29    class Object {
30    private:
31        struct Slot;
32
33    public:
34        Object();
35        Object(const Object&);
36        ~Object();
37
38        /**
39         *  Create a new slot with the specified name and value. The name
40         *  parameter is copied, but ownership of the Object parameter is
41         *  transferred. The Object parameter may be null, but the name must
42         *  not be null.
43         */
44        void addObject(const char name[], Object* value);
45
46        /**
47         *  Create a new slot with the specified name and value. The name
48         *  parameter is copied, but ownership of the Array parameter is
49         *  transferred. The Array parameter may be null, but the name must
50         *  not be null.
51         */
52        void addArray(const char name[], Array* value);
53
54        /**
55         *  Create a new slot with the specified name and value. Both parameters
56         *  are copied. The value parameter may be null, but the name must
57         *  not be null.
58         */
59        void addString(const char name[], const char value[]);
60
61        /**
62         *  Create a new slot with the specified name and value. The name
63         *  parameter is copied, and must not be null.
64         */
65        void addInt(const char name[], int32_t value);
66
67        /**
68         *  Create a new slot with the specified name and value. The name
69         *  parameter is copied, and must not be null.
70         */
71        void addFloat(const char name[], float value);
72
73        /**
74         *  Create a new slot with the specified name and value. The name
75         *  parameter is copied, and must not be null.
76         */
77        void addBool(const char name[], bool value);
78
79        /**
80         *  Return the number of slots/fields in this object. These can be
81         *  iterated using Iter.
82         */
83        int count() const;
84
85        /**
86         *  Returns true if a slot matching the name and Type is found.
87         */
88        bool find(const char name[], Type) const;
89        bool findObject(const char name[], Object** = NULL) const;
90        bool findArray(const char name[], Array** = NULL) const;
91        bool findString(const char name[], SkString* = NULL) const;
92        bool findInt(const char name[], int32_t* = NULL) const;
93        bool findFloat(const char name[], float* = NULL) const;
94        bool findBool(const char name[], bool* = NULL) const;
95
96        /**
97         *  Finds the first slot matching the name and Type and removes it.
98         *  Returns true if found, false if not.
99         */
100        bool remove(const char name[], Type);
101
102        void toDebugf() const;
103
104        /**
105         *  Iterator class which returns all of the fields/slots in an Object,
106         *  in the order that they were added.
107         */
108        class Iter {
109        public:
110            Iter(const Object&);
111
112            /**
113             *  Returns true when there are no more entries in the iterator.
114             *  In this case, no other methods should be called.
115             */
116            bool done() const;
117
118            /**
119             *  Moves the iterator to the next element. Should only be called
120             *  if done() returns false.
121             */
122            void next();
123
124            /**
125             *  Returns the type of the current element. Should only be called
126             *  if done() returns false.
127             */
128            Type type() const;
129
130            /**
131             *  Returns the name of the current element. Should only be called
132             *  if done() returns false.
133             */
134            const char* name() const;
135
136            /**
137             *  Returns the type of the current element. Should only be called
138             *  if done() returns false and type() returns kObject.
139             */
140            Object* objectValue() const;
141
142            /**
143             *  Returns the type of the current element. Should only be called
144             *  if done() returns false and type() returns kArray.
145             */
146            Array* arrayValue() const;
147
148            /**
149             *  Returns the type of the current element. Should only be called
150             *  if done() returns false and type() returns kString.
151             */
152            const char* stringValue() const;
153
154            /**
155             *  Returns the type of the current element. Should only be called
156             *  if done() returns false and type() returns kInt.
157             */
158            int32_t intValue() const;
159
160            /**
161             *  Returns the type of the current element. Should only be called
162             *  if done() returns false and type() returns kFloat.
163             */
164            float floatValue() const;
165
166            /**
167             *  Returns the type of the current element. Should only be called
168             *  if done() returns false and type() returns kBool.
169             */
170            bool boolValue() const;
171
172        private:
173            Slot* fSlot;
174        };
175
176    private:
177        Slot* fHead;
178        Slot* fTail;
179
180        const Slot* findSlot(const char name[], Type) const;
181        Slot* addSlot(Slot*);
182        void dumpLevel(int level) const;
183
184        friend class Array;
185    };
186
187    class Array {
188    public:
189        /**
190         *  Creates an array with the specified Type and element count. All
191         *  entries are initialized to NULL/0/false.
192         */
193        Array(Type, int count);
194
195        /**
196         *  Creates an array of ints, initialized by copying the specified
197         *  values.
198         */
199        Array(const int32_t values[], int count);
200
201        /**
202         *  Creates an array of floats, initialized by copying the specified
203         *  values.
204         */
205        Array(const float values[], int count);
206
207        /**
208         *  Creates an array of bools, initialized by copying the specified
209         *  values.
210         */
211        Array(const bool values[], int count);
212
213        Array(const Array&);
214        ~Array();
215
216        int count() const { return fCount; }
217        Type type() const { return fType; }
218
219        /**
220         *  Replace the element at the specified index with the specified
221         *  Object (which may be null). Ownership of the Object is transferred.
222         *  Should only be called if the Array's type is kObject.
223         */
224        void setObject(int index, Object*);
225
226        /**
227         *  Replace the element at the specified index with the specified
228         *  Array (which may be null). Ownership of the Array is transferred.
229         *  Should only be called if the Array's type is kArray.
230         */
231        void setArray(int index, Array*);
232
233        /**
234         *  Replace the element at the specified index with a copy of the
235         *  specified string (which may be null). Should only be called if the
236         *  Array's type is kString.
237         */
238        void setString(int index, const char str[]);
239
240        Object* const* objects() const {
241            SkASSERT(kObject == fType);
242            return fArray.fObjects;
243        }
244        Array* const* arrays() const {
245            SkASSERT(kObject == fType);
246            return fArray.fArrays;
247        }
248        const char* const* strings() const {
249            SkASSERT(kString == fType);
250            return fArray.fStrings;
251        }
252        int32_t* ints() const {
253            SkASSERT(kInt == fType);
254            return fArray.fInts;
255        }
256        float* floats() const {
257            SkASSERT(kFloat == fType);
258            return fArray.fFloats;
259        }
260        bool* bools() const {
261            SkASSERT(kBool == fType);
262            return fArray.fBools;
263        }
264
265    private:
266        int fCount;
267        Type fType;
268        union {
269            void*    fVoids;
270            Object** fObjects;
271            Array**  fArrays;
272            char**   fStrings;
273            int32_t* fInts;
274            float*   fFloats;
275            bool*    fBools;
276        } fArray;
277
278        void init(Type, int count, const void* src);
279        void dumpLevel(int level) const;
280
281        friend class Object;
282    };
283};
284
285#endif
286