blob: 215d54a604a1db6c4a3bd40e33617ca8e8b7cbea [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 };
26
27 class Array;
28
29 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);
mike@reedtribe.org0f175a62012-01-02 00:34:50 +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);
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 * Returns true if a slot matching the name and Type is found.
81 */
82 bool find(const char name[], Type) const;
mike@reedtribe.org0f175a62012-01-02 00:34:50 +000083 bool findObject(const char name[], Object** = NULL) const;
84 bool findArray(const char name[], Array** = NULL) const;
85 bool findString(const char name[], SkString* = NULL) const;
86 bool findInt(const char name[], int32_t* = NULL) const;
87 bool findFloat(const char name[], float* = NULL) const;
88 bool findBool(const char name[], bool* = NULL) const;
mike@reedtribe.orge4058b42012-01-04 03:37:40 +000089
90 /**
91 * Finds the first slot matching the name and Type and removes it.
92 * Returns true if found, false if not.
93 */
94 bool remove(const char name[], Type);
95
96 void toDebugf() const;
97
98 /**
99 * Iterator class which returns all of the fields/slots in an Object,
100 * in the order that they were added.
101 */
102 class Iter {
103 public:
104 Iter(const Object&);
105
106 /**
107 * Returns true when there are no more entries in the iterator.
108 * In this case, no other methods should be called.
109 */
110 bool done() const;
111
112 /**
113 * Moves the iterator to the next element. Should only be called
114 * if done() returns false.
115 */
116 void next();
117
118 /**
119 * Returns the type of the current element. Should only be called
120 * if done() returns false.
121 */
122 Type type() const;
123
124 /**
125 * Returns the name of the current element. Should only be called
126 * if done() returns false.
127 */
128 const char* name() const;
129
130 /**
131 * Returns the type of the current element. Should only be called
132 * if done() returns false and type() returns kObject.
133 */
134 Object* objectValue() const;
135
136 /**
137 * Returns the type of the current element. Should only be called
138 * if done() returns false and type() returns kArray.
139 */
140 Array* arrayValue() const;
141
142 /**
143 * Returns the type of the current element. Should only be called
144 * if done() returns false and type() returns kString.
145 */
146 const char* stringValue() const;
147
148 /**
149 * Returns the type of the current element. Should only be called
150 * if done() returns false and type() returns kInt.
151 */
152 int32_t intValue() const;
153
154 /**
155 * Returns the type of the current element. Should only be called
156 * if done() returns false and type() returns kFloat.
157 */
158 float floatValue() const;
159
160 /**
161 * Returns the type of the current element. Should only be called
162 * if done() returns false and type() returns kBool.
163 */
164 bool boolValue() const;
165
166 private:
167 Slot* fSlot;
168 };
169
mike@reedtribe.org0f175a62012-01-02 00:34:50 +0000170 private:
mike@reedtribe.org0f175a62012-01-02 00:34:50 +0000171 Slot* fHead;
172 Slot* fTail;
173
mike@reedtribe.orge4058b42012-01-04 03:37:40 +0000174 const Slot* findSlot(const char name[], Type) const;
mike@reedtribe.org0f175a62012-01-02 00:34:50 +0000175 Slot* addSlot(Slot*);
176 void dumpLevel(int level) const;
177
178 friend class Array;
179 };
180
181 class Array {
182 public:
mike@reedtribe.orge4058b42012-01-04 03:37:40 +0000183 /**
184 * Creates an array with the specified Type and element count. All
185 * entries are initialized to NULL/0/false.
186 */
mike@reedtribe.org0f175a62012-01-02 00:34:50 +0000187 Array(Type, int count);
mike@reedtribe.orge4058b42012-01-04 03:37:40 +0000188
189 /**
190 * Creates an array of ints, initialized by copying the specified
191 * values.
192 */
mike@reedtribe.org0f175a62012-01-02 00:34:50 +0000193 Array(const int32_t values[], int count);
mike@reedtribe.orge4058b42012-01-04 03:37:40 +0000194
195 /**
196 * Creates an array of floats, initialized by copying the specified
197 * values.
198 */
mike@reedtribe.org0f175a62012-01-02 00:34:50 +0000199 Array(const float values[], int count);
mike@reedtribe.orge4058b42012-01-04 03:37:40 +0000200
201 /**
202 * Creates an array of bools, initialized by copying the specified
203 * values.
204 */
mike@reedtribe.org0f175a62012-01-02 00:34:50 +0000205 Array(const bool values[], int count);
mike@reedtribe.orge4058b42012-01-04 03:37:40 +0000206
mike@reedtribe.org0f175a62012-01-02 00:34:50 +0000207 Array(const Array&);
208 ~Array();
209
210 int count() const { return fCount; }
211 Type type() const { return fType; }
mike@reedtribe.orge4058b42012-01-04 03:37:40 +0000212
213 /**
214 * Replace the element at the specified index with the specified
215 * Object (which may be null). Ownership of the Object is transferred.
216 * Should only be called if the Array's type is kObject.
217 */
218 void setObject(int index, Object*);
mike@reedtribe.org0f175a62012-01-02 00:34:50 +0000219
mike@reedtribe.orge4058b42012-01-04 03:37:40 +0000220 /**
221 * Replace the element at the specified index with the specified
222 * Array (which may be null). Ownership of the Array is transferred.
223 * Should only be called if the Array's type is kArray.
224 */
225 void setArray(int index, Array*);
226
227 /**
228 * Replace the element at the specified index with a copy of the
229 * specified string (which may be null). Should only be called if the
230 * Array's type is kString.
231 */
232 void setString(int index, const char str[]);
233
234 Object* const* objects() const {
235 SkASSERT(kObject == fType);
236 return fArray.fObjects;
237 }
238 Array* const* arrays() const {
239 SkASSERT(kObject == fType);
240 return fArray.fArrays;
241 }
242 const char* const* strings() const {
243 SkASSERT(kString == fType);
244 return fArray.fStrings;
245 }
246 int32_t* ints() const {
247 SkASSERT(kInt == fType);
248 return fArray.fInts;
249 }
250 float* floats() const {
251 SkASSERT(kFloat == fType);
252 return fArray.fFloats;
253 }
254 bool* bools() const {
255 SkASSERT(kBool == fType);
256 return fArray.fBools;
257 }
258
mike@reedtribe.org0f175a62012-01-02 00:34:50 +0000259 private:
260 int fCount;
261 Type fType;
262 union {
263 void* fVoids;
mike@reedtribe.orge4058b42012-01-04 03:37:40 +0000264 Object** fObjects;
265 Array** fArrays;
266 char** fStrings;
mike@reedtribe.org0f175a62012-01-02 00:34:50 +0000267 int32_t* fInts;
268 float* fFloats;
269 bool* fBools;
270 } fArray;
271
272 void init(Type, int count, const void* src);
273 void dumpLevel(int level) const;
274
275 friend class Object;
276 };
277};
278
279#endif