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 17template <typename T> class SkTDict : SkNoncopyable { 18public: 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 97public: 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 113public: 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 138private: 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