11cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 20910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/* 31cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Copyright 2006 The Android Open Source Project 40910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project * 51cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Use of this source code is governed by a BSD-style license that can be 61cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * found in the LICENSE file. 70910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project */ 80910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 91cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#ifndef SkTDict_DEFINED 110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SkTDict_DEFINED 120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkChunkAlloc.h" 140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkTSearch.h" 150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkTDArray.h" 160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projecttemplate <typename T> class SkTDict : SkNoncopyable { 180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectpublic: 190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkTDict(size_t minStringAlloc) : fStrings(minStringAlloc) {} 200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project void reset() 220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fArray.reset(); 240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fStrings.reset(); 250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int count() const { return fArray.count(); } 280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project bool set(const char name[], const T& value) 300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return set(name, strlen(name), value); 320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project bool set(const char name[], size_t len, const T& value) 350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(name); 370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int index = this->find_index(name, len); 390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (index >= 0) 410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fArray[index].fValue = value; 430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return false; 440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project else 460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project Pair* pair = fArray.insert(~index); 480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project char* copy = (char*)fStrings.alloc(len + 1, SkChunkAlloc::kThrow_AllocFailType); 490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project memcpy(copy, name, len); 500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project copy[len] = '\0'; 510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project pair->fName = copy; 520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project pair->fValue = value; 530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return true; 540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project bool find(const char name[]) const 580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return this->find_index(name) >= 0; 600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project bool find(const char name[], size_t len) const 630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return this->find_index(name, len) >= 0; 650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project bool find(const char name[], T* value) const 680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return find(name, strlen(name), value); 700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project bool find(const char name[], size_t len, T* value) const 730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int index = this->find_index(name, len); 750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (index >= 0) 770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (value) 790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *value = fArray[index].fValue; 800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return true; 810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return false; 830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project bool findKey(T& value, const char** name) const 860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project Pair* end = fArray.end(); 880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project for (Pair* pair = fArray.begin(); pair < end; pair++) { 890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (pair->fValue != value) 900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project continue; 910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *name = pair->fName; 920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return true; 930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return false; 950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectpublic: 980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project struct Pair { 990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const char* fName; 1000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project T fValue; 1010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project friend int operator<(const Pair& a, const Pair& b) 1030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 1040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return strcmp(a.fName, b.fName); 1050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 1060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project friend int operator!=(const Pair& a, const Pair& b) 1070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 1080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return strcmp(a.fName, b.fName); 1090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 1100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project }; 1110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project friend class Iter; 1120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectpublic: 1140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project class Iter { 1150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project public: 1160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project Iter(const SkTDict<T>& dict) 1170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 1180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fIter = dict.fArray.begin(); 1190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fStop = dict.fArray.end(); 1200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 1210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const char* next(T* value) 1220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 1230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const char* name = NULL; 1240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (fIter < fStop) 1250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 1260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project name = fIter->fName; 1270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (value) 1280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *value = fIter->fValue; 1290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fIter += 1; 1300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 1310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return name; 1320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 1330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project private: 1340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project Pair* fIter; 1350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project Pair* fStop; 1360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project }; 1370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectprivate: 1390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkTDArray<Pair> fArray; 1400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkChunkAlloc fStrings; 1410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int find_index(const char name[]) const 1430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 1440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return find_index(name, strlen(name)); 1450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 1460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int find_index(const char name[], size_t len) const 1480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 1490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(name); 1500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int count = fArray.count(); 1520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int index = ~0; 1530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (count) 1550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project index = SkStrSearch(&fArray.begin()->fName, count, name, len, sizeof(Pair)); 1560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return index; 1570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 1580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project friend class Iter; 1590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}; 1600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif 1620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 163