Home | History | Annotate | Download | only in core
      1 
      2 /*
      3  * Copyright 2006 The Android Open Source Project
      4  *
      5  * Use of this source code is governed by a BSD-style license that can be
      6  * found in the LICENSE file.
      7  */
      8 
      9 
     10 #ifndef SkTDict_DEFINED
     11 #define SkTDict_DEFINED
     12 
     13 #include "SkChunkAlloc.h"
     14 #include "SkTSearch.h"
     15 #include "SkTDArray.h"
     16 
     17 template <typename T> class SkTDict : SkNoncopyable {
     18 public:
     19     SkTDict(size_t minStringAlloc) : fStrings(minStringAlloc) {}
     20 
     21     void reset()
     22     {
     23         fArray.reset();
     24         fStrings.reset();
     25     }
     26 
     27     int count() const { return fArray.count(); }
     28 
     29     bool set(const char name[], const T& value)
     30     {
     31         return set(name, strlen(name), value);
     32     }
     33 
     34     bool set(const char name[], size_t len, const T& value)
     35     {
     36         SkASSERT(name);
     37 
     38         int index = this->find_index(name, len);
     39 
     40         if (index >= 0)
     41         {
     42             fArray[index].fValue = value;
     43             return false;
     44         }
     45         else
     46         {
     47             Pair*   pair = fArray.insert(~index);
     48             char*   copy = (char*)fStrings.alloc(len + 1, SkChunkAlloc::kThrow_AllocFailType);
     49             memcpy(copy, name, len);
     50             copy[len] = '\0';
     51             pair->fName = copy;
     52             pair->fValue = value;
     53             return true;
     54         }
     55     }
     56 
     57     bool find(const char name[]) const
     58     {
     59         return this->find_index(name) >= 0;
     60     }
     61 
     62     bool find(const char name[], size_t len) const
     63     {
     64         return this->find_index(name, len) >= 0;
     65     }
     66 
     67     bool find(const char name[], T* value) const
     68     {
     69         return find(name, strlen(name), value);
     70     }
     71 
     72     bool find(const char name[], size_t len, T* value) const
     73     {
     74         int index = this->find_index(name, len);
     75 
     76         if (index >= 0)
     77         {
     78             if (value)
     79                 *value = fArray[index].fValue;
     80             return true;
     81         }
     82         return false;
     83     }
     84 
     85     bool findKey(T& value, const char** name) const
     86     {
     87         Pair* end = fArray.end();
     88         for (Pair* pair = fArray.begin(); pair < end; pair++) {
     89             if (pair->fValue != value)
     90                 continue;
     91             *name = pair->fName;
     92             return true;
     93         }
     94         return false;
     95     }
     96 
     97 public:
     98     struct Pair {
     99         const char* fName;
    100         T           fValue;
    101 
    102         friend int operator<(const Pair& a, const Pair& b)
    103         {
    104             return strcmp(a.fName, b.fName);
    105         }
    106         friend int operator!=(const Pair& a, const Pair& b)
    107         {
    108             return strcmp(a.fName, b.fName);
    109         }
    110     };
    111     friend class Iter;
    112 
    113 public:
    114     class Iter {
    115     public:
    116         Iter(const SkTDict<T>& dict)
    117         {
    118             fIter = dict.fArray.begin();
    119             fStop = dict.fArray.end();
    120         }
    121         const char* next(T* value)
    122         {
    123             const char* name = NULL;
    124             if (fIter < fStop)
    125             {
    126                 name = fIter->fName;
    127                 if (value)
    128                     *value = fIter->fValue;
    129                 fIter += 1;
    130             }
    131             return name;
    132         }
    133     private:
    134         Pair*   fIter;
    135         Pair*   fStop;
    136     };
    137 
    138 private:
    139     SkTDArray<Pair> fArray;
    140     SkChunkAlloc    fStrings;
    141 
    142     int find_index(const char name[]) const
    143     {
    144         return find_index(name, strlen(name));
    145     }
    146 
    147     int find_index(const char name[], size_t len) const
    148     {
    149         SkASSERT(name);
    150 
    151         int count = fArray.count();
    152         int index = ~0;
    153 
    154         if (count)
    155             index = SkStrSearch(&fArray.begin()->fName, count, name, len, sizeof(Pair));
    156         return index;
    157     }
    158     friend class Iter;
    159 };
    160 
    161 #endif
    162 
    163