1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci * Copyright 2006 The Android Open Source Project 3cb93a386Sopenharmony_ci * 4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be 5cb93a386Sopenharmony_ci * found in the LICENSE file. 6cb93a386Sopenharmony_ci */ 7cb93a386Sopenharmony_ci 8cb93a386Sopenharmony_ci 9cb93a386Sopenharmony_ci#include "src/core/SkTSearch.h" 10cb93a386Sopenharmony_ci 11cb93a386Sopenharmony_ci#include "include/private/SkMalloc.h" 12cb93a386Sopenharmony_ci 13cb93a386Sopenharmony_ci#include <ctype.h> 14cb93a386Sopenharmony_ci 15cb93a386Sopenharmony_cistatic inline const char* index_into_base(const char*const* base, int index, 16cb93a386Sopenharmony_ci size_t elemSize) 17cb93a386Sopenharmony_ci{ 18cb93a386Sopenharmony_ci return *(const char*const*)((const char*)base + index * elemSize); 19cb93a386Sopenharmony_ci} 20cb93a386Sopenharmony_ci 21cb93a386Sopenharmony_ciint SkStrSearch(const char*const* base, int count, const char target[], 22cb93a386Sopenharmony_ci size_t target_len, size_t elemSize) 23cb93a386Sopenharmony_ci{ 24cb93a386Sopenharmony_ci if (count <= 0) 25cb93a386Sopenharmony_ci return ~0; 26cb93a386Sopenharmony_ci 27cb93a386Sopenharmony_ci SkASSERT(base != nullptr); 28cb93a386Sopenharmony_ci 29cb93a386Sopenharmony_ci int lo = 0; 30cb93a386Sopenharmony_ci int hi = count - 1; 31cb93a386Sopenharmony_ci 32cb93a386Sopenharmony_ci while (lo < hi) 33cb93a386Sopenharmony_ci { 34cb93a386Sopenharmony_ci int mid = (hi + lo) >> 1; 35cb93a386Sopenharmony_ci const char* elem = index_into_base(base, mid, elemSize); 36cb93a386Sopenharmony_ci 37cb93a386Sopenharmony_ci int cmp = strncmp(elem, target, target_len); 38cb93a386Sopenharmony_ci if (cmp < 0) 39cb93a386Sopenharmony_ci lo = mid + 1; 40cb93a386Sopenharmony_ci else if (cmp > 0 || strlen(elem) > target_len) 41cb93a386Sopenharmony_ci hi = mid; 42cb93a386Sopenharmony_ci else 43cb93a386Sopenharmony_ci return mid; 44cb93a386Sopenharmony_ci } 45cb93a386Sopenharmony_ci 46cb93a386Sopenharmony_ci const char* elem = index_into_base(base, hi, elemSize); 47cb93a386Sopenharmony_ci int cmp = strncmp(elem, target, target_len); 48cb93a386Sopenharmony_ci if (cmp || strlen(elem) > target_len) 49cb93a386Sopenharmony_ci { 50cb93a386Sopenharmony_ci if (cmp < 0) 51cb93a386Sopenharmony_ci hi += 1; 52cb93a386Sopenharmony_ci hi = ~hi; 53cb93a386Sopenharmony_ci } 54cb93a386Sopenharmony_ci return hi; 55cb93a386Sopenharmony_ci} 56cb93a386Sopenharmony_ci 57cb93a386Sopenharmony_ciint SkStrSearch(const char*const* base, int count, const char target[], 58cb93a386Sopenharmony_ci size_t elemSize) 59cb93a386Sopenharmony_ci{ 60cb93a386Sopenharmony_ci return SkStrSearch(base, count, target, strlen(target), elemSize); 61cb93a386Sopenharmony_ci} 62cb93a386Sopenharmony_ci 63cb93a386Sopenharmony_ciint SkStrLCSearch(const char*const* base, int count, const char target[], 64cb93a386Sopenharmony_ci size_t len, size_t elemSize) 65cb93a386Sopenharmony_ci{ 66cb93a386Sopenharmony_ci SkASSERT(target); 67cb93a386Sopenharmony_ci 68cb93a386Sopenharmony_ci SkAutoAsciiToLC tolc(target, len); 69cb93a386Sopenharmony_ci 70cb93a386Sopenharmony_ci return SkStrSearch(base, count, tolc.lc(), len, elemSize); 71cb93a386Sopenharmony_ci} 72cb93a386Sopenharmony_ci 73cb93a386Sopenharmony_ciint SkStrLCSearch(const char*const* base, int count, const char target[], 74cb93a386Sopenharmony_ci size_t elemSize) 75cb93a386Sopenharmony_ci{ 76cb93a386Sopenharmony_ci return SkStrLCSearch(base, count, target, strlen(target), elemSize); 77cb93a386Sopenharmony_ci} 78cb93a386Sopenharmony_ci 79cb93a386Sopenharmony_ci////////////////////////////////////////////////////////////////////////////// 80cb93a386Sopenharmony_ci 81cb93a386Sopenharmony_ciSkAutoAsciiToLC::SkAutoAsciiToLC(const char str[], size_t len) 82cb93a386Sopenharmony_ci{ 83cb93a386Sopenharmony_ci // see if we need to compute the length 84cb93a386Sopenharmony_ci if ((long)len < 0) { 85cb93a386Sopenharmony_ci len = strlen(str); 86cb93a386Sopenharmony_ci } 87cb93a386Sopenharmony_ci fLength = len; 88cb93a386Sopenharmony_ci 89cb93a386Sopenharmony_ci // assign lc to our preallocated storage if len is small enough, or allocate 90cb93a386Sopenharmony_ci // it on the heap 91cb93a386Sopenharmony_ci char* lc; 92cb93a386Sopenharmony_ci if (len <= STORAGE) { 93cb93a386Sopenharmony_ci lc = fStorage; 94cb93a386Sopenharmony_ci } else { 95cb93a386Sopenharmony_ci lc = (char*)sk_malloc_throw(len + 1); 96cb93a386Sopenharmony_ci } 97cb93a386Sopenharmony_ci fLC = lc; 98cb93a386Sopenharmony_ci 99cb93a386Sopenharmony_ci // convert any asii to lower-case. we let non-ascii (utf8) chars pass 100cb93a386Sopenharmony_ci // through unchanged 101cb93a386Sopenharmony_ci for (int i = (int)(len - 1); i >= 0; --i) { 102cb93a386Sopenharmony_ci int c = str[i]; 103cb93a386Sopenharmony_ci if ((c & 0x80) == 0) { // is just ascii 104cb93a386Sopenharmony_ci c = tolower(c); 105cb93a386Sopenharmony_ci } 106cb93a386Sopenharmony_ci lc[i] = c; 107cb93a386Sopenharmony_ci } 108cb93a386Sopenharmony_ci lc[len] = 0; 109cb93a386Sopenharmony_ci} 110cb93a386Sopenharmony_ci 111cb93a386Sopenharmony_ciSkAutoAsciiToLC::~SkAutoAsciiToLC() 112cb93a386Sopenharmony_ci{ 113cb93a386Sopenharmony_ci if (fLC != fStorage) { 114cb93a386Sopenharmony_ci sk_free(fLC); 115cb93a386Sopenharmony_ci } 116cb93a386Sopenharmony_ci} 117