859b92448b
patch from issue 338263003 BUG=skia: R=mtklein@google.com Author: reed@google.com Review URL: https://codereview.chromium.org/339183002
147 lines
3.5 KiB
C++
147 lines
3.5 KiB
C++
/*
|
|
* Copyright 2006 The Android Open Source Project
|
|
*
|
|
* Use of this source code is governed by a BSD-style license that can be
|
|
* found in the LICENSE file.
|
|
*/
|
|
|
|
#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 {
|
|
const Pair* end = fArray.end();
|
|
for (const 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:
|
|
const Pair* fIter;
|
|
const 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
|