diff options
author | initial.commit <initial.commit@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-07-27 00:09:42 +0000 |
---|---|---|
committer | initial.commit <initial.commit@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-07-27 00:09:42 +0000 |
commit | ae2c20f398933a9e86c387dcc465ec0f71065ffc (patch) | |
tree | de668b1411e2ee0b4e49b6d8f8b68183134ac990 /skia/sgl/SkTSearch.cpp | |
parent | 09911bf300f1a419907a9412154760efd0b7abc3 (diff) | |
download | chromium_src-ae2c20f398933a9e86c387dcc465ec0f71065ffc.zip chromium_src-ae2c20f398933a9e86c387dcc465ec0f71065ffc.tar.gz chromium_src-ae2c20f398933a9e86c387dcc465ec0f71065ffc.tar.bz2 |
Add skia to the repository.
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@16 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'skia/sgl/SkTSearch.cpp')
-rw-r--r-- | skia/sgl/SkTSearch.cpp | 219 |
1 files changed, 219 insertions, 0 deletions
diff --git a/skia/sgl/SkTSearch.cpp b/skia/sgl/SkTSearch.cpp new file mode 100644 index 0000000..3a1a7d4 --- /dev/null +++ b/skia/sgl/SkTSearch.cpp @@ -0,0 +1,219 @@ +/* libs/graphics/sgl/SkTSearch.cpp +** +** Copyright 2006, Google Inc. +** +** 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. +*/ + +#include "SkTSearch.h" +#include <ctype.h> + +static inline const char* index_into_base(const char*const* base, int index, + size_t elemSize) +{ + return *(const char*const*)((const char*)base + index * elemSize); +} + +int SkStrSearch(const char*const* base, int count, const char target[], + size_t target_len, size_t elemSize) +{ + if (count <= 0) + return ~0; + + SkASSERT(base != NULL); + + int lo = 0; + int hi = count - 1; + + while (lo < hi) + { + int mid = (hi + lo) >> 1; + const char* elem = index_into_base(base, mid, elemSize); + + int cmp = strncmp(elem, target, target_len); + if (cmp < 0) + lo = mid + 1; + else if (cmp > 0 || strlen(elem) > target_len) + hi = mid; + else + return mid; + } + + const char* elem = index_into_base(base, hi, elemSize); + int cmp = strncmp(elem, target, target_len); + if (cmp || strlen(elem) > target_len) + { + if (cmp < 0) + hi += 1; + hi = ~hi; + } + return hi; +} + +int SkStrSearch(const char*const* base, int count, const char target[], + size_t elemSize) +{ + return SkStrSearch(base, count, target, strlen(target), elemSize); +} + +int SkStrLCSearch(const char*const* base, int count, const char target[], + size_t len, size_t elemSize) +{ + SkASSERT(target); + + SkAutoAsciiToLC tolc(target, len); + + return SkStrSearch(base, count, tolc.lc(), len, elemSize); +} + +int SkStrLCSearch(const char*const* base, int count, const char target[], + size_t elemSize) +{ + return SkStrLCSearch(base, count, target, strlen(target), elemSize); +} + +////////////////////////////////////////////////////////////////////////////// + +SkAutoAsciiToLC::SkAutoAsciiToLC(const char str[], size_t len) +{ + // see if we need to compute the length + if ((long)len < 0) { + len = strlen(str); + } + fLength = len; + + // assign lc to our preallocated storage if len is small enough, or allocate + // it on the heap + char* lc; + if (len <= STORAGE) { + lc = fStorage; + } else { + lc = (char*)sk_malloc_throw(len + 1); + } + fLC = lc; + + // convert any asii to lower-case. we let non-ascii (utf8) chars pass + // through unchanged + for (int i = (int)(len - 1); i >= 0; --i) { + int c = str[i]; + if ((c & 0x80) == 0) { // is just ascii + c = tolower(c); + } + lc[i] = c; + } + lc[len] = 0; +} + +SkAutoAsciiToLC::~SkAutoAsciiToLC() +{ + if (fLC != fStorage) { + sk_free(fLC); + } +} + +////////////////////////////////////////////////////////////////////////////// + +#define SK_QSortTempSize 16 + +static inline void sk_qsort_swap(char a[], char b[], size_t elemSize) +{ + char tmp[SK_QSortTempSize]; + + while (elemSize > 0) + { + size_t size = elemSize; + if (size > SK_QSortTempSize) + size = SK_QSortTempSize; + elemSize -= size; + + memcpy(tmp, a, size); + memcpy(a, b, size); + memcpy(b, tmp, size); + a += size; + b += size; + } +} + +static void SkQSort_Partition(char* first, char* last, size_t elemSize, SkQSortCompareProc compare) +{ + char* left = first; + char* rite = last; + char* pivot = left; + + while (left <= rite) + { + while (left < last && compare(left, pivot) < 0) + left += elemSize; + while (first < rite && compare(rite, pivot) > 0) + rite -= elemSize; + if (left <= rite) + { + if (left < rite) + { + SkASSERT(compare(left, rite) >= 0); + sk_qsort_swap(left, rite, elemSize); + } + left += elemSize; + rite -= elemSize; + } + } + if (first < rite) + SkQSort_Partition(first, rite, elemSize, compare); + if (left < last) + SkQSort_Partition(left, last, elemSize, compare); +} + +void SkQSort(void* base, size_t count, size_t elemSize, SkQSortCompareProc compare) +{ + SkASSERT(base); + SkASSERT(compare); + SkASSERT(elemSize > 0); + + if (count <= 1) + return; + + SkQSort_Partition((char*)base, (char*)base + (count - 1) * elemSize, elemSize, compare); +} + +#ifdef SK_DEBUG + +#include "SkRandom.h" + +#ifdef SK_SUPPORT_UNITTEST +extern "C" { + int compare_int(const void* a, const void* b) + { + return *(const int*)a - *(const int*)b; + } +} +#endif + +void SkQSort_UnitTest() +{ +#ifdef SK_SUPPORT_UNITTEST + int array[100]; + SkRandom rand; + + for (int i = 0; i < 1000; i++) + { + int j, count = rand.nextRangeU(1, SK_ARRAY_COUNT(array)); + for (j = 0; j < count; j++) + array[j] = rand.nextS() & 0xFF; + SkQSort(array, count, sizeof(int), compare_int); + for (j = 1; j < count; j++) + SkASSERT(array[j-1] <= array[j]); + } +#endif +} + +#endif |