18a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/* 2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2006 The Android Open Source Project 38a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com * 4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be 5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file. 68a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 78a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 88a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifndef SkTDict_DEFINED 98a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkTDict_DEFINED 108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkChunkAlloc.h" 128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkTSearch.h" 138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkTDArray.h" 148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comtemplate <typename T> class SkTDict : SkNoncopyable { 168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkTDict(size_t minStringAlloc) : fStrings(minStringAlloc) {} 188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 19859b92448b27bb16852474f9a612748b3fd816d5reed void reset() { 208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fArray.reset(); 218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fStrings.reset(); 228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int count() const { return fArray.count(); } 258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 26859b92448b27bb16852474f9a612748b3fd816d5reed bool set(const char name[], const T& value) { 278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return set(name, strlen(name), value); 288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 30859b92448b27bb16852474f9a612748b3fd816d5reed bool set(const char name[], size_t len, const T& value) { 318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(name); 328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int index = this->find_index(name, len); 348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 35859b92448b27bb16852474f9a612748b3fd816d5reed if (index >= 0) { 368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fArray[index].fValue = value; 378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; 38859b92448b27bb16852474f9a612748b3fd816d5reed } else { 398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com Pair* pair = fArray.insert(~index); 408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com char* copy = (char*)fStrings.alloc(len + 1, SkChunkAlloc::kThrow_AllocFailType); 418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com memcpy(copy, name, len); 428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com copy[len] = '\0'; 438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com pair->fName = copy; 448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com pair->fValue = value; 458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 49859b92448b27bb16852474f9a612748b3fd816d5reed bool find(const char name[]) const { 508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return this->find_index(name) >= 0; 518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 53859b92448b27bb16852474f9a612748b3fd816d5reed bool find(const char name[], size_t len) const { 548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return this->find_index(name, len) >= 0; 558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 57859b92448b27bb16852474f9a612748b3fd816d5reed bool find(const char name[], T* value) const { 588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return find(name, strlen(name), value); 598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 61859b92448b27bb16852474f9a612748b3fd816d5reed bool find(const char name[], size_t len, T* value) const { 628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int index = this->find_index(name, len); 638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 64859b92448b27bb16852474f9a612748b3fd816d5reed if (index >= 0) { 65859b92448b27bb16852474f9a612748b3fd816d5reed if (value) { 668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *value = fArray[index].fValue; 67859b92448b27bb16852474f9a612748b3fd816d5reed } 688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; 718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 73859b92448b27bb16852474f9a612748b3fd816d5reed bool findKey(T& value, const char** name) const { 74aa537d4bdb2384cdcd0644a02a2ab7fb0ecdd3b3commit-bot@chromium.org const Pair* end = fArray.end(); 75aa537d4bdb2384cdcd0644a02a2ab7fb0ecdd3b3commit-bot@chromium.org for (const Pair* pair = fArray.begin(); pair < end; pair++) { 76859b92448b27bb16852474f9a612748b3fd816d5reed if (pair->fValue != value) { 778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com continue; 78859b92448b27bb16852474f9a612748b3fd816d5reed } 798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *name = pair->fName; 808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; 838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com struct Pair { 878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const char* fName; 888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com T fValue; 898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 90859b92448b27bb16852474f9a612748b3fd816d5reed friend int operator<(const Pair& a, const Pair& b) { 918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return strcmp(a.fName, b.fName); 928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 93859b92448b27bb16852474f9a612748b3fd816d5reed 94859b92448b27bb16852474f9a612748b3fd816d5reed friend int operator!=(const Pair& a, const Pair& b) { 958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return strcmp(a.fName, b.fName); 968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com }; 988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com friend class Iter; 998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 1018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com class Iter { 1028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com public: 103859b92448b27bb16852474f9a612748b3fd816d5reed Iter(const SkTDict<T>& dict) { 1048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fIter = dict.fArray.begin(); 1058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fStop = dict.fArray.end(); 1068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 107859b92448b27bb16852474f9a612748b3fd816d5reed 108859b92448b27bb16852474f9a612748b3fd816d5reed const char* next(T* value) { 1098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const char* name = NULL; 110859b92448b27bb16852474f9a612748b3fd816d5reed if (fIter < fStop) { 1118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com name = fIter->fName; 112859b92448b27bb16852474f9a612748b3fd816d5reed if (value) { 1138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *value = fIter->fValue; 114859b92448b27bb16852474f9a612748b3fd816d5reed } 1158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fIter += 1; 1168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return name; 1188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com private: 120aa537d4bdb2384cdcd0644a02a2ab7fb0ecdd3b3commit-bot@chromium.org const Pair* fIter; 121aa537d4bdb2384cdcd0644a02a2ab7fb0ecdd3b3commit-bot@chromium.org const Pair* fStop; 1228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com }; 1238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate: 1258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkTDArray<Pair> fArray; 1268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkChunkAlloc fStrings; 1278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 128859b92448b27bb16852474f9a612748b3fd816d5reed int find_index(const char name[]) const { 1298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return find_index(name, strlen(name)); 1308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 132859b92448b27bb16852474f9a612748b3fd816d5reed int find_index(const char name[], size_t len) const { 1338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(name); 1348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int count = fArray.count(); 1368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int index = ~0; 1378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 138859b92448b27bb16852474f9a612748b3fd816d5reed if (count) { 1398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com index = SkStrSearch(&fArray.begin()->fName, count, name, len, sizeof(Pair)); 140859b92448b27bb16852474f9a612748b3fd816d5reed } 1418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return index; 1428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com friend class Iter; 1448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 1458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 147