00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef SkTDict_DEFINED
00018 #define SkTDict_DEFINED
00019
00020 #include "SkChunkAlloc.h"
00021 #include "SkTSearch.h"
00022 #include "SkTDArray.h"
00023
00024 template <typename T> class SkTDict : SkNoncopyable {
00025 public:
00026 SkTDict(size_t minStringAlloc) : fStrings(minStringAlloc) {}
00027
00028 void reset()
00029 {
00030 fArray.reset();
00031 fStrings.reset();
00032 }
00033
00034 int count() const { return fArray.count(); }
00035
00036 bool set(const char name[], const T& value)
00037 {
00038 return set(name, strlen(name), value);
00039 }
00040
00041 bool set(const char name[], size_t len, const T& value)
00042 {
00043 SkASSERT(name);
00044
00045 int index = this->find_index(name, len);
00046
00047 if (index >= 0)
00048 {
00049 fArray[index].fValue = value;
00050 return false;
00051 }
00052 else
00053 {
00054 Pair* pair = fArray.insert(~index);
00055 char* copy = (char*)fStrings.alloc(len + 1, SkChunkAlloc::kThrow_AllocFailType);
00056 memcpy(copy, name, len);
00057 copy[len] = '\0';
00058 pair->fName = copy;
00059 pair->fValue = value;
00060 return true;
00061 }
00062 }
00063
00064 bool find(const char name[]) const
00065 {
00066 return this->find_index(name) >= 0;
00067 }
00068
00069 bool find(const char name[], size_t len) const
00070 {
00071 return this->find_index(name, len) >= 0;
00072 }
00073
00074 bool find(const char name[], T* value) const
00075 {
00076 return find(name, strlen(name), value);
00077 }
00078
00079 bool find(const char name[], size_t len, T* value) const
00080 {
00081 int index = this->find_index(name, len);
00082
00083 if (index >= 0)
00084 {
00085 if (value)
00086 *value = fArray[index].fValue;
00087 return true;
00088 }
00089 return false;
00090 }
00091
00092 bool findKey(T& value, const char** name) const
00093 {
00094 Pair* end = fArray.end();
00095 for (Pair* pair = fArray.begin(); pair < end; pair++) {
00096 if (pair->fValue != value)
00097 continue;
00098 *name = pair->fName;
00099 return true;
00100 }
00101 return false;
00102 }
00103
00104 public:
00105 struct Pair {
00106 const char* fName;
00107 T fValue;
00108
00109 friend int operator<(const Pair& a, const Pair& b)
00110 {
00111 return strcmp(a.fName, b.fName);
00112 }
00113 friend int operator!=(const Pair& a, const Pair& b)
00114 {
00115 return strcmp(a.fName, b.fName);
00116 }
00117 };
00118 friend class Iter;
00119
00120 public:
00121 class Iter {
00122 public:
00123 Iter(const SkTDict<T>& dict)
00124 {
00125 fIter = dict.fArray.begin();
00126 fStop = dict.fArray.end();
00127 }
00128 const char* next(T* value)
00129 {
00130 const char* name = NULL;
00131 if (fIter < fStop)
00132 {
00133 name = fIter->fName;
00134 if (value)
00135 *value = fIter->fValue;
00136 fIter += 1;
00137 }
00138 return name;
00139 }
00140 private:
00141 Pair* fIter;
00142 Pair* fStop;
00143 };
00144
00145 private:
00146 SkTDArray<Pair> fArray;
00147 SkChunkAlloc fStrings;
00148
00149 int find_index(const char name[]) const
00150 {
00151 return find_index(name, strlen(name));
00152 }
00153
00154 int find_index(const char name[], size_t len) const
00155 {
00156 SkASSERT(name);
00157
00158 int count = fArray.count();
00159 int index = ~0;
00160
00161 if (count)
00162 index = SkStrSearch(&fArray.begin()->fName, count, name, len, sizeof(Pair));
00163 return index;
00164 }
00165 friend class Iter;
00166 };
00167
00168 #endif
00169