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