1 :
2 : /*
3 : * Copyright 2006 The Android Open Source Project
4 : *
5 : * Use of this source code is governed by a BSD-style license that can be
6 : * found in the LICENSE file.
7 : */
8 :
9 :
10 : #ifndef SkTSearch_DEFINED
11 : #define SkTSearch_DEFINED
12 :
13 : #include "SkTypes.h"
14 :
15 : template <typename T>
16 0 : int SkTSearch(const T* base, int count, const T& target, size_t elemSize)
17 : {
18 0 : SkASSERT(count >= 0);
19 0 : if (count <= 0)
20 0 : return ~0;
21 :
22 0 : SkASSERT(base != NULL); // base may be NULL if count is zero
23 :
24 0 : int lo = 0;
25 0 : int hi = count - 1;
26 :
27 0 : while (lo < hi)
28 : {
29 0 : int mid = (hi + lo) >> 1;
30 0 : const T* elem = (const T*)((const char*)base + mid * elemSize);
31 :
32 0 : if (*elem < target)
33 0 : lo = mid + 1;
34 : else
35 0 : hi = mid;
36 : }
37 :
38 0 : const T* elem = (const T*)((const char*)base + hi * elemSize);
39 0 : if (*elem != target)
40 : {
41 0 : if (*elem < target)
42 0 : hi += 1;
43 0 : hi = ~hi;
44 : }
45 0 : return hi;
46 : }
47 :
48 : template <typename T>
49 0 : int SkTSearch(const T* base, int count, const T& target, size_t elemSize,
50 : int (*compare)(const T&, const T&))
51 : {
52 0 : SkASSERT(count >= 0);
53 0 : if (count <= 0) {
54 0 : return ~0;
55 : }
56 :
57 0 : SkASSERT(base != NULL); // base may be NULL if count is zero
58 :
59 0 : int lo = 0;
60 0 : int hi = count - 1;
61 :
62 0 : while (lo < hi) {
63 0 : int mid = (hi + lo) >> 1;
64 0 : const T* elem = (const T*)((const char*)base + mid * elemSize);
65 :
66 0 : if ((*compare)(*elem, target) < 0)
67 0 : lo = mid + 1;
68 : else
69 0 : hi = mid;
70 : }
71 :
72 0 : const T* elem = (const T*)((const char*)base + hi * elemSize);
73 0 : int pred = (*compare)(*elem, target);
74 0 : if (pred != 0) {
75 0 : if (pred < 0)
76 0 : hi += 1;
77 0 : hi = ~hi;
78 : }
79 0 : return hi;
80 : }
81 :
82 : template <typename T>
83 0 : int SkTSearch(const T** base, int count, const T* target, size_t elemSize,
84 : int (*compare)(const T*, const T*))
85 : {
86 0 : SkASSERT(count >= 0);
87 0 : if (count <= 0)
88 0 : return ~0;
89 :
90 0 : SkASSERT(base != NULL); // base may be NULL if count is zero
91 :
92 0 : int lo = 0;
93 0 : int hi = count - 1;
94 :
95 0 : while (lo < hi)
96 : {
97 0 : int mid = (hi + lo) >> 1;
98 0 : const T* elem = *(const T**)((const char*)base + mid * elemSize);
99 :
100 0 : if ((*compare)(elem, target) < 0)
101 0 : lo = mid + 1;
102 : else
103 0 : hi = mid;
104 : }
105 :
106 0 : const T* elem = *(const T**)((const char*)base + hi * elemSize);
107 0 : int pred = (*compare)(elem, target);
108 0 : if (pred != 0)
109 : {
110 0 : if (pred < 0)
111 0 : hi += 1;
112 0 : hi = ~hi;
113 : }
114 0 : return hi;
115 : }
116 :
117 : int SkStrSearch(const char*const* base, int count, const char target[],
118 : size_t target_len, size_t elemSize);
119 : int SkStrSearch(const char*const* base, int count, const char target[],
120 : size_t elemSize);
121 :
122 : /** Like SkStrSearch, but treats target as if it were all lower-case. Assumes that
123 : base points to a table of lower-case strings.
124 : */
125 : int SkStrLCSearch(const char*const* base, int count, const char target[],
126 : size_t target_len, size_t elemSize);
127 : int SkStrLCSearch(const char*const* base, int count, const char target[],
128 : size_t elemSize);
129 :
130 : /** Helper class to convert a string to lower-case, but only modifying the ascii
131 : characters. This makes the routine very fast and never changes the string
132 : length, but it is not suitable for linguistic purposes. Normally this is
133 : used for buiding and searching string tables.
134 : */
135 : class SkAutoAsciiToLC {
136 : public:
137 : SkAutoAsciiToLC(const char str[], size_t len = (size_t)-1);
138 : ~SkAutoAsciiToLC();
139 :
140 0 : const char* lc() const { return fLC; }
141 : size_t length() const { return fLength; }
142 :
143 : private:
144 : char* fLC; // points to either the heap or fStorage
145 : size_t fLength;
146 : enum {
147 : STORAGE = 64
148 : };
149 : char fStorage[STORAGE+1];
150 : };
151 :
152 : extern "C" {
153 : typedef int (*SkQSortCompareProc)(const void*, const void*);
154 : void SkQSort(void* base, size_t count, size_t elemSize, SkQSortCompareProc);
155 : }
156 :
157 : #endif
158 :
|