OpenCore  1.0.4
OpenCore Bootloader
Loading...
Searching...
No Matches
OcUnicodeLib.c
Go to the documentation of this file.
1
15#include <Base.h>
16
17#include <Library/BaseLib.h>
18#include <Library/BaseMemoryLib.h>
19#include <Library/BaseOverflowLib.h>
20#include <Library/DebugLib.h>
21#include <Library/OcStringLib.h>
22#include <Library/PrintLib.h>
23#include <Library/PcdLib.h>
24#include <Library/SortLib.h>
25
26INTN
27EFIAPI
29 IN CONST CHAR16 *FirstString,
30 IN CONST CHAR16 *SecondString
31 )
32{
33 CHAR16 UpperFirstString;
34 CHAR16 UpperSecondString;
35
36 //
37 // ASSERT both strings are less long than PcdMaximumUnicodeStringLength
38 //
39 ASSERT (StrSize (FirstString) != 0);
40 ASSERT (StrSize (SecondString) != 0);
41
42 UpperFirstString = CharToUpper (*FirstString);
43 UpperSecondString = CharToUpper (*SecondString);
44 while ((*FirstString != '\0') && (*SecondString != '\0') && (UpperFirstString == UpperSecondString)) {
45 FirstString++;
46 SecondString++;
47 UpperFirstString = CharToUpper (*FirstString);
48 UpperSecondString = CharToUpper (*SecondString);
49 }
50
51 return UpperFirstString - UpperSecondString;
52}
53
54INTN
55EFIAPI
57 IN CONST CHAR16 *FirstString,
58 IN CONST CHAR16 *SecondString,
59 IN UINTN Length
60 )
61{
62 CHAR16 UpperFirstString;
63 CHAR16 UpperSecondString;
64
65 if (Length == 0) {
66 return 0;
67 }
68
69 //
70 // ASSERT both strings are less long than PcdMaximumUnicodeStringLength.
71 // Length tests are performed inside StrLen().
72 //
73 ASSERT (StrSize (FirstString) != 0);
74 ASSERT (StrSize (SecondString) != 0);
75
76 UpperFirstString = CharToUpper (*FirstString);
77 UpperSecondString = CharToUpper (*SecondString);
78 while ((*FirstString != L'\0') &&
79 (*SecondString != L'\0') &&
80 (UpperFirstString == UpperSecondString) &&
81 (Length > 1))
82 {
83 FirstString++;
84 SecondString++;
85 UpperFirstString = CharToUpper (*FirstString);
86 UpperSecondString = CharToUpper (*SecondString);
87 Length--;
88 }
89
90 return UpperFirstString - UpperSecondString;
91}
92
93CHAR16 *
94EFIAPI
96 IN CONST CHAR16 *String,
97 IN CONST CHAR16 *SearchString
98 )
99{
100 CONST CHAR16 *FirstMatch;
101 CONST CHAR16 *SearchStringTmp;
102
103 //
104 // ASSERT both strings are less long than PcdMaximumUnicodeStringLength.
105 // Length tests are performed inside StrLen().
106 //
107 ASSERT (StrSize (String) != 0);
108 ASSERT (StrSize (SearchString) != 0);
109
110 if (*SearchString == L'\0') {
111 return (CHAR16 *)String;
112 }
113
114 while (*String != L'\0') {
115 SearchStringTmp = SearchString;
116 FirstMatch = String;
117
118 while ( (CharToUpper (*String) == CharToUpper (*SearchStringTmp))
119 && (*String != L'\0'))
120 {
121 String++;
122 SearchStringTmp++;
123 }
124
125 if (*SearchStringTmp == L'\0') {
126 return (CHAR16 *)FirstMatch;
127 }
128
129 if (*String == L'\0') {
130 return NULL;
131 }
132
133 String = FirstMatch + 1;
134 }
135
136 return NULL;
137}
138
139CONST CHAR16 *
141 CONST CHAR16 *String,
142 UINTN StringLength,
143 CONST CHAR16 *SearchString,
144 UINTN SearchStringLength
145 )
146{
147 UINTN Index;
148 UINTN Index2;
149 UINTN Index3;
150 INTN CmpResult;
151 CONST CHAR16 *Y;
152 CONST CHAR16 *X;
153
154 //
155 // REF: http://www-igm.univ-mlv.fr/~lecroq/string/node13.html#SECTION00130
156 //
157
158 if ( (SearchStringLength > StringLength)
159 || (SearchStringLength == 0)
160 || (StringLength == 0))
161 {
162 return NULL;
163 }
164
165 if (SearchStringLength > 1) {
166 Index = 0;
167
168 Y = (CONST CHAR16 *)String;
169 X = (CONST CHAR16 *)SearchString;
170
171 if (X[0] == X[1]) {
172 Index2 = 2;
173 Index3 = 1;
174 } else {
175 Index2 = 1;
176 Index3 = 2;
177 }
178
179 while (Index <= StringLength - SearchStringLength) {
180 if (X[1] != Y[Index+1]) {
181 Index += Index2;
182 } else {
183 CmpResult = CompareMem (X+2, Y+Index+2, (SearchStringLength - 2) * sizeof (*SearchString));
184 if ((CmpResult == 0) && (X[0] == Y[Index])) {
185 return &Y[Index];
186 }
187
188 Index += Index3;
189 }
190 }
191 } else {
192 return ScanMem16 (String, StringLength * sizeof (*SearchString), *SearchString);
193 }
194
195 return NULL;
196}
197
198CHAR16 *
199EFIAPI
201 IN CONST CHAR16 *String,
202 IN CHAR16 Char
203 )
204{
205 ASSERT (StrSize (String) != 0);
206
207 while (*String != '\0') {
208 //
209 // Return immediately when matching first occurrence of Char.
210 //
211 if (*String == Char) {
212 return (CHAR16 *)String;
213 }
214
215 ++String;
216 }
217
218 return NULL;
219}
220
221CHAR16 *
222EFIAPI
224 IN CONST CHAR16 *String,
225 IN CHAR16 Char
226 )
227{
228 CHAR16 *Save;
229
230 ASSERT (StrSize (String) != 0);
231
232 Save = NULL;
233
234 while (*String != '\0') {
235 //
236 // Record the last occurrence of Char.
237 //
238 if (*String == Char) {
239 Save = (CHAR16 *)String;
240 }
241
242 ++String;
243 }
244
245 return Save;
246}
247
248VOID
250 IN OUT CHAR16 *String
251 )
252{
253 CHAR16 *Needle;
254
255 Needle = String;
256 while ((Needle = StrStr (Needle, L"/")) != NULL) {
257 *Needle++ = L'\\';
258 }
259}
260
261BOOLEAN
263 IN OUT CHAR16 *String
264 )
265{
266 UINTN Length;
267
268 Length = StrLen (String);
269
270 //
271 // Drop starting slash (as it cannot be passed to some drivers).
272 //
273 if ((String[0] == '\\') || (String[0] == '/')) {
274 CopyMem (&String[0], &String[1], Length * sizeof (String[0]));
275 --Length;
276 }
277
278 //
279 // Empty paths have no root directory.
280 //
281 if (Length == 0) {
282 return FALSE;
283 }
284
285 //
286 // Drop trailing slash when getting a directory.
287 //
288 if ((String[Length - 1] == '\\') || (String[Length - 1] == '/')) {
289 --Length;
290 //
291 // Paths with just one slash have no root directory (e.g. \\/).
292 //
293 if (Length == 0) {
294 return FALSE;
295 }
296 }
297
298 //
299 // Find slash in the path.
300 //
301 while (String[Length - 1] != '\\' && String[Length - 1] != '/') {
302 --Length;
303
304 //
305 // Paths containing just a filename get normalised.
306 //
307 if (Length == 0) {
308 *String = '\0';
309 return TRUE;
310 }
311 }
312
313 //
314 // Path containing some other directory get its path.
315 //
316 String[Length - 1] = '\0';
317 return TRUE;
318}
319
320VOID
322 IN OUT CHAR16 *String,
323 IN BOOLEAN SingleLine
324 )
325{
326 while (*String != L'\0') {
327 if ((*String & 0x7FU) != *String) {
328 //
329 // Remove all unicode characters.
330 //
331 *String = L'_';
332 } else if (SingleLine && ((*String == L'\r') || (*String == L'\n'))) {
333 //
334 // Stop after printing one line.
335 //
336 *String = L'\0';
337 break;
338 } else if ((*String < 0x20) || (*String == 0x7F)) {
339 //
340 // Drop all unprintable spaces but space including tabs.
341 //
342 *String = L'_';
343 }
344
345 ++String;
346 }
347}
348
349BOOLEAN
351 IN CONST CHAR16 *String,
352 IN BOOLEAN SingleLine
353 )
354{
355 while (*String != L'\0') {
356 if ((*String & 0x7FU) != *String) {
357 return FALSE;
358 }
359
360 if (SingleLine && ((*String == L'\r') || (*String == L'\n'))) {
361 return FALSE;
362 }
363
364 if ((*String < 0x20) || (*String == 0x7F)) {
365 return FALSE;
366 }
367
368 ++String;
369 }
370
371 return TRUE;
372}
373
374EFI_STATUS
375EFIAPI
377 OUT CHAR16 *StartOfBuffer,
378 IN UINTN BufferSize,
379 IN CONST CHAR16 *FormatString,
380 ...
381 )
382{
383 EFI_STATUS Status;
384 VA_LIST Marker;
385 VA_LIST Marker2;
386 UINTN NumberOfPrinted;
387
388 ASSERT (StartOfBuffer != NULL);
389 ASSERT (BufferSize > 0);
390 ASSERT (FormatString != NULL);
391
392 VA_START (Marker, FormatString);
393
394 VA_COPY (Marker2, Marker);
395 NumberOfPrinted = SPrintLength (FormatString, Marker2);
396 VA_END (Marker2);
397
398 if (BufferSize - 1 >= NumberOfPrinted) {
399 UnicodeVSPrint (StartOfBuffer, BufferSize, FormatString, Marker);
400 Status = EFI_SUCCESS;
401 } else {
402 Status = EFI_OUT_OF_RESOURCES;
403 }
404
405 VA_END (Marker);
406
407 return Status;
408}
409
410BOOLEAN
411EFIAPI
413 IN CONST CHAR16 *String,
414 IN CONST CHAR16 *SearchString,
415 IN BOOLEAN CaseInsensitiveMatch
416 )
417{
418 UINTN StringLength;
419 UINTN SearchStringLength;
420
421 ASSERT (String != NULL);
422 ASSERT (SearchString != NULL);
423
424 StringLength = StrLen (String);
425 SearchStringLength = StrLen (SearchString);
426
427 if (CaseInsensitiveMatch) {
428 return StringLength >= SearchStringLength
429 && OcStrniCmp (&String[StringLength - SearchStringLength], SearchString, SearchStringLength) == 0;
430 }
431
432 return StringLength >= SearchStringLength
433 && StrnCmp (&String[StringLength - SearchStringLength], SearchString, SearchStringLength) == 0;
434}
435
436BOOLEAN
437EFIAPI
439 IN CONST CHAR16 *String,
440 IN CONST CHAR16 *SearchString,
441 IN BOOLEAN CaseInsensitiveMatch
442 )
443{
444 CHAR16 First;
445 CHAR16 Second;
446
447 ASSERT (String != NULL);
448 ASSERT (SearchString != NULL);
449
450 while (TRUE) {
451 First = *String++;
452 Second = *SearchString++;
453 if (Second == '\0') {
454 return TRUE;
455 }
456
457 if (First == '\0') {
458 return FALSE;
459 }
460
461 if (CaseInsensitiveMatch) {
462 First = CharToUpper (First);
463 Second = CharToUpper (Second);
464 }
465
466 if (First != Second) {
467 return FALSE;
468 }
469 }
470}
471
472BOOLEAN
474 IN CONST CHAR16 *String
475 )
476{
477 UINTN Length;
478 UINTN Index;
479 UINTN GuidLength = GUID_STRING_LENGTH;
480
481 Length = StrLen (String);
482 if (Length < GuidLength) {
483 return FALSE;
484 }
485
486 for (Index = 0; Index < GuidLength; ++Index) {
487 if ((Index == 8) || (Index == 13) || (Index == 18) || (Index == 23)) {
488 if (String[Index] != '-') {
489 return FALSE;
490 }
491 } else if ( !((String[Index] >= L'0') && (String[Index] <= L'9'))
492 && !((String[Index] >= L'A') && (String[Index] <= L'F'))
493 && !((String[Index] >= L'a') && (String[Index] <= L'f')))
494 {
495 return FALSE;
496 }
497 }
498
499 return TRUE;
500}
501
502INTN
504 IN CONST CHAR16 *FirstString,
505 IN CONST CHAR8 *SecondString
506 )
507{
508 while (*FirstString != '\0' && *FirstString == *SecondString) {
509 ++FirstString;
510 ++SecondString;
511 }
512
513 return *FirstString - *SecondString;
514}
515
516INTN
517EFIAPI
519 IN CONST VOID *Buffer1,
520 IN CONST VOID *Buffer2
521 )
522{
523 return -StringCompare (Buffer1, Buffer2);
524}
525
526BOOLEAN
528 CHAR16 Ch
529 )
530{
531 return (Ch == L' ') || (Ch == L'\t') || (Ch == L'\r') || (Ch == L'\n') || (Ch == L'\v') || (Ch == L'\f');
532}
533
534BOOLEAN
536 CHAR16 Ch
537 )
538{
539 return (Ch == CHAR_NULL) || OcIsSpace (Ch);
540}
UINT64 Length
INTN MixedStrCmp(IN CONST CHAR16 *FirstString, IN CONST CHAR8 *SecondString)
CHAR16 *EFIAPI OcStrChr(IN CONST CHAR16 *String, IN CHAR16 Char)
CHAR16 *EFIAPI OcStrrChr(IN CONST CHAR16 *String, IN CHAR16 Char)
INTN EFIAPI OcStrniCmp(IN CONST CHAR16 *FirstString, IN CONST CHAR16 *SecondString, IN UINTN Length)
BOOLEAN UnicodeIsFilteredString(IN CONST CHAR16 *String, IN BOOLEAN SingleLine)
VOID UnicodeUefiSlashes(IN OUT CHAR16 *String)
BOOLEAN OcIsSpace(CHAR16 Ch)
BOOLEAN HasValidGuidStringPrefix(IN CONST CHAR16 *String)
CHAR16 *EFIAPI OcStriStr(IN CONST CHAR16 *String, IN CONST CHAR16 *SearchString)
INTN EFIAPI OcStriCmp(IN CONST CHAR16 *FirstString, IN CONST CHAR16 *SecondString)
BOOLEAN UnicodeGetParentDirectory(IN OUT CHAR16 *String)
INTN EFIAPI OcReverseStringCompare(IN CONST VOID *Buffer1, IN CONST VOID *Buffer2)
EFI_STATUS EFIAPI OcUnicodeSafeSPrint(OUT CHAR16 *StartOfBuffer, IN UINTN BufferSize, IN CONST CHAR16 *FormatString,...)
VOID UnicodeFilterString(IN OUT CHAR16 *String, IN BOOLEAN SingleLine)
CONST CHAR16 * OcStrStrLength(CONST CHAR16 *String, UINTN StringLength, CONST CHAR16 *SearchString, UINTN SearchStringLength)
BOOLEAN EFIAPI OcUnicodeStartsWith(IN CONST CHAR16 *String, IN CONST CHAR16 *SearchString, IN BOOLEAN CaseInsensitiveMatch)
BOOLEAN EFIAPI OcUnicodeEndsWith(IN CONST CHAR16 *String, IN CONST CHAR16 *SearchString, IN BOOLEAN CaseInsensitiveMatch)
BOOLEAN OcIsSpaceOrNull(CHAR16 Ch)
VOID *EFIAPI ScanMem16(IN CONST VOID *Buffer, IN UINTN Length, IN UINT16 Value)
INTN EFIAPI CompareMem(IN CONST VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
#define ASSERT(x)
Definition coder.h:55