aboutsummaryrefslogtreecommitdiffhomepage
path: root/include/core/SkTDict.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/core/SkTDict.h')
-rw-r--r--include/core/SkTDict.h169
1 files changed, 169 insertions, 0 deletions
diff --git a/include/core/SkTDict.h b/include/core/SkTDict.h
new file mode 100644
index 0000000000..0b92779ce3
--- /dev/null
+++ b/include/core/SkTDict.h
@@ -0,0 +1,169 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkTDict_DEFINED
+#define SkTDict_DEFINED
+
+#include "SkChunkAlloc.h"
+#include "SkTSearch.h"
+#include "SkTDArray.h"
+
+template <typename T> class SkTDict : SkNoncopyable {
+public:
+ SkTDict(size_t minStringAlloc) : fStrings(minStringAlloc) {}
+
+ void reset()
+ {
+ fArray.reset();
+ fStrings.reset();
+ }
+
+ int count() const { return fArray.count(); }
+
+ bool set(const char name[], const T& value)
+ {
+ return set(name, strlen(name), value);
+ }
+
+ bool set(const char name[], size_t len, const T& value)
+ {
+ SkASSERT(name);
+
+ int index = this->find_index(name, len);
+
+ if (index >= 0)
+ {
+ fArray[index].fValue = value;
+ return false;
+ }
+ else
+ {
+ Pair* pair = fArray.insert(~index);
+ char* copy = (char*)fStrings.alloc(len + 1, SkChunkAlloc::kThrow_AllocFailType);
+ memcpy(copy, name, len);
+ copy[len] = '\0';
+ pair->fName = copy;
+ pair->fValue = value;
+ return true;
+ }
+ }
+
+ bool find(const char name[]) const
+ {
+ return this->find_index(name) >= 0;
+ }
+
+ bool find(const char name[], size_t len) const
+ {
+ return this->find_index(name, len) >= 0;
+ }
+
+ bool find(const char name[], T* value) const
+ {
+ return find(name, strlen(name), value);
+ }
+
+ bool find(const char name[], size_t len, T* value) const
+ {
+ int index = this->find_index(name, len);
+
+ if (index >= 0)
+ {
+ if (value)
+ *value = fArray[index].fValue;
+ return true;
+ }
+ return false;
+ }
+
+ bool findKey(T& value, const char** name) const
+ {
+ Pair* end = fArray.end();
+ for (Pair* pair = fArray.begin(); pair < end; pair++) {
+ if (pair->fValue != value)
+ continue;
+ *name = pair->fName;
+ return true;
+ }
+ return false;
+ }
+
+public:
+ struct Pair {
+ const char* fName;
+ T fValue;
+
+ friend int operator<(const Pair& a, const Pair& b)
+ {
+ return strcmp(a.fName, b.fName);
+ }
+ friend int operator!=(const Pair& a, const Pair& b)
+ {
+ return strcmp(a.fName, b.fName);
+ }
+ };
+ friend class Iter;
+
+public:
+ class Iter {
+ public:
+ Iter(const SkTDict<T>& dict)
+ {
+ fIter = dict.fArray.begin();
+ fStop = dict.fArray.end();
+ }
+ const char* next(T* value)
+ {
+ const char* name = NULL;
+ if (fIter < fStop)
+ {
+ name = fIter->fName;
+ if (value)
+ *value = fIter->fValue;
+ fIter += 1;
+ }
+ return name;
+ }
+ private:
+ Pair* fIter;
+ Pair* fStop;
+ };
+
+private:
+ SkTDArray<Pair> fArray;
+ SkChunkAlloc fStrings;
+
+ int find_index(const char name[]) const
+ {
+ return find_index(name, strlen(name));
+ }
+
+ int find_index(const char name[], size_t len) const
+ {
+ SkASSERT(name);
+
+ int count = fArray.count();
+ int index = ~0;
+
+ if (count)
+ index = SkStrSearch(&fArray.begin()->fName, count, name, len, sizeof(Pair));
+ return index;
+ }
+ friend class Iter;
+};
+
+#endif
+