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