mike@reedtribe.org | 0f175a6 | 2012-01-02 00:34:50 +0000 | [diff] [blame] | 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 | |
mike@reedtribe.org | e4058b4 | 2012-01-04 03:37:40 +0000 | [diff] [blame] | 13 | class SkStream; |
mike@reedtribe.org | 0f175a6 | 2012-01-02 00:34:50 +0000 | [diff] [blame] | 14 | class SkString; |
| 15 | |
| 16 | class SkJSON { |
| 17 | public: |
| 18 | enum Type { |
| 19 | kObject, |
| 20 | kArray, |
| 21 | kString, |
| 22 | kInt, |
| 23 | kFloat, |
| 24 | kBool, |
| 25 | }; |
rmistry@google.com | fbfcd56 | 2012-08-23 18:09:54 +0000 | [diff] [blame] | 26 | |
mike@reedtribe.org | 0f175a6 | 2012-01-02 00:34:50 +0000 | [diff] [blame] | 27 | class Array; |
rmistry@google.com | fbfcd56 | 2012-08-23 18:09:54 +0000 | [diff] [blame] | 28 | |
mike@reedtribe.org | 0f175a6 | 2012-01-02 00:34:50 +0000 | [diff] [blame] | 29 | class Object { |
mike@reedtribe.org | e4058b4 | 2012-01-04 03:37:40 +0000 | [diff] [blame] | 30 | private: |
| 31 | struct Slot; |
| 32 | |
mike@reedtribe.org | 0f175a6 | 2012-01-02 00:34:50 +0000 | [diff] [blame] | 33 | public: |
mike@reedtribe.org | e4058b4 | 2012-01-04 03:37:40 +0000 | [diff] [blame] | 34 | Object(); |
mike@reedtribe.org | 0f175a6 | 2012-01-02 00:34:50 +0000 | [diff] [blame] | 35 | Object(const Object&); |
| 36 | ~Object(); |
mike@reedtribe.org | e4058b4 | 2012-01-04 03:37:40 +0000 | [diff] [blame] | 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 | */ |
mike@reedtribe.org | 0f175a6 | 2012-01-02 00:34:50 +0000 | [diff] [blame] | 44 | void addObject(const char name[], Object* value); |
rmistry@google.com | fbfcd56 | 2012-08-23 18:09:54 +0000 | [diff] [blame] | 45 | |
mike@reedtribe.org | e4058b4 | 2012-01-04 03:37:40 +0000 | [diff] [blame] | 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); |
rmistry@google.com | fbfcd56 | 2012-08-23 18:09:54 +0000 | [diff] [blame] | 53 | |
mike@reedtribe.org | e4058b4 | 2012-01-04 03:37:40 +0000 | [diff] [blame] | 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[]); |
rmistry@google.com | fbfcd56 | 2012-08-23 18:09:54 +0000 | [diff] [blame] | 60 | |
mike@reedtribe.org | e4058b4 | 2012-01-04 03:37:40 +0000 | [diff] [blame] | 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); |
rmistry@google.com | fbfcd56 | 2012-08-23 18:09:54 +0000 | [diff] [blame] | 66 | |
mike@reedtribe.org | e4058b4 | 2012-01-04 03:37:40 +0000 | [diff] [blame] | 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); |
rmistry@google.com | fbfcd56 | 2012-08-23 18:09:54 +0000 | [diff] [blame] | 72 | |
mike@reedtribe.org | e4058b4 | 2012-01-04 03:37:40 +0000 | [diff] [blame] | 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 | /** |
mike@reedtribe.org | 0e3c9ca | 2012-01-04 11:37:46 +0000 | [diff] [blame] | 80 | * 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.org | e4058b4 | 2012-01-04 03:37:40 +0000 | [diff] [blame] | 86 | * Returns true if a slot matching the name and Type is found. |
| 87 | */ |
| 88 | bool find(const char name[], Type) const; |
mike@reedtribe.org | 0f175a6 | 2012-01-02 00:34:50 +0000 | [diff] [blame] | 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; |
mike@reedtribe.org | e4058b4 | 2012-01-04 03:37:40 +0000 | [diff] [blame] | 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&); |
rmistry@google.com | fbfcd56 | 2012-08-23 18:09:54 +0000 | [diff] [blame] | 111 | |
mike@reedtribe.org | e4058b4 | 2012-01-04 03:37:40 +0000 | [diff] [blame] | 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; |
rmistry@google.com | fbfcd56 | 2012-08-23 18:09:54 +0000 | [diff] [blame] | 129 | |
mike@reedtribe.org | e4058b4 | 2012-01-04 03:37:40 +0000 | [diff] [blame] | 130 | /** |
| 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.com | fbfcd56 | 2012-08-23 18:09:54 +0000 | [diff] [blame] | 135 | |
mike@reedtribe.org | e4058b4 | 2012-01-04 03:37:40 +0000 | [diff] [blame] | 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; |
rmistry@google.com | fbfcd56 | 2012-08-23 18:09:54 +0000 | [diff] [blame] | 141 | |
mike@reedtribe.org | e4058b4 | 2012-01-04 03:37:40 +0000 | [diff] [blame] | 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; |
rmistry@google.com | fbfcd56 | 2012-08-23 18:09:54 +0000 | [diff] [blame] | 147 | |
mike@reedtribe.org | e4058b4 | 2012-01-04 03:37:40 +0000 | [diff] [blame] | 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; |
rmistry@google.com | fbfcd56 | 2012-08-23 18:09:54 +0000 | [diff] [blame] | 153 | |
mike@reedtribe.org | e4058b4 | 2012-01-04 03:37:40 +0000 | [diff] [blame] | 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; |
rmistry@google.com | fbfcd56 | 2012-08-23 18:09:54 +0000 | [diff] [blame] | 159 | |
mike@reedtribe.org | e4058b4 | 2012-01-04 03:37:40 +0000 | [diff] [blame] | 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; |
rmistry@google.com | fbfcd56 | 2012-08-23 18:09:54 +0000 | [diff] [blame] | 165 | |
mike@reedtribe.org | e4058b4 | 2012-01-04 03:37:40 +0000 | [diff] [blame] | 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 | |
mike@reedtribe.org | 0f175a6 | 2012-01-02 00:34:50 +0000 | [diff] [blame] | 176 | private: |
mike@reedtribe.org | 0f175a6 | 2012-01-02 00:34:50 +0000 | [diff] [blame] | 177 | Slot* fHead; |
| 178 | Slot* fTail; |
rmistry@google.com | fbfcd56 | 2012-08-23 18:09:54 +0000 | [diff] [blame] | 179 | |
mike@reedtribe.org | e4058b4 | 2012-01-04 03:37:40 +0000 | [diff] [blame] | 180 | const Slot* findSlot(const char name[], Type) const; |
mike@reedtribe.org | 0f175a6 | 2012-01-02 00:34:50 +0000 | [diff] [blame] | 181 | Slot* addSlot(Slot*); |
| 182 | void dumpLevel(int level) const; |
rmistry@google.com | fbfcd56 | 2012-08-23 18:09:54 +0000 | [diff] [blame] | 183 | |
mike@reedtribe.org | 0f175a6 | 2012-01-02 00:34:50 +0000 | [diff] [blame] | 184 | friend class Array; |
| 185 | }; |
rmistry@google.com | fbfcd56 | 2012-08-23 18:09:54 +0000 | [diff] [blame] | 186 | |
mike@reedtribe.org | 0f175a6 | 2012-01-02 00:34:50 +0000 | [diff] [blame] | 187 | class Array { |
| 188 | public: |
mike@reedtribe.org | e4058b4 | 2012-01-04 03:37:40 +0000 | [diff] [blame] | 189 | /** |
| 190 | * Creates an array with the specified Type and element count. All |
| 191 | * entries are initialized to NULL/0/false. |
| 192 | */ |
mike@reedtribe.org | 0f175a6 | 2012-01-02 00:34:50 +0000 | [diff] [blame] | 193 | Array(Type, int count); |
mike@reedtribe.org | e4058b4 | 2012-01-04 03:37:40 +0000 | [diff] [blame] | 194 | |
| 195 | /** |
| 196 | * Creates an array of ints, initialized by copying the specified |
| 197 | * values. |
| 198 | */ |
mike@reedtribe.org | 0f175a6 | 2012-01-02 00:34:50 +0000 | [diff] [blame] | 199 | Array(const int32_t values[], int count); |
rmistry@google.com | fbfcd56 | 2012-08-23 18:09:54 +0000 | [diff] [blame] | 200 | |
mike@reedtribe.org | e4058b4 | 2012-01-04 03:37:40 +0000 | [diff] [blame] | 201 | /** |
| 202 | * Creates an array of floats, initialized by copying the specified |
| 203 | * values. |
| 204 | */ |
mike@reedtribe.org | 0f175a6 | 2012-01-02 00:34:50 +0000 | [diff] [blame] | 205 | Array(const float values[], int count); |
rmistry@google.com | fbfcd56 | 2012-08-23 18:09:54 +0000 | [diff] [blame] | 206 | |
mike@reedtribe.org | e4058b4 | 2012-01-04 03:37:40 +0000 | [diff] [blame] | 207 | /** |
| 208 | * Creates an array of bools, initialized by copying the specified |
| 209 | * values. |
| 210 | */ |
mike@reedtribe.org | 0f175a6 | 2012-01-02 00:34:50 +0000 | [diff] [blame] | 211 | Array(const bool values[], int count); |
rmistry@google.com | fbfcd56 | 2012-08-23 18:09:54 +0000 | [diff] [blame] | 212 | |
mike@reedtribe.org | 0f175a6 | 2012-01-02 00:34:50 +0000 | [diff] [blame] | 213 | Array(const Array&); |
| 214 | ~Array(); |
rmistry@google.com | fbfcd56 | 2012-08-23 18:09:54 +0000 | [diff] [blame] | 215 | |
mike@reedtribe.org | 0f175a6 | 2012-01-02 00:34:50 +0000 | [diff] [blame] | 216 | int count() const { return fCount; } |
| 217 | Type type() const { return fType; } |
mike@reedtribe.org | e4058b4 | 2012-01-04 03:37:40 +0000 | [diff] [blame] | 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*); |
rmistry@google.com | fbfcd56 | 2012-08-23 18:09:54 +0000 | [diff] [blame] | 225 | |
mike@reedtribe.org | e4058b4 | 2012-01-04 03:37:40 +0000 | [diff] [blame] | 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 | |
mike@reedtribe.org | 0f175a6 | 2012-01-02 00:34:50 +0000 | [diff] [blame] | 265 | private: |
| 266 | int fCount; |
| 267 | Type fType; |
| 268 | union { |
| 269 | void* fVoids; |
mike@reedtribe.org | e4058b4 | 2012-01-04 03:37:40 +0000 | [diff] [blame] | 270 | Object** fObjects; |
| 271 | Array** fArrays; |
| 272 | char** fStrings; |
mike@reedtribe.org | 0f175a6 | 2012-01-02 00:34:50 +0000 | [diff] [blame] | 273 | int32_t* fInts; |
| 274 | float* fFloats; |
| 275 | bool* fBools; |
| 276 | } fArray; |
rmistry@google.com | fbfcd56 | 2012-08-23 18:09:54 +0000 | [diff] [blame] | 277 | |
mike@reedtribe.org | 0f175a6 | 2012-01-02 00:34:50 +0000 | [diff] [blame] | 278 | void init(Type, int count, const void* src); |
| 279 | void dumpLevel(int level) const; |
rmistry@google.com | fbfcd56 | 2012-08-23 18:09:54 +0000 | [diff] [blame] | 280 | |
mike@reedtribe.org | 0f175a6 | 2012-01-02 00:34:50 +0000 | [diff] [blame] | 281 | friend class Object; |
| 282 | }; |
| 283 | }; |
| 284 | |
| 285 | #endif |