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