blob: c601fa89b57879000d2b0da219ed5bc02e848387 [file] [log] [blame]
mike@reedtribe.org0f175a62012-01-02 00:34:50 +00001/*
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
mike@reedtribe.orge4058b42012-01-04 03:37:40 +000013class SkStream;
mike@reedtribe.org0f175a62012-01-02 00:34:50 +000014class SkString;
15
16class SkJSON {
17public:
18 enum Type {
19 kObject,
20 kArray,
21 kString,
22 kInt,
23 kFloat,
24 kBool,
25 };
rmistry@google.comfbfcd562012-08-23 18:09:54 +000026
mike@reedtribe.org0f175a62012-01-02 00:34:50 +000027 class Array;
rmistry@google.comfbfcd562012-08-23 18:09:54 +000028
mike@reedtribe.org0f175a62012-01-02 00:34:50 +000029 class Object {
mike@reedtribe.orge4058b42012-01-04 03:37:40 +000030 private:
31 struct Slot;
32
mike@reedtribe.org0f175a62012-01-02 00:34:50 +000033 public:
mike@reedtribe.orge4058b42012-01-04 03:37:40 +000034 Object();
mike@reedtribe.org0f175a62012-01-02 00:34:50 +000035 Object(const Object&);
36 ~Object();
mike@reedtribe.orge4058b42012-01-04 03:37:40 +000037
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 */
mike@reedtribe.org0f175a62012-01-02 00:34:50 +000044 void addObject(const char name[], Object* value);
rmistry@google.comfbfcd562012-08-23 18:09:54 +000045
mike@reedtribe.orge4058b42012-01-04 03:37:40 +000046 /**
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);
rmistry@google.comfbfcd562012-08-23 18:09:54 +000053
mike@reedtribe.orge4058b42012-01-04 03:37:40 +000054 /**
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[]);
rmistry@google.comfbfcd562012-08-23 18:09:54 +000060
mike@reedtribe.orge4058b42012-01-04 03:37:40 +000061 /**
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);
rmistry@google.comfbfcd562012-08-23 18:09:54 +000066
mike@reedtribe.orge4058b42012-01-04 03:37:40 +000067 /**
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);
rmistry@google.comfbfcd562012-08-23 18:09:54 +000072
mike@reedtribe.orge4058b42012-01-04 03:37:40 +000073 /**
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 /**
mike@reedtribe.org0e3c9ca2012-01-04 11:37:46 +000080 * Return the number of slots/fields in this object. These can be
81 * iterated using Iter.
82 */
83 int count() const;
84
85 /**
mike@reedtribe.orge4058b42012-01-04 03:37:40 +000086 * Returns true if a slot matching the name and Type is found.
87 */
88 bool find(const char name[], Type) const;
mike@reedtribe.org0f175a62012-01-02 00:34:50 +000089 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;
mike@reedtribe.orge4058b42012-01-04 03:37:40 +000095
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&);
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000111
mike@reedtribe.orge4058b42012-01-04 03:37:40 +0000112 /**
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;
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000129
mike@reedtribe.orge4058b42012-01-04 03:37:40 +0000130 /**
131 * Returns the name of the current element. Should only be called
132 * if done() returns false.
133 */
134 const char* name() const;
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000135
mike@reedtribe.orge4058b42012-01-04 03:37:40 +0000136 /**
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;
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000141
mike@reedtribe.orge4058b42012-01-04 03:37:40 +0000142 /**
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;
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000147
mike@reedtribe.orge4058b42012-01-04 03:37:40 +0000148 /**
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;
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000153
mike@reedtribe.orge4058b42012-01-04 03:37:40 +0000154 /**
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;
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000159
mike@reedtribe.orge4058b42012-01-04 03:37:40 +0000160 /**
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;
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000165
mike@reedtribe.orge4058b42012-01-04 03:37:40 +0000166 /**
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
mike@reedtribe.org0f175a62012-01-02 00:34:50 +0000176 private:
mike@reedtribe.org0f175a62012-01-02 00:34:50 +0000177 Slot* fHead;
178 Slot* fTail;
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000179
mike@reedtribe.orge4058b42012-01-04 03:37:40 +0000180 const Slot* findSlot(const char name[], Type) const;
mike@reedtribe.org0f175a62012-01-02 00:34:50 +0000181 Slot* addSlot(Slot*);
182 void dumpLevel(int level) const;
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000183
mike@reedtribe.org0f175a62012-01-02 00:34:50 +0000184 friend class Array;
185 };
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000186
mike@reedtribe.org0f175a62012-01-02 00:34:50 +0000187 class Array {
188 public:
mike@reedtribe.orge4058b42012-01-04 03:37:40 +0000189 /**
190 * Creates an array with the specified Type and element count. All
191 * entries are initialized to NULL/0/false.
192 */
mike@reedtribe.org0f175a62012-01-02 00:34:50 +0000193 Array(Type, int count);
mike@reedtribe.orge4058b42012-01-04 03:37:40 +0000194
195 /**
196 * Creates an array of ints, initialized by copying the specified
197 * values.
198 */
mike@reedtribe.org0f175a62012-01-02 00:34:50 +0000199 Array(const int32_t values[], int count);
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000200
mike@reedtribe.orge4058b42012-01-04 03:37:40 +0000201 /**
202 * Creates an array of floats, initialized by copying the specified
203 * values.
204 */
mike@reedtribe.org0f175a62012-01-02 00:34:50 +0000205 Array(const float values[], int count);
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000206
mike@reedtribe.orge4058b42012-01-04 03:37:40 +0000207 /**
208 * Creates an array of bools, initialized by copying the specified
209 * values.
210 */
mike@reedtribe.org0f175a62012-01-02 00:34:50 +0000211 Array(const bool values[], int count);
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000212
mike@reedtribe.org0f175a62012-01-02 00:34:50 +0000213 Array(const Array&);
214 ~Array();
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000215
mike@reedtribe.org0f175a62012-01-02 00:34:50 +0000216 int count() const { return fCount; }
217 Type type() const { return fType; }
mike@reedtribe.orge4058b42012-01-04 03:37:40 +0000218
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*);
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000225
mike@reedtribe.orge4058b42012-01-04 03:37:40 +0000226 /**
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
mike@reedtribe.org0f175a62012-01-02 00:34:50 +0000265 private:
266 int fCount;
267 Type fType;
268 union {
269 void* fVoids;
mike@reedtribe.orge4058b42012-01-04 03:37:40 +0000270 Object** fObjects;
271 Array** fArrays;
272 char** fStrings;
mike@reedtribe.org0f175a62012-01-02 00:34:50 +0000273 int32_t* fInts;
274 float* fFloats;
275 bool* fBools;
276 } fArray;
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000277
mike@reedtribe.org0f175a62012-01-02 00:34:50 +0000278 void init(Type, int count, const void* src);
279 void dumpLevel(int level) const;
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000280
mike@reedtribe.org0f175a62012-01-02 00:34:50 +0000281 friend class Object;
282 };
283};
284
285#endif