Home | History | Annotate | Download | only in utils
      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 
    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