]>
Commit | Line | Data |
---|---|---|
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 | |
27 | extern UINT8 *__wchar_bitmap;\r | |
28 | extern UINTN __wchar_bitmap_size;\r | |
29 | extern 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 | |
39 | wchar_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 | |
49 | static 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 | |
57 | static\r | |
58 | void\r | |
59 | BuildBitmap(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 | |
84 | size_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 | |
113 | wchar_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 | |
137 | wchar_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 | |
154 | size_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 | |
179 | wchar_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 | |
219 | wchar_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 | |
267 | wchar_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 |