michael@0: michael@0: /* michael@0: * Copyright 2006 The Android Open Source Project michael@0: * michael@0: * Use of this source code is governed by a BSD-style license that can be michael@0: * found in the LICENSE file. michael@0: */ michael@0: michael@0: michael@0: #ifndef SkTDict_DEFINED michael@0: #define SkTDict_DEFINED michael@0: michael@0: #include "SkChunkAlloc.h" michael@0: #include "SkTSearch.h" michael@0: #include "SkTDArray.h" michael@0: michael@0: template class SkTDict : SkNoncopyable { michael@0: public: michael@0: SkTDict(size_t minStringAlloc) : fStrings(minStringAlloc) {} michael@0: michael@0: void reset() michael@0: { michael@0: fArray.reset(); michael@0: fStrings.reset(); michael@0: } michael@0: michael@0: int count() const { return fArray.count(); } michael@0: michael@0: bool set(const char name[], const T& value) michael@0: { michael@0: return set(name, strlen(name), value); michael@0: } michael@0: michael@0: bool set(const char name[], size_t len, const T& value) michael@0: { michael@0: SkASSERT(name); michael@0: michael@0: int index = this->find_index(name, len); michael@0: michael@0: if (index >= 0) michael@0: { michael@0: fArray[index].fValue = value; michael@0: return false; michael@0: } michael@0: else michael@0: { michael@0: Pair* pair = fArray.insert(~index); michael@0: char* copy = (char*)fStrings.alloc(len + 1, SkChunkAlloc::kThrow_AllocFailType); michael@0: memcpy(copy, name, len); michael@0: copy[len] = '\0'; michael@0: pair->fName = copy; michael@0: pair->fValue = value; michael@0: return true; michael@0: } michael@0: } michael@0: michael@0: bool find(const char name[]) const michael@0: { michael@0: return this->find_index(name) >= 0; michael@0: } michael@0: michael@0: bool find(const char name[], size_t len) const michael@0: { michael@0: return this->find_index(name, len) >= 0; michael@0: } michael@0: michael@0: bool find(const char name[], T* value) const michael@0: { michael@0: return find(name, strlen(name), value); michael@0: } michael@0: michael@0: bool find(const char name[], size_t len, T* value) const michael@0: { michael@0: int index = this->find_index(name, len); michael@0: michael@0: if (index >= 0) michael@0: { michael@0: if (value) michael@0: *value = fArray[index].fValue; michael@0: return true; michael@0: } michael@0: return false; michael@0: } michael@0: michael@0: bool findKey(T& value, const char** name) const michael@0: { michael@0: const Pair* end = fArray.end(); michael@0: for (const Pair* pair = fArray.begin(); pair < end; pair++) { michael@0: if (pair->fValue != value) michael@0: continue; michael@0: *name = pair->fName; michael@0: return true; michael@0: } michael@0: return false; michael@0: } michael@0: michael@0: public: michael@0: struct Pair { michael@0: const char* fName; michael@0: T fValue; michael@0: michael@0: friend int operator<(const Pair& a, const Pair& b) michael@0: { michael@0: return strcmp(a.fName, b.fName); michael@0: } michael@0: friend int operator!=(const Pair& a, const Pair& b) michael@0: { michael@0: return strcmp(a.fName, b.fName); michael@0: } michael@0: }; michael@0: friend class Iter; michael@0: michael@0: public: michael@0: class Iter { michael@0: public: michael@0: Iter(const SkTDict& dict) michael@0: { michael@0: fIter = dict.fArray.begin(); michael@0: fStop = dict.fArray.end(); michael@0: } michael@0: const char* next(T* value) michael@0: { michael@0: const char* name = NULL; michael@0: if (fIter < fStop) michael@0: { michael@0: name = fIter->fName; michael@0: if (value) michael@0: *value = fIter->fValue; michael@0: fIter += 1; michael@0: } michael@0: return name; michael@0: } michael@0: private: michael@0: const Pair* fIter; michael@0: const Pair* fStop; michael@0: }; michael@0: michael@0: private: michael@0: SkTDArray fArray; michael@0: SkChunkAlloc fStrings; michael@0: michael@0: int find_index(const char name[]) const michael@0: { michael@0: return find_index(name, strlen(name)); michael@0: } michael@0: michael@0: int find_index(const char name[], size_t len) const michael@0: { michael@0: SkASSERT(name); michael@0: michael@0: int count = fArray.count(); michael@0: int index = ~0; michael@0: michael@0: if (count) michael@0: index = SkStrSearch(&fArray.begin()->fName, count, name, len, sizeof(Pair)); michael@0: return index; michael@0: } michael@0: friend class Iter; michael@0: }; michael@0: michael@0: #endif