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 13 class SkStream; 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 }; 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 count()216 int count() const { return fCount; } type()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 objects()240 Object* const* objects() const { 241 SkASSERT(kObject == fType); 242 return fArray.fObjects; 243 } arrays()244 Array* const* arrays() const { 245 SkASSERT(kObject == fType); 246 return fArray.fArrays; 247 } strings()248 const char* const* strings() const { 249 SkASSERT(kString == fType); 250 return fArray.fStrings; 251 } ints()252 int32_t* ints() const { 253 SkASSERT(kInt == fType); 254 return fArray.fInts; 255 } floats()256 float* floats() const { 257 SkASSERT(kFloat == fType); 258 return fArray.fFloats; 259 } bools()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