summaryrefslogtreecommitdiffstats
path: root/skia/sgl/SkTSearch.cpp
diff options
context:
space:
mode:
authorinitial.commit <initial.commit@0039d316-1c4b-4281-b951-d872f2087c98>2008-07-27 00:09:42 +0000
committerinitial.commit <initial.commit@0039d316-1c4b-4281-b951-d872f2087c98>2008-07-27 00:09:42 +0000
commitae2c20f398933a9e86c387dcc465ec0f71065ffc (patch)
treede668b1411e2ee0b4e49b6d8f8b68183134ac990 /skia/sgl/SkTSearch.cpp
parent09911bf300f1a419907a9412154760efd0b7abc3 (diff)
downloadchromium_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.cpp219
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