| OLD | NEW |
| (Empty) |
| 1 /* libs/graphics/sgl/SkTSearch.cpp | |
| 2 ** | |
| 3 ** Copyright 2006, The Android Open Source Project | |
| 4 ** | |
| 5 ** Licensed under the Apache License, Version 2.0 (the "License"); | |
| 6 ** you may not use this file except in compliance with the License. | |
| 7 ** You may obtain a copy of the License at | |
| 8 ** | |
| 9 ** http://www.apache.org/licenses/LICENSE-2.0 | |
| 10 ** | |
| 11 ** Unless required by applicable law or agreed to in writing, software | |
| 12 ** distributed under the License is distributed on an "AS IS" BASIS, | |
| 13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| 14 ** See the License for the specific language governing permissions and | |
| 15 ** limitations under the License. | |
| 16 */ | |
| 17 | |
| 18 #include "SkTSearch.h" | |
| 19 #include <ctype.h> | |
| 20 | |
| 21 static inline const char* index_into_base(const char*const* base, int index, | |
| 22 size_t elemSize) | |
| 23 { | |
| 24 return *(const char*const*)((const char*)base + index * elemSize); | |
| 25 } | |
| 26 | |
| 27 int SkStrSearch(const char*const* base, int count, const char target[], | |
| 28 size_t target_len, size_t elemSize) | |
| 29 { | |
| 30 if (count <= 0) | |
| 31 return ~0; | |
| 32 | |
| 33 SkASSERT(base != NULL); | |
| 34 | |
| 35 int lo = 0; | |
| 36 int hi = count - 1; | |
| 37 | |
| 38 while (lo < hi) | |
| 39 { | |
| 40 int mid = (hi + lo) >> 1; | |
| 41 const char* elem = index_into_base(base, mid, elemSize); | |
| 42 | |
| 43 int cmp = strncmp(elem, target, target_len); | |
| 44 if (cmp < 0) | |
| 45 lo = mid + 1; | |
| 46 else if (cmp > 0 || strlen(elem) > target_len) | |
| 47 hi = mid; | |
| 48 else | |
| 49 return mid; | |
| 50 } | |
| 51 | |
| 52 const char* elem = index_into_base(base, hi, elemSize); | |
| 53 int cmp = strncmp(elem, target, target_len); | |
| 54 if (cmp || strlen(elem) > target_len) | |
| 55 { | |
| 56 if (cmp < 0) | |
| 57 hi += 1; | |
| 58 hi = ~hi; | |
| 59 } | |
| 60 return hi; | |
| 61 } | |
| 62 | |
| 63 int SkStrSearch(const char*const* base, int count, const char target[], | |
| 64 size_t elemSize) | |
| 65 { | |
| 66 return SkStrSearch(base, count, target, strlen(target), elemSize); | |
| 67 } | |
| 68 | |
| 69 int SkStrLCSearch(const char*const* base, int count, const char target[], | |
| 70 size_t len, size_t elemSize) | |
| 71 { | |
| 72 SkASSERT(target); | |
| 73 | |
| 74 SkAutoAsciiToLC tolc(target, len); | |
| 75 | |
| 76 return SkStrSearch(base, count, tolc.lc(), len, elemSize); | |
| 77 } | |
| 78 | |
| 79 int SkStrLCSearch(const char*const* base, int count, const char target[], | |
| 80 size_t elemSize) | |
| 81 { | |
| 82 return SkStrLCSearch(base, count, target, strlen(target), elemSize); | |
| 83 } | |
| 84 | |
| 85 ////////////////////////////////////////////////////////////////////////////// | |
| 86 | |
| 87 SkAutoAsciiToLC::SkAutoAsciiToLC(const char str[], size_t len) | |
| 88 { | |
| 89 // see if we need to compute the length | |
| 90 if ((long)len < 0) { | |
| 91 len = strlen(str); | |
| 92 } | |
| 93 fLength = len; | |
| 94 | |
| 95 // assign lc to our preallocated storage if len is small enough, or allocate | |
| 96 // it on the heap | |
| 97 char* lc; | |
| 98 if (len <= STORAGE) { | |
| 99 lc = fStorage; | |
| 100 } else { | |
| 101 lc = (char*)sk_malloc_throw(len + 1); | |
| 102 } | |
| 103 fLC = lc; | |
| 104 | |
| 105 // convert any asii to lower-case. we let non-ascii (utf8) chars pass | |
| 106 // through unchanged | |
| 107 for (int i = (int)(len - 1); i >= 0; --i) { | |
| 108 int c = str[i]; | |
| 109 if ((c & 0x80) == 0) { // is just ascii | |
| 110 c = tolower(c); | |
| 111 } | |
| 112 lc[i] = c; | |
| 113 } | |
| 114 lc[len] = 0; | |
| 115 } | |
| 116 | |
| 117 SkAutoAsciiToLC::~SkAutoAsciiToLC() | |
| 118 { | |
| 119 if (fLC != fStorage) { | |
| 120 sk_free(fLC); | |
| 121 } | |
| 122 } | |
| 123 | |
| 124 ////////////////////////////////////////////////////////////////////////////// | |
| 125 | |
| 126 #define SK_QSortTempSize 16 | |
| 127 | |
| 128 static inline void sk_qsort_swap(char a[], char b[], size_t elemSize) | |
| 129 { | |
| 130 char tmp[SK_QSortTempSize]; | |
| 131 | |
| 132 while (elemSize > 0) | |
| 133 { | |
| 134 size_t size = elemSize; | |
| 135 if (size > SK_QSortTempSize) | |
| 136 size = SK_QSortTempSize; | |
| 137 elemSize -= size; | |
| 138 | |
| 139 memcpy(tmp, a, size); | |
| 140 memcpy(a, b, size); | |
| 141 memcpy(b, tmp, size); | |
| 142 a += size; | |
| 143 b += size; | |
| 144 } | |
| 145 } | |
| 146 | |
| 147 static void SkQSort_Partition(char* first, char* last, size_t elemSize, SkQSortC
ompareProc compare) | |
| 148 { | |
| 149 char* left = first; | |
| 150 char* rite = last; | |
| 151 char* pivot = left; | |
| 152 | |
| 153 while (left <= rite) | |
| 154 { | |
| 155 while (left < last && compare(left, pivot) < 0) | |
| 156 left += elemSize; | |
| 157 while (first < rite && compare(rite, pivot) > 0) | |
| 158 rite -= elemSize; | |
| 159 if (left <= rite) | |
| 160 { | |
| 161 if (left < rite) | |
| 162 { | |
| 163 SkASSERT(compare(left, rite) >= 0); | |
| 164 sk_qsort_swap(left, rite, elemSize); | |
| 165 } | |
| 166 left += elemSize; | |
| 167 rite -= elemSize; | |
| 168 } | |
| 169 } | |
| 170 if (first < rite) | |
| 171 SkQSort_Partition(first, rite, elemSize, compare); | |
| 172 if (left < last) | |
| 173 SkQSort_Partition(left, last, elemSize, compare); | |
| 174 } | |
| 175 | |
| 176 void SkQSort(void* base, size_t count, size_t elemSize, SkQSortCompareProc compa
re) | |
| 177 { | |
| 178 SkASSERT(base); | |
| 179 SkASSERT(compare); | |
| 180 SkASSERT(elemSize > 0); | |
| 181 | |
| 182 if (count <= 1) | |
| 183 return; | |
| 184 | |
| 185 SkQSort_Partition((char*)base, (char*)base + (count - 1) * elemSize, elemSiz
e, compare); | |
| 186 } | |
| 187 | |
| 188 #ifdef SK_DEBUG | |
| 189 | |
| 190 #include "SkRandom.h" | |
| 191 | |
| 192 #ifdef SK_SUPPORT_UNITTEST | |
| 193 extern "C" { | |
| 194 int compare_int(const void* a, const void* b) | |
| 195 { | |
| 196 return *(const int*)a - *(const int*)b; | |
| 197 } | |
| 198 } | |
| 199 #endif | |
| 200 | |
| 201 void SkQSort_UnitTest() | |
| 202 { | |
| 203 #ifdef SK_SUPPORT_UNITTEST | |
| 204 int array[100]; | |
| 205 SkRandom rand; | |
| 206 | |
| 207 for (int i = 0; i < 1000; i++) | |
| 208 { | |
| 209 int j, count = rand.nextRangeU(1, SK_ARRAY_COUNT(array)); | |
| 210 for (j = 0; j < count; j++) | |
| 211 array[j] = rand.nextS() & 0xFF; | |
| 212 SkQSort(array, count, sizeof(int), compare_int); | |
| 213 for (j = 1; j < count; j++) | |
| 214 SkASSERT(array[j-1] <= array[j]); | |
| 215 } | |
| 216 #endif | |
| 217 } | |
| 218 | |
| 219 #endif | |
| OLD | NEW |