• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
SkTDict(size_t minStringAlloc)19     SkTDict(size_t minStringAlloc) : fStrings(minStringAlloc) {}
20 
reset()21     void reset()
22     {
23         fArray.reset();
24         fStrings.reset();
25     }
26 
count()27     int count() const { return fArray.count(); }
28 
set(const char name[],const T & value)29     bool set(const char name[], const T& value)
30     {
31         return set(name, strlen(name), value);
32     }
33 
set(const char name[],size_t len,const T & value)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 
find(const char name[])57     bool find(const char name[]) const
58     {
59         return this->find_index(name) >= 0;
60     }
61 
find(const char name[],size_t len)62     bool find(const char name[], size_t len) const
63     {
64         return this->find_index(name, len) >= 0;
65     }
66 
find(const char name[],T * value)67     bool find(const char name[], T* value) const
68     {
69         return find(name, strlen(name), value);
70     }
71 
find(const char name[],size_t len,T * value)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 
findKey(T & value,const char ** name)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:
Iter(const SkTDict<T> & dict)116         Iter(const SkTDict<T>& dict)
117         {
118             fIter = dict.fArray.begin();
119             fStop = dict.fArray.end();
120         }
next(T * value)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 
find_index(const char name[])142     int find_index(const char name[]) const
143     {
144         return find_index(name, strlen(name));
145     }
146 
find_index(const char name[],size_t len)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