]> git.proxmox.com Git - mirror_edk2.git/blame - StdLib/LibC/Wchar/Searching.c
Add device abstraction code for the UEFI Console and UEFI Shell-based file systems.
[mirror_edk2.git] / StdLib / LibC / Wchar / Searching.c
CommitLineData
2aa62f2b 1/** @file\r
2 Search Functions for <wchar.h>.\r
3\r
4 Unless explicitly stated otherwise, the functions defined in this file order\r
5 two wide characters the same way as two integers of the underlying integer\r
6 type designated by wchar_t.\r
7\r
53e1e5c6 8 Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.<BR>\r
2aa62f2b 9 This program and the accompanying materials are licensed and made available under\r
10 the terms and conditions of the BSD License that accompanies this distribution.\r
11 The full text of the license may be found at\r
12 http://opensource.org/licenses/bsd-license.php.\r
13\r
14 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
15 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
16**/\r
17#include <Uefi.h>\r
18#include <Library/BaseLib.h>\r
19#include <Library/BaseMemoryLib.h>\r
20#include <Library/MemoryAllocationLib.h>\r
21\r
22#include <LibConfig.h>\r
23\r
24#include <wchar.h>\r
25\r
26/* Data initialized by the library constructor */\r
27extern UINT8 *__wchar_bitmap;\r
28extern UINTN __wchar_bitmap_size;\r
29extern UINTN __wchar_bitmap_64;\r
30\r
31/** The wcschr function locates the first occurrence of c in the wide string\r
32 pointed to by s. The terminating null wide character is considered to be\r
33 part of the wide string.\r
34\r
35 @return The wcschr function returns a pointer to the located wide\r
36 character, or a null pointer if the wide character does not occur\r
37 in the wide string.\r
38**/\r
39wchar_t *wcschr(const wchar_t *s, wchar_t c)\r
40{\r
41 do {\r
42 if( *s == c) {\r
43 return (wchar_t *)s;\r
44 }\r
45 } while(*s++ != 0);\r
46 return NULL;\r
47}\r
48\r
49static UINT8 BitMask[] = {\r
50 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80\r
51 };\r
52\r
53#define WHICH8(c) ((unsigned short)(c) >> 3)\r
54#define WHICH_BIT(c) (BitMask[((c) & 0x7)])\r
55#define BITMAP64 ((UINT64 *)bitmap)\r
56\r
57static\r
58void\r
59BuildBitmap(unsigned char * bitmap, const wchar_t *s2, UINTN n)\r
60{\r
61 UINT8 bit;\r
62 UINTN index;\r
63\r
64 //// Initialize bitmap. Bit 0 is always 1 which corresponds to '\0'\r
65 //for (BITMAP64[0] = index = 1; index < n; index++)\r
66 // BITMAP64[index] = 0;\r
67 (void)wmemset( (wchar_t *)bitmap, 0, n / sizeof(wchar_t));\r
68 bitmap[0] = 1;\r
69\r
70 // Set bits in bitmap corresponding to the characters in s2\r
71 for (; *s2 != 0; ++s2) {\r
72 index = WHICH8(*s2);\r
73 bit = WHICH_BIT(*s2);\r
74 bitmap[index] |= bit;\r
75 }\r
76}\r
77\r
78/** The wcscspn function computes the length of the maximum initial segment of\r
79 the wide string pointed to by s1 which consists entirely of wide characters\r
80 not from the wide string pointed to by s2.\r
81\r
82 @return The wcscspn function returns the length of the segment.\r
83**/\r
84size_t wcscspn(const wchar_t *s1, const wchar_t *s2)\r
85{\r
86 const wchar_t *str;\r
87 UINT8 bit;\r
88 int index;\r
53e1e5c6 89 size_t s1len;\r
2aa62f2b 90\r
91 if(*s1 == 0) return 0;\r
53e1e5c6 92 s1len = wcslen(s1);\r
2aa62f2b 93\r
94 BuildBitmap( __wchar_bitmap, s2, __wchar_bitmap_size);\r
95\r
53e1e5c6 96 for(str = s1; str < &s1[s1len] ; str++) {\r
2aa62f2b 97 index = WHICH8(*str);\r
98 bit = WHICH_BIT(*str);\r
99 if ((__wchar_bitmap[index] & bit) != 0)\r
100 break;\r
101 }\r
102 return (str - s1);\r
103}\r
104\r
105/** The wcspbrk function locates the first occurrence in the wide string\r
106 pointed to by s1 of any wide character from the wide string\r
107 pointed to by s2.\r
108\r
109 @return The wcspbrk function returns a pointer to the wide character\r
110 in s1, or a null pointer if no wide character from s2 occurs\r
111 in s1.\r
112**/\r
113wchar_t *wcspbrk(const wchar_t *s1, const wchar_t *s2)\r
114{\r
115 UINT8 bit;\r
116 int index;\r
117\r
118 BuildBitmap( __wchar_bitmap, s2, __wchar_bitmap_size);\r
119\r
120 for( ; *s1 != 0; ++s1) {\r
121 index = WHICH8(*s1);\r
122 bit = WHICH_BIT(*s1);\r
123 if( (__wchar_bitmap[index] & bit) != 0) {\r
124 return (wchar_t *)s1;\r
125 }\r
126 }\r
127 return NULL;\r
128}\r
129\r
130/** The wcsrchr function locates the last occurrence of c in the wide string\r
131 pointed to by s. The terminating null wide character is considered to be\r
132 part of the wide string.\r
133\r
134 @return The wcsrchr function returns a pointer to the wide character,\r
135 or a null pointer if c does not occur in the wide string.\r
136**/\r
137wchar_t *wcsrchr(const wchar_t *s, wchar_t c)\r
138{\r
139 wchar_t *found = NULL;\r
140\r
141 do {\r
142 if( *s == c) found = (wchar_t *)s;\r
143 } while( *s++ != 0);\r
144\r
145 return found;\r
146}\r
147\r
148/** The wcsspn function computes the length of the maximum initial segment of\r
149 the wide string pointed to by s1 which consists entirely of wide characters\r
150 from the wide string pointed to by s2.\r
151\r
152 @return The wcsspn function returns the length of the segment.\r
153**/\r
154size_t wcsspn(const wchar_t *s1, const wchar_t *s2)\r
155{\r
156 size_t length = 0;\r
157 int index;\r
158 UINT8 bit;\r
159\r
160 BuildBitmap( __wchar_bitmap, s2, __wchar_bitmap_size);\r
161\r
162 for( ; *s1 != 0; ++s1) {\r
163 index = WHICH8(*s1);\r
164 bit = WHICH_BIT(*s1);\r
165 if( (__wchar_bitmap[index] & bit) == 0) break;\r
166 ++length;\r
167 }\r
168 return length;\r
169}\r
170\r
171/** The wcsstr function locates the first occurrence in the wide string pointed\r
172 to by s1 of the sequence of wide characters (excluding the terminating null\r
173 wide character) in the wide string pointed to by s2.\r
174\r
175 @return The wcsstr function returns a pointer to the located wide string,\r
176 or a null pointer if the wide string is not found. If s2 points\r
177 to a wide string with zero length, the function returns s1.\r
178**/\r
179wchar_t *wcsstr(const wchar_t *s1, const wchar_t *s2)\r
180{\r
181 return (wchar_t *)StrStr( (CONST CHAR16 *)s1, (CONST CHAR16 *)s2);\r
182}\r
183\r
184/** A sequence of calls to the wcstok function breaks the wide string pointed\r
185 to by s1 into a sequence of tokens, each of which is delimited by a wide\r
186 character from the wide string pointed to by s2. The third argument points\r
187 to a caller-provided wchar_t pointer into which the wcstok function stores\r
188 information necessary for it to continue scanning the same wide string.\r
189\r
190 The first call in a sequence has a non-null first argument and stores an\r
191 initial value in the object pointed to by ptr. Subsequent calls in the\r
192 sequence have a null first argument and the object pointed to by ptr is\r
193 required to have the value stored by the previous call in the sequence,\r
194 which is then updated. The separator wide string pointed to by s2 may be\r
195 different from call to call.\r
196\r
197 The first call in the sequence searches the wide string pointed to by s1\r
198 for the first wide character that is not contained in the current separator\r
199 wide string pointed to by s2. If no such wide character is found, then\r
200 there are no tokens in the wide string pointed to by s1 and the wcstok\r
201 function returns a null pointer. If such a wide character is found, it is\r
202 the start of the first token.\r
203\r
204 The wcstok function then searches from there for a wide character that is\r
205 contained in the current separator wide string. If no such wide character\r
206 is found, the current token extends to the end of the wide string pointed\r
207 to by s1, and subsequent searches in the same wide string for a token\r
208 return a null pointer. If such a wide character is found, it is overwritten\r
209 by a null wide character, which terminates the current token.\r
210\r
211 In all cases, the wcstok function stores sufficient information in the\r
212 pointer pointed to by ptr so that subsequent calls, with a null pointer for\r
213 s1 and the unmodified pointer value for ptr, shall start searching just\r
214 past the element overwritten by a null wide character (if any).\r
215\r
216 @return The wcstok function returns a pointer to the first wide character\r
217 of a token, or a null pointer if there is no token.\r
218**/\r
219wchar_t *wcstok(wchar_t * __restrict s1, const wchar_t * __restrict s2, wchar_t ** __restrict ptr)\r
220{\r
221 wchar_t *Token = NULL;\r
222 int index;\r
223 UINT8 bit;\r
224\r
225 if( (s1 == NULL)\r
226 && ((s1 = *ptr) == NULL))\r
227 {\r
228 return NULL;\r
229 }\r
230\r
231 // s2 can be different on each call, so build the bitmap each time.\r
232 BuildBitmap( __wchar_bitmap, s2, __wchar_bitmap_size);\r
233\r
234 // skip leading delimiters: all chars in s2\r
235 for( ; *s1 != 0; ++s1) {\r
236 index = WHICH8(*s1);\r
237 bit = WHICH_BIT(*s1);\r
238 if( (__wchar_bitmap[index] & bit) == 0) break;\r
239 }\r
240 if( *s1 != 0)\r
241 {\r
242 // Remember this point, it is the start of the token\r
243 Token = s1++;\r
244\r
245 // find the next delimiter and replace it with a '\0'\r
246 for( ; *s1 != 0; ++s1) {\r
247 index = WHICH8(*s1);\r
248 bit = WHICH_BIT(*s1);\r
249 if( (__wchar_bitmap[index] & bit) != 0) {\r
250 *s1++ = 0;\r
251 *ptr = s1;\r
252 return Token;\r
253 }\r
254 }\r
255 }\r
256 *ptr = NULL;\r
257 return Token;\r
258}\r
259\r
260/** The wmemchr function locates the first occurrence of c in the initial n\r
261 wide characters of the object pointed to by s.\r
262\r
263 @return The wmemchr function returns a pointer to the located wide\r
264 character, or a null pointer if the wide character does not occur\r
265 in the object.\r
266**/\r
267wchar_t *wmemchr(const wchar_t *s, wchar_t c, size_t n)\r
268{\r
269 return (wchar_t *)ScanMem16( s, (UINTN)(n * sizeof(wchar_t)), (UINT16)c);\r
270}\r