4 Copyright (c) 2014 - 2019, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
9 #include "BaseLibInternals.h"
11 #define RSIZE_MAX (PcdGet32 (PcdMaximumUnicodeStringLength))
13 #define ASCII_RSIZE_MAX (PcdGet32 (PcdMaximumAsciiStringLength))
15 #define SAFE_STRING_CONSTRAINT_CHECK(Expression, Status) \
17 if (!(Expression)) { \
18 DEBUG ((DEBUG_VERBOSE, \
19 "%a(%d) %a: SAFE_STRING_CONSTRAINT_CHECK(%a) failed. Return %r\n", \
20 __FILE__, DEBUG_LINE_NUMBER, __FUNCTION__, DEBUG_EXPRESSION_STRING (Expression), Status)); \
26 Returns if 2 memory blocks are overlapped.
28 @param Base1 Base address of 1st memory block.
29 @param Size1 Size of 1st memory block.
30 @param Base2 Base address of 2nd memory block.
31 @param Size2 Size of 2nd memory block.
33 @retval TRUE 2 memory blocks are overlapped.
34 @retval FALSE 2 memory blocks are not overlapped.
37 InternalSafeStringIsOverlap (
44 if ((((UINTN
)Base1
>= (UINTN
)Base2
) && ((UINTN
)Base1
< (UINTN
)Base2
+ Size2
)) ||
45 (((UINTN
)Base2
>= (UINTN
)Base1
) && ((UINTN
)Base2
< (UINTN
)Base1
+ Size1
)))
54 Returns if 2 Unicode strings are not overlapped.
56 @param Str1 Start address of 1st Unicode string.
57 @param Size1 The number of char in 1st Unicode string,
58 including terminating null char.
59 @param Str2 Start address of 2nd Unicode string.
60 @param Size2 The number of char in 2nd Unicode string,
61 including terminating null char.
63 @retval TRUE 2 Unicode strings are NOT overlapped.
64 @retval FALSE 2 Unicode strings are overlapped.
67 InternalSafeStringNoStrOverlap (
74 return !InternalSafeStringIsOverlap (Str1
, Size1
* sizeof (CHAR16
), Str2
, Size2
* sizeof (CHAR16
));
78 Returns if 2 Ascii strings are not overlapped.
80 @param Str1 Start address of 1st Ascii string.
81 @param Size1 The number of char in 1st Ascii string,
82 including terminating null char.
83 @param Str2 Start address of 2nd Ascii string.
84 @param Size2 The number of char in 2nd Ascii string,
85 including terminating null char.
87 @retval TRUE 2 Ascii strings are NOT overlapped.
88 @retval FALSE 2 Ascii strings are overlapped.
91 InternalSafeStringNoAsciiStrOverlap (
98 return !InternalSafeStringIsOverlap (Str1
, Size1
, Str2
, Size2
);
102 Returns the length of a Null-terminated Unicode string.
104 This function is similar as strlen_s defined in C11.
106 If String is not aligned on a 16-bit boundary, then ASSERT().
108 @param String A pointer to a Null-terminated Unicode string.
109 @param MaxSize The maximum number of Destination Unicode
110 char, including terminating null char.
112 @retval 0 If String is NULL.
113 @retval MaxSize If there is no null character in the first MaxSize characters of String.
114 @return The number of characters that percede the terminating null character.
120 IN CONST CHAR16
*String
,
126 ASSERT (((UINTN
)String
& BIT0
) == 0);
129 // If String is a null pointer or MaxSize is 0, then the StrnLenS function returns zero.
131 if ((String
== NULL
) || (MaxSize
== 0)) {
136 // Otherwise, the StrnLenS function returns the number of characters that precede the
137 // terminating null character. If there is no null character in the first MaxSize characters of
138 // String then StrnLenS returns MaxSize. At most the first MaxSize characters of String shall
139 // be accessed by StrnLenS.
142 while (String
[Length
] != 0) {
143 if (Length
>= MaxSize
- 1) {
154 Returns the size of a Null-terminated Unicode string in bytes, including the
157 This function returns the size of the Null-terminated Unicode string
158 specified by String in bytes, including the Null terminator.
160 If String is not aligned on a 16-bit boundary, then ASSERT().
162 @param String A pointer to a Null-terminated Unicode string.
163 @param MaxSize The maximum number of Destination Unicode
164 char, including the Null terminator.
166 @retval 0 If String is NULL.
167 @retval (sizeof (CHAR16) * (MaxSize + 1))
168 If there is no Null terminator in the first MaxSize characters of
170 @return The size of the Null-terminated Unicode string in bytes, including
177 IN CONST CHAR16
*String
,
182 // If String is a null pointer, then the StrnSizeS function returns zero.
184 if (String
== NULL
) {
189 // Otherwise, the StrnSizeS function returns the size of the Null-terminated
190 // Unicode string in bytes, including the Null terminator. If there is no
191 // Null terminator in the first MaxSize characters of String, then StrnSizeS
192 // returns (sizeof (CHAR16) * (MaxSize + 1)) to keep a consistent map with
193 // the StrnLenS function.
195 return (StrnLenS (String
, MaxSize
) + 1) * sizeof (*String
);
199 Copies the string pointed to by Source (including the terminating null char)
200 to the array pointed to by Destination.
202 This function is similar as strcpy_s defined in C11.
204 If Destination is not aligned on a 16-bit boundary, then ASSERT().
205 If Source is not aligned on a 16-bit boundary, then ASSERT().
207 If an error is returned, then the Destination is unmodified.
209 @param Destination A pointer to a Null-terminated Unicode string.
210 @param DestMax The maximum number of Destination Unicode
211 char, including terminating null char.
212 @param Source A pointer to a Null-terminated Unicode string.
214 @retval RETURN_SUCCESS String is copied.
215 @retval RETURN_BUFFER_TOO_SMALL If DestMax is NOT greater than StrLen(Source).
216 @retval RETURN_INVALID_PARAMETER If Destination is NULL.
218 If PcdMaximumUnicodeStringLength is not zero,
219 and DestMax is greater than
220 PcdMaximumUnicodeStringLength.
222 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.
227 OUT CHAR16
*Destination
,
229 IN CONST CHAR16
*Source
234 ASSERT (((UINTN
)Destination
& BIT0
) == 0);
235 ASSERT (((UINTN
)Source
& BIT0
) == 0);
238 // 1. Neither Destination nor Source shall be a null pointer.
240 SAFE_STRING_CONSTRAINT_CHECK ((Destination
!= NULL
), RETURN_INVALID_PARAMETER
);
241 SAFE_STRING_CONSTRAINT_CHECK ((Source
!= NULL
), RETURN_INVALID_PARAMETER
);
244 // 2. DestMax shall not be greater than RSIZE_MAX.
246 if (RSIZE_MAX
!= 0) {
247 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
<= RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
251 // 3. DestMax shall not equal zero.
253 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
!= 0), RETURN_INVALID_PARAMETER
);
256 // 4. DestMax shall be greater than StrnLenS(Source, DestMax).
258 SourceLen
= StrnLenS (Source
, DestMax
);
259 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
> SourceLen
), RETURN_BUFFER_TOO_SMALL
);
262 // 5. Copying shall not take place between objects that overlap.
264 SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoStrOverlap (Destination
, DestMax
, (CHAR16
*)Source
, SourceLen
+ 1), RETURN_ACCESS_DENIED
);
267 // The StrCpyS function copies the string pointed to by Source (including the terminating
268 // null character) into the array pointed to by Destination.
270 while (*Source
!= 0) {
271 *(Destination
++) = *(Source
++);
276 return RETURN_SUCCESS
;
280 Copies not more than Length successive char from the string pointed to by
281 Source to the array pointed to by Destination. If no null char is copied from
282 Source, then Destination[Length] is always set to null.
284 This function is similar as strncpy_s defined in C11.
286 If Length > 0 and Destination is not aligned on a 16-bit boundary, then ASSERT().
287 If Length > 0 and Source is not aligned on a 16-bit boundary, then ASSERT().
289 If an error is returned, then the Destination is unmodified.
291 @param Destination A pointer to a Null-terminated Unicode string.
292 @param DestMax The maximum number of Destination Unicode
293 char, including terminating null char.
294 @param Source A pointer to a Null-terminated Unicode string.
295 @param Length The maximum number of Unicode characters to copy.
297 @retval RETURN_SUCCESS String is copied.
298 @retval RETURN_BUFFER_TOO_SMALL If DestMax is NOT greater than
299 MIN(StrLen(Source), Length).
300 @retval RETURN_INVALID_PARAMETER If Destination is NULL.
302 If PcdMaximumUnicodeStringLength is not zero,
303 and DestMax is greater than
304 PcdMaximumUnicodeStringLength.
306 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.
311 OUT CHAR16
*Destination
,
313 IN CONST CHAR16
*Source
,
319 ASSERT (((UINTN
)Destination
& BIT0
) == 0);
320 ASSERT (((UINTN
)Source
& BIT0
) == 0);
323 // 1. Neither Destination nor Source shall be a null pointer.
325 SAFE_STRING_CONSTRAINT_CHECK ((Destination
!= NULL
), RETURN_INVALID_PARAMETER
);
326 SAFE_STRING_CONSTRAINT_CHECK ((Source
!= NULL
), RETURN_INVALID_PARAMETER
);
329 // 2. Neither DestMax nor Length shall be greater than RSIZE_MAX
331 if (RSIZE_MAX
!= 0) {
332 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
<= RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
333 SAFE_STRING_CONSTRAINT_CHECK ((Length
<= RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
337 // 3. DestMax shall not equal zero.
339 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
!= 0), RETURN_INVALID_PARAMETER
);
342 // 4. If Length is not less than DestMax, then DestMax shall be greater than StrnLenS(Source, DestMax).
344 SourceLen
= StrnLenS (Source
, MIN (DestMax
, Length
));
345 if (Length
>= DestMax
) {
346 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
> SourceLen
), RETURN_BUFFER_TOO_SMALL
);
350 // 5. Copying shall not take place between objects that overlap.
352 if (SourceLen
> Length
) {
356 SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoStrOverlap (Destination
, DestMax
, (CHAR16
*)Source
, SourceLen
+ 1), RETURN_ACCESS_DENIED
);
359 // The StrnCpyS function copies not more than Length successive characters (characters that
360 // follow a null character are not copied) from the array pointed to by Source to the array
361 // pointed to by Destination. If no null character was copied from Source, then Destination[Length] is set to a null
364 while ((SourceLen
> 0) && (*Source
!= 0)) {
365 *(Destination
++) = *(Source
++);
371 return RETURN_SUCCESS
;
375 Appends a copy of the string pointed to by Source (including the terminating
376 null char) to the end of the string pointed to by Destination.
378 This function is similar as strcat_s defined in C11.
380 If Destination is not aligned on a 16-bit boundary, then ASSERT().
381 If Source is not aligned on a 16-bit boundary, then ASSERT().
383 If an error is returned, then the Destination is unmodified.
385 @param Destination A pointer to a Null-terminated Unicode string.
386 @param DestMax The maximum number of Destination Unicode
387 char, including terminating null char.
388 @param Source A pointer to a Null-terminated Unicode string.
390 @retval RETURN_SUCCESS String is appended.
391 @retval RETURN_BAD_BUFFER_SIZE If DestMax is NOT greater than
393 @retval RETURN_BUFFER_TOO_SMALL If (DestMax - StrLen(Destination)) is NOT
394 greater than StrLen(Source).
395 @retval RETURN_INVALID_PARAMETER If Destination is NULL.
397 If PcdMaximumUnicodeStringLength is not zero,
398 and DestMax is greater than
399 PcdMaximumUnicodeStringLength.
401 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.
406 IN OUT CHAR16
*Destination
,
408 IN CONST CHAR16
*Source
415 ASSERT (((UINTN
)Destination
& BIT0
) == 0);
416 ASSERT (((UINTN
)Source
& BIT0
) == 0);
419 // Let CopyLen denote the value DestMax - StrnLenS(Destination, DestMax) upon entry to StrCatS.
421 DestLen
= StrnLenS (Destination
, DestMax
);
422 CopyLen
= DestMax
- DestLen
;
425 // 1. Neither Destination nor Source shall be a null pointer.
427 SAFE_STRING_CONSTRAINT_CHECK ((Destination
!= NULL
), RETURN_INVALID_PARAMETER
);
428 SAFE_STRING_CONSTRAINT_CHECK ((Source
!= NULL
), RETURN_INVALID_PARAMETER
);
431 // 2. DestMax shall not be greater than RSIZE_MAX.
433 if (RSIZE_MAX
!= 0) {
434 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
<= RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
438 // 3. DestMax shall not equal zero.
440 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
!= 0), RETURN_INVALID_PARAMETER
);
443 // 4. CopyLen shall not equal zero.
445 SAFE_STRING_CONSTRAINT_CHECK ((CopyLen
!= 0), RETURN_BAD_BUFFER_SIZE
);
448 // 5. CopyLen shall be greater than StrnLenS(Source, CopyLen).
450 SourceLen
= StrnLenS (Source
, CopyLen
);
451 SAFE_STRING_CONSTRAINT_CHECK ((CopyLen
> SourceLen
), RETURN_BUFFER_TOO_SMALL
);
454 // 6. Copying shall not take place between objects that overlap.
456 SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoStrOverlap (Destination
, DestMax
, (CHAR16
*)Source
, SourceLen
+ 1), RETURN_ACCESS_DENIED
);
459 // The StrCatS function appends a copy of the string pointed to by Source (including the
460 // terminating null character) to the end of the string pointed to by Destination. The initial character
461 // from Source overwrites the null character at the end of Destination.
463 Destination
= Destination
+ DestLen
;
464 while (*Source
!= 0) {
465 *(Destination
++) = *(Source
++);
470 return RETURN_SUCCESS
;
474 Appends not more than Length successive char from the string pointed to by
475 Source to the end of the string pointed to by Destination. If no null char is
476 copied from Source, then Destination[StrLen(Destination) + Length] is always
479 This function is similar as strncat_s defined in C11.
481 If Destination is not aligned on a 16-bit boundary, then ASSERT().
482 If Source is not aligned on a 16-bit boundary, then ASSERT().
484 If an error is returned, then the Destination is unmodified.
486 @param Destination A pointer to a Null-terminated Unicode string.
487 @param DestMax The maximum number of Destination Unicode
488 char, including terminating null char.
489 @param Source A pointer to a Null-terminated Unicode string.
490 @param Length The maximum number of Unicode characters to copy.
492 @retval RETURN_SUCCESS String is appended.
493 @retval RETURN_BAD_BUFFER_SIZE If DestMax is NOT greater than
495 @retval RETURN_BUFFER_TOO_SMALL If (DestMax - StrLen(Destination)) is NOT
496 greater than MIN(StrLen(Source), Length).
497 @retval RETURN_INVALID_PARAMETER If Destination is NULL.
499 If PcdMaximumUnicodeStringLength is not zero,
500 and DestMax is greater than
501 PcdMaximumUnicodeStringLength.
503 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.
508 IN OUT CHAR16
*Destination
,
510 IN CONST CHAR16
*Source
,
518 ASSERT (((UINTN
)Destination
& BIT0
) == 0);
519 ASSERT (((UINTN
)Source
& BIT0
) == 0);
522 // Let CopyLen denote the value DestMax - StrnLenS(Destination, DestMax) upon entry to StrnCatS.
524 DestLen
= StrnLenS (Destination
, DestMax
);
525 CopyLen
= DestMax
- DestLen
;
528 // 1. Neither Destination nor Source shall be a null pointer.
530 SAFE_STRING_CONSTRAINT_CHECK ((Destination
!= NULL
), RETURN_INVALID_PARAMETER
);
531 SAFE_STRING_CONSTRAINT_CHECK ((Source
!= NULL
), RETURN_INVALID_PARAMETER
);
534 // 2. Neither DestMax nor Length shall be greater than RSIZE_MAX.
536 if (RSIZE_MAX
!= 0) {
537 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
<= RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
538 SAFE_STRING_CONSTRAINT_CHECK ((Length
<= RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
542 // 3. DestMax shall not equal zero.
544 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
!= 0), RETURN_INVALID_PARAMETER
);
547 // 4. CopyLen shall not equal zero.
549 SAFE_STRING_CONSTRAINT_CHECK ((CopyLen
!= 0), RETURN_BAD_BUFFER_SIZE
);
552 // 5. If Length is not less than CopyLen, then CopyLen shall be greater than StrnLenS(Source, CopyLen).
554 SourceLen
= StrnLenS (Source
, MIN (CopyLen
, Length
));
555 if (Length
>= CopyLen
) {
556 SAFE_STRING_CONSTRAINT_CHECK ((CopyLen
> SourceLen
), RETURN_BUFFER_TOO_SMALL
);
560 // 6. Copying shall not take place between objects that overlap.
562 if (SourceLen
> Length
) {
566 SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoStrOverlap (Destination
, DestMax
, (CHAR16
*)Source
, SourceLen
+ 1), RETURN_ACCESS_DENIED
);
569 // The StrnCatS function appends not more than Length successive characters (characters
570 // that follow a null character are not copied) from the array pointed to by Source to the end of
571 // the string pointed to by Destination. The initial character from Source overwrites the null character at
572 // the end of Destination. If no null character was copied from Source, then Destination[DestMax-CopyLen+Length] is set to
575 Destination
= Destination
+ DestLen
;
576 while ((SourceLen
> 0) && (*Source
!= 0)) {
577 *(Destination
++) = *(Source
++);
583 return RETURN_SUCCESS
;
587 Convert a Null-terminated Unicode decimal string to a value of type UINTN.
589 This function outputs a value of type UINTN by interpreting the contents of
590 the Unicode string specified by String as a decimal number. The format of the
591 input Unicode string String is:
593 [spaces] [decimal digits].
595 The valid decimal digit character is in the range [0-9]. The function will
596 ignore the pad space, which includes spaces or tab characters, before
597 [decimal digits]. The running zero in the beginning of [decimal digits] will
598 be ignored. Then, the function stops at the first character that is a not a
599 valid decimal character or a Null-terminator, whichever one comes first.
601 If String is not aligned in a 16-bit boundary, then ASSERT().
603 If String has no valid decimal digits in the above format, then 0 is stored
604 at the location pointed to by Data.
605 If the number represented by String exceeds the range defined by UINTN, then
606 MAX_UINTN is stored at the location pointed to by Data.
608 If EndPointer is not NULL, a pointer to the character that stopped the scan
609 is stored at the location pointed to by EndPointer. If String has no valid
610 decimal digits right after the optional pad spaces, the value of String is
611 stored at the location pointed to by EndPointer.
613 @param String Pointer to a Null-terminated Unicode string.
614 @param EndPointer Pointer to character that stops scan.
615 @param Data Pointer to the converted value.
617 @retval RETURN_SUCCESS Value is translated from String.
618 @retval RETURN_INVALID_PARAMETER If String is NULL.
620 If PcdMaximumUnicodeStringLength is not
621 zero, and String contains more than
622 PcdMaximumUnicodeStringLength Unicode
623 characters, not including the
625 @retval RETURN_UNSUPPORTED If the number represented by String exceeds
626 the range defined by UINTN.
632 IN CONST CHAR16
*String
,
633 OUT CHAR16
**EndPointer OPTIONAL
,
637 ASSERT (((UINTN
)String
& BIT0
) == 0);
640 // 1. Neither String nor Data shall be a null pointer.
642 SAFE_STRING_CONSTRAINT_CHECK ((String
!= NULL
), RETURN_INVALID_PARAMETER
);
643 SAFE_STRING_CONSTRAINT_CHECK ((Data
!= NULL
), RETURN_INVALID_PARAMETER
);
646 // 2. The length of String shall not be greater than RSIZE_MAX.
648 if (RSIZE_MAX
!= 0) {
649 SAFE_STRING_CONSTRAINT_CHECK ((StrnLenS (String
, RSIZE_MAX
+ 1) <= RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
652 if (EndPointer
!= NULL
) {
653 *EndPointer
= (CHAR16
*)String
;
657 // Ignore the pad spaces (space or tab)
659 while ((*String
== L
' ') || (*String
== L
'\t')) {
664 // Ignore leading Zeros after the spaces
666 while (*String
== L
'0') {
672 while (InternalIsDecimalDigitCharacter (*String
)) {
674 // If the number represented by String overflows according to the range
675 // defined by UINTN, then MAX_UINTN is stored in *Data and
676 // RETURN_UNSUPPORTED is returned.
678 if (*Data
> ((MAX_UINTN
- (*String
- L
'0')) / 10)) {
680 if (EndPointer
!= NULL
) {
681 *EndPointer
= (CHAR16
*)String
;
684 return RETURN_UNSUPPORTED
;
687 *Data
= *Data
* 10 + (*String
- L
'0');
691 if (EndPointer
!= NULL
) {
692 *EndPointer
= (CHAR16
*)String
;
695 return RETURN_SUCCESS
;
699 Convert a Null-terminated Unicode decimal string to a value of type UINT64.
701 This function outputs a value of type UINT64 by interpreting the contents of
702 the Unicode string specified by String as a decimal number. The format of the
703 input Unicode string String is:
705 [spaces] [decimal digits].
707 The valid decimal digit character is in the range [0-9]. The function will
708 ignore the pad space, which includes spaces or tab characters, before
709 [decimal digits]. The running zero in the beginning of [decimal digits] will
710 be ignored. Then, the function stops at the first character that is a not a
711 valid decimal character or a Null-terminator, whichever one comes first.
713 If String is not aligned in a 16-bit boundary, then ASSERT().
715 If String has no valid decimal digits in the above format, then 0 is stored
716 at the location pointed to by Data.
717 If the number represented by String exceeds the range defined by UINT64, then
718 MAX_UINT64 is stored at the location pointed to by Data.
720 If EndPointer is not NULL, a pointer to the character that stopped the scan
721 is stored at the location pointed to by EndPointer. If String has no valid
722 decimal digits right after the optional pad spaces, the value of String is
723 stored at the location pointed to by EndPointer.
725 @param String Pointer to a Null-terminated Unicode string.
726 @param EndPointer Pointer to character that stops scan.
727 @param Data Pointer to the converted value.
729 @retval RETURN_SUCCESS Value is translated from String.
730 @retval RETURN_INVALID_PARAMETER If String is NULL.
732 If PcdMaximumUnicodeStringLength is not
733 zero, and String contains more than
734 PcdMaximumUnicodeStringLength Unicode
735 characters, not including the
737 @retval RETURN_UNSUPPORTED If the number represented by String exceeds
738 the range defined by UINT64.
743 StrDecimalToUint64S (
744 IN CONST CHAR16
*String
,
745 OUT CHAR16
**EndPointer OPTIONAL
,
749 ASSERT (((UINTN
)String
& BIT0
) == 0);
752 // 1. Neither String nor Data shall be a null pointer.
754 SAFE_STRING_CONSTRAINT_CHECK ((String
!= NULL
), RETURN_INVALID_PARAMETER
);
755 SAFE_STRING_CONSTRAINT_CHECK ((Data
!= NULL
), RETURN_INVALID_PARAMETER
);
758 // 2. The length of String shall not be greater than RSIZE_MAX.
760 if (RSIZE_MAX
!= 0) {
761 SAFE_STRING_CONSTRAINT_CHECK ((StrnLenS (String
, RSIZE_MAX
+ 1) <= RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
764 if (EndPointer
!= NULL
) {
765 *EndPointer
= (CHAR16
*)String
;
769 // Ignore the pad spaces (space or tab)
771 while ((*String
== L
' ') || (*String
== L
'\t')) {
776 // Ignore leading Zeros after the spaces
778 while (*String
== L
'0') {
784 while (InternalIsDecimalDigitCharacter (*String
)) {
786 // If the number represented by String overflows according to the range
787 // defined by UINT64, then MAX_UINT64 is stored in *Data and
788 // RETURN_UNSUPPORTED is returned.
790 if (*Data
> DivU64x32 (MAX_UINT64
- (*String
- L
'0'), 10)) {
792 if (EndPointer
!= NULL
) {
793 *EndPointer
= (CHAR16
*)String
;
796 return RETURN_UNSUPPORTED
;
799 *Data
= MultU64x32 (*Data
, 10) + (*String
- L
'0');
803 if (EndPointer
!= NULL
) {
804 *EndPointer
= (CHAR16
*)String
;
807 return RETURN_SUCCESS
;
811 Convert a Null-terminated Unicode hexadecimal string to a value of type
814 This function outputs a value of type UINTN by interpreting the contents of
815 the Unicode string specified by String as a hexadecimal number. The format of
816 the input Unicode string String is:
818 [spaces][zeros][x][hexadecimal digits].
820 The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].
821 The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix.
822 If "x" appears in the input string, it must be prefixed with at least one 0.
823 The function will ignore the pad space, which includes spaces or tab
824 characters, before [zeros], [x] or [hexadecimal digit]. The running zero
825 before [x] or [hexadecimal digit] will be ignored. Then, the decoding starts
826 after [x] or the first valid hexadecimal digit. Then, the function stops at
827 the first character that is a not a valid hexadecimal character or NULL,
828 whichever one comes first.
830 If String is not aligned in a 16-bit boundary, then ASSERT().
832 If String has no valid hexadecimal digits in the above format, then 0 is
833 stored at the location pointed to by Data.
834 If the number represented by String exceeds the range defined by UINTN, then
835 MAX_UINTN is stored at the location pointed to by Data.
837 If EndPointer is not NULL, a pointer to the character that stopped the scan
838 is stored at the location pointed to by EndPointer. If String has no valid
839 hexadecimal digits right after the optional pad spaces, the value of String
840 is stored at the location pointed to by EndPointer.
842 @param String Pointer to a Null-terminated Unicode string.
843 @param EndPointer Pointer to character that stops scan.
844 @param Data Pointer to the converted value.
846 @retval RETURN_SUCCESS Value is translated from String.
847 @retval RETURN_INVALID_PARAMETER If String is NULL.
849 If PcdMaximumUnicodeStringLength is not
850 zero, and String contains more than
851 PcdMaximumUnicodeStringLength Unicode
852 characters, not including the
854 @retval RETURN_UNSUPPORTED If the number represented by String exceeds
855 the range defined by UINTN.
861 IN CONST CHAR16
*String
,
862 OUT CHAR16
**EndPointer OPTIONAL
,
866 BOOLEAN FoundLeadingZero
;
868 FoundLeadingZero
= FALSE
;
869 ASSERT (((UINTN
)String
& BIT0
) == 0);
872 // 1. Neither String nor Data shall be a null pointer.
874 SAFE_STRING_CONSTRAINT_CHECK ((String
!= NULL
), RETURN_INVALID_PARAMETER
);
875 SAFE_STRING_CONSTRAINT_CHECK ((Data
!= NULL
), RETURN_INVALID_PARAMETER
);
878 // 2. The length of String shall not be greater than RSIZE_MAX.
880 if (RSIZE_MAX
!= 0) {
881 SAFE_STRING_CONSTRAINT_CHECK ((StrnLenS (String
, RSIZE_MAX
+ 1) <= RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
884 if (EndPointer
!= NULL
) {
885 *EndPointer
= (CHAR16
*)String
;
889 // Ignore the pad spaces (space or tab)
891 while ((*String
== L
' ') || (*String
== L
'\t')) {
896 // Ignore leading Zeros after the spaces
899 FoundLeadingZero
= *String
== L
'0';
900 while (*String
== L
'0') {
904 if (CharToUpper (*String
) == L
'X') {
905 if (!FoundLeadingZero
) {
907 return RETURN_SUCCESS
;
918 while (InternalIsHexaDecimalDigitCharacter (*String
)) {
920 // If the number represented by String overflows according to the range
921 // defined by UINTN, then MAX_UINTN is stored in *Data and
922 // RETURN_UNSUPPORTED is returned.
924 if (*Data
> ((MAX_UINTN
- InternalHexCharToUintn (*String
)) >> 4)) {
926 if (EndPointer
!= NULL
) {
927 *EndPointer
= (CHAR16
*)String
;
930 return RETURN_UNSUPPORTED
;
933 *Data
= (*Data
<< 4) + InternalHexCharToUintn (*String
);
937 if (EndPointer
!= NULL
) {
938 *EndPointer
= (CHAR16
*)String
;
941 return RETURN_SUCCESS
;
945 Convert a Null-terminated Unicode hexadecimal string to a value of type
948 This function outputs a value of type UINT64 by interpreting the contents of
949 the Unicode string specified by String as a hexadecimal number. The format of
950 the input Unicode string String is:
952 [spaces][zeros][x][hexadecimal digits].
954 The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].
955 The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix.
956 If "x" appears in the input string, it must be prefixed with at least one 0.
957 The function will ignore the pad space, which includes spaces or tab
958 characters, before [zeros], [x] or [hexadecimal digit]. The running zero
959 before [x] or [hexadecimal digit] will be ignored. Then, the decoding starts
960 after [x] or the first valid hexadecimal digit. Then, the function stops at
961 the first character that is a not a valid hexadecimal character or NULL,
962 whichever one comes first.
964 If String is not aligned in a 16-bit boundary, then ASSERT().
966 If String has no valid hexadecimal digits in the above format, then 0 is
967 stored at the location pointed to by Data.
968 If the number represented by String exceeds the range defined by UINT64, then
969 MAX_UINT64 is stored at the location pointed to by Data.
971 If EndPointer is not NULL, a pointer to the character that stopped the scan
972 is stored at the location pointed to by EndPointer. If String has no valid
973 hexadecimal digits right after the optional pad spaces, the value of String
974 is stored at the location pointed to by EndPointer.
976 @param String Pointer to a Null-terminated Unicode string.
977 @param EndPointer Pointer to character that stops scan.
978 @param Data Pointer to the converted value.
980 @retval RETURN_SUCCESS Value is translated from String.
981 @retval RETURN_INVALID_PARAMETER If String is NULL.
983 If PcdMaximumUnicodeStringLength is not
984 zero, and String contains more than
985 PcdMaximumUnicodeStringLength Unicode
986 characters, not including the
988 @retval RETURN_UNSUPPORTED If the number represented by String exceeds
989 the range defined by UINT64.
995 IN CONST CHAR16
*String
,
996 OUT CHAR16
**EndPointer OPTIONAL
,
1000 BOOLEAN FoundLeadingZero
;
1002 FoundLeadingZero
= FALSE
;
1003 ASSERT (((UINTN
)String
& BIT0
) == 0);
1006 // 1. Neither String nor Data shall be a null pointer.
1008 SAFE_STRING_CONSTRAINT_CHECK ((String
!= NULL
), RETURN_INVALID_PARAMETER
);
1009 SAFE_STRING_CONSTRAINT_CHECK ((Data
!= NULL
), RETURN_INVALID_PARAMETER
);
1012 // 2. The length of String shall not be greater than RSIZE_MAX.
1014 if (RSIZE_MAX
!= 0) {
1015 SAFE_STRING_CONSTRAINT_CHECK ((StrnLenS (String
, RSIZE_MAX
+ 1) <= RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
1018 if (EndPointer
!= NULL
) {
1019 *EndPointer
= (CHAR16
*)String
;
1023 // Ignore the pad spaces (space or tab)
1025 while ((*String
== L
' ') || (*String
== L
'\t')) {
1030 // Ignore leading Zeros after the spaces
1032 FoundLeadingZero
= *String
== L
'0';
1033 while (*String
== L
'0') {
1037 if (CharToUpper (*String
) == L
'X') {
1038 if (!FoundLeadingZero
) {
1040 return RETURN_SUCCESS
;
1051 while (InternalIsHexaDecimalDigitCharacter (*String
)) {
1053 // If the number represented by String overflows according to the range
1054 // defined by UINT64, then MAX_UINT64 is stored in *Data and
1055 // RETURN_UNSUPPORTED is returned.
1057 if (*Data
> RShiftU64 (MAX_UINT64
- InternalHexCharToUintn (*String
), 4)) {
1059 if (EndPointer
!= NULL
) {
1060 *EndPointer
= (CHAR16
*)String
;
1063 return RETURN_UNSUPPORTED
;
1066 *Data
= LShiftU64 (*Data
, 4) + InternalHexCharToUintn (*String
);
1070 if (EndPointer
!= NULL
) {
1071 *EndPointer
= (CHAR16
*)String
;
1074 return RETURN_SUCCESS
;
1078 Convert a Null-terminated Unicode string to IPv6 address and prefix length.
1080 This function outputs a value of type IPv6_ADDRESS and may output a value
1081 of type UINT8 by interpreting the contents of the Unicode string specified
1082 by String. The format of the input Unicode string String is as follows:
1086 X contains one to four hexadecimal digit characters in the range [0-9], [a-f] and
1087 [A-F]. X is converted to a value of type UINT16, whose low byte is stored in low
1088 memory address and high byte is stored in high memory address. P contains decimal
1089 digit characters in the range [0-9]. The running zero in the beginning of P will
1090 be ignored. /P is optional.
1092 When /P is not in the String, the function stops at the first character that is
1093 not a valid hexadecimal digit character after eight X's are converted.
1095 When /P is in the String, the function stops at the first character that is not
1096 a valid decimal digit character after P is converted.
1098 "::" can be used to compress one or more groups of X when X contains only 0.
1099 The "::" can only appear once in the String.
1101 If String is not aligned in a 16-bit boundary, then ASSERT().
1103 If EndPointer is not NULL and Address is translated from String, a pointer
1104 to the character that stopped the scan is stored at the location pointed to
1107 @param String Pointer to a Null-terminated Unicode string.
1108 @param EndPointer Pointer to character that stops scan.
1109 @param Address Pointer to the converted IPv6 address.
1110 @param PrefixLength Pointer to the converted IPv6 address prefix
1111 length. MAX_UINT8 is returned when /P is
1114 @retval RETURN_SUCCESS Address is translated from String.
1115 @retval RETURN_INVALID_PARAMETER If String is NULL.
1117 @retval RETURN_UNSUPPORTED If X contains more than four hexadecimal
1119 If String contains "::" and number of X
1121 If P starts with character that is not a
1122 valid decimal digit character.
1123 If the decimal number converted from P
1130 IN CONST CHAR16
*String
,
1131 OUT CHAR16
**EndPointer OPTIONAL
,
1132 OUT IPv6_ADDRESS
*Address
,
1133 OUT UINT8
*PrefixLength OPTIONAL
1136 RETURN_STATUS Status
;
1139 IPv6_ADDRESS LocalAddress
;
1140 UINT8 LocalPrefixLength
;
1141 CONST CHAR16
*Pointer
;
1143 UINTN CompressStart
;
1144 BOOLEAN ExpectPrefix
;
1146 LocalPrefixLength
= MAX_UINT8
;
1147 CompressStart
= ARRAY_SIZE (Address
->Addr
);
1148 ExpectPrefix
= FALSE
;
1150 ASSERT (((UINTN
)String
& BIT0
) == 0);
1153 // 1. None of String or Guid shall be a null pointer.
1155 SAFE_STRING_CONSTRAINT_CHECK ((String
!= NULL
), RETURN_INVALID_PARAMETER
);
1156 SAFE_STRING_CONSTRAINT_CHECK ((Address
!= NULL
), RETURN_INVALID_PARAMETER
);
1158 for (Pointer
= String
, AddressIndex
= 0; AddressIndex
< ARRAY_SIZE (Address
->Addr
) + 1;) {
1159 if (!InternalIsHexaDecimalDigitCharacter (*Pointer
)) {
1160 if (*Pointer
!= L
':') {
1162 // ":" or "/" should be followed by digit characters.
1164 return RETURN_UNSUPPORTED
;
1168 // Meet second ":" after previous ":" or "/"
1169 // or meet first ":" in the beginning of String.
1173 // ":" shall not be after "/"
1175 return RETURN_UNSUPPORTED
;
1178 if ((CompressStart
!= ARRAY_SIZE (Address
->Addr
)) || (AddressIndex
== ARRAY_SIZE (Address
->Addr
))) {
1180 // "::" can only appear once.
1181 // "::" can only appear when address is not full length.
1183 return RETURN_UNSUPPORTED
;
1186 // Remember the start of zero compressing.
1188 CompressStart
= AddressIndex
;
1191 if (CompressStart
== 0) {
1192 if (*Pointer
!= L
':') {
1194 // Single ":" shall not be in the beginning of String.
1196 return RETURN_UNSUPPORTED
;
1204 if (!InternalIsHexaDecimalDigitCharacter (*Pointer
)) {
1205 if (*Pointer
== L
'/') {
1207 // Might be optional "/P" after "::".
1209 if (CompressStart
!= AddressIndex
) {
1210 return RETURN_UNSUPPORTED
;
1216 if (!ExpectPrefix
) {
1220 Status
= StrHexToUintnS (Pointer
, &End
, &Uintn
);
1221 if (RETURN_ERROR (Status
) || (End
- Pointer
> 4)) {
1223 // Number of hexadecimal digit characters is no more than 4.
1225 return RETURN_UNSUPPORTED
;
1230 // Uintn won't exceed MAX_UINT16 if number of hexadecimal digit characters is no more than 4.
1232 ASSERT (AddressIndex
+ 1 < ARRAY_SIZE (Address
->Addr
));
1233 LocalAddress
.Addr
[AddressIndex
] = (UINT8
)((UINT16
)Uintn
>> 8);
1234 LocalAddress
.Addr
[AddressIndex
+ 1] = (UINT8
)Uintn
;
1238 // Get P, then exit the loop.
1240 Status
= StrDecimalToUintnS (Pointer
, &End
, &Uintn
);
1241 if (RETURN_ERROR (Status
) || (End
== Pointer
) || (Uintn
> 128)) {
1243 // Prefix length should not exceed 128.
1245 return RETURN_UNSUPPORTED
;
1248 LocalPrefixLength
= (UINT8
)Uintn
;
1257 if (*Pointer
== L
'/') {
1258 ExpectPrefix
= TRUE
;
1259 } else if (*Pointer
== L
':') {
1260 if (AddressIndex
== ARRAY_SIZE (Address
->Addr
)) {
1262 // Meet additional ":" after all 8 16-bit address
1268 // Meet other character that is not "/" or ":" after all 8 16-bit address
1276 if (((AddressIndex
== ARRAY_SIZE (Address
->Addr
)) && (CompressStart
!= ARRAY_SIZE (Address
->Addr
))) ||
1277 ((AddressIndex
!= ARRAY_SIZE (Address
->Addr
)) && (CompressStart
== ARRAY_SIZE (Address
->Addr
)))
1281 // Full length of address shall not have compressing zeros.
1282 // Non-full length of address shall have compressing zeros.
1284 return RETURN_UNSUPPORTED
;
1287 CopyMem (&Address
->Addr
[0], &LocalAddress
.Addr
[0], CompressStart
);
1288 ZeroMem (&Address
->Addr
[CompressStart
], ARRAY_SIZE (Address
->Addr
) - AddressIndex
);
1289 if (AddressIndex
> CompressStart
) {
1291 &Address
->Addr
[CompressStart
+ ARRAY_SIZE (Address
->Addr
) - AddressIndex
],
1292 &LocalAddress
.Addr
[CompressStart
],
1293 AddressIndex
- CompressStart
1297 if (PrefixLength
!= NULL
) {
1298 *PrefixLength
= LocalPrefixLength
;
1301 if (EndPointer
!= NULL
) {
1302 *EndPointer
= (CHAR16
*)Pointer
;
1305 return RETURN_SUCCESS
;
1309 Convert a Null-terminated Unicode string to IPv4 address and prefix length.
1311 This function outputs a value of type IPv4_ADDRESS and may output a value
1312 of type UINT8 by interpreting the contents of the Unicode string specified
1313 by String. The format of the input Unicode string String is as follows:
1317 D and P are decimal digit characters in the range [0-9]. The running zero in
1318 the beginning of D and P will be ignored. /P is optional.
1320 When /P is not in the String, the function stops at the first character that is
1321 not a valid decimal digit character after four D's are converted.
1323 When /P is in the String, the function stops at the first character that is not
1324 a valid decimal digit character after P is converted.
1326 If String is not aligned in a 16-bit boundary, then ASSERT().
1328 If EndPointer is not NULL and Address is translated from String, a pointer
1329 to the character that stopped the scan is stored at the location pointed to
1332 @param String Pointer to a Null-terminated Unicode string.
1333 @param EndPointer Pointer to character that stops scan.
1334 @param Address Pointer to the converted IPv4 address.
1335 @param PrefixLength Pointer to the converted IPv4 address prefix
1336 length. MAX_UINT8 is returned when /P is
1339 @retval RETURN_SUCCESS Address is translated from String.
1340 @retval RETURN_INVALID_PARAMETER If String is NULL.
1342 @retval RETURN_UNSUPPORTED If String is not in the correct format.
1343 If any decimal number converted from D
1345 If the decimal number converted from P
1352 IN CONST CHAR16
*String
,
1353 OUT CHAR16
**EndPointer OPTIONAL
,
1354 OUT IPv4_ADDRESS
*Address
,
1355 OUT UINT8
*PrefixLength OPTIONAL
1358 RETURN_STATUS Status
;
1361 IPv4_ADDRESS LocalAddress
;
1362 UINT8 LocalPrefixLength
;
1365 LocalPrefixLength
= MAX_UINT8
;
1367 ASSERT (((UINTN
)String
& BIT0
) == 0);
1370 // 1. None of String or Guid shall be a null pointer.
1372 SAFE_STRING_CONSTRAINT_CHECK ((String
!= NULL
), RETURN_INVALID_PARAMETER
);
1373 SAFE_STRING_CONSTRAINT_CHECK ((Address
!= NULL
), RETURN_INVALID_PARAMETER
);
1375 for (Pointer
= (CHAR16
*)String
, AddressIndex
= 0; AddressIndex
< ARRAY_SIZE (Address
->Addr
) + 1;) {
1376 if (!InternalIsDecimalDigitCharacter (*Pointer
)) {
1378 // D or P contains invalid characters.
1386 Status
= StrDecimalToUintnS ((CONST CHAR16
*)Pointer
, &Pointer
, &Uintn
);
1387 if (RETURN_ERROR (Status
)) {
1388 return RETURN_UNSUPPORTED
;
1391 if (AddressIndex
== ARRAY_SIZE (Address
->Addr
)) {
1396 return RETURN_UNSUPPORTED
;
1399 LocalPrefixLength
= (UINT8
)Uintn
;
1404 if (Uintn
> MAX_UINT8
) {
1405 return RETURN_UNSUPPORTED
;
1408 LocalAddress
.Addr
[AddressIndex
] = (UINT8
)Uintn
;
1413 // Check the '.' or '/', depending on the AddressIndex.
1415 if (AddressIndex
== ARRAY_SIZE (Address
->Addr
)) {
1416 if (*Pointer
== L
'/') {
1418 // '/P' is in the String.
1419 // Skip "/" and get P in next loop.
1424 // '/P' is not in the String.
1428 } else if (AddressIndex
< ARRAY_SIZE (Address
->Addr
)) {
1429 if (*Pointer
== L
'.') {
1431 // D should be followed by '.'
1435 return RETURN_UNSUPPORTED
;
1440 if (AddressIndex
< ARRAY_SIZE (Address
->Addr
)) {
1441 return RETURN_UNSUPPORTED
;
1444 CopyMem (Address
, &LocalAddress
, sizeof (*Address
));
1445 if (PrefixLength
!= NULL
) {
1446 *PrefixLength
= LocalPrefixLength
;
1449 if (EndPointer
!= NULL
) {
1450 *EndPointer
= Pointer
;
1453 return RETURN_SUCCESS
;
1457 Convert a Null-terminated Unicode GUID string to a value of type
1460 This function outputs a GUID value by interpreting the contents of
1461 the Unicode string specified by String. The format of the input
1462 Unicode string String consists of 36 characters, as follows:
1464 aabbccdd-eeff-gghh-iijj-kkllmmnnoopp
1466 The pairs aa - pp are two characters in the range [0-9], [a-f] and
1467 [A-F], with each pair representing a single byte hexadecimal value.
1469 The mapping between String and the EFI_GUID structure is as follows:
1487 If String is not aligned in a 16-bit boundary, then ASSERT().
1489 @param String Pointer to a Null-terminated Unicode string.
1490 @param Guid Pointer to the converted GUID.
1492 @retval RETURN_SUCCESS Guid is translated from String.
1493 @retval RETURN_INVALID_PARAMETER If String is NULL.
1495 @retval RETURN_UNSUPPORTED If String is not as the above format.
1501 IN CONST CHAR16
*String
,
1505 RETURN_STATUS Status
;
1508 ASSERT (((UINTN
)String
& BIT0
) == 0);
1511 // 1. None of String or Guid shall be a null pointer.
1513 SAFE_STRING_CONSTRAINT_CHECK ((String
!= NULL
), RETURN_INVALID_PARAMETER
);
1514 SAFE_STRING_CONSTRAINT_CHECK ((Guid
!= NULL
), RETURN_INVALID_PARAMETER
);
1517 // Get aabbccdd in big-endian.
1519 Status
= StrHexToBytes (String
, 2 * sizeof (LocalGuid
.Data1
), (UINT8
*)&LocalGuid
.Data1
, sizeof (LocalGuid
.Data1
));
1520 if (RETURN_ERROR (Status
) || (String
[2 * sizeof (LocalGuid
.Data1
)] != L
'-')) {
1521 return RETURN_UNSUPPORTED
;
1525 // Convert big-endian to little-endian.
1527 LocalGuid
.Data1
= SwapBytes32 (LocalGuid
.Data1
);
1528 String
+= 2 * sizeof (LocalGuid
.Data1
) + 1;
1531 // Get eeff in big-endian.
1533 Status
= StrHexToBytes (String
, 2 * sizeof (LocalGuid
.Data2
), (UINT8
*)&LocalGuid
.Data2
, sizeof (LocalGuid
.Data2
));
1534 if (RETURN_ERROR (Status
) || (String
[2 * sizeof (LocalGuid
.Data2
)] != L
'-')) {
1535 return RETURN_UNSUPPORTED
;
1539 // Convert big-endian to little-endian.
1541 LocalGuid
.Data2
= SwapBytes16 (LocalGuid
.Data2
);
1542 String
+= 2 * sizeof (LocalGuid
.Data2
) + 1;
1545 // Get gghh in big-endian.
1547 Status
= StrHexToBytes (String
, 2 * sizeof (LocalGuid
.Data3
), (UINT8
*)&LocalGuid
.Data3
, sizeof (LocalGuid
.Data3
));
1548 if (RETURN_ERROR (Status
) || (String
[2 * sizeof (LocalGuid
.Data3
)] != L
'-')) {
1549 return RETURN_UNSUPPORTED
;
1553 // Convert big-endian to little-endian.
1555 LocalGuid
.Data3
= SwapBytes16 (LocalGuid
.Data3
);
1556 String
+= 2 * sizeof (LocalGuid
.Data3
) + 1;
1561 Status
= StrHexToBytes (String
, 2 * 2, &LocalGuid
.Data4
[0], 2);
1562 if (RETURN_ERROR (Status
) || (String
[2 * 2] != L
'-')) {
1563 return RETURN_UNSUPPORTED
;
1566 String
+= 2 * 2 + 1;
1569 // Get kkllmmnnoopp.
1571 Status
= StrHexToBytes (String
, 2 * 6, &LocalGuid
.Data4
[2], 6);
1572 if (RETURN_ERROR (Status
)) {
1573 return RETURN_UNSUPPORTED
;
1576 CopyGuid (Guid
, &LocalGuid
);
1577 return RETURN_SUCCESS
;
1581 Convert a Null-terminated Unicode hexadecimal string to a byte array.
1583 This function outputs a byte array by interpreting the contents of
1584 the Unicode string specified by String in hexadecimal format. The format of
1585 the input Unicode string String is:
1589 X is a hexadecimal digit character in the range [0-9], [a-f] and [A-F].
1590 The function decodes every two hexadecimal digit characters as one byte. The
1591 decoding stops after Length of characters and outputs Buffer containing
1594 If String is not aligned in a 16-bit boundary, then ASSERT().
1596 @param String Pointer to a Null-terminated Unicode string.
1597 @param Length The number of Unicode characters to decode.
1598 @param Buffer Pointer to the converted bytes array.
1599 @param MaxBufferSize The maximum size of Buffer.
1601 @retval RETURN_SUCCESS Buffer is translated from String.
1602 @retval RETURN_INVALID_PARAMETER If String is NULL.
1604 If Length is not multiple of 2.
1605 If PcdMaximumUnicodeStringLength is not zero,
1606 and Length is greater than
1607 PcdMaximumUnicodeStringLength.
1608 @retval RETURN_UNSUPPORTED If Length of characters from String contain
1609 a character that is not valid hexadecimal
1610 digit characters, or a Null-terminator.
1611 @retval RETURN_BUFFER_TOO_SMALL If MaxBufferSize is less than (Length / 2).
1616 IN CONST CHAR16
*String
,
1619 IN UINTN MaxBufferSize
1624 ASSERT (((UINTN
)String
& BIT0
) == 0);
1627 // 1. None of String or Buffer shall be a null pointer.
1629 SAFE_STRING_CONSTRAINT_CHECK ((String
!= NULL
), RETURN_INVALID_PARAMETER
);
1630 SAFE_STRING_CONSTRAINT_CHECK ((Buffer
!= NULL
), RETURN_INVALID_PARAMETER
);
1633 // 2. Length shall not be greater than RSIZE_MAX.
1635 if (RSIZE_MAX
!= 0) {
1636 SAFE_STRING_CONSTRAINT_CHECK ((Length
<= RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
1640 // 3. Length shall not be odd.
1642 SAFE_STRING_CONSTRAINT_CHECK (((Length
& BIT0
) == 0), RETURN_INVALID_PARAMETER
);
1645 // 4. MaxBufferSize shall equal to or greater than Length / 2.
1647 SAFE_STRING_CONSTRAINT_CHECK ((MaxBufferSize
>= Length
/ 2), RETURN_BUFFER_TOO_SMALL
);
1650 // 5. String shall not contains invalid hexadecimal digits.
1652 for (Index
= 0; Index
< Length
; Index
++) {
1653 if (!InternalIsHexaDecimalDigitCharacter (String
[Index
])) {
1658 if (Index
!= Length
) {
1659 return RETURN_UNSUPPORTED
;
1663 // Convert the hex string to bytes.
1665 for (Index
= 0; Index
< Length
; Index
++) {
1667 // For even characters, write the upper nibble for each buffer byte,
1668 // and for even characters, the lower nibble.
1670 if ((Index
& BIT0
) == 0) {
1671 Buffer
[Index
/ 2] = (UINT8
)InternalHexCharToUintn (String
[Index
]) << 4;
1673 Buffer
[Index
/ 2] |= (UINT8
)InternalHexCharToUintn (String
[Index
]);
1677 return RETURN_SUCCESS
;
1681 Returns the length of a Null-terminated Ascii string.
1683 This function is similar as strlen_s defined in C11.
1685 @param String A pointer to a Null-terminated Ascii string.
1686 @param MaxSize The maximum number of Destination Ascii
1687 char, including terminating null char.
1689 @retval 0 If String is NULL.
1690 @retval MaxSize If there is no null character in the first MaxSize characters of String.
1691 @return The number of characters that percede the terminating null character.
1697 IN CONST CHAR8
*String
,
1704 // If String is a null pointer or MaxSize is 0, then the AsciiStrnLenS function returns zero.
1706 if ((String
== NULL
) || (MaxSize
== 0)) {
1711 // Otherwise, the AsciiStrnLenS function returns the number of characters that precede the
1712 // terminating null character. If there is no null character in the first MaxSize characters of
1713 // String then AsciiStrnLenS returns MaxSize. At most the first MaxSize characters of String shall
1714 // be accessed by AsciiStrnLenS.
1717 while (String
[Length
] != 0) {
1718 if (Length
>= MaxSize
- 1) {
1729 Returns the size of a Null-terminated Ascii string in bytes, including the
1732 This function returns the size of the Null-terminated Ascii string specified
1733 by String in bytes, including the Null terminator.
1735 @param String A pointer to a Null-terminated Ascii string.
1736 @param MaxSize The maximum number of Destination Ascii
1737 char, including the Null terminator.
1739 @retval 0 If String is NULL.
1740 @retval (sizeof (CHAR8) * (MaxSize + 1))
1741 If there is no Null terminator in the first MaxSize characters of
1743 @return The size of the Null-terminated Ascii string in bytes, including the
1750 IN CONST CHAR8
*String
,
1755 // If String is a null pointer, then the AsciiStrnSizeS function returns
1758 if (String
== NULL
) {
1763 // Otherwise, the AsciiStrnSizeS function returns the size of the
1764 // Null-terminated Ascii string in bytes, including the Null terminator. If
1765 // there is no Null terminator in the first MaxSize characters of String,
1766 // then AsciiStrnSizeS returns (sizeof (CHAR8) * (MaxSize + 1)) to keep a
1767 // consistent map with the AsciiStrnLenS function.
1769 return (AsciiStrnLenS (String
, MaxSize
) + 1) * sizeof (*String
);
1773 Copies the string pointed to by Source (including the terminating null char)
1774 to the array pointed to by Destination.
1776 This function is similar as strcpy_s defined in C11.
1778 If an error is returned, then the Destination is unmodified.
1780 @param Destination A pointer to a Null-terminated Ascii string.
1781 @param DestMax The maximum number of Destination Ascii
1782 char, including terminating null char.
1783 @param Source A pointer to a Null-terminated Ascii string.
1785 @retval RETURN_SUCCESS String is copied.
1786 @retval RETURN_BUFFER_TOO_SMALL If DestMax is NOT greater than StrLen(Source).
1787 @retval RETURN_INVALID_PARAMETER If Destination is NULL.
1789 If PcdMaximumAsciiStringLength is not zero,
1790 and DestMax is greater than
1791 PcdMaximumAsciiStringLength.
1793 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.
1798 OUT CHAR8
*Destination
,
1800 IN CONST CHAR8
*Source
1806 // 1. Neither Destination nor Source shall be a null pointer.
1808 SAFE_STRING_CONSTRAINT_CHECK ((Destination
!= NULL
), RETURN_INVALID_PARAMETER
);
1809 SAFE_STRING_CONSTRAINT_CHECK ((Source
!= NULL
), RETURN_INVALID_PARAMETER
);
1812 // 2. DestMax shall not be greater than ASCII_RSIZE_MAX.
1814 if (ASCII_RSIZE_MAX
!= 0) {
1815 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
<= ASCII_RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
1819 // 3. DestMax shall not equal zero.
1821 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
!= 0), RETURN_INVALID_PARAMETER
);
1824 // 4. DestMax shall be greater than AsciiStrnLenS(Source, DestMax).
1826 SourceLen
= AsciiStrnLenS (Source
, DestMax
);
1827 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
> SourceLen
), RETURN_BUFFER_TOO_SMALL
);
1830 // 5. Copying shall not take place between objects that overlap.
1832 SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoAsciiStrOverlap (Destination
, DestMax
, (CHAR8
*)Source
, SourceLen
+ 1), RETURN_ACCESS_DENIED
);
1835 // The AsciiStrCpyS function copies the string pointed to by Source (including the terminating
1836 // null character) into the array pointed to by Destination.
1838 while (*Source
!= 0) {
1839 *(Destination
++) = *(Source
++);
1844 return RETURN_SUCCESS
;
1848 Copies not more than Length successive char from the string pointed to by
1849 Source to the array pointed to by Destination. If no null char is copied from
1850 Source, then Destination[Length] is always set to null.
1852 This function is similar as strncpy_s defined in C11.
1854 If an error is returned, then the Destination is unmodified.
1856 @param Destination A pointer to a Null-terminated Ascii string.
1857 @param DestMax The maximum number of Destination Ascii
1858 char, including terminating null char.
1859 @param Source A pointer to a Null-terminated Ascii string.
1860 @param Length The maximum number of Ascii characters to copy.
1862 @retval RETURN_SUCCESS String is copied.
1863 @retval RETURN_BUFFER_TOO_SMALL If DestMax is NOT greater than
1864 MIN(StrLen(Source), Length).
1865 @retval RETURN_INVALID_PARAMETER If Destination is NULL.
1867 If PcdMaximumAsciiStringLength is not zero,
1868 and DestMax is greater than
1869 PcdMaximumAsciiStringLength.
1871 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.
1876 OUT CHAR8
*Destination
,
1878 IN CONST CHAR8
*Source
,
1885 // 1. Neither Destination nor Source shall be a null pointer.
1887 SAFE_STRING_CONSTRAINT_CHECK ((Destination
!= NULL
), RETURN_INVALID_PARAMETER
);
1888 SAFE_STRING_CONSTRAINT_CHECK ((Source
!= NULL
), RETURN_INVALID_PARAMETER
);
1891 // 2. Neither DestMax nor Length shall be greater than ASCII_RSIZE_MAX
1893 if (ASCII_RSIZE_MAX
!= 0) {
1894 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
<= ASCII_RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
1895 SAFE_STRING_CONSTRAINT_CHECK ((Length
<= ASCII_RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
1899 // 3. DestMax shall not equal zero.
1901 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
!= 0), RETURN_INVALID_PARAMETER
);
1904 // 4. If Length is not less than DestMax, then DestMax shall be greater than AsciiStrnLenS(Source, DestMax).
1906 SourceLen
= AsciiStrnLenS (Source
, MIN (DestMax
, Length
));
1907 if (Length
>= DestMax
) {
1908 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
> SourceLen
), RETURN_BUFFER_TOO_SMALL
);
1912 // 5. Copying shall not take place between objects that overlap.
1914 if (SourceLen
> Length
) {
1918 SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoAsciiStrOverlap (Destination
, DestMax
, (CHAR8
*)Source
, SourceLen
+ 1), RETURN_ACCESS_DENIED
);
1921 // The AsciiStrnCpyS function copies not more than Length successive characters (characters that
1922 // follow a null character are not copied) from the array pointed to by Source to the array
1923 // pointed to by Destination. If no null character was copied from Source, then Destination[Length] is set to a null
1926 while ((SourceLen
> 0) && (*Source
!= 0)) {
1927 *(Destination
++) = *(Source
++);
1933 return RETURN_SUCCESS
;
1937 Appends a copy of the string pointed to by Source (including the terminating
1938 null char) to the end of the string pointed to by Destination.
1940 This function is similar as strcat_s defined in C11.
1942 If an error is returned, then the Destination is unmodified.
1944 @param Destination A pointer to a Null-terminated Ascii string.
1945 @param DestMax The maximum number of Destination Ascii
1946 char, including terminating null char.
1947 @param Source A pointer to a Null-terminated Ascii string.
1949 @retval RETURN_SUCCESS String is appended.
1950 @retval RETURN_BAD_BUFFER_SIZE If DestMax is NOT greater than
1951 StrLen(Destination).
1952 @retval RETURN_BUFFER_TOO_SMALL If (DestMax - StrLen(Destination)) is NOT
1953 greater than StrLen(Source).
1954 @retval RETURN_INVALID_PARAMETER If Destination is NULL.
1956 If PcdMaximumAsciiStringLength is not zero,
1957 and DestMax is greater than
1958 PcdMaximumAsciiStringLength.
1960 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.
1965 IN OUT CHAR8
*Destination
,
1967 IN CONST CHAR8
*Source
1975 // Let CopyLen denote the value DestMax - AsciiStrnLenS(Destination, DestMax) upon entry to AsciiStrCatS.
1977 DestLen
= AsciiStrnLenS (Destination
, DestMax
);
1978 CopyLen
= DestMax
- DestLen
;
1981 // 1. Neither Destination nor Source shall be a null pointer.
1983 SAFE_STRING_CONSTRAINT_CHECK ((Destination
!= NULL
), RETURN_INVALID_PARAMETER
);
1984 SAFE_STRING_CONSTRAINT_CHECK ((Source
!= NULL
), RETURN_INVALID_PARAMETER
);
1987 // 2. DestMax shall not be greater than ASCII_RSIZE_MAX.
1989 if (ASCII_RSIZE_MAX
!= 0) {
1990 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
<= ASCII_RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
1994 // 3. DestMax shall not equal zero.
1996 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
!= 0), RETURN_INVALID_PARAMETER
);
1999 // 4. CopyLen shall not equal zero.
2001 SAFE_STRING_CONSTRAINT_CHECK ((CopyLen
!= 0), RETURN_BAD_BUFFER_SIZE
);
2004 // 5. CopyLen shall be greater than AsciiStrnLenS(Source, CopyLen).
2006 SourceLen
= AsciiStrnLenS (Source
, CopyLen
);
2007 SAFE_STRING_CONSTRAINT_CHECK ((CopyLen
> SourceLen
), RETURN_BUFFER_TOO_SMALL
);
2010 // 6. Copying shall not take place between objects that overlap.
2012 SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoAsciiStrOverlap (Destination
, DestMax
, (CHAR8
*)Source
, SourceLen
+ 1), RETURN_ACCESS_DENIED
);
2015 // The AsciiStrCatS function appends a copy of the string pointed to by Source (including the
2016 // terminating null character) to the end of the string pointed to by Destination. The initial character
2017 // from Source overwrites the null character at the end of Destination.
2019 Destination
= Destination
+ DestLen
;
2020 while (*Source
!= 0) {
2021 *(Destination
++) = *(Source
++);
2026 return RETURN_SUCCESS
;
2030 Appends not more than Length successive char from the string pointed to by
2031 Source to the end of the string pointed to by Destination. If no null char is
2032 copied from Source, then Destination[StrLen(Destination) + Length] is always
2035 This function is similar as strncat_s defined in C11.
2037 If an error is returned, then the Destination is unmodified.
2039 @param Destination A pointer to a Null-terminated Ascii string.
2040 @param DestMax The maximum number of Destination Ascii
2041 char, including terminating null char.
2042 @param Source A pointer to a Null-terminated Ascii string.
2043 @param Length The maximum number of Ascii characters to copy.
2045 @retval RETURN_SUCCESS String is appended.
2046 @retval RETURN_BAD_BUFFER_SIZE If DestMax is NOT greater than
2047 StrLen(Destination).
2048 @retval RETURN_BUFFER_TOO_SMALL If (DestMax - StrLen(Destination)) is NOT
2049 greater than MIN(StrLen(Source), Length).
2050 @retval RETURN_INVALID_PARAMETER If Destination is NULL.
2052 If PcdMaximumAsciiStringLength is not zero,
2053 and DestMax is greater than
2054 PcdMaximumAsciiStringLength.
2056 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.
2061 IN OUT CHAR8
*Destination
,
2063 IN CONST CHAR8
*Source
,
2072 // Let CopyLen denote the value DestMax - AsciiStrnLenS(Destination, DestMax) upon entry to AsciiStrnCatS.
2074 DestLen
= AsciiStrnLenS (Destination
, DestMax
);
2075 CopyLen
= DestMax
- DestLen
;
2078 // 1. Neither Destination nor Source shall be a null pointer.
2080 SAFE_STRING_CONSTRAINT_CHECK ((Destination
!= NULL
), RETURN_INVALID_PARAMETER
);
2081 SAFE_STRING_CONSTRAINT_CHECK ((Source
!= NULL
), RETURN_INVALID_PARAMETER
);
2084 // 2. Neither DestMax nor Length shall be greater than ASCII_RSIZE_MAX.
2086 if (ASCII_RSIZE_MAX
!= 0) {
2087 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
<= ASCII_RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
2088 SAFE_STRING_CONSTRAINT_CHECK ((Length
<= ASCII_RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
2092 // 3. DestMax shall not equal zero.
2094 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
!= 0), RETURN_INVALID_PARAMETER
);
2097 // 4. CopyLen shall not equal zero.
2099 SAFE_STRING_CONSTRAINT_CHECK ((CopyLen
!= 0), RETURN_BAD_BUFFER_SIZE
);
2102 // 5. If Length is not less than CopyLen, then CopyLen shall be greater than AsciiStrnLenS(Source, CopyLen).
2104 SourceLen
= AsciiStrnLenS (Source
, MIN (CopyLen
, Length
));
2105 if (Length
>= CopyLen
) {
2106 SAFE_STRING_CONSTRAINT_CHECK ((CopyLen
> SourceLen
), RETURN_BUFFER_TOO_SMALL
);
2110 // 6. Copying shall not take place between objects that overlap.
2112 if (SourceLen
> Length
) {
2116 SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoAsciiStrOverlap (Destination
, DestMax
, (CHAR8
*)Source
, SourceLen
+ 1), RETURN_ACCESS_DENIED
);
2119 // The AsciiStrnCatS function appends not more than Length successive characters (characters
2120 // that follow a null character are not copied) from the array pointed to by Source to the end of
2121 // the string pointed to by Destination. The initial character from Source overwrites the null character at
2122 // the end of Destination. If no null character was copied from Source, then Destination[DestMax-CopyLen+Length] is set to
2123 // a null character.
2125 Destination
= Destination
+ DestLen
;
2126 while ((SourceLen
> 0) && (*Source
!= 0)) {
2127 *(Destination
++) = *(Source
++);
2133 return RETURN_SUCCESS
;
2137 Convert a Null-terminated Ascii decimal string to a value of type UINTN.
2139 This function outputs a value of type UINTN by interpreting the contents of
2140 the Ascii string specified by String as a decimal number. The format of the
2141 input Ascii string String is:
2143 [spaces] [decimal digits].
2145 The valid decimal digit character is in the range [0-9]. The function will
2146 ignore the pad space, which includes spaces or tab characters, before
2147 [decimal digits]. The running zero in the beginning of [decimal digits] will
2148 be ignored. Then, the function stops at the first character that is a not a
2149 valid decimal character or a Null-terminator, whichever one comes first.
2151 If String has no valid decimal digits in the above format, then 0 is stored
2152 at the location pointed to by Data.
2153 If the number represented by String exceeds the range defined by UINTN, then
2154 MAX_UINTN is stored at the location pointed to by Data.
2156 If EndPointer is not NULL, a pointer to the character that stopped the scan
2157 is stored at the location pointed to by EndPointer. If String has no valid
2158 decimal digits right after the optional pad spaces, the value of String is
2159 stored at the location pointed to by EndPointer.
2161 @param String Pointer to a Null-terminated Ascii string.
2162 @param EndPointer Pointer to character that stops scan.
2163 @param Data Pointer to the converted value.
2165 @retval RETURN_SUCCESS Value is translated from String.
2166 @retval RETURN_INVALID_PARAMETER If String is NULL.
2168 If PcdMaximumAsciiStringLength is not zero,
2169 and String contains more than
2170 PcdMaximumAsciiStringLength Ascii
2171 characters, not including the
2173 @retval RETURN_UNSUPPORTED If the number represented by String exceeds
2174 the range defined by UINTN.
2179 AsciiStrDecimalToUintnS (
2180 IN CONST CHAR8
*String
,
2181 OUT CHAR8
**EndPointer OPTIONAL
,
2186 // 1. Neither String nor Data shall be a null pointer.
2188 SAFE_STRING_CONSTRAINT_CHECK ((String
!= NULL
), RETURN_INVALID_PARAMETER
);
2189 SAFE_STRING_CONSTRAINT_CHECK ((Data
!= NULL
), RETURN_INVALID_PARAMETER
);
2192 // 2. The length of String shall not be greater than ASCII_RSIZE_MAX.
2194 if (ASCII_RSIZE_MAX
!= 0) {
2195 SAFE_STRING_CONSTRAINT_CHECK ((AsciiStrnLenS (String
, ASCII_RSIZE_MAX
+ 1) <= ASCII_RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
2198 if (EndPointer
!= NULL
) {
2199 *EndPointer
= (CHAR8
*)String
;
2203 // Ignore the pad spaces (space or tab)
2205 while ((*String
== ' ') || (*String
== '\t')) {
2210 // Ignore leading Zeros after the spaces
2212 while (*String
== '0') {
2218 while (InternalAsciiIsDecimalDigitCharacter (*String
)) {
2220 // If the number represented by String overflows according to the range
2221 // defined by UINTN, then MAX_UINTN is stored in *Data and
2222 // RETURN_UNSUPPORTED is returned.
2224 if (*Data
> ((MAX_UINTN
- (*String
- '0')) / 10)) {
2226 if (EndPointer
!= NULL
) {
2227 *EndPointer
= (CHAR8
*)String
;
2230 return RETURN_UNSUPPORTED
;
2233 *Data
= *Data
* 10 + (*String
- '0');
2237 if (EndPointer
!= NULL
) {
2238 *EndPointer
= (CHAR8
*)String
;
2241 return RETURN_SUCCESS
;
2245 Convert a Null-terminated Ascii decimal string to a value of type UINT64.
2247 This function outputs a value of type UINT64 by interpreting the contents of
2248 the Ascii string specified by String as a decimal number. The format of the
2249 input Ascii string String is:
2251 [spaces] [decimal digits].
2253 The valid decimal digit character is in the range [0-9]. The function will
2254 ignore the pad space, which includes spaces or tab characters, before
2255 [decimal digits]. The running zero in the beginning of [decimal digits] will
2256 be ignored. Then, the function stops at the first character that is a not a
2257 valid decimal character or a Null-terminator, whichever one comes first.
2259 If String has no valid decimal digits in the above format, then 0 is stored
2260 at the location pointed to by Data.
2261 If the number represented by String exceeds the range defined by UINT64, then
2262 MAX_UINT64 is stored at the location pointed to by Data.
2264 If EndPointer is not NULL, a pointer to the character that stopped the scan
2265 is stored at the location pointed to by EndPointer. If String has no valid
2266 decimal digits right after the optional pad spaces, the value of String is
2267 stored at the location pointed to by EndPointer.
2269 @param String Pointer to a Null-terminated Ascii string.
2270 @param EndPointer Pointer to character that stops scan.
2271 @param Data Pointer to the converted value.
2273 @retval RETURN_SUCCESS Value is translated from String.
2274 @retval RETURN_INVALID_PARAMETER If String is NULL.
2276 If PcdMaximumAsciiStringLength is not zero,
2277 and String contains more than
2278 PcdMaximumAsciiStringLength Ascii
2279 characters, not including the
2281 @retval RETURN_UNSUPPORTED If the number represented by String exceeds
2282 the range defined by UINT64.
2287 AsciiStrDecimalToUint64S (
2288 IN CONST CHAR8
*String
,
2289 OUT CHAR8
**EndPointer OPTIONAL
,
2294 // 1. Neither String nor Data shall be a null pointer.
2296 SAFE_STRING_CONSTRAINT_CHECK ((String
!= NULL
), RETURN_INVALID_PARAMETER
);
2297 SAFE_STRING_CONSTRAINT_CHECK ((Data
!= NULL
), RETURN_INVALID_PARAMETER
);
2300 // 2. The length of String shall not be greater than ASCII_RSIZE_MAX.
2302 if (ASCII_RSIZE_MAX
!= 0) {
2303 SAFE_STRING_CONSTRAINT_CHECK ((AsciiStrnLenS (String
, ASCII_RSIZE_MAX
+ 1) <= ASCII_RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
2306 if (EndPointer
!= NULL
) {
2307 *EndPointer
= (CHAR8
*)String
;
2311 // Ignore the pad spaces (space or tab)
2313 while ((*String
== ' ') || (*String
== '\t')) {
2318 // Ignore leading Zeros after the spaces
2320 while (*String
== '0') {
2326 while (InternalAsciiIsDecimalDigitCharacter (*String
)) {
2328 // If the number represented by String overflows according to the range
2329 // defined by UINT64, then MAX_UINT64 is stored in *Data and
2330 // RETURN_UNSUPPORTED is returned.
2332 if (*Data
> DivU64x32 (MAX_UINT64
- (*String
- '0'), 10)) {
2334 if (EndPointer
!= NULL
) {
2335 *EndPointer
= (CHAR8
*)String
;
2338 return RETURN_UNSUPPORTED
;
2341 *Data
= MultU64x32 (*Data
, 10) + (*String
- '0');
2345 if (EndPointer
!= NULL
) {
2346 *EndPointer
= (CHAR8
*)String
;
2349 return RETURN_SUCCESS
;
2353 Convert a Null-terminated Ascii hexadecimal string to a value of type UINTN.
2355 This function outputs a value of type UINTN by interpreting the contents of
2356 the Ascii string specified by String as a hexadecimal number. The format of
2357 the input Ascii string String is:
2359 [spaces][zeros][x][hexadecimal digits].
2361 The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].
2362 The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix. If
2363 "x" appears in the input string, it must be prefixed with at least one 0. The
2364 function will ignore the pad space, which includes spaces or tab characters,
2365 before [zeros], [x] or [hexadecimal digits]. The running zero before [x] or
2366 [hexadecimal digits] will be ignored. Then, the decoding starts after [x] or
2367 the first valid hexadecimal digit. Then, the function stops at the first
2368 character that is a not a valid hexadecimal character or Null-terminator,
2369 whichever on comes first.
2371 If String has no valid hexadecimal digits in the above format, then 0 is
2372 stored at the location pointed to by Data.
2373 If the number represented by String exceeds the range defined by UINTN, then
2374 MAX_UINTN is stored at the location pointed to by Data.
2376 If EndPointer is not NULL, a pointer to the character that stopped the scan
2377 is stored at the location pointed to by EndPointer. If String has no valid
2378 hexadecimal digits right after the optional pad spaces, the value of String
2379 is stored at the location pointed to by EndPointer.
2381 @param String Pointer to a Null-terminated Ascii string.
2382 @param EndPointer Pointer to character that stops scan.
2383 @param Data Pointer to the converted value.
2385 @retval RETURN_SUCCESS Value is translated from String.
2386 @retval RETURN_INVALID_PARAMETER If String is NULL.
2388 If PcdMaximumAsciiStringLength is not zero,
2389 and String contains more than
2390 PcdMaximumAsciiStringLength Ascii
2391 characters, not including the
2393 @retval RETURN_UNSUPPORTED If the number represented by String exceeds
2394 the range defined by UINTN.
2399 AsciiStrHexToUintnS (
2400 IN CONST CHAR8
*String
,
2401 OUT CHAR8
**EndPointer OPTIONAL
,
2405 BOOLEAN FoundLeadingZero
;
2407 FoundLeadingZero
= FALSE
;
2409 // 1. Neither String nor Data shall be a null pointer.
2411 SAFE_STRING_CONSTRAINT_CHECK ((String
!= NULL
), RETURN_INVALID_PARAMETER
);
2412 SAFE_STRING_CONSTRAINT_CHECK ((Data
!= NULL
), RETURN_INVALID_PARAMETER
);
2415 // 2. The length of String shall not be greater than ASCII_RSIZE_MAX.
2417 if (ASCII_RSIZE_MAX
!= 0) {
2418 SAFE_STRING_CONSTRAINT_CHECK ((AsciiStrnLenS (String
, ASCII_RSIZE_MAX
+ 1) <= ASCII_RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
2421 if (EndPointer
!= NULL
) {
2422 *EndPointer
= (CHAR8
*)String
;
2426 // Ignore the pad spaces (space or tab)
2428 while ((*String
== ' ') || (*String
== '\t')) {
2433 // Ignore leading Zeros after the spaces
2435 FoundLeadingZero
= *String
== '0';
2436 while (*String
== '0') {
2440 if (AsciiCharToUpper (*String
) == 'X') {
2441 if (!FoundLeadingZero
) {
2443 return RETURN_SUCCESS
;
2454 while (InternalAsciiIsHexaDecimalDigitCharacter (*String
)) {
2456 // If the number represented by String overflows according to the range
2457 // defined by UINTN, then MAX_UINTN is stored in *Data and
2458 // RETURN_UNSUPPORTED is returned.
2460 if (*Data
> ((MAX_UINTN
- InternalAsciiHexCharToUintn (*String
)) >> 4)) {
2462 if (EndPointer
!= NULL
) {
2463 *EndPointer
= (CHAR8
*)String
;
2466 return RETURN_UNSUPPORTED
;
2469 *Data
= (*Data
<< 4) + InternalAsciiHexCharToUintn (*String
);
2473 if (EndPointer
!= NULL
) {
2474 *EndPointer
= (CHAR8
*)String
;
2477 return RETURN_SUCCESS
;
2481 Convert a Null-terminated Ascii hexadecimal string to a value of type UINT64.
2483 This function outputs a value of type UINT64 by interpreting the contents of
2484 the Ascii string specified by String as a hexadecimal number. The format of
2485 the input Ascii string String is:
2487 [spaces][zeros][x][hexadecimal digits].
2489 The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].
2490 The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix. If
2491 "x" appears in the input string, it must be prefixed with at least one 0. The
2492 function will ignore the pad space, which includes spaces or tab characters,
2493 before [zeros], [x] or [hexadecimal digits]. The running zero before [x] or
2494 [hexadecimal digits] will be ignored. Then, the decoding starts after [x] or
2495 the first valid hexadecimal digit. Then, the function stops at the first
2496 character that is a not a valid hexadecimal character or Null-terminator,
2497 whichever on comes first.
2499 If String has no valid hexadecimal digits in the above format, then 0 is
2500 stored at the location pointed to by Data.
2501 If the number represented by String exceeds the range defined by UINT64, then
2502 MAX_UINT64 is stored at the location pointed to by Data.
2504 If EndPointer is not NULL, a pointer to the character that stopped the scan
2505 is stored at the location pointed to by EndPointer. If String has no valid
2506 hexadecimal digits right after the optional pad spaces, the value of String
2507 is stored at the location pointed to by EndPointer.
2509 @param String Pointer to a Null-terminated Ascii string.
2510 @param EndPointer Pointer to character that stops scan.
2511 @param Data Pointer to the converted value.
2513 @retval RETURN_SUCCESS Value is translated from String.
2514 @retval RETURN_INVALID_PARAMETER If String is NULL.
2516 If PcdMaximumAsciiStringLength is not zero,
2517 and String contains more than
2518 PcdMaximumAsciiStringLength Ascii
2519 characters, not including the
2521 @retval RETURN_UNSUPPORTED If the number represented by String exceeds
2522 the range defined by UINT64.
2527 AsciiStrHexToUint64S (
2528 IN CONST CHAR8
*String
,
2529 OUT CHAR8
**EndPointer OPTIONAL
,
2533 BOOLEAN FoundLeadingZero
;
2535 FoundLeadingZero
= FALSE
;
2537 // 1. Neither String nor Data shall be a null pointer.
2539 SAFE_STRING_CONSTRAINT_CHECK ((String
!= NULL
), RETURN_INVALID_PARAMETER
);
2540 SAFE_STRING_CONSTRAINT_CHECK ((Data
!= NULL
), RETURN_INVALID_PARAMETER
);
2543 // 2. The length of String shall not be greater than ASCII_RSIZE_MAX.
2545 if (ASCII_RSIZE_MAX
!= 0) {
2546 SAFE_STRING_CONSTRAINT_CHECK ((AsciiStrnLenS (String
, ASCII_RSIZE_MAX
+ 1) <= ASCII_RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
2549 if (EndPointer
!= NULL
) {
2550 *EndPointer
= (CHAR8
*)String
;
2554 // Ignore the pad spaces (space or tab)
2556 while ((*String
== ' ') || (*String
== '\t')) {
2561 // Ignore leading Zeros after the spaces
2563 FoundLeadingZero
= *String
== '0';
2564 while (*String
== '0') {
2568 if (AsciiCharToUpper (*String
) == 'X') {
2569 if (!FoundLeadingZero
) {
2571 return RETURN_SUCCESS
;
2582 while (InternalAsciiIsHexaDecimalDigitCharacter (*String
)) {
2584 // If the number represented by String overflows according to the range
2585 // defined by UINT64, then MAX_UINT64 is stored in *Data and
2586 // RETURN_UNSUPPORTED is returned.
2588 if (*Data
> RShiftU64 (MAX_UINT64
- InternalAsciiHexCharToUintn (*String
), 4)) {
2590 if (EndPointer
!= NULL
) {
2591 *EndPointer
= (CHAR8
*)String
;
2594 return RETURN_UNSUPPORTED
;
2597 *Data
= LShiftU64 (*Data
, 4) + InternalAsciiHexCharToUintn (*String
);
2601 if (EndPointer
!= NULL
) {
2602 *EndPointer
= (CHAR8
*)String
;
2605 return RETURN_SUCCESS
;
2609 Convert a Null-terminated Unicode string to a Null-terminated
2612 This function is similar to AsciiStrCpyS.
2614 This function converts the content of the Unicode string Source
2615 to the ASCII string Destination by copying the lower 8 bits of
2616 each Unicode character. The function terminates the ASCII string
2617 Destination by appending a Null-terminator character at the end.
2619 The caller is responsible to make sure Destination points to a buffer with size
2620 equal or greater than ((StrLen (Source) + 1) * sizeof (CHAR8)) in bytes.
2622 If any Unicode characters in Source contain non-zero value in
2623 the upper 8 bits, then ASSERT().
2625 If Source is not aligned on a 16-bit boundary, then ASSERT().
2627 If an error is returned, then the Destination is unmodified.
2629 @param Source The pointer to a Null-terminated Unicode string.
2630 @param Destination The pointer to a Null-terminated ASCII string.
2631 @param DestMax The maximum number of Destination Ascii
2632 char, including terminating null char.
2634 @retval RETURN_SUCCESS String is converted.
2635 @retval RETURN_BUFFER_TOO_SMALL If DestMax is NOT greater than StrLen(Source).
2636 @retval RETURN_INVALID_PARAMETER If Destination is NULL.
2638 If PcdMaximumAsciiStringLength is not zero,
2639 and DestMax is greater than
2640 PcdMaximumAsciiStringLength.
2641 If PcdMaximumUnicodeStringLength is not zero,
2642 and DestMax is greater than
2643 PcdMaximumUnicodeStringLength.
2645 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.
2650 UnicodeStrToAsciiStrS (
2651 IN CONST CHAR16
*Source
,
2652 OUT CHAR8
*Destination
,
2658 ASSERT (((UINTN
)Source
& BIT0
) == 0);
2661 // 1. Neither Destination nor Source shall be a null pointer.
2663 SAFE_STRING_CONSTRAINT_CHECK ((Destination
!= NULL
), RETURN_INVALID_PARAMETER
);
2664 SAFE_STRING_CONSTRAINT_CHECK ((Source
!= NULL
), RETURN_INVALID_PARAMETER
);
2667 // 2. DestMax shall not be greater than ASCII_RSIZE_MAX or RSIZE_MAX.
2669 if (ASCII_RSIZE_MAX
!= 0) {
2670 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
<= ASCII_RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
2673 if (RSIZE_MAX
!= 0) {
2674 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
<= RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
2678 // 3. DestMax shall not equal zero.
2680 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
!= 0), RETURN_INVALID_PARAMETER
);
2683 // 4. DestMax shall be greater than StrnLenS (Source, DestMax).
2685 SourceLen
= StrnLenS (Source
, DestMax
);
2686 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
> SourceLen
), RETURN_BUFFER_TOO_SMALL
);
2689 // 5. Copying shall not take place between objects that overlap.
2691 SAFE_STRING_CONSTRAINT_CHECK (!InternalSafeStringIsOverlap (Destination
, DestMax
, (VOID
*)Source
, (SourceLen
+ 1) * sizeof (CHAR16
)), RETURN_ACCESS_DENIED
);
2696 while (*Source
!= '\0') {
2698 // If any Unicode characters in Source contain
2699 // non-zero value in the upper 8 bits, then ASSERT().
2701 ASSERT (*Source
< 0x100);
2702 *(Destination
++) = (CHAR8
)*(Source
++);
2705 *Destination
= '\0';
2707 return RETURN_SUCCESS
;
2711 Convert not more than Length successive characters from a Null-terminated
2712 Unicode string to a Null-terminated Ascii string. If no null char is copied
2713 from Source, then Destination[Length] is always set to null.
2715 This function converts not more than Length successive characters from the
2716 Unicode string Source to the Ascii string Destination by copying the lower 8
2717 bits of each Unicode character. The function terminates the Ascii string
2718 Destination by appending a Null-terminator character at the end.
2720 The caller is responsible to make sure Destination points to a buffer with
2721 size not smaller than ((MIN(StrLen(Source), Length) + 1) * sizeof (CHAR8))
2724 If any Unicode characters in Source contain non-zero value in the upper 8
2725 bits, then ASSERT().
2726 If Source is not aligned on a 16-bit boundary, then ASSERT().
2728 If an error is returned, then Destination and DestinationLength are
2731 @param Source The pointer to a Null-terminated Unicode string.
2732 @param Length The maximum number of Unicode characters to
2734 @param Destination The pointer to a Null-terminated Ascii string.
2735 @param DestMax The maximum number of Destination Ascii char,
2736 including terminating null char.
2737 @param DestinationLength The number of Unicode characters converted.
2739 @retval RETURN_SUCCESS String is converted.
2740 @retval RETURN_INVALID_PARAMETER If Destination is NULL.
2742 If DestinationLength is NULL.
2743 If PcdMaximumAsciiStringLength is not zero,
2744 and Length or DestMax is greater than
2745 PcdMaximumAsciiStringLength.
2746 If PcdMaximumUnicodeStringLength is not
2747 zero, and Length or DestMax is greater than
2748 PcdMaximumUnicodeStringLength.
2750 @retval RETURN_BUFFER_TOO_SMALL If DestMax is NOT greater than
2751 MIN(StrLen(Source), Length).
2752 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.
2757 UnicodeStrnToAsciiStrS (
2758 IN CONST CHAR16
*Source
,
2760 OUT CHAR8
*Destination
,
2762 OUT UINTN
*DestinationLength
2767 ASSERT (((UINTN
)Source
& BIT0
) == 0);
2770 // 1. None of Destination, Source or DestinationLength shall be a null
2773 SAFE_STRING_CONSTRAINT_CHECK ((Destination
!= NULL
), RETURN_INVALID_PARAMETER
);
2774 SAFE_STRING_CONSTRAINT_CHECK ((Source
!= NULL
), RETURN_INVALID_PARAMETER
);
2775 SAFE_STRING_CONSTRAINT_CHECK ((DestinationLength
!= NULL
), RETURN_INVALID_PARAMETER
);
2778 // 2. Neither Length nor DestMax shall be greater than ASCII_RSIZE_MAX or
2781 if (ASCII_RSIZE_MAX
!= 0) {
2782 SAFE_STRING_CONSTRAINT_CHECK ((Length
<= ASCII_RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
2783 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
<= ASCII_RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
2786 if (RSIZE_MAX
!= 0) {
2787 SAFE_STRING_CONSTRAINT_CHECK ((Length
<= RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
2788 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
<= RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
2792 // 3. DestMax shall not equal zero.
2794 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
!= 0), RETURN_INVALID_PARAMETER
);
2797 // 4. If Length is not less than DestMax, then DestMax shall be greater than
2798 // StrnLenS(Source, DestMax).
2800 SourceLen
= StrnLenS (Source
, DestMax
);
2801 if (Length
>= DestMax
) {
2802 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
> SourceLen
), RETURN_BUFFER_TOO_SMALL
);
2806 // 5. Copying shall not take place between objects that overlap.
2808 if (SourceLen
> Length
) {
2812 SAFE_STRING_CONSTRAINT_CHECK (!InternalSafeStringIsOverlap (Destination
, DestMax
, (VOID
*)Source
, (SourceLen
+ 1) * sizeof (CHAR16
)), RETURN_ACCESS_DENIED
);
2814 *DestinationLength
= 0;
2819 while ((*Source
!= 0) && (SourceLen
> 0)) {
2821 // If any Unicode characters in Source contain non-zero value in the upper
2822 // 8 bits, then ASSERT().
2824 ASSERT (*Source
< 0x100);
2825 *(Destination
++) = (CHAR8
)*(Source
++);
2827 (*DestinationLength
)++;
2832 return RETURN_SUCCESS
;
2836 Convert one Null-terminated ASCII string to a Null-terminated
2839 This function is similar to StrCpyS.
2841 This function converts the contents of the ASCII string Source to the Unicode
2842 string Destination. The function terminates the Unicode string Destination by
2843 appending a Null-terminator character at the end.
2845 The caller is responsible to make sure Destination points to a buffer with size
2846 equal or greater than ((AsciiStrLen (Source) + 1) * sizeof (CHAR16)) in bytes.
2848 If Destination is not aligned on a 16-bit boundary, then ASSERT().
2850 If an error is returned, then the Destination is unmodified.
2852 @param Source The pointer to a Null-terminated ASCII string.
2853 @param Destination The pointer to a Null-terminated Unicode string.
2854 @param DestMax The maximum number of Destination Unicode
2855 char, including terminating null char.
2857 @retval RETURN_SUCCESS String is converted.
2858 @retval RETURN_BUFFER_TOO_SMALL If DestMax is NOT greater than StrLen(Source).
2859 @retval RETURN_INVALID_PARAMETER If Destination is NULL.
2861 If PcdMaximumUnicodeStringLength is not zero,
2862 and DestMax is greater than
2863 PcdMaximumUnicodeStringLength.
2864 If PcdMaximumAsciiStringLength is not zero,
2865 and DestMax is greater than
2866 PcdMaximumAsciiStringLength.
2868 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.
2873 AsciiStrToUnicodeStrS (
2874 IN CONST CHAR8
*Source
,
2875 OUT CHAR16
*Destination
,
2881 ASSERT (((UINTN
)Destination
& BIT0
) == 0);
2884 // 1. Neither Destination nor Source shall be a null pointer.
2886 SAFE_STRING_CONSTRAINT_CHECK ((Destination
!= NULL
), RETURN_INVALID_PARAMETER
);
2887 SAFE_STRING_CONSTRAINT_CHECK ((Source
!= NULL
), RETURN_INVALID_PARAMETER
);
2890 // 2. DestMax shall not be greater than RSIZE_MAX or ASCII_RSIZE_MAX.
2892 if (RSIZE_MAX
!= 0) {
2893 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
<= RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
2896 if (ASCII_RSIZE_MAX
!= 0) {
2897 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
<= ASCII_RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
2901 // 3. DestMax shall not equal zero.
2903 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
!= 0), RETURN_INVALID_PARAMETER
);
2906 // 4. DestMax shall be greater than AsciiStrnLenS(Source, DestMax).
2908 SourceLen
= AsciiStrnLenS (Source
, DestMax
);
2909 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
> SourceLen
), RETURN_BUFFER_TOO_SMALL
);
2912 // 5. Copying shall not take place between objects that overlap.
2914 SAFE_STRING_CONSTRAINT_CHECK (!InternalSafeStringIsOverlap (Destination
, DestMax
* sizeof (CHAR16
), (VOID
*)Source
, SourceLen
+ 1), RETURN_ACCESS_DENIED
);
2919 while (*Source
!= '\0') {
2920 *(Destination
++) = (CHAR16
)(UINT8
)*(Source
++);
2923 *Destination
= '\0';
2925 return RETURN_SUCCESS
;
2929 Convert not more than Length successive characters from a Null-terminated
2930 Ascii string to a Null-terminated Unicode string. If no null char is copied
2931 from Source, then Destination[Length] is always set to null.
2933 This function converts not more than Length successive characters from the
2934 Ascii string Source to the Unicode string Destination. The function
2935 terminates the Unicode string Destination by appending a Null-terminator
2936 character at the end.
2938 The caller is responsible to make sure Destination points to a buffer with
2939 size not smaller than
2940 ((MIN(AsciiStrLen(Source), Length) + 1) * sizeof (CHAR8)) in bytes.
2942 If Destination is not aligned on a 16-bit boundary, then ASSERT().
2944 If an error is returned, then Destination and DestinationLength are
2947 @param Source The pointer to a Null-terminated Ascii string.
2948 @param Length The maximum number of Ascii characters to convert.
2949 @param Destination The pointer to a Null-terminated Unicode string.
2950 @param DestMax The maximum number of Destination Unicode char,
2951 including terminating null char.
2952 @param DestinationLength The number of Ascii characters converted.
2954 @retval RETURN_SUCCESS String is converted.
2955 @retval RETURN_INVALID_PARAMETER If Destination is NULL.
2957 If DestinationLength is NULL.
2958 If PcdMaximumUnicodeStringLength is not
2959 zero, and Length or DestMax is greater than
2960 PcdMaximumUnicodeStringLength.
2961 If PcdMaximumAsciiStringLength is not zero,
2962 and Length or DestMax is greater than
2963 PcdMaximumAsciiStringLength.
2965 @retval RETURN_BUFFER_TOO_SMALL If DestMax is NOT greater than
2966 MIN(AsciiStrLen(Source), Length).
2967 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.
2972 AsciiStrnToUnicodeStrS (
2973 IN CONST CHAR8
*Source
,
2975 OUT CHAR16
*Destination
,
2977 OUT UINTN
*DestinationLength
2982 ASSERT (((UINTN
)Destination
& BIT0
) == 0);
2985 // 1. None of Destination, Source or DestinationLength shall be a null
2988 SAFE_STRING_CONSTRAINT_CHECK ((Destination
!= NULL
), RETURN_INVALID_PARAMETER
);
2989 SAFE_STRING_CONSTRAINT_CHECK ((Source
!= NULL
), RETURN_INVALID_PARAMETER
);
2990 SAFE_STRING_CONSTRAINT_CHECK ((DestinationLength
!= NULL
), RETURN_INVALID_PARAMETER
);
2993 // 2. Neither Length nor DestMax shall be greater than ASCII_RSIZE_MAX or
2996 if (RSIZE_MAX
!= 0) {
2997 SAFE_STRING_CONSTRAINT_CHECK ((Length
<= RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
2998 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
<= RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
3001 if (ASCII_RSIZE_MAX
!= 0) {
3002 SAFE_STRING_CONSTRAINT_CHECK ((Length
<= ASCII_RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
3003 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
<= ASCII_RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
3007 // 3. DestMax shall not equal zero.
3009 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
!= 0), RETURN_INVALID_PARAMETER
);
3012 // 4. If Length is not less than DestMax, then DestMax shall be greater than
3013 // AsciiStrnLenS(Source, DestMax).
3015 SourceLen
= AsciiStrnLenS (Source
, DestMax
);
3016 if (Length
>= DestMax
) {
3017 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
> SourceLen
), RETURN_BUFFER_TOO_SMALL
);
3021 // 5. Copying shall not take place between objects that overlap.
3023 if (SourceLen
> Length
) {
3027 SAFE_STRING_CONSTRAINT_CHECK (!InternalSafeStringIsOverlap (Destination
, DestMax
* sizeof (CHAR16
), (VOID
*)Source
, SourceLen
+ 1), RETURN_ACCESS_DENIED
);
3029 *DestinationLength
= 0;
3034 while ((*Source
!= 0) && (SourceLen
> 0)) {
3035 *(Destination
++) = (CHAR16
)(UINT8
)*(Source
++);
3037 (*DestinationLength
)++;
3042 return RETURN_SUCCESS
;
3046 Convert a Null-terminated ASCII string to IPv6 address and prefix length.
3048 This function outputs a value of type IPv6_ADDRESS and may output a value
3049 of type UINT8 by interpreting the contents of the ASCII string specified
3050 by String. The format of the input ASCII string String is as follows:
3054 X contains one to four hexadecimal digit characters in the range [0-9], [a-f] and
3055 [A-F]. X is converted to a value of type UINT16, whose low byte is stored in low
3056 memory address and high byte is stored in high memory address. P contains decimal
3057 digit characters in the range [0-9]. The running zero in the beginning of P will
3058 be ignored. /P is optional.
3060 When /P is not in the String, the function stops at the first character that is
3061 not a valid hexadecimal digit character after eight X's are converted.
3063 When /P is in the String, the function stops at the first character that is not
3064 a valid decimal digit character after P is converted.
3066 "::" can be used to compress one or more groups of X when X contains only 0.
3067 The "::" can only appear once in the String.
3069 If EndPointer is not NULL and Address is translated from String, a pointer
3070 to the character that stopped the scan is stored at the location pointed to
3073 @param String Pointer to a Null-terminated ASCII string.
3074 @param EndPointer Pointer to character that stops scan.
3075 @param Address Pointer to the converted IPv6 address.
3076 @param PrefixLength Pointer to the converted IPv6 address prefix
3077 length. MAX_UINT8 is returned when /P is
3080 @retval RETURN_SUCCESS Address is translated from String.
3081 @retval RETURN_INVALID_PARAMETER If String is NULL.
3083 @retval RETURN_UNSUPPORTED If X contains more than four hexadecimal
3085 If String contains "::" and number of X
3087 If P starts with character that is not a
3088 valid decimal digit character.
3089 If the decimal number converted from P
3095 AsciiStrToIpv6Address (
3096 IN CONST CHAR8
*String
,
3097 OUT CHAR8
**EndPointer OPTIONAL
,
3098 OUT IPv6_ADDRESS
*Address
,
3099 OUT UINT8
*PrefixLength OPTIONAL
3102 RETURN_STATUS Status
;
3105 IPv6_ADDRESS LocalAddress
;
3106 UINT8 LocalPrefixLength
;
3107 CONST CHAR8
*Pointer
;
3109 UINTN CompressStart
;
3110 BOOLEAN ExpectPrefix
;
3112 LocalPrefixLength
= MAX_UINT8
;
3113 CompressStart
= ARRAY_SIZE (Address
->Addr
);
3114 ExpectPrefix
= FALSE
;
3117 // None of String or Address shall be a null pointer.
3119 SAFE_STRING_CONSTRAINT_CHECK ((String
!= NULL
), RETURN_INVALID_PARAMETER
);
3120 SAFE_STRING_CONSTRAINT_CHECK ((Address
!= NULL
), RETURN_INVALID_PARAMETER
);
3122 for (Pointer
= String
, AddressIndex
= 0; AddressIndex
< ARRAY_SIZE (Address
->Addr
) + 1;) {
3123 if (!InternalAsciiIsHexaDecimalDigitCharacter (*Pointer
)) {
3124 if (*Pointer
!= ':') {
3126 // ":" or "/" should be followed by digit characters.
3128 return RETURN_UNSUPPORTED
;
3132 // Meet second ":" after previous ":" or "/"
3133 // or meet first ":" in the beginning of String.
3137 // ":" shall not be after "/"
3139 return RETURN_UNSUPPORTED
;
3142 if ((CompressStart
!= ARRAY_SIZE (Address
->Addr
)) || (AddressIndex
== ARRAY_SIZE (Address
->Addr
))) {
3144 // "::" can only appear once.
3145 // "::" can only appear when address is not full length.
3147 return RETURN_UNSUPPORTED
;
3150 // Remember the start of zero compressing.
3152 CompressStart
= AddressIndex
;
3155 if (CompressStart
== 0) {
3156 if (*Pointer
!= ':') {
3158 // Single ":" shall not be in the beginning of String.
3160 return RETURN_UNSUPPORTED
;
3168 if (!InternalAsciiIsHexaDecimalDigitCharacter (*Pointer
)) {
3169 if (*Pointer
== '/') {
3171 // Might be optional "/P" after "::".
3173 if (CompressStart
!= AddressIndex
) {
3174 return RETURN_UNSUPPORTED
;
3180 if (!ExpectPrefix
) {
3184 Status
= AsciiStrHexToUintnS (Pointer
, &End
, &Uintn
);
3185 if (RETURN_ERROR (Status
) || (End
- Pointer
> 4)) {
3187 // Number of hexadecimal digit characters is no more than 4.
3189 return RETURN_UNSUPPORTED
;
3194 // Uintn won't exceed MAX_UINT16 if number of hexadecimal digit characters is no more than 4.
3196 ASSERT (AddressIndex
+ 1 < ARRAY_SIZE (Address
->Addr
));
3197 LocalAddress
.Addr
[AddressIndex
] = (UINT8
)((UINT16
)Uintn
>> 8);
3198 LocalAddress
.Addr
[AddressIndex
+ 1] = (UINT8
)Uintn
;
3202 // Get P, then exit the loop.
3204 Status
= AsciiStrDecimalToUintnS (Pointer
, &End
, &Uintn
);
3205 if (RETURN_ERROR (Status
) || (End
== Pointer
) || (Uintn
> 128)) {
3207 // Prefix length should not exceed 128.
3209 return RETURN_UNSUPPORTED
;
3212 LocalPrefixLength
= (UINT8
)Uintn
;
3221 if (*Pointer
== '/') {
3222 ExpectPrefix
= TRUE
;
3223 } else if (*Pointer
== ':') {
3224 if (AddressIndex
== ARRAY_SIZE (Address
->Addr
)) {
3226 // Meet additional ":" after all 8 16-bit address
3232 // Meet other character that is not "/" or ":" after all 8 16-bit address
3240 if (((AddressIndex
== ARRAY_SIZE (Address
->Addr
)) && (CompressStart
!= ARRAY_SIZE (Address
->Addr
))) ||
3241 ((AddressIndex
!= ARRAY_SIZE (Address
->Addr
)) && (CompressStart
== ARRAY_SIZE (Address
->Addr
)))
3245 // Full length of address shall not have compressing zeros.
3246 // Non-full length of address shall have compressing zeros.
3248 return RETURN_UNSUPPORTED
;
3251 CopyMem (&Address
->Addr
[0], &LocalAddress
.Addr
[0], CompressStart
);
3252 ZeroMem (&Address
->Addr
[CompressStart
], ARRAY_SIZE (Address
->Addr
) - AddressIndex
);
3253 if (AddressIndex
> CompressStart
) {
3255 &Address
->Addr
[CompressStart
+ ARRAY_SIZE (Address
->Addr
) - AddressIndex
],
3256 &LocalAddress
.Addr
[CompressStart
],
3257 AddressIndex
- CompressStart
3261 if (PrefixLength
!= NULL
) {
3262 *PrefixLength
= LocalPrefixLength
;
3265 if (EndPointer
!= NULL
) {
3266 *EndPointer
= (CHAR8
*)Pointer
;
3269 return RETURN_SUCCESS
;
3273 Convert a Null-terminated ASCII string to IPv4 address and prefix length.
3275 This function outputs a value of type IPv4_ADDRESS and may output a value
3276 of type UINT8 by interpreting the contents of the ASCII string specified
3277 by String. The format of the input ASCII string String is as follows:
3281 D and P are decimal digit characters in the range [0-9]. The running zero in
3282 the beginning of D and P will be ignored. /P is optional.
3284 When /P is not in the String, the function stops at the first character that is
3285 not a valid decimal digit character after four D's are converted.
3287 When /P is in the String, the function stops at the first character that is not
3288 a valid decimal digit character after P is converted.
3290 If EndPointer is not NULL and Address is translated from String, a pointer
3291 to the character that stopped the scan is stored at the location pointed to
3294 @param String Pointer to a Null-terminated ASCII string.
3295 @param EndPointer Pointer to character that stops scan.
3296 @param Address Pointer to the converted IPv4 address.
3297 @param PrefixLength Pointer to the converted IPv4 address prefix
3298 length. MAX_UINT8 is returned when /P is
3301 @retval RETURN_SUCCESS Address is translated from String.
3302 @retval RETURN_INVALID_PARAMETER If String is NULL.
3304 @retval RETURN_UNSUPPORTED If String is not in the correct format.
3305 If any decimal number converted from D
3307 If the decimal number converted from P
3313 AsciiStrToIpv4Address (
3314 IN CONST CHAR8
*String
,
3315 OUT CHAR8
**EndPointer OPTIONAL
,
3316 OUT IPv4_ADDRESS
*Address
,
3317 OUT UINT8
*PrefixLength OPTIONAL
3320 RETURN_STATUS Status
;
3323 IPv4_ADDRESS LocalAddress
;
3324 UINT8 LocalPrefixLength
;
3327 LocalPrefixLength
= MAX_UINT8
;
3330 // None of String or Address shall be a null pointer.
3332 SAFE_STRING_CONSTRAINT_CHECK ((String
!= NULL
), RETURN_INVALID_PARAMETER
);
3333 SAFE_STRING_CONSTRAINT_CHECK ((Address
!= NULL
), RETURN_INVALID_PARAMETER
);
3335 for (Pointer
= (CHAR8
*)String
, AddressIndex
= 0; AddressIndex
< ARRAY_SIZE (Address
->Addr
) + 1;) {
3336 if (!InternalAsciiIsDecimalDigitCharacter (*Pointer
)) {
3338 // D or P contains invalid characters.
3346 Status
= AsciiStrDecimalToUintnS ((CONST CHAR8
*)Pointer
, &Pointer
, &Uintn
);
3347 if (RETURN_ERROR (Status
)) {
3348 return RETURN_UNSUPPORTED
;
3351 if (AddressIndex
== ARRAY_SIZE (Address
->Addr
)) {
3356 return RETURN_UNSUPPORTED
;
3359 LocalPrefixLength
= (UINT8
)Uintn
;
3364 if (Uintn
> MAX_UINT8
) {
3365 return RETURN_UNSUPPORTED
;
3368 LocalAddress
.Addr
[AddressIndex
] = (UINT8
)Uintn
;
3373 // Check the '.' or '/', depending on the AddressIndex.
3375 if (AddressIndex
== ARRAY_SIZE (Address
->Addr
)) {
3376 if (*Pointer
== '/') {
3378 // '/P' is in the String.
3379 // Skip "/" and get P in next loop.
3384 // '/P' is not in the String.
3388 } else if (AddressIndex
< ARRAY_SIZE (Address
->Addr
)) {
3389 if (*Pointer
== '.') {
3391 // D should be followed by '.'
3395 return RETURN_UNSUPPORTED
;
3400 if (AddressIndex
< ARRAY_SIZE (Address
->Addr
)) {
3401 return RETURN_UNSUPPORTED
;
3404 CopyMem (Address
, &LocalAddress
, sizeof (*Address
));
3405 if (PrefixLength
!= NULL
) {
3406 *PrefixLength
= LocalPrefixLength
;
3409 if (EndPointer
!= NULL
) {
3410 *EndPointer
= Pointer
;
3413 return RETURN_SUCCESS
;
3417 Convert a Null-terminated ASCII GUID string to a value of type
3420 This function outputs a GUID value by interpreting the contents of
3421 the ASCII string specified by String. The format of the input
3422 ASCII string String consists of 36 characters, as follows:
3424 aabbccdd-eeff-gghh-iijj-kkllmmnnoopp
3426 The pairs aa - pp are two characters in the range [0-9], [a-f] and
3427 [A-F], with each pair representing a single byte hexadecimal value.
3429 The mapping between String and the EFI_GUID structure is as follows:
3447 @param String Pointer to a Null-terminated ASCII string.
3448 @param Guid Pointer to the converted GUID.
3450 @retval RETURN_SUCCESS Guid is translated from String.
3451 @retval RETURN_INVALID_PARAMETER If String is NULL.
3453 @retval RETURN_UNSUPPORTED If String is not as the above format.
3459 IN CONST CHAR8
*String
,
3463 RETURN_STATUS Status
;
3467 // None of String or Guid shall be a null pointer.
3469 SAFE_STRING_CONSTRAINT_CHECK ((String
!= NULL
), RETURN_INVALID_PARAMETER
);
3470 SAFE_STRING_CONSTRAINT_CHECK ((Guid
!= NULL
), RETURN_INVALID_PARAMETER
);
3473 // Get aabbccdd in big-endian.
3475 Status
= AsciiStrHexToBytes (String
, 2 * sizeof (LocalGuid
.Data1
), (UINT8
*)&LocalGuid
.Data1
, sizeof (LocalGuid
.Data1
));
3476 if (RETURN_ERROR (Status
) || (String
[2 * sizeof (LocalGuid
.Data1
)] != '-')) {
3477 return RETURN_UNSUPPORTED
;
3481 // Convert big-endian to little-endian.
3483 LocalGuid
.Data1
= SwapBytes32 (LocalGuid
.Data1
);
3484 String
+= 2 * sizeof (LocalGuid
.Data1
) + 1;
3487 // Get eeff in big-endian.
3489 Status
= AsciiStrHexToBytes (String
, 2 * sizeof (LocalGuid
.Data2
), (UINT8
*)&LocalGuid
.Data2
, sizeof (LocalGuid
.Data2
));
3490 if (RETURN_ERROR (Status
) || (String
[2 * sizeof (LocalGuid
.Data2
)] != '-')) {
3491 return RETURN_UNSUPPORTED
;
3495 // Convert big-endian to little-endian.
3497 LocalGuid
.Data2
= SwapBytes16 (LocalGuid
.Data2
);
3498 String
+= 2 * sizeof (LocalGuid
.Data2
) + 1;
3501 // Get gghh in big-endian.
3503 Status
= AsciiStrHexToBytes (String
, 2 * sizeof (LocalGuid
.Data3
), (UINT8
*)&LocalGuid
.Data3
, sizeof (LocalGuid
.Data3
));
3504 if (RETURN_ERROR (Status
) || (String
[2 * sizeof (LocalGuid
.Data3
)] != '-')) {
3505 return RETURN_UNSUPPORTED
;
3509 // Convert big-endian to little-endian.
3511 LocalGuid
.Data3
= SwapBytes16 (LocalGuid
.Data3
);
3512 String
+= 2 * sizeof (LocalGuid
.Data3
) + 1;
3517 Status
= AsciiStrHexToBytes (String
, 2 * 2, &LocalGuid
.Data4
[0], 2);
3518 if (RETURN_ERROR (Status
) || (String
[2 * 2] != '-')) {
3519 return RETURN_UNSUPPORTED
;
3522 String
+= 2 * 2 + 1;
3525 // Get kkllmmnnoopp.
3527 Status
= AsciiStrHexToBytes (String
, 2 * 6, &LocalGuid
.Data4
[2], 6);
3528 if (RETURN_ERROR (Status
)) {
3529 return RETURN_UNSUPPORTED
;
3532 CopyGuid (Guid
, &LocalGuid
);
3533 return RETURN_SUCCESS
;
3537 Convert a Null-terminated ASCII hexadecimal string to a byte array.
3539 This function outputs a byte array by interpreting the contents of
3540 the ASCII string specified by String in hexadecimal format. The format of
3541 the input ASCII string String is:
3545 X is a hexadecimal digit character in the range [0-9], [a-f] and [A-F].
3546 The function decodes every two hexadecimal digit characters as one byte. The
3547 decoding stops after Length of characters and outputs Buffer containing
3550 @param String Pointer to a Null-terminated ASCII string.
3551 @param Length The number of ASCII characters to decode.
3552 @param Buffer Pointer to the converted bytes array.
3553 @param MaxBufferSize The maximum size of Buffer.
3555 @retval RETURN_SUCCESS Buffer is translated from String.
3556 @retval RETURN_INVALID_PARAMETER If String is NULL.
3558 If Length is not multiple of 2.
3559 If PcdMaximumAsciiStringLength is not zero,
3560 and Length is greater than
3561 PcdMaximumAsciiStringLength.
3562 @retval RETURN_UNSUPPORTED If Length of characters from String contain
3563 a character that is not valid hexadecimal
3564 digit characters, or a Null-terminator.
3565 @retval RETURN_BUFFER_TOO_SMALL If MaxBufferSize is less than (Length / 2).
3569 AsciiStrHexToBytes (
3570 IN CONST CHAR8
*String
,
3573 IN UINTN MaxBufferSize
3579 // 1. None of String or Buffer shall be a null pointer.
3581 SAFE_STRING_CONSTRAINT_CHECK ((String
!= NULL
), RETURN_INVALID_PARAMETER
);
3582 SAFE_STRING_CONSTRAINT_CHECK ((Buffer
!= NULL
), RETURN_INVALID_PARAMETER
);
3585 // 2. Length shall not be greater than ASCII_RSIZE_MAX.
3587 if (ASCII_RSIZE_MAX
!= 0) {
3588 SAFE_STRING_CONSTRAINT_CHECK ((Length
<= ASCII_RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
3592 // 3. Length shall not be odd.
3594 SAFE_STRING_CONSTRAINT_CHECK (((Length
& BIT0
) == 0), RETURN_INVALID_PARAMETER
);
3597 // 4. MaxBufferSize shall equal to or greater than Length / 2.
3599 SAFE_STRING_CONSTRAINT_CHECK ((MaxBufferSize
>= Length
/ 2), RETURN_BUFFER_TOO_SMALL
);
3602 // 5. String shall not contains invalid hexadecimal digits.
3604 for (Index
= 0; Index
< Length
; Index
++) {
3605 if (!InternalAsciiIsHexaDecimalDigitCharacter (String
[Index
])) {
3610 if (Index
!= Length
) {
3611 return RETURN_UNSUPPORTED
;
3615 // Convert the hex string to bytes.
3617 for (Index
= 0; Index
< Length
; Index
++) {
3619 // For even characters, write the upper nibble for each buffer byte,
3620 // and for even characters, the lower nibble.
3622 if ((Index
& BIT0
) == 0) {
3623 Buffer
[Index
/ 2] = (UINT8
)InternalAsciiHexCharToUintn (String
[Index
]) << 4;
3625 Buffer
[Index
/ 2] |= (UINT8
)InternalAsciiHexCharToUintn (String
[Index
]);
3629 return RETURN_SUCCESS
;