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