]> git.proxmox.com Git - mirror_edk2.git/blame - MdePkg/Library/BaseLib/String.c
Update MDE and EdkModule packages for ICC build with /W4 /WX /Ox switches, for some...
[mirror_edk2.git] / MdePkg / Library / BaseLib / String.c
CommitLineData
d958721a 1/** @file
2 Unicode and ASCII string primatives.
3
4 Copyright (c) 2006 - 2007, Intel Corporation<BR>
5 All rights reserved. This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
9
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12
13 Module Name: String.c
14
15**/
16
17#include "BaseLibInternals.h"
18
19/**
20 Copies one Null-terminated Unicode string to another Null-terminated Unicode
21 string and returns the new Unicode string.
22
23 This function copies the contents of the Unicode string Source to the Unicode
24 string Destination, and returns Destination. If Source and Destination
25 overlap, then the results are undefined.
26
27 If Destination is NULL, then ASSERT().
28 If Source is NULL, then ASSERT().
29 If Source and Destination overlap, then ASSERT().
30 If PcdMaximumUnicodeStringLength is not zero, and Source contains more than
31 PcdMaximumUnicodeStringLength Unicode characters not including the
32 Null-terminator, then ASSERT().
33
34 @param Destination Pointer to a Null-terminated Unicode string.
35 @param Source Pointer to a Null-terminated Unicode string.
36
37 @return Destiantion
38
39**/
40CHAR16 *
41EFIAPI
42StrCpy (
43 OUT CHAR16 *Destination,
44 IN CONST CHAR16 *Source
45 )
46{
47 CHAR16 *ReturnValue;
48
49 //
50 // Destination cannot be NULL
51 //
52 ASSERT (Destination != NULL);
53
54 //
55 // Destination and source cannot overlap
56 //
57 ASSERT ((UINTN)(Destination - Source) > StrLen (Source));
58 ASSERT ((UINTN)(Source - Destination) > StrLen (Source));
59
60 ReturnValue = Destination;
61 while (*Source) {
62 *(Destination++) = *(Source++);
63 }
64 *Destination = 0;
65 return ReturnValue;
66}
67
68/**
69 Copies one Null-terminated Unicode string with a maximum length to another
70 Null-terminated Unicode string with a maximum length and returns the new
71 Unicode string.
72
73 This function copies the contents of the Unicode string Source to the Unicode
74 string Destination, and returns Destination. At most, Length Unicode
75 characters are copied from Source to Destination. If Length is 0, then
76 Destination is returned unmodified. If Length is greater that the number of
77 Unicode characters in Source, then Destination is padded with Null Unicode
78 characters. If Source and Destination overlap, then the results are
79 undefined.
80
81 If Destination is NULL, then ASSERT().
82 If Source is NULL, then ASSERT().
83 If Source and Destination overlap, then ASSERT().
84 If PcdMaximumUnicodeStringLength is not zero, and Source contains more than
85 PcdMaximumUnicodeStringLength Unicode characters not including the
86 Null-terminator, then ASSERT().
87
88 @param Destination Pointer to a Null-terminated Unicode string.
89 @param Source Pointer to a Null-terminated Unicode string.
90 @param Length Maximum number of Unicode characters to copy.
91
92 @return Destination
93
94**/
95CHAR16 *
96EFIAPI
97StrnCpy (
98 OUT CHAR16 *Destination,
99 IN CONST CHAR16 *Source,
100 IN UINTN Length
101 )
102{
103 CHAR16 *ReturnValue;
104
105 if (Length == 0) {
106 return Destination;
107 }
108
109 //
110 // Destination cannot be NULL if Length is not zero
111 //
112 ASSERT (Destination != NULL);
113
114 //
115 // Destination and source cannot overlap
116 // Q: Does Source have to be NULL-terminated?
117 //
118 ASSERT ((UINTN)(Destination - Source) > StrLen (Source));
119 ASSERT ((UINTN)(Source - Destination) >= Length);
120
121 ReturnValue = Destination;
122
123 while ((*Source != L'\0') && (Length > 0)) {
124 *(Destination++) = *(Source++);
125 Length--;
126 }
127
128 ZeroMem (Destination, Length * sizeof (*Destination));
129 return ReturnValue;
130}
131
132/**
133 Returns the length of a Null-terminated Unicode string.
134
135 This function returns the number of Unicode characters in the Null-terminated
136 Unicode string specified by String.
137
138 If String is NULL, then ASSERT().
139 If PcdMaximumUnicodeStringLength is not zero, and String contains more than
140 PcdMaximumUnicodeStringLength Unicode characters not including the
141 Null-terminator, then ASSERT().
142
143 @param String Pointer to a Null-terminated Unicode string.
144
145 @return The length of String.
146
147**/
148UINTN
149EFIAPI
150StrLen (
151 IN CONST CHAR16 *String
152 )
153{
154 UINTN Length;
155
156 ASSERT (String != NULL);
157
158 for (Length = 0; *String != L'\0'; String++, Length++) {
159 //
160 // If PcdMaximumUnicodeStringLength is not zero,
161 // length should not more than PcdMaximumUnicodeStringLength
162 //
163 if (PcdGet32 (PcdMaximumUnicodeStringLength) != 0) {
164 ASSERT (Length < PcdGet32 (PcdMaximumUnicodeStringLength));
165 }
166 }
167 return Length;
168}
169
170/**
171 Returns the size of a Null-terminated Unicode string in bytes, including the
172 Null terminator.
173
174 This function returns the size, in bytes, of the Null-terminated Unicode
175 string specified by String.
176
177 If String is NULL, then ASSERT().
178 If PcdMaximumUnicodeStringLength is not zero, and String contains more than
179 PcdMaximumUnicodeStringLength Unicode characters not including the
180 Null-terminator, then ASSERT().
181
182 @param String Pointer to a Null-terminated Unicode string.
183
184 @return The size of String.
185
186**/
187UINTN
188EFIAPI
189StrSize (
190 IN CONST CHAR16 *String
191 )
192{
193 return (StrLen (String) + 1) * sizeof (*String);
194}
195
196/**
197 Compares two Null-terminated Unicode strings, and returns the difference
198 between the first mismatched Unicode characters.
199
200 This function compares the Null-terminated Unicode string FirstString to the
201 Null-terminated Unicode string SecondString. If FirstString is identical to
202 SecondString, then 0 is returned. Otherwise, the value returned is the first
203 mismatched Unicode character in SecondString subtracted from the first
204 mismatched Unicode character in FirstString.
205
206 If FirstString is NULL, then ASSERT().
207 If SecondString is NULL, then ASSERT().
208 If PcdMaximumUnicodeStringLength is not zero, and FirstString contains more
209 than PcdMaximumUnicodeStringLength Unicode characters not including the
210 Null-terminator, then ASSERT().
211 If PcdMaximumUnicodeStringLength is not zero, and SecondString contains more
212 than PcdMaximumUnicodeStringLength Unicode characters not including the
213 Null-terminator, then ASSERT().
214
215 @param FirstString Pointer to a Null-terminated Unicode string.
216 @param SecondString Pointer to a Null-terminated Unicode string.
217
218 @retval 0 FirstString is identical to SecondString.
219 @retval !=0 FirstString is not identical to SecondString.
220
221**/
222INTN
223EFIAPI
224StrCmp (
225 IN CONST CHAR16 *FirstString,
226 IN CONST CHAR16 *SecondString
227 )
228{
229 //
230 // ASSERT both strings are less long than PcdMaximumUnicodeStringLength
231 //
232 ASSERT (StrSize (FirstString) != 0);
233 ASSERT (StrSize (SecondString) != 0);
234
235 while ((*FirstString != L'\0') && (*FirstString == *SecondString)) {
236 FirstString++;
237 SecondString++;
238 }
239 return *FirstString - *SecondString;
240}
241
242/**
243 Compares two Null-terminated Unicode strings with maximum lengths, and
244 returns the difference between the first mismatched Unicode characters.
245
246 This function compares the Null-terminated Unicode string FirstString to the
247 Null-terminated Unicode string SecondString. At most, Length Unicode
248 characters will be compared. If Length is 0, then 0 is returned. If
249 FirstString is identical to SecondString, then 0 is returned. Otherwise, the
250 value returned is the first mismatched Unicode character in SecondString
251 subtracted from the first mismatched Unicode character in FirstString.
252
253 If FirstString is NULL, then ASSERT().
254 If SecondString is NULL, then ASSERT().
255 If PcdMaximumUnicodeStringLength is not zero, and FirstString contains more
256 than PcdMaximumUnicodeStringLength Unicode characters not including the
257 Null-terminator, then ASSERT().
258 If PcdMaximumUnicodeStringLength is not zero, and SecondString contains more
259 than PcdMaximumUnicodeStringLength Unicode characters not including the
260 Null-terminator, then ASSERT().
261
262 @param FirstString Pointer to a Null-terminated Unicode string.
263 @param SecondString Pointer to a Null-terminated Unicode string.
264 @param Length Maximum number of Unicode characters to compare.
265
266 @retval 0 FirstString is identical to SecondString.
267 @retval !=0 FirstString is not identical to SecondString.
268
269**/
270INTN
271EFIAPI
272StrnCmp (
273 IN CONST CHAR16 *FirstString,
274 IN CONST CHAR16 *SecondString,
275 IN UINTN Length
276 )
277{
278 if (Length == 0) {
279 return 0;
280 }
281
282 //
283 // ASSERT both strings are less long than PcdMaximumUnicodeStringLength.
284 // Length tests are performed inside StrLen().
285 //
286 ASSERT (StrSize (FirstString) != 0);
287 ASSERT (StrSize (SecondString) != 0);
288
289 while ((*FirstString != L'\0') &&
290 (*FirstString == *SecondString) &&
291 (Length > 1)) {
292 FirstString++;
293 SecondString++;
294 Length--;
295 }
296
297 return *FirstString - *SecondString;
298}
299
300/**
301 Concatenates one Null-terminated Unicode string to another Null-terminated
302 Unicode string, and returns the concatenated Unicode string.
303
304 This function concatenates two Null-terminated Unicode strings. The contents
305 of Null-terminated Unicode string Source are concatenated to the end of
306 Null-terminated Unicode string Destination. The Null-terminated concatenated
307 Unicode String is returned. If Source and Destination overlap, then the
308 results are undefined.
309
310 If Destination is NULL, then ASSERT().
311 If Source is NULL, then ASSERT().
312 If Source and Destination overlap, then ASSERT().
313 If PcdMaximumUnicodeStringLength is not zero, and Destination contains more
314 than PcdMaximumUnicodeStringLength Unicode characters not including the
315 Null-terminator, then ASSERT().
316 If PcdMaximumUnicodeStringLength is not zero, and Source contains more than
317 PcdMaximumUnicodeStringLength Unicode characters not including the
318 Null-terminator, then ASSERT().
319 If PcdMaximumUnicodeStringLength is not zero, and concatenating Destination
320 and Source results in a Unicode string with more than
321 PcdMaximumUnicodeStringLength Unicode characters not including the
322 Null-terminator, then ASSERT().
323
324 @param Destination Pointer to a Null-terminated Unicode string.
325 @param Source Pointer to a Null-terminated Unicode string.
326
327 @return Destination
328
329**/
330CHAR16 *
331EFIAPI
332StrCat (
333 IN OUT CHAR16 *Destination,
334 IN CONST CHAR16 *Source
335 )
336{
337 StrCpy (Destination + StrLen (Destination), Source);
338
339 //
340 // Size of the resulting string should never be zero.
341 // PcdMaximumUnicodeStringLength is tested inside StrLen().
342 //
343 ASSERT (StrSize (Destination) != 0);
344 return Destination;
345}
346
347/**
348 Concatenates one Null-terminated Unicode string with a maximum length to the
349 end of another Null-terminated Unicode string, and returns the concatenated
350 Unicode string.
351
352 This function concatenates two Null-terminated Unicode strings. The contents
353 of Null-terminated Unicode string Source are concatenated to the end of
354 Null-terminated Unicode string Destination, and Destination is returned. At
355 most, Length Unicode characters are concatenated from Source to the end of
356 Destination, and Destination is always Null-terminated. If Length is 0, then
357 Destination is returned unmodified. If Source and Destination overlap, then
358 the results are undefined.
359
360 If Destination is NULL, then ASSERT().
361 If Source is NULL, then ASSERT().
362 If Source and Destination overlap, then ASSERT().
363 If PcdMaximumUnicodeStringLength is not zero, and Destination contains more
364 than PcdMaximumUnicodeStringLength Unicode characters not including the
365 Null-terminator, then ASSERT().
366 If PcdMaximumUnicodeStringLength is not zero, and Source contains more than
367 PcdMaximumUnicodeStringLength Unicode characters not including the
368 Null-terminator, then ASSERT().
369 If PcdMaximumUnicodeStringLength is not zero, and concatenating Destination
370 and Source results in a Unicode string with more than
371 PcdMaximumUnicodeStringLength Unicode characters not including the
372 Null-terminator, then ASSERT().
373
374 @param Destination Pointer to a Null-terminated Unicode string.
375 @param Source Pointer to a Null-terminated Unicode string.
376 @param Length Maximum number of Unicode characters to concatenate from
377 Source.
378
379 @return Destination
380
381**/
382CHAR16 *
383EFIAPI
384StrnCat (
385 IN OUT CHAR16 *Destination,
386 IN CONST CHAR16 *Source,
387 IN UINTN Length
388 )
389{
390 StrnCpy (Destination + StrLen (Destination), Source, Length);
391
392 //
393 // Size of the resulting string should never be zero.
394 // PcdMaximumUnicodeStringLength is tested inside StrLen().
395 //
396 ASSERT (StrSize (Destination) != 0);
397 return Destination;
398}
399
400/**
401 Returns the first occurance of a Null-terminated Unicode sub-string
402 in a Null-terminated Unicode string.
403
404 This function scans the contents of the Null-terminated Unicode string
405 specified by String and returns the first occurrence of SearchString.
406 If SearchString is not found in String, then NULL is returned. If
407 the length of SearchString is zero, then String is
408 returned.
409
410 If String is NULL, then ASSERT().
411 If String is not aligned on a 16-bit boundary, then ASSERT().
412 If SearchString is NULL, then ASSERT().
413 If SearchString is not aligned on a 16-bit boundary, then ASSERT().
414
415 If PcdMaximumUnicodeStringLength is not zero, and SearchString
416 or String contains more than PcdMaximumUnicodeStringLength Unicode
417 characters not including the Null-terminator, then ASSERT().
418
419 @param String Pointer to a Null-terminated Unicode string.
420 @param SearchString Pointer to a Null-terminated Unicode string to search for.
421
422 @retval NULL If the SearchString does not appear in String.
423 @retval !NULL If there is a match.
424
425**/
426CHAR16 *
427EFIAPI
428StrStr (
429 IN CONST CHAR16 *String,
430 IN CONST CHAR16 *SearchString
431 )
432{
433 CONST CHAR16 *FirstMatch;
434 CONST CHAR16 *SearchStringTmp;
435
436 ASSERT (String != NULL);
437 ASSERT (((UINTN) String & 0x01) == 0);
438 ASSERT (SearchString != NULL);
439 ASSERT (((UINTN) SearchString & 0x01) == 0);
440
441 //
442 // If PcdMaximumUnicodeStringLength is not zero,
443 // length of String should not more than PcdMaximumUnicodeStringLength
444 //
445 if (PcdGet32 (PcdMaximumUnicodeStringLength) != 0) {
446 ASSERT (StrLen (String) < PcdGet32 (PcdMaximumUnicodeStringLength));
447 }
448
449 //
450 // If PcdMaximumUnicodeStringLength is not zero,
451 // length of SearchString should not more than PcdMaximumUnicodeStringLength
452 //
453 if (PcdGet32 (PcdMaximumUnicodeStringLength) != 0) {
454 ASSERT (StrLen (SearchString) < PcdGet32 (PcdMaximumAsciiStringLength));
455 }
456
457 while (*String != '\0') {
458 SearchStringTmp = SearchString;
459 FirstMatch = String;
460
461 while ((*String == *SearchStringTmp)
462 && (*SearchStringTmp != '\0')
463 && (*String != '\0')) {
464 String++;
465 SearchStringTmp++;
466 }
467
468 if (*SearchStringTmp == '\0') {
469 return (CHAR16 *) FirstMatch;
470 }
471
472 if (SearchStringTmp == SearchString) {
473 //
474 // If no character from SearchString match,
475 // move the pointer to the String under search
476 // by one character.
477 //
478 String++;
479 }
480 }
481
482 return NULL;
483}
484
485/**
486 Check if a Unicode character is a decimal character.
487
488 This internal function checks if a Unicode character is a
489 decimal character. The valid decimal character is from
490 L'0' to L'9'.
491
492
493 @param Char The character to check against.
494
495 @retval TRUE If the Char is a decmial character.
496 @retval FALSE Otherwise.
497
498**/
499STATIC
500BOOLEAN
501InternalIsDecimalDigitCharacter (
502 IN CHAR16 Char
503 )
504{
505 return (BOOLEAN) (Char >= L'0' && Char <= L'9');
506}
507
508/**
509 Convert a Unicode character to upper case only if
510 it maps to a valid small-case ASCII character.
511
512 This internal function only deal with Unicode character
513 which maps to a valid small-case ASII character, i.e.
514 L'a' to L'z'. For other Unicode character, the input character
515 is returned directly.
516
517
518 @param Char The character to convert.
519
520 @retval LowerCharacter If the Char is with range L'a' to L'z'.
521 @retval Unchanged Otherwise.
522
523**/
524STATIC
525CHAR16
526InternalCharToUpper (
527 IN CHAR16 Char
528 )
529{
530 if (Char >= L'a' && Char <= L'z') {
15f83a88 531 return (CHAR16) (Char - (L'a' - L'A'));
d958721a 532 }
533
534 return Char;
535}
536
537/**
538 Convert a Unicode character to numerical value.
539
540 This internal function only deal with Unicode character
541 which maps to a valid hexadecimal ASII character, i.e.
542 L'0' to L'9', L'a' to L'f' or L'A' to L'F'. For other
543 Unicode character, the value returned does not make sense.
544
545 @param Char The character to convert.
546
547 @retval UINTN The numerical value converted.
548
549**/
550STATIC
551UINTN
552InternalHexCharToUintn (
553 IN CHAR16 Char
554 )
555{
556 if (InternalIsDecimalDigitCharacter (Char)) {
557 return Char - L'0';
558 }
559
560 return (UINTN) (10 + InternalCharToUpper (Char) - L'A');
561}
562
563/**
564 Check if a Unicode character is a hexadecimal character.
565
566 This internal function checks if a Unicode character is a
567 decimal character. The valid hexadecimal character is
568 L'0' to L'9', L'a' to L'f', or L'A' to L'F'.
569
570
571 @param Char The character to check against.
572
573 @retval TRUE If the Char is a hexadecmial character.
574 @retval FALSE Otherwise.
575
576**/
577STATIC
578BOOLEAN
579InternalIsHexaDecimalDigitCharacter (
580 IN CHAR16 Char
581 )
582{
583
584 return (BOOLEAN) (InternalIsDecimalDigitCharacter (Char) ||
585 (Char >= L'A' && Char <= L'F') ||
586 (Char >= L'a' && Char <= L'f'));
587}
588
589/**
590 Convert a Null-terminated Unicode decimal string to a value of
591 type UINTN.
592
593 This function returns a value of type UINTN by interpreting the contents
594 of the Unicode string specified by String as a decimal number. The format
595 of the input Unicode string String is:
596
597 [spaces] [decimal digits].
598
599 The valid decimal digit character is in the range [0-9]. The
600 function will ignore the pad space, which includes spaces or
601 tab characters, before [decimal digits]. The running zero in the
602 beginning of [decimal digits] will be ignored. Then, the function
603 stops at the first character that is a not a valid decimal character
604 or a Null-terminator, whichever one comes first.
605
606 If String is NULL, then ASSERT().
607 If String is not aligned in a 16-bit boundary, then ASSERT().
608 If String has only pad spaces, then 0 is returned.
609 If String has no pad spaces or valid decimal digits,
610 then 0 is returned.
611 If the number represented by String overflows according
612 to the range defined by UINTN, then ASSERT().
613
614 If PcdMaximumUnicodeStringLength is not zero, and String contains
615 more than PcdMaximumUnicodeStringLength Unicode characters not including
616 the Null-terminator, then ASSERT().
617
618 @param String Pointer to a Null-terminated Unicode string.
619
620 @retval UINTN
621
622**/
623UINTN
624EFIAPI
625StrDecimalToUintn (
626 IN CONST CHAR16 *String
627 )
628{
629 UINTN Result;
630
631 ASSERT (String != NULL);
632 ASSERT (((UINTN) String & 0x01) == 0);
633 ASSERT (StrLen (String) < PcdGet32 (PcdMaximumUnicodeStringLength));
634
635 //
636 // Ignore the pad spaces (space or tab)
637 //
638 while ((*String == L' ') || (*String == L'\t')) {
639 String++;
640 }
641
642 //
643 // Ignore leading Zeros after the spaces
644 //
645 while (*String == L'0') {
646 String++;
647 }
648
649 Result = 0;
650
651 while (InternalIsDecimalDigitCharacter (*String)) {
652 //
653 // If the number represented by String overflows according
654 // to the range defined by UINTN, then ASSERT().
655 //
656 ASSERT ((Result < QUIENT_MAX_UINTN_DIVIDED_BY_10) ||
657 ((Result == QUIENT_MAX_UINTN_DIVIDED_BY_10) &&
658 (*String - L'0') <= REMINDER_MAX_UINTN_DIVIDED_BY_10)
659 );
660
661 Result = Result * 10 + (*String - L'0');
662 String++;
663 }
664
665 return Result;
666}
667
668
669/**
670 Convert a Null-terminated Unicode decimal string to a value of
671 type UINT64.
672
673 This function returns a value of type UINT64 by interpreting the contents
674 of the Unicode string specified by String as a decimal number. The format
675 of the input Unicode string String is:
676
677 [spaces] [decimal digits].
678
679 The valid decimal digit character is in the range [0-9]. The
680 function will ignore the pad space, which includes spaces or
681 tab characters, before [decimal digits]. The running zero in the
682 beginning of [decimal digits] will be ignored. Then, the function
683 stops at the first character that is a not a valid decimal character
684 or a Null-terminator, whichever one comes first.
685
686 If String is NULL, then ASSERT().
687 If String is not aligned in a 16-bit boundary, then ASSERT().
688 If String has only pad spaces, then 0 is returned.
689 If String has no pad spaces or valid decimal digits,
690 then 0 is returned.
691 If the number represented by String overflows according
692 to the range defined by UINT64, then ASSERT().
693
694 If PcdMaximumUnicodeStringLength is not zero, and String contains
695 more than PcdMaximumUnicodeStringLength Unicode characters not including
696 the Null-terminator, then ASSERT().
697
698 @param String Pointer to a Null-terminated Unicode string.
699
700 @retval UINT64
701
702**/
703UINT64
704EFIAPI
705StrDecimalToUint64 (
706 IN CONST CHAR16 *String
707 )
708{
709 UINT64 Result;
710
711 ASSERT (String != NULL);
712 ASSERT (((UINTN) String & 0x01) == 0);
713 ASSERT (StrLen (String) < PcdGet32 (PcdMaximumUnicodeStringLength));
714
715 //
716 // Ignore the pad spaces (space or tab)
717 //
718 while ((*String == L' ') || (*String == L'\t')) {
719 String++;
720 }
721
722 //
723 // Ignore leading Zeros after the spaces
724 //
725 while (*String == L'0') {
726 String++;
727 }
728
729 Result = 0;
730
731 while (InternalIsDecimalDigitCharacter (*String)) {
732 //
733 // If the number represented by String overflows according
734 // to the range defined by UINTN, then ASSERT().
735 //
736 ASSERT ((Result < QUIENT_MAX_UINT64_DIVIDED_BY_10) ||
737 ((Result == QUIENT_MAX_UINT64_DIVIDED_BY_10) &&
738 (*String - L'0') <= REMINDER_MAX_UINT64_DIVIDED_BY_10)
739 );
740
741 Result = MultU64x32 (Result, 10) + (*String - L'0');
742 String++;
743 }
744
745 return Result;
746}
747
748/**
749 Convert a Null-terminated Unicode hexadecimal string to a value of type UINTN.
750
751 This function returns a value of type UINTN by interpreting the contents
752 of the Unicode string specified by String as a hexadecimal number.
753 The format of the input Unicode string String is:
754
755 [spaces][zeros][x][hexadecimal digits].
756
757 The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].
758 The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix.
759 If "x" appears in the input string, it must be prefixed with at least one 0.
760 The function will ignore the pad space, which includes spaces or tab characters,
761 before [zeros], [x] or [hexadecimal digit]. The running zero before [x] or
762 [hexadecimal digit] will be ignored. Then, the decoding starts after [x] or the
763 first valid hexadecimal digit. Then, the function stops at the first character that is
764 a not a valid hexadecimal character or NULL, whichever one comes first.
765
766 If String is NULL, then ASSERT().
767 If String is not aligned in a 16-bit boundary, then ASSERT().
768 If String has only pad spaces, then zero is returned.
769 If String has no leading pad spaces, leading zeros or valid hexadecimal digits,
770 then zero is returned.
771 If the number represented by String overflows according to the range defined by
772 UINTN, then ASSERT().
773
774 If PcdMaximumUnicodeStringLength is not zero, and String contains more than
775 PcdMaximumUnicodeStringLength Unicode characters not including the Null-terminator,
776 then ASSERT().
777
778 @param String Pointer to a Null-terminated Unicode string.
779
780 @retval UINTN
781
782**/
783UINTN
784EFIAPI
785StrHexToUintn (
786 IN CONST CHAR16 *String
787 )
788{
789 UINTN Result;
790
791 ASSERT (String != NULL);
792 ASSERT (StrLen (String) < PcdGet32 (PcdMaximumUnicodeStringLength));
793
794 //
795 // Ignore the pad spaces (space or tab)
796 //
797 while ((*String == L' ') || (*String == L'\t')) {
798 String++;
799 }
800
801 //
802 // Ignore leading Zeros after the spaces
803 //
804 while (*String == L'0') {
805 String++;
806 }
807
808 if (InternalCharToUpper (*String) == L'X') {
809 ASSERT (*(String - 1) == L'0');
810 if (*(String - 1) != L'0') {
811 return 0;
812 }
813 //
814 // Skip the 'X'
815 //
816 String++;
817 }
818
819 Result = 0;
820
821 while (InternalIsHexaDecimalDigitCharacter (*String)) {
822 //
823 // If the Hex Number represented by String overflows according
824 // to the range defined by UINTN, then ASSERT().
825 //
826 ASSERT ((Result < QUIENT_MAX_UINTN_DIVIDED_BY_16) ||
827 ((Result == QUIENT_MAX_UINTN_DIVIDED_BY_16) &&
828 (InternalHexCharToUintn (*String) <= REMINDER_MAX_UINTN_DIVIDED_BY_16))
829 );
830
831 Result = (Result << 4) + InternalHexCharToUintn (*String);
832 String++;
833 }
834
835 return Result;
836}
837
838
839/**
840 Convert a Null-terminated Unicode hexadecimal string to a value of type UINT64.
841
842 This function returns a value of type UINT64 by interpreting the contents
843 of the Unicode string specified by String as a hexadecimal number.
844 The format of the input Unicode string String is
845
846 [spaces][zeros][x][hexadecimal digits].
847
848 The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].
849 The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix.
850 If "x" appears in the input string, it must be prefixed with at least one 0.
851 The function will ignore the pad space, which includes spaces or tab characters,
852 before [zeros], [x] or [hexadecimal digit]. The running zero before [x] or
853 [hexadecimal digit] will be ignored. Then, the decoding starts after [x] or the
854 first valid hexadecimal digit. Then, the function stops at the first character that is
855 a not a valid hexadecimal character or NULL, whichever one comes first.
856
857 If String is NULL, then ASSERT().
858 If String is not aligned in a 16-bit boundary, then ASSERT().
859 If String has only pad spaces, then zero is returned.
860 If String has no leading pad spaces, leading zeros or valid hexadecimal digits,
861 then zero is returned.
862 If the number represented by String overflows according to the range defined by
863 UINT64, then ASSERT().
864
865 If PcdMaximumUnicodeStringLength is not zero, and String contains more than
866 PcdMaximumUnicodeStringLength Unicode characters not including the Null-terminator,
867 then ASSERT().
868
869 @param String Pointer to a Null-terminated Unicode string.
870
871 @retval UINT64
872
873**/
874UINT64
875EFIAPI
876StrHexToUint64 (
877 IN CONST CHAR16 *String
878 )
879{
880 UINT64 Result;
881
882 ASSERT (String != NULL);
883 ASSERT (StrLen (String) < PcdGet32 (PcdMaximumUnicodeStringLength));
884
885 //
886 // Ignore the pad spaces (space or tab)
887 //
888 while ((*String == L' ') || (*String == L'\t')) {
889 String++;
890 }
891
892 //
893 // Ignore leading Zeros after the spaces
894 //
895 while (*String == L'0') {
896 String++;
897 }
898
899 if (InternalCharToUpper (*String) == L'X') {
900 ASSERT (*(String - 1) == L'0');
901 if (*(String - 1) != L'0') {
902 return 0;
903 }
904 //
905 // Skip the 'X'
906 //
907 String++;
908 }
909
910 Result = 0;
911
912 while (InternalIsHexaDecimalDigitCharacter (*String)) {
913 //
914 // If the Hex Number represented by String overflows according
915 // to the range defined by UINTN, then ASSERT().
916 //
917 ASSERT ((Result < QUIENT_MAX_UINT64_DIVIDED_BY_16)||
918 ((Result == QUIENT_MAX_UINT64_DIVIDED_BY_16) &&
919 (InternalHexCharToUintn (*String) <= REMINDER_MAX_UINT64_DIVIDED_BY_16))
920 );
921
15f83a88 922 Result = LShiftU64 (Result, 4);
923 Result = Result + InternalHexCharToUintn (*String);
d958721a 924 String++;
925 }
926
927 return Result;
928}
929
930/**
931 Check if a ASCII character is a decimal character.
932
933 This internal function checks if a Unicode character is a
934 decimal character. The valid decimal character is from
935 '0' to '9'.
936
937 @param Char The character to check against.
938
939 @retval TRUE If the Char is a decmial character.
940 @retval FALSE Otherwise.
941
942**/
943STATIC
944BOOLEAN
945InternalAsciiIsDecimalDigitCharacter (
946 IN CHAR8 Char
947 )
948{
949 return (BOOLEAN) (Char >= '0' && Char <= '9');
950}
951
952/**
953 Check if a ASCII character is a hexadecimal character.
954
955 This internal function checks if a ASCII character is a
956 decimal character. The valid hexadecimal character is
957 L'0' to L'9', L'a' to L'f', or L'A' to L'F'.
958
959
960 @param Char The character to check against.
961
962 @retval TRUE If the Char is a hexadecmial character.
963 @retval FALSE Otherwise.
964
965**/
966STATIC
967BOOLEAN
968InternalAsciiIsHexaDecimalDigitCharacter (
969 IN CHAR8 Char
970 )
971{
972
973 return (BOOLEAN) (InternalAsciiIsDecimalDigitCharacter (Char) ||
974 (Char >= 'A' && Char <= 'F') ||
975 (Char >= 'a' && Char <= 'f'));
976}
977
978/**
979 Convert a Null-terminated Unicode string to a Null-terminated
980 ASCII string and returns the ASCII string.
981
982 This function converts the content of the Unicode string Source
983 to the ASCII string Destination by copying the lower 8 bits of
984 each Unicode character. It returns Destination. The function terminates
985 the ASCII string Destination by appending a Null-terminator character
986 at the end. The caller is responsible to make sure Destination points
987 to a buffer with size equal or greater than (StrLen (Source) + 1) in bytes.
988
989 If Destination is NULL, then ASSERT().
990 If Source is NULL, then ASSERT().
991 If Source is not aligned on a 16-bit boundary, then ASSERT().
992 If Source and Destination overlap, then ASSERT().
993
994 If any Unicode characters in Source contain non-zero value in
995 the upper 8 bits, then ASSERT().
996
997 If PcdMaximumUnicodeStringLength is not zero, and Source contains
998 more than PcdMaximumUnicodeStringLength Unicode characters not including
999 the Null-terminator, then ASSERT().
1000
1001 If PcdMaximumAsciiStringLength is not zero, and Source contains more
1002 than PcdMaximumAsciiStringLength Unicode characters not including the
1003 Null-terminator, then ASSERT().
1004
1005 @param Source Pointer to a Null-terminated Unicode string.
1006 @param Destination Pointer to a Null-terminated ASCII string.
1007
1008 @reture Destination
1009
1010**/
1011CHAR8 *
1012EFIAPI
1013UnicodeStrToAsciiStr (
1014 IN CONST CHAR16 *Source,
1015 OUT CHAR8 *Destination
1016 )
1017{
1018 ASSERT (Destination != NULL);
1019 ASSERT (Source != NULL);
1020
1021 //
1022 // Source and Destination should not overlap
1023 //
1024 ASSERT ((UINTN) ((CHAR16 *) Destination - Source) > StrLen (Source));
1025 ASSERT ((UINTN) ((CHAR8 *) Source - Destination) > StrLen (Source));
1026
1027 //
1028 // If PcdMaximumUnicodeStringLength is not zero,
1029 // length of Source should not more than PcdMaximumUnicodeStringLength
1030 //
1031 if (PcdGet32 (PcdMaximumUnicodeStringLength) != 0) {
1032 ASSERT (StrLen (Source) < PcdGet32 (PcdMaximumUnicodeStringLength));
1033 }
1034
1035 while (*Source != '\0') {
1036 //
1037 // If any Unicode characters in Source contain
1038 // non-zero value in the upper 8 bits, then ASSERT().
1039 //
1040 ASSERT (*Source < 0x100);
1041 *(Destination++) = (CHAR8) *(Source++);
1042 }
1043
1044 *Destination = '\0';
1045
1046 return Destination;
1047}
1048
1049
1050/**
1051 Copies one Null-terminated ASCII string to another Null-terminated ASCII
1052 string and returns the new ASCII string.
1053
1054 This function copies the contents of the ASCII string Source to the ASCII
1055 string Destination, and returns Destination. If Source and Destination
1056 overlap, then the results are undefined.
1057
1058 If Destination is NULL, then ASSERT().
1059 If Source is NULL, then ASSERT().
1060 If Source and Destination overlap, then ASSERT().
1061 If PcdMaximumAsciiStringLength is not zero and Source contains more than
1062 PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator,
1063 then ASSERT().
1064
1065 @param Destination Pointer to a Null-terminated ASCII string.
1066 @param Source Pointer to a Null-terminated ASCII string.
1067
1068 @return Destination
1069
1070**/
1071CHAR8 *
1072EFIAPI
1073AsciiStrCpy (
1074 OUT CHAR8 *Destination,
1075 IN CONST CHAR8 *Source
1076 )
1077{
1078 CHAR8 *ReturnValue;
1079
1080 //
1081 // Destination cannot be NULL
1082 //
1083 ASSERT (Destination != NULL);
1084
1085 //
1086 // Destination and source cannot overlap
1087 //
1088 ASSERT ((UINTN)(Destination - Source) > AsciiStrLen (Source));
1089 ASSERT ((UINTN)(Source - Destination) > AsciiStrLen (Source));
1090
1091 ReturnValue = Destination;
1092 while (*Source) {
1093 *(Destination++) = *(Source++);
1094 }
1095 *Destination = 0;
1096 return ReturnValue;
1097}
1098
1099/**
1100 Copies one Null-terminated ASCII string with a maximum length to another
1101 Null-terminated ASCII string with a maximum length and returns the new ASCII
1102 string.
1103
1104 This function copies the contents of the ASCII string Source to the ASCII
1105 string Destination, and returns Destination. At most, Length ASCII characters
1106 are copied from Source to Destination. If Length is 0, then Destination is
1107 returned unmodified. If Length is greater that the number of ASCII characters
1108 in Source, then Destination is padded with Null ASCII characters. If Source
1109 and Destination overlap, then the results are undefined.
1110
1111 If Destination is NULL, then ASSERT().
1112 If Source is NULL, then ASSERT().
1113 If Source and Destination overlap, then ASSERT().
1114 If PcdMaximumAsciiStringLength is not zero, and Source contains more than
1115 PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator,
1116 then ASSERT().
1117
1118 @param Destination Pointer to a Null-terminated ASCII string.
1119 @param Source Pointer to a Null-terminated ASCII string.
1120 @param Length Maximum number of ASCII characters to copy.
1121
1122 @return Destination
1123
1124**/
1125CHAR8 *
1126EFIAPI
1127AsciiStrnCpy (
1128 OUT CHAR8 *Destination,
1129 IN CONST CHAR8 *Source,
1130 IN UINTN Length
1131 )
1132{
1133 CHAR8 *ReturnValue;
1134
1135 if (Length == 0) {
1136 return Destination;
1137 }
1138
1139 //
1140 // Destination cannot be NULL
1141 //
1142 ASSERT (Destination != NULL);
1143
1144 //
1145 // Destination and source cannot overlap
1146 //
1147 ASSERT ((UINTN)(Destination - Source) > AsciiStrLen (Source));
1148 ASSERT ((UINTN)(Source - Destination) >= Length);
1149
1150 ReturnValue = Destination;
1151
1152 while (*Source && Length > 0) {
1153 *(Destination++) = *(Source++);
1154 Length--;
1155 }
1156
1157 ZeroMem (Destination, Length * sizeof (*Destination));
1158 return ReturnValue;
1159}
1160
1161/**
1162 Returns the length of a Null-terminated ASCII string.
1163
1164 This function returns the number of ASCII characters in the Null-terminated
1165 ASCII string specified by String.
1166
1167 If String is NULL, then ASSERT().
1168 If PcdMaximumAsciiStringLength is not zero and String contains more than
1169 PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator,
1170 then ASSERT().
1171
1172 @param String Pointer to a Null-terminated ASCII string.
1173
1174 @return The length of String.
1175
1176**/
1177UINTN
1178EFIAPI
1179AsciiStrLen (
1180 IN CONST CHAR8 *String
1181 )
1182{
1183 UINTN Length;
1184
1185 ASSERT (String != NULL);
1186
1187 for (Length = 0; *String != '\0'; String++, Length++) {
1188 //
1189 // If PcdMaximumUnicodeStringLength is not zero,
1190 // length should not more than PcdMaximumUnicodeStringLength
1191 //
1192 if (PcdGet32 (PcdMaximumAsciiStringLength) != 0) {
1193 ASSERT (Length < PcdGet32 (PcdMaximumAsciiStringLength));
1194 }
1195 }
1196 return Length;
1197}
1198
1199/**
1200 Returns the size of a Null-terminated ASCII string in bytes, including the
1201 Null terminator.
1202
1203 This function returns the size, in bytes, of the Null-terminated ASCII string
1204 specified by String.
1205
1206 If String is NULL, then ASSERT().
1207 If PcdMaximumAsciiStringLength is not zero and String contains more than
1208 PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator,
1209 then ASSERT().
1210
1211 @param String Pointer to a Null-terminated ASCII string.
1212
1213 @return The size of String.
1214
1215**/
1216UINTN
1217EFIAPI
1218AsciiStrSize (
1219 IN CONST CHAR8 *String
1220 )
1221{
1222 return (AsciiStrLen (String) + 1) * sizeof (*String);
1223}
1224
1225/**
1226 Compares two Null-terminated ASCII strings, and returns the difference
1227 between the first mismatched ASCII characters.
1228
1229 This function compares the Null-terminated ASCII string FirstString to the
1230 Null-terminated ASCII string SecondString. If FirstString is identical to
1231 SecondString, then 0 is returned. Otherwise, the value returned is the first
1232 mismatched ASCII character in SecondString subtracted from the first
1233 mismatched ASCII character in FirstString.
1234
1235 If FirstString is NULL, then ASSERT().
1236 If SecondString is NULL, then ASSERT().
1237 If PcdMaximumAsciiStringLength is not zero and FirstString contains more than
1238 PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator,
1239 then ASSERT().
1240 If PcdMaximumAsciiStringLength is not zero and SecondString contains more
1241 than PcdMaximumAsciiStringLength ASCII characters not including the
1242 Null-terminator, then ASSERT().
1243
1244 @param FirstString Pointer to a Null-terminated ASCII string.
1245 @param SecondString Pointer to a Null-terminated ASCII string.
1246
1247 @retval 0 FirstString is identical to SecondString.
1248 @retval !=0 FirstString is not identical to SecondString.
1249
1250**/
1251INTN
1252EFIAPI
1253AsciiStrCmp (
1254 IN CONST CHAR8 *FirstString,
1255 IN CONST CHAR8 *SecondString
1256 )
1257{
1258 //
1259 // ASSERT both strings are less long than PcdMaximumAsciiStringLength
1260 //
1261 ASSERT (AsciiStrSize (FirstString));
1262 ASSERT (AsciiStrSize (SecondString));
1263
1264 while ((*FirstString != '\0') && (*FirstString == *SecondString)) {
1265 FirstString++;
1266 SecondString++;
1267 }
1268
1269 return *FirstString - *SecondString;
1270}
1271
1272/**
1273 Converts a lowercase Ascii character to upper one
1274
1275 If Chr is lowercase Ascii character, then converts it to upper one.
1276
1277 If Value >= 0xA0, then ASSERT().
1278 If (Value & 0x0F) >= 0x0A, then ASSERT().
1279
1280 @param chr one Ascii character
1281
1282 @return The uppercase value of Ascii character
1283
1284**/
1285STATIC
1286CHAR8
1287AsciiToUpper (
1288 IN CHAR8 Chr
1289 )
1290{
1291 return (UINT8) ((Chr >= 'a' && Chr <= 'z') ? Chr - ('a' - 'A') : Chr);
1292}
1293
1294/**
1295 Convert a ASCII character to numerical value.
1296
1297 This internal function only deal with Unicode character
1298 which maps to a valid hexadecimal ASII character, i.e.
1299 '0' to '9', 'a' to 'f' or 'A' to 'F'. For other
1300 ASCII character, the value returned does not make sense.
1301
1302 @param Char The character to convert.
1303
1304 @retval UINTN The numerical value converted.
1305
1306**/
1307STATIC
1308UINTN
1309InternalAsciiHexCharToUintn (
1310 IN CHAR8 Char
1311 )
1312{
1313 if (InternalIsDecimalDigitCharacter (Char)) {
1314 return Char - '0';
1315 }
1316
1317 return (UINTN) (10 + AsciiToUpper (Char) - 'A');
1318}
1319
1320
1321/**
1322 Performs a case insensitive comparison of two Null-terminated ASCII strings,
1323 and returns the difference between the first mismatched ASCII characters.
1324
1325 This function performs a case insensitive comparison of the Null-terminated
1326 ASCII string FirstString to the Null-terminated ASCII string SecondString. If
1327 FirstString is identical to SecondString, then 0 is returned. Otherwise, the
1328 value returned is the first mismatched lower case ASCII character in
1329 SecondString subtracted from the first mismatched lower case ASCII character
1330 in FirstString.
1331
1332 If FirstString is NULL, then ASSERT().
1333 If SecondString is NULL, then ASSERT().
1334 If PcdMaximumAsciiStringLength is not zero and FirstString contains more than
1335 PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator,
1336 then ASSERT().
1337 If PcdMaximumAsciiStringLength is not zero and SecondString contains more
1338 than PcdMaximumAsciiStringLength ASCII characters not including the
1339 Null-terminator, then ASSERT().
1340
1341 @param FirstString Pointer to a Null-terminated ASCII string.
1342 @param SecondString Pointer to a Null-terminated ASCII string.
1343
1344 @retval 0 FirstString is identical to SecondString using case insensitive
1345 comparisons.
1346 @retval !=0 FirstString is not identical to SecondString using case
1347 insensitive comparisons.
1348
1349**/
1350INTN
1351EFIAPI
1352AsciiStriCmp (
1353 IN CONST CHAR8 *FirstString,
1354 IN CONST CHAR8 *SecondString
1355 )
1356{
1357 CHAR8 UpperFirstString;
1358 CHAR8 UpperSecondString;
1359
1360 //
1361 // ASSERT both strings are less long than PcdMaximumAsciiStringLength
1362 //
1363 ASSERT (AsciiStrSize (FirstString));
1364 ASSERT (AsciiStrSize (SecondString));
1365
1366 UpperFirstString = AsciiToUpper (*FirstString);
1367 UpperSecondString = AsciiToUpper (*SecondString);
1368 while ((*FirstString != '\0') && (UpperFirstString == UpperSecondString)) {
1369 FirstString++;
1370 SecondString++;
1371 UpperFirstString = AsciiToUpper (*FirstString);
1372 UpperSecondString = AsciiToUpper (*SecondString);
1373 }
1374
1375 return UpperFirstString - UpperSecondString;
1376}
1377
1378/**
1379 Compares two Null-terminated ASCII strings with maximum lengths, and returns
1380 the difference between the first mismatched ASCII characters.
1381
1382 This function compares the Null-terminated ASCII string FirstString to the
1383 Null-terminated ASCII string SecondString. At most, Length ASCII characters
1384 will be compared. If Length is 0, then 0 is returned. If FirstString is
1385 identical to SecondString, then 0 is returned. Otherwise, the value returned
1386 is the first mismatched ASCII character in SecondString subtracted from the
1387 first mismatched ASCII character in FirstString.
1388
1389 If FirstString is NULL, then ASSERT().
1390 If SecondString is NULL, then ASSERT().
1391 If PcdMaximumAsciiStringLength is not zero and FirstString contains more than
1392 PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator,
1393 then ASSERT().
1394 If PcdMaximumAsciiStringLength is not zero and SecondString contains more than
1395 PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator,
1396 then ASSERT().
1397
1398 @param FirstString Pointer to a Null-terminated ASCII string.
1399 @param SecondString Pointer to a Null-terminated ASCII string.
1400
1401 @retval 0 FirstString is identical to SecondString.
1402 @retval !=0 FirstString is not identical to SecondString.
1403
1404**/
1405INTN
1406EFIAPI
1407AsciiStrnCmp (
1408 IN CONST CHAR8 *FirstString,
1409 IN CONST CHAR8 *SecondString,
1410 IN UINTN Length
1411 )
1412{
1413 if (Length == 0) {
1414 return 0;
1415 }
1416
1417 //
1418 // ASSERT both strings are less long than PcdMaximumAsciiStringLength
1419 //
1420 ASSERT (AsciiStrSize (FirstString));
1421 ASSERT (AsciiStrSize (SecondString));
1422
1423 while ((*FirstString != '\0') &&
1424 (*FirstString == *SecondString) &&
1425 (Length > 1)) {
1426 FirstString++;
1427 SecondString++;
1428 Length--;
1429 }
1430 return *FirstString - *SecondString;
1431}
1432
1433/**
1434 Concatenates one Null-terminated ASCII string to another Null-terminated
1435 ASCII string, and returns the concatenated ASCII string.
1436
1437 This function concatenates two Null-terminated ASCII strings. The contents of
1438 Null-terminated ASCII string Source are concatenated to the end of Null-
1439 terminated ASCII string Destination. The Null-terminated concatenated ASCII
1440 String is returned.
1441
1442 If Destination is NULL, then ASSERT().
1443 If Source is NULL, then ASSERT().
1444 If PcdMaximumAsciiStringLength is not zero and Destination contains more than
1445 PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator,
1446 then ASSERT().
1447 If PcdMaximumAsciiStringLength is not zero and Source contains more than
1448 PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator,
1449 then ASSERT().
1450 If PcdMaximumAsciiStringLength is not zero and concatenating Destination and
1451 Source results in a ASCII string with more than PcdMaximumAsciiStringLength
1452 ASCII characters, then ASSERT().
1453
1454 @param Destination Pointer to a Null-terminated ASCII string.
1455 @param Source Pointer to a Null-terminated ASCII string.
1456
1457 @return Destination
1458
1459**/
1460CHAR8 *
1461EFIAPI
1462AsciiStrCat (
1463 IN OUT CHAR8 *Destination,
1464 IN CONST CHAR8 *Source
1465 )
1466{
1467 AsciiStrCpy (Destination + AsciiStrLen (Destination), Source);
1468
1469 //
1470 // Size of the resulting string should never be zero.
1471 // PcdMaximumUnicodeStringLength is tested inside StrLen().
1472 //
1473 ASSERT (AsciiStrSize (Destination) != 0);
1474 return Destination;
1475}
1476
1477/**
1478 Concatenates one Null-terminated ASCII string with a maximum length to the
1479 end of another Null-terminated ASCII string, and returns the concatenated
1480 ASCII string.
1481
1482 This function concatenates two Null-terminated ASCII strings. The contents
1483 of Null-terminated ASCII string Source are concatenated to the end of Null-
1484 terminated ASCII string Destination, and Destination is returned. At most,
1485 Length ASCII characters are concatenated from Source to the end of
1486 Destination, and Destination is always Null-terminated. If Length is 0, then
1487 Destination is returned unmodified. If Source and Destination overlap, then
1488 the results are undefined.
1489
1490 If Destination is NULL, then ASSERT().
1491 If Source is NULL, then ASSERT().
1492 If Source and Destination overlap, then ASSERT().
1493 If PcdMaximumAsciiStringLength is not zero, and Destination contains more than
1494 PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator,
1495 then ASSERT().
1496 If PcdMaximumAsciiStringLength is not zero, and Source contains more than
1497 PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator,
1498 then ASSERT().
1499 If PcdMaximumAsciiStringLength is not zero, and concatenating Destination and
1500 Source results in a ASCII string with more than PcdMaximumAsciiStringLength
1501 ASCII characters not including the Null-terminator, then ASSERT().
1502
1503 @param Destination Pointer to a Null-terminated ASCII string.
1504 @param Source Pointer to a Null-terminated ASCII string.
1505 @param Length Maximum number of ASCII characters to concatenate from
1506 Source.
1507
1508 @return Destination
1509
1510**/
1511CHAR8 *
1512EFIAPI
1513AsciiStrnCat (
1514 IN OUT CHAR8 *Destination,
1515 IN CONST CHAR8 *Source,
1516 IN UINTN Length
1517 )
1518{
1519 AsciiStrnCpy (Destination + AsciiStrLen (Destination), Source, Length);
1520
1521 //
1522 // Size of the resulting string should never be zero.
1523 // PcdMaximumUnicodeStringLength is tested inside StrLen().
1524 //
1525 ASSERT (AsciiStrSize (Destination) != 0);
1526 return Destination;
1527}
1528
1529/**
1530 Returns the first occurance of a Null-terminated ASCII sub-string
1531 in a Null-terminated ASCII string.
1532
1533 This function scans the contents of the ASCII string specified by String
1534 and returns the first occurrence of SearchString. If SearchString is not
1535 found in String, then NULL is returned. If the length of SearchString is zero,
1536 then String is returned.
1537
1538 If String is NULL, then ASSERT().
1539 If SearchString is NULL, then ASSERT().
1540
1541 If PcdMaximumAsciiStringLength is not zero, and SearchString or
1542 String contains more than PcdMaximumAsciiStringLength Unicode characters
1543 not including the Null-terminator, then ASSERT().
1544
1545 @param String Pointer to a Null-terminated ASCII string.
1546 @param SearchString Pointer to a Null-terminated ASCII string to search for.
1547
1548 @retval NULL If the SearchString does not appear in String.
1549 @retval !NULL If there is a match.
1550
1551**/
1552CHAR8 *
1553EFIAPI
1554AsciiStrStr (
1555 IN CONST CHAR8 *String,
1556 IN CONST CHAR8 *SearchString
1557 )
1558{
1559 CONST CHAR8 *FirstMatch;
1560 CONST CHAR8 *SearchStringTmp;
1561
1562 ASSERT (String != NULL);
1563 ASSERT (SearchString != NULL);
1564
1565 //
1566 // If PcdMaximumUnicodeStringLength is not zero,
1567 // length of String should not more than PcdMaximumUnicodeStringLength
1568 //
1569 if (PcdGet32 (PcdMaximumAsciiStringLength) != 0) {
1570 ASSERT (AsciiStrLen (String) < PcdGet32 (PcdMaximumAsciiStringLength));
1571 }
1572
1573 //
1574 // If PcdMaximumUnicodeStringLength is not zero,
1575 // length of SearchString should not more than PcdMaximumUnicodeStringLength
1576 //
1577 if (PcdGet32 (PcdMaximumAsciiStringLength) != 0) {
1578 ASSERT (AsciiStrLen (SearchString) < PcdGet32 (PcdMaximumAsciiStringLength));
1579 }
1580
1581 while (*String != '\0') {
1582 SearchStringTmp = SearchString;
1583 FirstMatch = String;
1584
1585 while ((*String == *SearchStringTmp)
1586 && (*SearchStringTmp != '\0')
1587 && (*String != '\0')) {
1588 String++;
1589 SearchStringTmp++;
1590 }
1591
1592 if (*SearchStringTmp == '\0') {
1593 return (CHAR8 *) FirstMatch;
1594 }
1595
1596 if (SearchStringTmp == SearchString) {
1597 //
1598 // If no character from SearchString match,
1599 // move the pointer to the String under search
1600 // by one character.
1601 //
1602 String++;
1603 }
1604
1605 }
1606
1607 return NULL;
1608}
1609
1610/**
1611 Convert a Null-terminated ASCII decimal string to a value of type
1612 UINTN.
1613
1614 This function returns a value of type UINTN by interpreting the contents
1615 of the ASCII string String as a decimal number. The format of the input
1616 ASCII string String is:
1617
1618 [spaces] [decimal digits].
1619
1620 The valid decimal digit character is in the range [0-9]. The function will
1621 ignore the pad space, which includes spaces or tab characters, before the digits.
1622 The running zero in the beginning of [decimal digits] will be ignored. Then, the
1623 function stops at the first character that is a not a valid decimal character or
1624 Null-terminator, whichever on comes first.
1625
1626 If String has only pad spaces, then 0 is returned.
1627 If String has no pad spaces or valid decimal digits, then 0 is returned.
1628 If the number represented by String overflows according to the range defined by
1629 UINTN, then ASSERT().
1630 If String is NULL, then ASSERT().
1631 If PcdMaximumAsciiStringLength is not zero, and String contains more than
1632 PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator,
1633 then ASSERT().
1634
1635 @param String Pointer to a Null-terminated ASCII string.
1636
1637 @retval UINTN
1638
1639**/
1640UINTN
1641EFIAPI
1642AsciiStrDecimalToUintn (
1643 IN CONST CHAR8 *String
1644 )
1645{
1646 UINTN Result;
1647
1648 ASSERT (String != NULL);
1649 ASSERT (AsciiStrLen (String) < PcdGet32 (PcdMaximumAsciiStringLength));
1650
1651 //
1652 // Ignore the pad spaces (space or tab)
1653 //
1654 while ((*String == ' ') || (*String == '\t')) {
1655 String++;
1656 }
1657
1658 //
1659 // Ignore leading Zeros after the spaces
1660 //
1661 while (*String == '0') {
1662 String++;
1663 }
1664
1665 Result = 0;
1666
1667 while (InternalAsciiIsDecimalDigitCharacter (*String)) {
1668 //
1669 // If the number represented by String overflows according
1670 // to the range defined by UINTN, then ASSERT().
1671 //
1672 ASSERT ((Result < QUIENT_MAX_UINTN_DIVIDED_BY_10) ||
1673 ((Result == QUIENT_MAX_UINTN_DIVIDED_BY_10) &&
1674 (*String - '0') <= REMINDER_MAX_UINTN_DIVIDED_BY_10)
1675 );
1676
1677 Result = Result * 10 + (*String - '0');
1678 String++;
1679 }
1680
1681 return Result;
1682}
1683
1684
1685/**
1686 Convert a Null-terminated ASCII decimal string to a value of type
1687 UINT64.
1688
1689 This function returns a value of type UINT64 by interpreting the contents
1690 of the ASCII string String as a decimal number. The format of the input
1691 ASCII string String is:
1692
1693 [spaces] [decimal digits].
1694
1695 The valid decimal digit character is in the range [0-9]. The function will
1696 ignore the pad space, which includes spaces or tab characters, before the digits.
1697 The running zero in the beginning of [decimal digits] will be ignored. Then, the
1698 function stops at the first character that is a not a valid decimal character or
1699 Null-terminator, whichever on comes first.
1700
1701 If String has only pad spaces, then 0 is returned.
1702 If String has no pad spaces or valid decimal digits, then 0 is returned.
1703 If the number represented by String overflows according to the range defined by
1704 UINT64, then ASSERT().
1705 If String is NULL, then ASSERT().
1706 If PcdMaximumAsciiStringLength is not zero, and String contains more than
1707 PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator,
1708 then ASSERT().
1709
1710 @param String Pointer to a Null-terminated ASCII string.
1711
1712 @retval UINT64
1713
1714**/
1715UINT64
1716EFIAPI
1717AsciiStrDecimalToUint64 (
1718 IN CONST CHAR8 *String
1719 )
1720{
1721 UINT64 Result;
1722
1723 ASSERT (String != NULL);
1724 ASSERT (AsciiStrLen (String) < PcdGet32 (PcdMaximumAsciiStringLength));
1725
1726 //
1727 // Ignore the pad spaces (space or tab)
1728 //
1729 while ((*String == ' ') || (*String == '\t')) {
1730 String++;
1731 }
1732
1733 //
1734 // Ignore leading Zeros after the spaces
1735 //
1736 while (*String == '0') {
1737 String++;
1738 }
1739
1740 Result = 0;
1741
1742 while (InternalAsciiIsDecimalDigitCharacter (*String)) {
1743 //
1744 // If the number represented by String overflows according
1745 // to the range defined by UINTN, then ASSERT().
1746 //
1747 ASSERT ((Result < QUIENT_MAX_UINT64_DIVIDED_BY_10) ||
1748 ((Result == QUIENT_MAX_UINT64_DIVIDED_BY_10) &&
1749 (*String - '0') <= REMINDER_MAX_UINT64_DIVIDED_BY_10)
1750 );
1751
1752 Result = MultU64x32 (Result, 10) + (*String - '0');
1753 String++;
1754 }
1755
1756 return Result;
1757}
1758
1759/**
1760 Convert a Null-terminated ASCII hexadecimal string to a value of type UINTN.
1761
1762 This function returns a value of type UINTN by interpreting the contents of
1763 the ASCII string String as a hexadecimal number. The format of the input ASCII
1764 string String is:
1765
1766 [spaces][zeros][x][hexadecimal digits].
1767
1768 The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].
1769 The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix. If "x"
1770 appears in the input string, it must be prefixed with at least one 0. The function
1771 will ignore the pad space, which includes spaces or tab characters, before [zeros],
1772 [x] or [hexadecimal digits]. The running zero before [x] or [hexadecimal digits]
1773 will be ignored. Then, the decoding starts after [x] or the first valid hexadecimal
1774 digit. Then, the function stops at the first character that is a not a valid
1775 hexadecimal character or Null-terminator, whichever on comes first.
1776
1777 If String has only pad spaces, then 0 is returned.
1778 If String has no leading pad spaces, leading zeros or valid hexadecimal digits, then
1779 0 is returned.
1780
1781 If the number represented by String overflows according to the range defined by UINTN,
1782 then ASSERT().
1783 If String is NULL, then ASSERT().
1784 If PcdMaximumAsciiStringLength is not zero,
1785 and String contains more than PcdMaximumAsciiStringLength ASCII characters not including
1786 the Null-terminator, then ASSERT().
1787
1788 @param String Pointer to a Null-terminated ASCII string.
1789
1790 @retval UINTN
1791
1792**/
1793UINTN
1794EFIAPI
1795AsciiStrHexToUintn (
1796 IN CONST CHAR8 *String
1797 )
1798{
1799 UINTN Result;
1800
1801 ASSERT (String != NULL);
1802 ASSERT (AsciiStrLen (String) < PcdGet32 (PcdMaximumAsciiStringLength));
1803
1804 //
1805 // Ignore the pad spaces (space or tab)
1806 //
1807 while ((*String == ' ') || (*String == '\t')) {
1808 String++;
1809 }
1810
1811 //
1812 // Ignore leading Zeros after the spaces
1813 //
1814 while (*String == '0') {
1815 String++;
1816 }
1817
1818 if (AsciiToUpper (*String) == 'X') {
1819 ASSERT (*(String - 1) == '0');
1820 if (*(String - 1) != '0') {
1821 return 0;
1822 }
1823 //
1824 // Skip the 'X'
1825 //
1826 String++;
1827 }
1828
1829 Result = 0;
1830
1831 while (InternalAsciiIsHexaDecimalDigitCharacter (*String)) {
1832 //
1833 // If the Hex Number represented by String overflows according
1834 // to the range defined by UINTN, then ASSERT().
1835 //
1836 ASSERT ((Result < QUIENT_MAX_UINTN_DIVIDED_BY_16) ||
1837 ((Result == QUIENT_MAX_UINTN_DIVIDED_BY_16) &&
1838 (InternalAsciiHexCharToUintn (*String) <= REMINDER_MAX_UINTN_DIVIDED_BY_16))
1839 );
1840
1841 Result = (Result << 4) + InternalAsciiHexCharToUintn (*String);
1842 String++;
1843 }
1844
1845 return Result;
1846}
1847
1848
1849/**
1850 Convert a Null-terminated ASCII hexadecimal string to a value of type UINT64.
1851
1852 This function returns a value of type UINT64 by interpreting the contents of
1853 the ASCII string String as a hexadecimal number. The format of the input ASCII
1854 string String is:
1855
1856 [spaces][zeros][x][hexadecimal digits].
1857
1858 The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].
1859 The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix. If "x"
1860 appears in the input string, it must be prefixed with at least one 0. The function
1861 will ignore the pad space, which includes spaces or tab characters, before [zeros],
1862 [x] or [hexadecimal digits]. The running zero before [x] or [hexadecimal digits]
1863 will be ignored. Then, the decoding starts after [x] or the first valid hexadecimal
1864 digit. Then, the function stops at the first character that is a not a valid
1865 hexadecimal character or Null-terminator, whichever on comes first.
1866
1867 If String has only pad spaces, then 0 is returned.
1868 If String has no leading pad spaces, leading zeros or valid hexadecimal digits, then
1869 0 is returned.
1870
1871 If the number represented by String overflows according to the range defined by UINT64,
1872 then ASSERT().
1873 If String is NULL, then ASSERT().
1874 If PcdMaximumAsciiStringLength is not zero,
1875 and String contains more than PcdMaximumAsciiStringLength ASCII characters not including
1876 the Null-terminator, then ASSERT().
1877
1878 @param String Pointer to a Null-terminated ASCII string.
1879
1880 @retval UINT64
1881
1882**/
1883UINT64
1884EFIAPI
1885AsciiStrHexToUint64 (
1886 IN CONST CHAR8 *String
1887 )
1888{
1889 UINT64 Result;
1890
1891 ASSERT (String != NULL);
1892 ASSERT (AsciiStrLen (String) < PcdGet32 (PcdMaximumUnicodeStringLength));
1893
1894 //
1895 // Ignore the pad spaces (space or tab) and leading Zeros
1896 //
1897 //
1898 // Ignore the pad spaces (space or tab)
1899 //
1900 while ((*String == ' ') || (*String == '\t')) {
1901 String++;
1902 }
1903
1904 //
1905 // Ignore leading Zeros after the spaces
1906 //
1907 while (*String == '0') {
1908 String++;
1909 }
1910
1911 if (AsciiToUpper (*String) == 'X') {
1912 ASSERT (*(String - 1) == '0');
1913 if (*(String - 1) != '0') {
1914 return 0;
1915 }
1916 //
1917 // Skip the 'X'
1918 //
1919 String++;
1920 }
1921
1922 Result = 0;
1923
1924 while (InternalAsciiIsHexaDecimalDigitCharacter (*String)) {
1925 //
1926 // If the Hex Number represented by String overflows according
1927 // to the range defined by UINTN, then ASSERT().
1928 //
1929 ASSERT ((Result < QUIENT_MAX_UINT64_DIVIDED_BY_16) ||
1930 ((Result == QUIENT_MAX_UINT64_DIVIDED_BY_16) &&
1931 (InternalAsciiHexCharToUintn (*String) <= REMINDER_MAX_UINT64_DIVIDED_BY_16))
1932 );
1933
15f83a88 1934 Result = LShiftU64 (Result, 4);
1935 Result = Result + InternalAsciiHexCharToUintn (*String);
d958721a 1936 String++;
1937 }
1938
1939 return Result;
1940}
1941
1942
1943/**
1944 Convert one Null-terminated ASCII string to a Null-terminated
1945 Unicode string and returns the Unicode string.
1946
1947 This function converts the contents of the ASCII string Source to the Unicode
1948 string Destination, and returns Destination. The function terminates the
1949 Unicode string Destination by appending a Null-terminator character at the end.
1950 The caller is responsible to make sure Destination points to a buffer with size
1951 equal or greater than ((AsciiStrLen (Source) + 1) * sizeof (CHAR16)) in bytes.
1952
1953 If Destination is NULL, then ASSERT().
1954 If Destination is not aligned on a 16-bit boundary, then ASSERT().
1955 If Source is NULL, then ASSERT().
1956 If Source and Destination overlap, then ASSERT().
1957 If PcdMaximumAsciiStringLength is not zero, and Source contains more than
1958 PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator,
1959 then ASSERT().
1960 If PcdMaximumUnicodeStringLength is not zero, and Source contains more than
1961 PcdMaximumUnicodeStringLength ASCII characters not including the
1962 Null-terminator, then ASSERT().
1963
1964 @param Source Pointer to a Null-terminated ASCII string.
1965 @param Destination Pointer to a Null-terminated Unicode string.
1966
1967 @reture Destination
1968
1969**/
1970CHAR16 *
1971EFIAPI
1972AsciiStrToUnicodeStr (
1973 IN CONST CHAR8 *Source,
1974 OUT CHAR16 *Destination
1975 )
1976{
1977 ASSERT (Destination != NULL);
1978 ASSERT (Source != NULL);
1979
1980 //
1981 // Source and Destination should not overlap
1982 //
1983 ASSERT ((UINTN) ((CHAR8 *) Destination - Source) > AsciiStrLen (Source));
1984 ASSERT ((UINTN) (Source - (CHAR8 *) Destination) > (AsciiStrLen (Source) * sizeof (CHAR16)));
1985
1986 //
1987 // If PcdMaximumAsciiStringLength is not zero,
1988 // length of Source should not more than PcdMaximumUnicodeStringLength
1989 //
1990 if (PcdGet32 (PcdMaximumAsciiStringLength) != 0) {
1991 ASSERT (AsciiStrLen (Source) < PcdGet32 (PcdMaximumAsciiStringLength));
1992 }
1993
1994 while (*Source != '\0') {
1995 *(Destination++) = (CHAR16) *(Source++);
1996 }
1997 //
1998 // End the Destination with a NULL.
1999 //
2000 *Destination = '\0';
2001
2002 return Destination;
2003}
2004
2005/**
2006 Converts an 8-bit value to an 8-bit BCD value.
2007
2008 Converts the 8-bit value specified by Value to BCD. The BCD value is
2009 returned.
2010
2011 If Value >= 100, then ASSERT().
2012
2013 @param Value The 8-bit value to convert to BCD. Range 0..99.
2014
2015 @return The BCD value
2016
2017**/
2018UINT8
2019EFIAPI
2020DecimalToBcd8 (
2021 IN UINT8 Value
2022 )
2023{
2024 ASSERT (Value < 100);
2025 return (UINT8) (((Value / 10) << 4) | (Value % 10));
2026}
2027
2028/**
2029 Converts an 8-bit BCD value to an 8-bit value.
2030
2031 Converts the 8-bit BCD value specified by Value to an 8-bit value. The 8-bit
2032 value is returned.
2033
2034 If Value >= 0xA0, then ASSERT().
2035 If (Value & 0x0F) >= 0x0A, then ASSERT().
2036
2037 @param Value The 8-bit BCD value to convert to an 8-bit value.
2038
2039 @return The 8-bit value is returned.
2040
2041**/
2042UINT8
2043EFIAPI
2044BcdToDecimal8 (
2045 IN UINT8 Value
2046 )
2047{
2048 ASSERT (Value < 0xa0);
2049 ASSERT ((Value & 0xf) < 0xa);
2050 return (UINT8) ((Value >> 4) * 10 + (Value & 0xf));
2051}
2052
2053