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
))) {
52 Returns if 2 Unicode strings are not overlapped.
54 @param Str1 Start address of 1st Unicode string.
55 @param Size1 The number of char in 1st Unicode string,
56 including terminating null char.
57 @param Str2 Start address of 2nd Unicode string.
58 @param Size2 The number of char in 2nd Unicode string,
59 including terminating null char.
61 @retval TRUE 2 Unicode strings are NOT overlapped.
62 @retval FALSE 2 Unicode strings are overlapped.
65 InternalSafeStringNoStrOverlap (
72 return !InternalSafeStringIsOverlap (Str1
, Size1
* sizeof(CHAR16
), Str2
, Size2
* sizeof(CHAR16
));
76 Returns if 2 Ascii strings are not overlapped.
78 @param Str1 Start address of 1st Ascii string.
79 @param Size1 The number of char in 1st Ascii string,
80 including terminating null char.
81 @param Str2 Start address of 2nd Ascii string.
82 @param Size2 The number of char in 2nd Ascii string,
83 including terminating null char.
85 @retval TRUE 2 Ascii strings are NOT overlapped.
86 @retval FALSE 2 Ascii strings are overlapped.
89 InternalSafeStringNoAsciiStrOverlap (
96 return !InternalSafeStringIsOverlap (Str1
, Size1
, Str2
, Size2
);
100 Returns the length of a Null-terminated Unicode string.
102 This function is similar as strlen_s defined in C11.
104 If String is not aligned on a 16-bit boundary, then ASSERT().
106 @param String A pointer to a Null-terminated Unicode string.
107 @param MaxSize The maximum number of Destination Unicode
108 char, including terminating null char.
110 @retval 0 If String is NULL.
111 @retval MaxSize If there is no null character in the first MaxSize characters of String.
112 @return The number of characters that percede the terminating null character.
118 IN CONST CHAR16
*String
,
124 ASSERT (((UINTN
) String
& BIT0
) == 0);
127 // If String is a null pointer or MaxSize is 0, then the StrnLenS function returns zero.
129 if ((String
== NULL
) || (MaxSize
== 0)) {
134 // Otherwise, the StrnLenS function returns the number of characters that precede the
135 // terminating null character. If there is no null character in the first MaxSize characters of
136 // String then StrnLenS returns MaxSize. At most the first MaxSize characters of String shall
137 // be accessed by StrnLenS.
140 while (String
[Length
] != 0) {
141 if (Length
>= MaxSize
- 1) {
150 Returns the size of a Null-terminated Unicode string in bytes, including the
153 This function returns the size of the Null-terminated Unicode string
154 specified by String in bytes, including the Null terminator.
156 If String is not aligned on a 16-bit boundary, then ASSERT().
158 @param String A pointer to a Null-terminated Unicode string.
159 @param MaxSize The maximum number of Destination Unicode
160 char, including the Null terminator.
162 @retval 0 If String is NULL.
163 @retval (sizeof (CHAR16) * (MaxSize + 1))
164 If there is no Null terminator in the first MaxSize characters of
166 @return The size of the Null-terminated Unicode string in bytes, including
173 IN CONST CHAR16
*String
,
178 // If String is a null pointer, then the StrnSizeS function returns zero.
180 if (String
== NULL
) {
185 // Otherwise, the StrnSizeS function returns the size of the Null-terminated
186 // Unicode string in bytes, including the Null terminator. If there is no
187 // Null terminator in the first MaxSize characters of String, then StrnSizeS
188 // returns (sizeof (CHAR16) * (MaxSize + 1)) to keep a consistent map with
189 // the StrnLenS function.
191 return (StrnLenS (String
, MaxSize
) + 1) * sizeof (*String
);
195 Copies the string pointed to by Source (including the terminating null char)
196 to the array pointed to by Destination.
198 This function is similar as strcpy_s defined in C11.
200 If Destination is not aligned on a 16-bit boundary, then ASSERT().
201 If Source is not aligned on a 16-bit boundary, then ASSERT().
203 If an error is returned, then the Destination is unmodified.
205 @param Destination A pointer to a Null-terminated Unicode string.
206 @param DestMax The maximum number of Destination Unicode
207 char, including terminating null char.
208 @param Source A pointer to a Null-terminated Unicode string.
210 @retval RETURN_SUCCESS String is copied.
211 @retval RETURN_BUFFER_TOO_SMALL If DestMax is NOT greater than StrLen(Source).
212 @retval RETURN_INVALID_PARAMETER If Destination is NULL.
214 If PcdMaximumUnicodeStringLength is not zero,
215 and DestMax is greater than
216 PcdMaximumUnicodeStringLength.
218 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.
223 OUT CHAR16
*Destination
,
225 IN CONST CHAR16
*Source
230 ASSERT (((UINTN
) Destination
& BIT0
) == 0);
231 ASSERT (((UINTN
) Source
& BIT0
) == 0);
234 // 1. Neither Destination nor Source shall be a null pointer.
236 SAFE_STRING_CONSTRAINT_CHECK ((Destination
!= NULL
), RETURN_INVALID_PARAMETER
);
237 SAFE_STRING_CONSTRAINT_CHECK ((Source
!= NULL
), RETURN_INVALID_PARAMETER
);
240 // 2. DestMax shall not be greater than RSIZE_MAX.
242 if (RSIZE_MAX
!= 0) {
243 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
<= RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
247 // 3. DestMax shall not equal zero.
249 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
!= 0), RETURN_INVALID_PARAMETER
);
252 // 4. DestMax shall be greater than StrnLenS(Source, DestMax).
254 SourceLen
= StrnLenS (Source
, DestMax
);
255 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
> SourceLen
), RETURN_BUFFER_TOO_SMALL
);
258 // 5. Copying shall not take place between objects that overlap.
260 SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoStrOverlap (Destination
, DestMax
, (CHAR16
*)Source
, SourceLen
+ 1), RETURN_ACCESS_DENIED
);
263 // The StrCpyS function copies the string pointed to by Source (including the terminating
264 // null character) into the array pointed to by Destination.
266 while (*Source
!= 0) {
267 *(Destination
++) = *(Source
++);
271 return RETURN_SUCCESS
;
275 Copies not more than Length successive char from the string pointed to by
276 Source to the array pointed to by Destination. If no null char is copied from
277 Source, then Destination[Length] is always set to null.
279 This function is similar as strncpy_s defined in C11.
281 If Length > 0 and Destination is not aligned on a 16-bit boundary, then ASSERT().
282 If Length > 0 and Source is not aligned on a 16-bit boundary, then ASSERT().
284 If an error is returned, then the Destination is unmodified.
286 @param Destination A pointer to a Null-terminated Unicode string.
287 @param DestMax The maximum number of Destination Unicode
288 char, including terminating null char.
289 @param Source A pointer to a Null-terminated Unicode string.
290 @param Length The maximum number of Unicode characters to copy.
292 @retval RETURN_SUCCESS String is copied.
293 @retval RETURN_BUFFER_TOO_SMALL If DestMax is NOT greater than
294 MIN(StrLen(Source), Length).
295 @retval RETURN_INVALID_PARAMETER If Destination is NULL.
297 If PcdMaximumUnicodeStringLength is not zero,
298 and DestMax is greater than
299 PcdMaximumUnicodeStringLength.
301 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.
306 OUT CHAR16
*Destination
,
308 IN CONST CHAR16
*Source
,
314 ASSERT (((UINTN
) Destination
& BIT0
) == 0);
315 ASSERT (((UINTN
) Source
& BIT0
) == 0);
318 // 1. Neither Destination nor Source shall be a null pointer.
320 SAFE_STRING_CONSTRAINT_CHECK ((Destination
!= NULL
), RETURN_INVALID_PARAMETER
);
321 SAFE_STRING_CONSTRAINT_CHECK ((Source
!= NULL
), RETURN_INVALID_PARAMETER
);
324 // 2. Neither DestMax nor Length shall be greater than RSIZE_MAX
326 if (RSIZE_MAX
!= 0) {
327 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
<= RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
328 SAFE_STRING_CONSTRAINT_CHECK ((Length
<= RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
332 // 3. DestMax shall not equal zero.
334 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
!= 0), RETURN_INVALID_PARAMETER
);
337 // 4. If Length is not less than DestMax, then DestMax shall be greater than StrnLenS(Source, DestMax).
339 SourceLen
= StrnLenS (Source
, MIN (DestMax
, Length
));
340 if (Length
>= DestMax
) {
341 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
> SourceLen
), RETURN_BUFFER_TOO_SMALL
);
345 // 5. Copying shall not take place between objects that overlap.
347 if (SourceLen
> Length
) {
350 SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoStrOverlap (Destination
, DestMax
, (CHAR16
*)Source
, SourceLen
+ 1), RETURN_ACCESS_DENIED
);
353 // The StrnCpyS function copies not more than Length successive characters (characters that
354 // follow a null character are not copied) from the array pointed to by Source to the array
355 // pointed to by Destination. If no null character was copied from Source, then Destination[Length] is set to a null
358 while ((SourceLen
> 0) && (*Source
!= 0)) {
359 *(Destination
++) = *(Source
++);
364 return RETURN_SUCCESS
;
368 Appends a copy of the string pointed to by Source (including the terminating
369 null char) to the end of the string pointed to by Destination.
371 This function is similar as strcat_s defined in C11.
373 If Destination is not aligned on a 16-bit boundary, then ASSERT().
374 If Source is not aligned on a 16-bit boundary, then ASSERT().
376 If an error is returned, then the Destination is unmodified.
378 @param Destination A pointer to a Null-terminated Unicode string.
379 @param DestMax The maximum number of Destination Unicode
380 char, including terminating null char.
381 @param Source A pointer to a Null-terminated Unicode string.
383 @retval RETURN_SUCCESS String is appended.
384 @retval RETURN_BAD_BUFFER_SIZE If DestMax is NOT greater than
386 @retval RETURN_BUFFER_TOO_SMALL If (DestMax - StrLen(Destination)) is NOT
387 greater than StrLen(Source).
388 @retval RETURN_INVALID_PARAMETER If Destination is NULL.
390 If PcdMaximumUnicodeStringLength is not zero,
391 and DestMax is greater than
392 PcdMaximumUnicodeStringLength.
394 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.
399 IN OUT CHAR16
*Destination
,
401 IN CONST CHAR16
*Source
408 ASSERT (((UINTN
) Destination
& BIT0
) == 0);
409 ASSERT (((UINTN
) Source
& BIT0
) == 0);
412 // Let CopyLen denote the value DestMax - StrnLenS(Destination, DestMax) upon entry to StrCatS.
414 DestLen
= StrnLenS (Destination
, DestMax
);
415 CopyLen
= DestMax
- DestLen
;
418 // 1. Neither Destination nor Source shall be a null pointer.
420 SAFE_STRING_CONSTRAINT_CHECK ((Destination
!= NULL
), RETURN_INVALID_PARAMETER
);
421 SAFE_STRING_CONSTRAINT_CHECK ((Source
!= NULL
), RETURN_INVALID_PARAMETER
);
424 // 2. DestMax shall not be greater than RSIZE_MAX.
426 if (RSIZE_MAX
!= 0) {
427 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
<= RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
431 // 3. DestMax shall not equal zero.
433 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
!= 0), RETURN_INVALID_PARAMETER
);
436 // 4. CopyLen shall not equal zero.
438 SAFE_STRING_CONSTRAINT_CHECK ((CopyLen
!= 0), RETURN_BAD_BUFFER_SIZE
);
441 // 5. CopyLen shall be greater than StrnLenS(Source, CopyLen).
443 SourceLen
= StrnLenS (Source
, CopyLen
);
444 SAFE_STRING_CONSTRAINT_CHECK ((CopyLen
> SourceLen
), RETURN_BUFFER_TOO_SMALL
);
447 // 6. Copying shall not take place between objects that overlap.
449 SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoStrOverlap (Destination
, DestMax
, (CHAR16
*)Source
, SourceLen
+ 1), RETURN_ACCESS_DENIED
);
452 // The StrCatS function appends a copy of the string pointed to by Source (including the
453 // terminating null character) to the end of the string pointed to by Destination. The initial character
454 // from Source overwrites the null character at the end of Destination.
456 Destination
= Destination
+ DestLen
;
457 while (*Source
!= 0) {
458 *(Destination
++) = *(Source
++);
462 return RETURN_SUCCESS
;
466 Appends not more than Length successive char from the string pointed to by
467 Source to the end of the string pointed to by Destination. If no null char is
468 copied from Source, then Destination[StrLen(Destination) + Length] is always
471 This function is similar as strncat_s defined in C11.
473 If Destination is not aligned on a 16-bit boundary, then ASSERT().
474 If Source is not aligned on a 16-bit boundary, then ASSERT().
476 If an error is returned, then the Destination is unmodified.
478 @param Destination A pointer to a Null-terminated Unicode string.
479 @param DestMax The maximum number of Destination Unicode
480 char, including terminating null char.
481 @param Source A pointer to a Null-terminated Unicode string.
482 @param Length The maximum number of Unicode characters to copy.
484 @retval RETURN_SUCCESS String is appended.
485 @retval RETURN_BAD_BUFFER_SIZE If DestMax is NOT greater than
487 @retval RETURN_BUFFER_TOO_SMALL If (DestMax - StrLen(Destination)) is NOT
488 greater than MIN(StrLen(Source), Length).
489 @retval RETURN_INVALID_PARAMETER If Destination is NULL.
491 If PcdMaximumUnicodeStringLength is not zero,
492 and DestMax is greater than
493 PcdMaximumUnicodeStringLength.
495 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.
500 IN OUT CHAR16
*Destination
,
502 IN CONST CHAR16
*Source
,
510 ASSERT (((UINTN
) Destination
& BIT0
) == 0);
511 ASSERT (((UINTN
) Source
& BIT0
) == 0);
514 // Let CopyLen denote the value DestMax - StrnLenS(Destination, DestMax) upon entry to StrnCatS.
516 DestLen
= StrnLenS (Destination
, DestMax
);
517 CopyLen
= DestMax
- DestLen
;
520 // 1. Neither Destination nor Source shall be a null pointer.
522 SAFE_STRING_CONSTRAINT_CHECK ((Destination
!= NULL
), RETURN_INVALID_PARAMETER
);
523 SAFE_STRING_CONSTRAINT_CHECK ((Source
!= NULL
), RETURN_INVALID_PARAMETER
);
526 // 2. Neither DestMax nor Length shall be greater than RSIZE_MAX.
528 if (RSIZE_MAX
!= 0) {
529 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
<= RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
530 SAFE_STRING_CONSTRAINT_CHECK ((Length
<= RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
534 // 3. DestMax shall not equal zero.
536 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
!= 0), RETURN_INVALID_PARAMETER
);
539 // 4. CopyLen shall not equal zero.
541 SAFE_STRING_CONSTRAINT_CHECK ((CopyLen
!= 0), RETURN_BAD_BUFFER_SIZE
);
544 // 5. If Length is not less than CopyLen, then CopyLen shall be greater than StrnLenS(Source, CopyLen).
546 SourceLen
= StrnLenS (Source
, MIN (CopyLen
, Length
));
547 if (Length
>= CopyLen
) {
548 SAFE_STRING_CONSTRAINT_CHECK ((CopyLen
> SourceLen
), RETURN_BUFFER_TOO_SMALL
);
552 // 6. Copying shall not take place between objects that overlap.
554 if (SourceLen
> Length
) {
557 SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoStrOverlap (Destination
, DestMax
, (CHAR16
*)Source
, SourceLen
+ 1), RETURN_ACCESS_DENIED
);
560 // The StrnCatS function appends not more than Length successive characters (characters
561 // that follow a null character are not copied) from the array pointed to by Source to the end of
562 // the string pointed to by Destination. The initial character from Source overwrites the null character at
563 // the end of Destination. If no null character was copied from Source, then Destination[DestMax-CopyLen+Length] is set to
566 Destination
= Destination
+ DestLen
;
567 while ((SourceLen
> 0) && (*Source
!= 0)) {
568 *(Destination
++) = *(Source
++);
573 return RETURN_SUCCESS
;
577 Convert a Null-terminated Unicode decimal string to a value of type UINTN.
579 This function outputs a value of type UINTN by interpreting the contents of
580 the Unicode string specified by String as a decimal number. The format of the
581 input Unicode string String is:
583 [spaces] [decimal digits].
585 The valid decimal digit character is in the range [0-9]. The function will
586 ignore the pad space, which includes spaces or tab characters, before
587 [decimal digits]. The running zero in the beginning of [decimal digits] will
588 be ignored. Then, the function stops at the first character that is a not a
589 valid decimal character or a Null-terminator, whichever one comes first.
591 If String is not aligned in a 16-bit boundary, then ASSERT().
593 If String has no valid decimal digits in the above format, then 0 is stored
594 at the location pointed to by Data.
595 If the number represented by String exceeds the range defined by UINTN, then
596 MAX_UINTN is stored at the location pointed to by Data.
598 If EndPointer is not NULL, a pointer to the character that stopped the scan
599 is stored at the location pointed to by EndPointer. If String has no valid
600 decimal digits right after the optional pad spaces, the value of String is
601 stored at the location pointed to by EndPointer.
603 @param String Pointer to a Null-terminated Unicode string.
604 @param EndPointer Pointer to character that stops scan.
605 @param Data Pointer to the converted value.
607 @retval RETURN_SUCCESS Value is translated from String.
608 @retval RETURN_INVALID_PARAMETER If String is NULL.
610 If PcdMaximumUnicodeStringLength is not
611 zero, and String contains more than
612 PcdMaximumUnicodeStringLength Unicode
613 characters, not including the
615 @retval RETURN_UNSUPPORTED If the number represented by String exceeds
616 the range defined by UINTN.
622 IN CONST CHAR16
*String
,
623 OUT CHAR16
**EndPointer
, OPTIONAL
627 ASSERT (((UINTN
) String
& BIT0
) == 0);
630 // 1. Neither String nor Data shall be a null pointer.
632 SAFE_STRING_CONSTRAINT_CHECK ((String
!= NULL
), RETURN_INVALID_PARAMETER
);
633 SAFE_STRING_CONSTRAINT_CHECK ((Data
!= NULL
), RETURN_INVALID_PARAMETER
);
636 // 2. The length of String shall not be greater than RSIZE_MAX.
638 if (RSIZE_MAX
!= 0) {
639 SAFE_STRING_CONSTRAINT_CHECK ((StrnLenS (String
, RSIZE_MAX
+ 1) <= RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
642 if (EndPointer
!= NULL
) {
643 *EndPointer
= (CHAR16
*) String
;
647 // Ignore the pad spaces (space or tab)
649 while ((*String
== L
' ') || (*String
== L
'\t')) {
654 // Ignore leading Zeros after the spaces
656 while (*String
== L
'0') {
662 while (InternalIsDecimalDigitCharacter (*String
)) {
664 // If the number represented by String overflows according to the range
665 // defined by UINTN, then MAX_UINTN is stored in *Data and
666 // RETURN_UNSUPPORTED is returned.
668 if (*Data
> ((MAX_UINTN
- (*String
- L
'0')) / 10)) {
670 if (EndPointer
!= NULL
) {
671 *EndPointer
= (CHAR16
*) String
;
673 return RETURN_UNSUPPORTED
;
676 *Data
= *Data
* 10 + (*String
- L
'0');
680 if (EndPointer
!= NULL
) {
681 *EndPointer
= (CHAR16
*) String
;
683 return RETURN_SUCCESS
;
687 Convert a Null-terminated Unicode decimal string to a value of type UINT64.
689 This function outputs a value of type UINT64 by interpreting the contents of
690 the Unicode string specified by String as a decimal number. The format of the
691 input Unicode string String is:
693 [spaces] [decimal digits].
695 The valid decimal digit character is in the range [0-9]. The function will
696 ignore the pad space, which includes spaces or tab characters, before
697 [decimal digits]. The running zero in the beginning of [decimal digits] will
698 be ignored. Then, the function stops at the first character that is a not a
699 valid decimal character or a Null-terminator, whichever one comes first.
701 If String is not aligned in a 16-bit boundary, then ASSERT().
703 If String has no valid decimal digits in the above format, then 0 is stored
704 at the location pointed to by Data.
705 If the number represented by String exceeds the range defined by UINT64, then
706 MAX_UINT64 is stored at the location pointed to by Data.
708 If EndPointer is not NULL, a pointer to the character that stopped the scan
709 is stored at the location pointed to by EndPointer. If String has no valid
710 decimal digits right after the optional pad spaces, the value of String is
711 stored at the location pointed to by EndPointer.
713 @param String Pointer to a Null-terminated Unicode string.
714 @param EndPointer Pointer to character that stops scan.
715 @param Data Pointer to the converted value.
717 @retval RETURN_SUCCESS Value is translated from String.
718 @retval RETURN_INVALID_PARAMETER If String is NULL.
720 If PcdMaximumUnicodeStringLength is not
721 zero, and String contains more than
722 PcdMaximumUnicodeStringLength Unicode
723 characters, not including the
725 @retval RETURN_UNSUPPORTED If the number represented by String exceeds
726 the range defined by UINT64.
731 StrDecimalToUint64S (
732 IN CONST CHAR16
*String
,
733 OUT CHAR16
**EndPointer
, OPTIONAL
737 ASSERT (((UINTN
) String
& BIT0
) == 0);
740 // 1. Neither String nor Data shall be a null pointer.
742 SAFE_STRING_CONSTRAINT_CHECK ((String
!= NULL
), RETURN_INVALID_PARAMETER
);
743 SAFE_STRING_CONSTRAINT_CHECK ((Data
!= NULL
), RETURN_INVALID_PARAMETER
);
746 // 2. The length of String shall not be greater than RSIZE_MAX.
748 if (RSIZE_MAX
!= 0) {
749 SAFE_STRING_CONSTRAINT_CHECK ((StrnLenS (String
, RSIZE_MAX
+ 1) <= RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
752 if (EndPointer
!= NULL
) {
753 *EndPointer
= (CHAR16
*) String
;
757 // Ignore the pad spaces (space or tab)
759 while ((*String
== L
' ') || (*String
== L
'\t')) {
764 // Ignore leading Zeros after the spaces
766 while (*String
== L
'0') {
772 while (InternalIsDecimalDigitCharacter (*String
)) {
774 // If the number represented by String overflows according to the range
775 // defined by UINT64, then MAX_UINT64 is stored in *Data and
776 // RETURN_UNSUPPORTED is returned.
778 if (*Data
> DivU64x32 (MAX_UINT64
- (*String
- L
'0'), 10)) {
780 if (EndPointer
!= NULL
) {
781 *EndPointer
= (CHAR16
*) String
;
783 return RETURN_UNSUPPORTED
;
786 *Data
= MultU64x32 (*Data
, 10) + (*String
- L
'0');
790 if (EndPointer
!= NULL
) {
791 *EndPointer
= (CHAR16
*) String
;
793 return RETURN_SUCCESS
;
797 Convert a Null-terminated Unicode hexadecimal string to a value of type
800 This function outputs a value of type UINTN by interpreting the contents of
801 the Unicode string specified by String as a hexadecimal number. The format of
802 the input Unicode string String is:
804 [spaces][zeros][x][hexadecimal digits].
806 The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].
807 The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix.
808 If "x" appears in the input string, it must be prefixed with at least one 0.
809 The function will ignore the pad space, which includes spaces or tab
810 characters, before [zeros], [x] or [hexadecimal digit]. The running zero
811 before [x] or [hexadecimal digit] will be ignored. Then, the decoding starts
812 after [x] or the first valid hexadecimal digit. Then, the function stops at
813 the first character that is a not a valid hexadecimal character or NULL,
814 whichever one comes first.
816 If String is not aligned in a 16-bit boundary, then ASSERT().
818 If String has no valid hexadecimal digits in the above format, then 0 is
819 stored at the location pointed to by Data.
820 If the number represented by String exceeds the range defined by UINTN, then
821 MAX_UINTN is stored at the location pointed to by Data.
823 If EndPointer is not NULL, a pointer to the character that stopped the scan
824 is stored at the location pointed to by EndPointer. If String has no valid
825 hexadecimal digits right after the optional pad spaces, the value of String
826 is stored at the location pointed to by EndPointer.
828 @param String Pointer to a Null-terminated Unicode string.
829 @param EndPointer Pointer to character that stops scan.
830 @param Data Pointer to the converted value.
832 @retval RETURN_SUCCESS Value is translated from String.
833 @retval RETURN_INVALID_PARAMETER If String is NULL.
835 If PcdMaximumUnicodeStringLength is not
836 zero, and String contains more than
837 PcdMaximumUnicodeStringLength Unicode
838 characters, not including the
840 @retval RETURN_UNSUPPORTED If the number represented by String exceeds
841 the range defined by UINTN.
847 IN CONST CHAR16
*String
,
848 OUT CHAR16
**EndPointer
, OPTIONAL
852 ASSERT (((UINTN
) String
& BIT0
) == 0);
855 // 1. Neither String nor Data shall be a null pointer.
857 SAFE_STRING_CONSTRAINT_CHECK ((String
!= NULL
), RETURN_INVALID_PARAMETER
);
858 SAFE_STRING_CONSTRAINT_CHECK ((Data
!= NULL
), RETURN_INVALID_PARAMETER
);
861 // 2. The length of String shall not be greater than RSIZE_MAX.
863 if (RSIZE_MAX
!= 0) {
864 SAFE_STRING_CONSTRAINT_CHECK ((StrnLenS (String
, RSIZE_MAX
+ 1) <= RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
867 if (EndPointer
!= NULL
) {
868 *EndPointer
= (CHAR16
*) String
;
872 // Ignore the pad spaces (space or tab)
874 while ((*String
== L
' ') || (*String
== L
'\t')) {
879 // Ignore leading Zeros after the spaces
881 while (*String
== L
'0') {
885 if (CharToUpper (*String
) == L
'X') {
886 if (*(String
- 1) != L
'0') {
888 return RETURN_SUCCESS
;
898 while (InternalIsHexaDecimalDigitCharacter (*String
)) {
900 // If the number represented by String overflows according to the range
901 // defined by UINTN, then MAX_UINTN is stored in *Data and
902 // RETURN_UNSUPPORTED is returned.
904 if (*Data
> ((MAX_UINTN
- InternalHexCharToUintn (*String
)) >> 4)) {
906 if (EndPointer
!= NULL
) {
907 *EndPointer
= (CHAR16
*) String
;
909 return RETURN_UNSUPPORTED
;
912 *Data
= (*Data
<< 4) + InternalHexCharToUintn (*String
);
916 if (EndPointer
!= NULL
) {
917 *EndPointer
= (CHAR16
*) String
;
919 return RETURN_SUCCESS
;
923 Convert a Null-terminated Unicode hexadecimal string to a value of type
926 This function outputs a value of type UINT64 by interpreting the contents of
927 the Unicode string specified by String as a hexadecimal number. The format of
928 the input Unicode string String is:
930 [spaces][zeros][x][hexadecimal digits].
932 The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].
933 The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix.
934 If "x" appears in the input string, it must be prefixed with at least one 0.
935 The function will ignore the pad space, which includes spaces or tab
936 characters, before [zeros], [x] or [hexadecimal digit]. The running zero
937 before [x] or [hexadecimal digit] will be ignored. Then, the decoding starts
938 after [x] or the first valid hexadecimal digit. Then, the function stops at
939 the first character that is a not a valid hexadecimal character or NULL,
940 whichever one comes first.
942 If String is not aligned in a 16-bit boundary, then ASSERT().
944 If String has no valid hexadecimal digits in the above format, then 0 is
945 stored at the location pointed to by Data.
946 If the number represented by String exceeds the range defined by UINT64, then
947 MAX_UINT64 is stored at the location pointed to by Data.
949 If EndPointer is not NULL, a pointer to the character that stopped the scan
950 is stored at the location pointed to by EndPointer. If String has no valid
951 hexadecimal digits right after the optional pad spaces, the value of String
952 is stored at the location pointed to by EndPointer.
954 @param String Pointer to a Null-terminated Unicode string.
955 @param EndPointer Pointer to character that stops scan.
956 @param Data Pointer to the converted value.
958 @retval RETURN_SUCCESS Value is translated from String.
959 @retval RETURN_INVALID_PARAMETER If String is NULL.
961 If PcdMaximumUnicodeStringLength is not
962 zero, and String contains more than
963 PcdMaximumUnicodeStringLength Unicode
964 characters, not including the
966 @retval RETURN_UNSUPPORTED If the number represented by String exceeds
967 the range defined by UINT64.
973 IN CONST CHAR16
*String
,
974 OUT CHAR16
**EndPointer
, OPTIONAL
978 ASSERT (((UINTN
) String
& BIT0
) == 0);
981 // 1. Neither String nor Data shall be a null pointer.
983 SAFE_STRING_CONSTRAINT_CHECK ((String
!= NULL
), RETURN_INVALID_PARAMETER
);
984 SAFE_STRING_CONSTRAINT_CHECK ((Data
!= NULL
), RETURN_INVALID_PARAMETER
);
987 // 2. The length of String shall not be greater than RSIZE_MAX.
989 if (RSIZE_MAX
!= 0) {
990 SAFE_STRING_CONSTRAINT_CHECK ((StrnLenS (String
, RSIZE_MAX
+ 1) <= RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
993 if (EndPointer
!= NULL
) {
994 *EndPointer
= (CHAR16
*) String
;
998 // Ignore the pad spaces (space or tab)
1000 while ((*String
== L
' ') || (*String
== L
'\t')) {
1005 // Ignore leading Zeros after the spaces
1007 while (*String
== L
'0') {
1011 if (CharToUpper (*String
) == L
'X') {
1012 if (*(String
- 1) != L
'0') {
1014 return RETURN_SUCCESS
;
1024 while (InternalIsHexaDecimalDigitCharacter (*String
)) {
1026 // If the number represented by String overflows according to the range
1027 // defined by UINT64, then MAX_UINT64 is stored in *Data and
1028 // RETURN_UNSUPPORTED is returned.
1030 if (*Data
> RShiftU64 (MAX_UINT64
- InternalHexCharToUintn (*String
), 4)) {
1032 if (EndPointer
!= NULL
) {
1033 *EndPointer
= (CHAR16
*) String
;
1035 return RETURN_UNSUPPORTED
;
1038 *Data
= LShiftU64 (*Data
, 4) + InternalHexCharToUintn (*String
);
1042 if (EndPointer
!= NULL
) {
1043 *EndPointer
= (CHAR16
*) String
;
1045 return RETURN_SUCCESS
;
1049 Convert a Null-terminated Unicode string to IPv6 address and prefix length.
1051 This function outputs a value of type IPv6_ADDRESS and may output a value
1052 of type UINT8 by interpreting the contents of the Unicode string specified
1053 by String. The format of the input Unicode string String is as follows:
1057 X contains one to four hexadecimal digit characters in the range [0-9], [a-f] and
1058 [A-F]. X is converted to a value of type UINT16, whose low byte is stored in low
1059 memory address and high byte is stored in high memory address. P contains decimal
1060 digit characters in the range [0-9]. The running zero in the beginning of P will
1061 be ignored. /P is optional.
1063 When /P is not in the String, the function stops at the first character that is
1064 not a valid hexadecimal digit character after eight X's are converted.
1066 When /P is in the String, the function stops at the first character that is not
1067 a valid decimal digit character after P is converted.
1069 "::" can be used to compress one or more groups of X when X contains only 0.
1070 The "::" can only appear once in the String.
1072 If String is not aligned in a 16-bit boundary, then ASSERT().
1074 If EndPointer is not NULL and Address is translated from String, a pointer
1075 to the character that stopped the scan is stored at the location pointed to
1078 @param String Pointer to a Null-terminated Unicode string.
1079 @param EndPointer Pointer to character that stops scan.
1080 @param Address Pointer to the converted IPv6 address.
1081 @param PrefixLength Pointer to the converted IPv6 address prefix
1082 length. MAX_UINT8 is returned when /P is
1085 @retval RETURN_SUCCESS Address is translated from String.
1086 @retval RETURN_INVALID_PARAMETER If String is NULL.
1088 @retval RETURN_UNSUPPORTED If X contains more than four hexadecimal
1090 If String contains "::" and number of X
1092 If P starts with character that is not a
1093 valid decimal digit character.
1094 If the decimal number converted from P
1101 IN CONST CHAR16
*String
,
1102 OUT CHAR16
**EndPointer
, OPTIONAL
1103 OUT IPv6_ADDRESS
*Address
,
1104 OUT UINT8
*PrefixLength OPTIONAL
1107 RETURN_STATUS Status
;
1110 IPv6_ADDRESS LocalAddress
;
1111 UINT8 LocalPrefixLength
;
1112 CONST CHAR16
*Pointer
;
1114 UINTN CompressStart
;
1115 BOOLEAN ExpectPrefix
;
1117 LocalPrefixLength
= MAX_UINT8
;
1118 CompressStart
= ARRAY_SIZE (Address
->Addr
);
1119 ExpectPrefix
= FALSE
;
1121 ASSERT (((UINTN
) String
& BIT0
) == 0);
1124 // 1. None of String or Guid shall be a null pointer.
1126 SAFE_STRING_CONSTRAINT_CHECK ((String
!= NULL
), RETURN_INVALID_PARAMETER
);
1127 SAFE_STRING_CONSTRAINT_CHECK ((Address
!= NULL
), RETURN_INVALID_PARAMETER
);
1129 for (Pointer
= String
, AddressIndex
= 0; AddressIndex
< ARRAY_SIZE (Address
->Addr
) + 1;) {
1130 if (!InternalIsHexaDecimalDigitCharacter (*Pointer
)) {
1131 if (*Pointer
!= L
':') {
1133 // ":" or "/" should be followed by digit characters.
1135 return RETURN_UNSUPPORTED
;
1139 // Meet second ":" after previous ":" or "/"
1140 // or meet first ":" in the beginning of String.
1144 // ":" shall not be after "/"
1146 return RETURN_UNSUPPORTED
;
1149 if (CompressStart
!= ARRAY_SIZE (Address
->Addr
) || AddressIndex
== ARRAY_SIZE (Address
->Addr
)) {
1151 // "::" can only appear once.
1152 // "::" can only appear when address is not full length.
1154 return RETURN_UNSUPPORTED
;
1157 // Remember the start of zero compressing.
1159 CompressStart
= AddressIndex
;
1162 if (CompressStart
== 0) {
1163 if (*Pointer
!= L
':') {
1165 // Single ":" shall not be in the beginning of String.
1167 return RETURN_UNSUPPORTED
;
1174 if (!InternalIsHexaDecimalDigitCharacter (*Pointer
)) {
1175 if (*Pointer
== L
'/') {
1177 // Might be optional "/P" after "::".
1179 if (CompressStart
!= AddressIndex
) {
1180 return RETURN_UNSUPPORTED
;
1186 if (!ExpectPrefix
) {
1190 Status
= StrHexToUintnS (Pointer
, &End
, &Uintn
);
1191 if (RETURN_ERROR (Status
) || End
- Pointer
> 4) {
1193 // Number of hexadecimal digit characters is no more than 4.
1195 return RETURN_UNSUPPORTED
;
1199 // Uintn won't exceed MAX_UINT16 if number of hexadecimal digit characters is no more than 4.
1201 ASSERT (AddressIndex
+ 1 < ARRAY_SIZE (Address
->Addr
));
1202 LocalAddress
.Addr
[AddressIndex
] = (UINT8
) ((UINT16
) Uintn
>> 8);
1203 LocalAddress
.Addr
[AddressIndex
+ 1] = (UINT8
) Uintn
;
1207 // Get P, then exit the loop.
1209 Status
= StrDecimalToUintnS (Pointer
, &End
, &Uintn
);
1210 if (RETURN_ERROR (Status
) || End
== Pointer
|| Uintn
> 128) {
1212 // Prefix length should not exceed 128.
1214 return RETURN_UNSUPPORTED
;
1216 LocalPrefixLength
= (UINT8
) Uintn
;
1225 if (*Pointer
== L
'/') {
1226 ExpectPrefix
= TRUE
;
1227 } else if (*Pointer
== L
':') {
1228 if (AddressIndex
== ARRAY_SIZE (Address
->Addr
)) {
1230 // Meet additional ":" after all 8 16-bit address
1236 // Meet other character that is not "/" or ":" after all 8 16-bit address
1243 if ((AddressIndex
== ARRAY_SIZE (Address
->Addr
) && CompressStart
!= ARRAY_SIZE (Address
->Addr
)) ||
1244 (AddressIndex
!= ARRAY_SIZE (Address
->Addr
) && CompressStart
== ARRAY_SIZE (Address
->Addr
))
1247 // Full length of address shall not have compressing zeros.
1248 // Non-full length of address shall have compressing zeros.
1250 return RETURN_UNSUPPORTED
;
1252 CopyMem (&Address
->Addr
[0], &LocalAddress
.Addr
[0], CompressStart
);
1253 ZeroMem (&Address
->Addr
[CompressStart
], ARRAY_SIZE (Address
->Addr
) - AddressIndex
);
1254 if (AddressIndex
> CompressStart
) {
1256 &Address
->Addr
[CompressStart
+ ARRAY_SIZE (Address
->Addr
) - AddressIndex
],
1257 &LocalAddress
.Addr
[CompressStart
],
1258 AddressIndex
- CompressStart
1262 if (PrefixLength
!= NULL
) {
1263 *PrefixLength
= LocalPrefixLength
;
1265 if (EndPointer
!= NULL
) {
1266 *EndPointer
= (CHAR16
*) Pointer
;
1269 return RETURN_SUCCESS
;
1273 Convert a Null-terminated Unicode string to IPv4 address and prefix length.
1275 This function outputs a value of type IPv4_ADDRESS and may output a value
1276 of type UINT8 by interpreting the contents of the Unicode string specified
1277 by String. The format of the input Unicode string String is as follows:
1281 D and P are decimal digit characters in the range [0-9]. The running zero in
1282 the beginning of D and P will be ignored. /P is optional.
1284 When /P is not in the String, the function stops at the first character that is
1285 not a valid decimal digit character after four D's are converted.
1287 When /P is in the String, the function stops at the first character that is not
1288 a valid decimal digit character after P is converted.
1290 If String is not aligned in a 16-bit boundary, then ASSERT().
1292 If EndPointer is not NULL and Address is translated from String, a pointer
1293 to the character that stopped the scan is stored at the location pointed to
1296 @param String Pointer to a Null-terminated Unicode string.
1297 @param EndPointer Pointer to character that stops scan.
1298 @param Address Pointer to the converted IPv4 address.
1299 @param PrefixLength Pointer to the converted IPv4 address prefix
1300 length. MAX_UINT8 is returned when /P is
1303 @retval RETURN_SUCCESS Address is translated from String.
1304 @retval RETURN_INVALID_PARAMETER If String is NULL.
1306 @retval RETURN_UNSUPPORTED If String is not in the correct format.
1307 If any decimal number converted from D
1309 If the decimal number converted from P
1316 IN CONST CHAR16
*String
,
1317 OUT CHAR16
**EndPointer
, OPTIONAL
1318 OUT IPv4_ADDRESS
*Address
,
1319 OUT UINT8
*PrefixLength OPTIONAL
1322 RETURN_STATUS Status
;
1325 IPv4_ADDRESS LocalAddress
;
1326 UINT8 LocalPrefixLength
;
1329 LocalPrefixLength
= MAX_UINT8
;
1331 ASSERT (((UINTN
) String
& BIT0
) == 0);
1334 // 1. None of String or Guid shall be a null pointer.
1336 SAFE_STRING_CONSTRAINT_CHECK ((String
!= NULL
), RETURN_INVALID_PARAMETER
);
1337 SAFE_STRING_CONSTRAINT_CHECK ((Address
!= NULL
), RETURN_INVALID_PARAMETER
);
1339 for (Pointer
= (CHAR16
*) String
, AddressIndex
= 0; AddressIndex
< ARRAY_SIZE (Address
->Addr
) + 1;) {
1340 if (!InternalIsDecimalDigitCharacter (*Pointer
)) {
1342 // D or P contains invalid characters.
1350 Status
= StrDecimalToUintnS ((CONST CHAR16
*) Pointer
, &Pointer
, &Uintn
);
1351 if (RETURN_ERROR (Status
)) {
1352 return RETURN_UNSUPPORTED
;
1354 if (AddressIndex
== ARRAY_SIZE (Address
->Addr
)) {
1359 return RETURN_UNSUPPORTED
;
1361 LocalPrefixLength
= (UINT8
) Uintn
;
1366 if (Uintn
> MAX_UINT8
) {
1367 return RETURN_UNSUPPORTED
;
1369 LocalAddress
.Addr
[AddressIndex
] = (UINT8
) Uintn
;
1374 // Check the '.' or '/', depending on the AddressIndex.
1376 if (AddressIndex
== ARRAY_SIZE (Address
->Addr
)) {
1377 if (*Pointer
== L
'/') {
1379 // '/P' is in the String.
1380 // Skip "/" and get P in next loop.
1385 // '/P' is not in the String.
1389 } else if (AddressIndex
< ARRAY_SIZE (Address
->Addr
)) {
1390 if (*Pointer
== L
'.') {
1392 // D should be followed by '.'
1396 return RETURN_UNSUPPORTED
;
1401 if (AddressIndex
< ARRAY_SIZE (Address
->Addr
)) {
1402 return RETURN_UNSUPPORTED
;
1405 CopyMem (Address
, &LocalAddress
, sizeof (*Address
));
1406 if (PrefixLength
!= NULL
) {
1407 *PrefixLength
= LocalPrefixLength
;
1409 if (EndPointer
!= NULL
) {
1410 *EndPointer
= Pointer
;
1413 return RETURN_SUCCESS
;
1417 Convert a Null-terminated Unicode GUID string to a value of type
1420 This function outputs a GUID value by interpreting the contents of
1421 the Unicode string specified by String. The format of the input
1422 Unicode string String consists of 36 characters, as follows:
1424 aabbccdd-eeff-gghh-iijj-kkllmmnnoopp
1426 The pairs aa - pp are two characters in the range [0-9], [a-f] and
1427 [A-F], with each pair representing a single byte hexadecimal value.
1429 The mapping between String and the EFI_GUID structure is as follows:
1447 If String is not aligned in a 16-bit boundary, then ASSERT().
1449 @param String Pointer to a Null-terminated Unicode string.
1450 @param Guid Pointer to the converted GUID.
1452 @retval RETURN_SUCCESS Guid is translated from String.
1453 @retval RETURN_INVALID_PARAMETER If String is NULL.
1455 @retval RETURN_UNSUPPORTED If String is not as the above format.
1461 IN CONST CHAR16
*String
,
1465 RETURN_STATUS Status
;
1468 ASSERT (((UINTN
) String
& BIT0
) == 0);
1471 // 1. None of String or Guid shall be a null pointer.
1473 SAFE_STRING_CONSTRAINT_CHECK ((String
!= NULL
), RETURN_INVALID_PARAMETER
);
1474 SAFE_STRING_CONSTRAINT_CHECK ((Guid
!= NULL
), RETURN_INVALID_PARAMETER
);
1477 // Get aabbccdd in big-endian.
1479 Status
= StrHexToBytes (String
, 2 * sizeof (LocalGuid
.Data1
), (UINT8
*) &LocalGuid
.Data1
, sizeof (LocalGuid
.Data1
));
1480 if (RETURN_ERROR (Status
) || String
[2 * sizeof (LocalGuid
.Data1
)] != L
'-') {
1481 return RETURN_UNSUPPORTED
;
1484 // Convert big-endian to little-endian.
1486 LocalGuid
.Data1
= SwapBytes32 (LocalGuid
.Data1
);
1487 String
+= 2 * sizeof (LocalGuid
.Data1
) + 1;
1490 // Get eeff in big-endian.
1492 Status
= StrHexToBytes (String
, 2 * sizeof (LocalGuid
.Data2
), (UINT8
*) &LocalGuid
.Data2
, sizeof (LocalGuid
.Data2
));
1493 if (RETURN_ERROR (Status
) || String
[2 * sizeof (LocalGuid
.Data2
)] != L
'-') {
1494 return RETURN_UNSUPPORTED
;
1497 // Convert big-endian to little-endian.
1499 LocalGuid
.Data2
= SwapBytes16 (LocalGuid
.Data2
);
1500 String
+= 2 * sizeof (LocalGuid
.Data2
) + 1;
1503 // Get gghh in big-endian.
1505 Status
= StrHexToBytes (String
, 2 * sizeof (LocalGuid
.Data3
), (UINT8
*) &LocalGuid
.Data3
, sizeof (LocalGuid
.Data3
));
1506 if (RETURN_ERROR (Status
) || String
[2 * sizeof (LocalGuid
.Data3
)] != L
'-') {
1507 return RETURN_UNSUPPORTED
;
1510 // Convert big-endian to little-endian.
1512 LocalGuid
.Data3
= SwapBytes16 (LocalGuid
.Data3
);
1513 String
+= 2 * sizeof (LocalGuid
.Data3
) + 1;
1518 Status
= StrHexToBytes (String
, 2 * 2, &LocalGuid
.Data4
[0], 2);
1519 if (RETURN_ERROR (Status
) || String
[2 * 2] != L
'-') {
1520 return RETURN_UNSUPPORTED
;
1522 String
+= 2 * 2 + 1;
1525 // Get kkllmmnnoopp.
1527 Status
= StrHexToBytes (String
, 2 * 6, &LocalGuid
.Data4
[2], 6);
1528 if (RETURN_ERROR (Status
)) {
1529 return RETURN_UNSUPPORTED
;
1532 CopyGuid (Guid
, &LocalGuid
);
1533 return RETURN_SUCCESS
;
1537 Convert a Null-terminated Unicode hexadecimal string to a byte array.
1539 This function outputs a byte array by interpreting the contents of
1540 the Unicode string specified by String in hexadecimal format. The format of
1541 the input Unicode string String is:
1545 X is a hexadecimal digit character in the range [0-9], [a-f] and [A-F].
1546 The function decodes every two hexadecimal digit characters as one byte. The
1547 decoding stops after Length of characters and outputs Buffer containing
1550 If String is not aligned in a 16-bit boundary, then ASSERT().
1552 @param String Pointer to a Null-terminated Unicode string.
1553 @param Length The number of Unicode characters to decode.
1554 @param Buffer Pointer to the converted bytes array.
1555 @param MaxBufferSize The maximum size of Buffer.
1557 @retval RETURN_SUCCESS Buffer is translated from String.
1558 @retval RETURN_INVALID_PARAMETER If String is NULL.
1560 If Length is not multiple of 2.
1561 If PcdMaximumUnicodeStringLength is not zero,
1562 and Length is greater than
1563 PcdMaximumUnicodeStringLength.
1564 @retval RETURN_UNSUPPORTED If Length of characters from String contain
1565 a character that is not valid hexadecimal
1566 digit characters, or a Null-terminator.
1567 @retval RETURN_BUFFER_TOO_SMALL If MaxBufferSize is less than (Length / 2).
1572 IN CONST CHAR16
*String
,
1575 IN UINTN MaxBufferSize
1580 ASSERT (((UINTN
) String
& BIT0
) == 0);
1583 // 1. None of String or Buffer shall be a null pointer.
1585 SAFE_STRING_CONSTRAINT_CHECK ((String
!= NULL
), RETURN_INVALID_PARAMETER
);
1586 SAFE_STRING_CONSTRAINT_CHECK ((Buffer
!= NULL
), RETURN_INVALID_PARAMETER
);
1589 // 2. Length shall not be greater than RSIZE_MAX.
1591 if (RSIZE_MAX
!= 0) {
1592 SAFE_STRING_CONSTRAINT_CHECK ((Length
<= RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
1596 // 3. Length shall not be odd.
1598 SAFE_STRING_CONSTRAINT_CHECK (((Length
& BIT0
) == 0), RETURN_INVALID_PARAMETER
);
1601 // 4. MaxBufferSize shall equal to or greater than Length / 2.
1603 SAFE_STRING_CONSTRAINT_CHECK ((MaxBufferSize
>= Length
/ 2), RETURN_BUFFER_TOO_SMALL
);
1606 // 5. String shall not contains invalid hexadecimal digits.
1608 for (Index
= 0; Index
< Length
; Index
++) {
1609 if (!InternalIsHexaDecimalDigitCharacter (String
[Index
])) {
1613 if (Index
!= Length
) {
1614 return RETURN_UNSUPPORTED
;
1618 // Convert the hex string to bytes.
1620 for(Index
= 0; Index
< Length
; Index
++) {
1623 // For even characters, write the upper nibble for each buffer byte,
1624 // and for even characters, the lower nibble.
1626 if ((Index
& BIT0
) == 0) {
1627 Buffer
[Index
/ 2] = (UINT8
) InternalHexCharToUintn (String
[Index
]) << 4;
1629 Buffer
[Index
/ 2] |= (UINT8
) InternalHexCharToUintn (String
[Index
]);
1632 return RETURN_SUCCESS
;
1636 Returns the length of a Null-terminated Ascii string.
1638 This function is similar as strlen_s defined in C11.
1640 @param String A pointer to a Null-terminated Ascii string.
1641 @param MaxSize The maximum number of Destination Ascii
1642 char, including terminating null char.
1644 @retval 0 If String is NULL.
1645 @retval MaxSize If there is no null character in the first MaxSize characters of String.
1646 @return The number of characters that percede the terminating null character.
1652 IN CONST CHAR8
*String
,
1659 // If String is a null pointer or MaxSize is 0, then the AsciiStrnLenS function returns zero.
1661 if ((String
== NULL
) || (MaxSize
== 0)) {
1666 // Otherwise, the AsciiStrnLenS function returns the number of characters that precede the
1667 // terminating null character. If there is no null character in the first MaxSize characters of
1668 // String then AsciiStrnLenS returns MaxSize. At most the first MaxSize characters of String shall
1669 // be accessed by AsciiStrnLenS.
1672 while (String
[Length
] != 0) {
1673 if (Length
>= MaxSize
- 1) {
1682 Returns the size of a Null-terminated Ascii string in bytes, including the
1685 This function returns the size of the Null-terminated Ascii string specified
1686 by String in bytes, including the Null terminator.
1688 @param String A pointer to a Null-terminated Ascii string.
1689 @param MaxSize The maximum number of Destination Ascii
1690 char, including the Null terminator.
1692 @retval 0 If String is NULL.
1693 @retval (sizeof (CHAR8) * (MaxSize + 1))
1694 If there is no Null terminator in the first MaxSize characters of
1696 @return The size of the Null-terminated Ascii string in bytes, including the
1703 IN CONST CHAR8
*String
,
1708 // If String is a null pointer, then the AsciiStrnSizeS function returns
1711 if (String
== NULL
) {
1716 // Otherwise, the AsciiStrnSizeS function returns the size of the
1717 // Null-terminated Ascii string in bytes, including the Null terminator. If
1718 // there is no Null terminator in the first MaxSize characters of String,
1719 // then AsciiStrnSizeS returns (sizeof (CHAR8) * (MaxSize + 1)) to keep a
1720 // consistent map with the AsciiStrnLenS function.
1722 return (AsciiStrnLenS (String
, MaxSize
) + 1) * sizeof (*String
);
1726 Copies the string pointed to by Source (including the terminating null char)
1727 to the array pointed to by Destination.
1729 This function is similar as strcpy_s defined in C11.
1731 If an error is returned, then the Destination is unmodified.
1733 @param Destination A pointer to a Null-terminated Ascii string.
1734 @param DestMax The maximum number of Destination Ascii
1735 char, including terminating null char.
1736 @param Source A pointer to a Null-terminated Ascii string.
1738 @retval RETURN_SUCCESS String is copied.
1739 @retval RETURN_BUFFER_TOO_SMALL If DestMax is NOT greater than StrLen(Source).
1740 @retval RETURN_INVALID_PARAMETER If Destination is NULL.
1742 If PcdMaximumAsciiStringLength is not zero,
1743 and DestMax is greater than
1744 PcdMaximumAsciiStringLength.
1746 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.
1751 OUT CHAR8
*Destination
,
1753 IN CONST CHAR8
*Source
1759 // 1. Neither Destination nor Source shall be a null pointer.
1761 SAFE_STRING_CONSTRAINT_CHECK ((Destination
!= NULL
), RETURN_INVALID_PARAMETER
);
1762 SAFE_STRING_CONSTRAINT_CHECK ((Source
!= NULL
), RETURN_INVALID_PARAMETER
);
1765 // 2. DestMax shall not be greater than ASCII_RSIZE_MAX.
1767 if (ASCII_RSIZE_MAX
!= 0) {
1768 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
<= ASCII_RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
1772 // 3. DestMax shall not equal zero.
1774 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
!= 0), RETURN_INVALID_PARAMETER
);
1777 // 4. DestMax shall be greater than AsciiStrnLenS(Source, DestMax).
1779 SourceLen
= AsciiStrnLenS (Source
, DestMax
);
1780 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
> SourceLen
), RETURN_BUFFER_TOO_SMALL
);
1783 // 5. Copying shall not take place between objects that overlap.
1785 SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoAsciiStrOverlap (Destination
, DestMax
, (CHAR8
*)Source
, SourceLen
+ 1), RETURN_ACCESS_DENIED
);
1788 // The AsciiStrCpyS function copies the string pointed to by Source (including the terminating
1789 // null character) into the array pointed to by Destination.
1791 while (*Source
!= 0) {
1792 *(Destination
++) = *(Source
++);
1796 return RETURN_SUCCESS
;
1800 Copies not more than Length successive char from the string pointed to by
1801 Source to the array pointed to by Destination. If no null char is copied from
1802 Source, then Destination[Length] is always set to null.
1804 This function is similar as strncpy_s defined in C11.
1806 If an error is returned, then the Destination is unmodified.
1808 @param Destination A pointer to a Null-terminated Ascii string.
1809 @param DestMax The maximum number of Destination Ascii
1810 char, including terminating null char.
1811 @param Source A pointer to a Null-terminated Ascii string.
1812 @param Length The maximum number of Ascii characters to copy.
1814 @retval RETURN_SUCCESS String is copied.
1815 @retval RETURN_BUFFER_TOO_SMALL If DestMax is NOT greater than
1816 MIN(StrLen(Source), Length).
1817 @retval RETURN_INVALID_PARAMETER If Destination is NULL.
1819 If PcdMaximumAsciiStringLength is not zero,
1820 and DestMax is greater than
1821 PcdMaximumAsciiStringLength.
1823 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.
1828 OUT CHAR8
*Destination
,
1830 IN CONST CHAR8
*Source
,
1837 // 1. Neither Destination nor Source shall be a null pointer.
1839 SAFE_STRING_CONSTRAINT_CHECK ((Destination
!= NULL
), RETURN_INVALID_PARAMETER
);
1840 SAFE_STRING_CONSTRAINT_CHECK ((Source
!= NULL
), RETURN_INVALID_PARAMETER
);
1843 // 2. Neither DestMax nor Length shall be greater than ASCII_RSIZE_MAX
1845 if (ASCII_RSIZE_MAX
!= 0) {
1846 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
<= ASCII_RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
1847 SAFE_STRING_CONSTRAINT_CHECK ((Length
<= ASCII_RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
1851 // 3. DestMax shall not equal zero.
1853 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
!= 0), RETURN_INVALID_PARAMETER
);
1856 // 4. If Length is not less than DestMax, then DestMax shall be greater than AsciiStrnLenS(Source, DestMax).
1858 SourceLen
= AsciiStrnLenS (Source
, MIN (DestMax
, Length
));
1859 if (Length
>= DestMax
) {
1860 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
> SourceLen
), RETURN_BUFFER_TOO_SMALL
);
1864 // 5. Copying shall not take place between objects that overlap.
1866 if (SourceLen
> Length
) {
1869 SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoAsciiStrOverlap (Destination
, DestMax
, (CHAR8
*)Source
, SourceLen
+ 1), RETURN_ACCESS_DENIED
);
1872 // The AsciiStrnCpyS function copies not more than Length successive characters (characters that
1873 // follow a null character are not copied) from the array pointed to by Source to the array
1874 // pointed to by Destination. If no null character was copied from Source, then Destination[Length] is set to a null
1877 while ((SourceLen
> 0) && (*Source
!= 0)) {
1878 *(Destination
++) = *(Source
++);
1883 return RETURN_SUCCESS
;
1887 Appends a copy of the string pointed to by Source (including the terminating
1888 null char) to the end of the string pointed to by Destination.
1890 This function is similar as strcat_s defined in C11.
1892 If an error is returned, then the Destination is unmodified.
1894 @param Destination A pointer to a Null-terminated Ascii string.
1895 @param DestMax The maximum number of Destination Ascii
1896 char, including terminating null char.
1897 @param Source A pointer to a Null-terminated Ascii string.
1899 @retval RETURN_SUCCESS String is appended.
1900 @retval RETURN_BAD_BUFFER_SIZE If DestMax is NOT greater than
1901 StrLen(Destination).
1902 @retval RETURN_BUFFER_TOO_SMALL If (DestMax - StrLen(Destination)) is NOT
1903 greater than StrLen(Source).
1904 @retval RETURN_INVALID_PARAMETER If Destination is NULL.
1906 If PcdMaximumAsciiStringLength is not zero,
1907 and DestMax is greater than
1908 PcdMaximumAsciiStringLength.
1910 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.
1915 IN OUT CHAR8
*Destination
,
1917 IN CONST CHAR8
*Source
1925 // Let CopyLen denote the value DestMax - AsciiStrnLenS(Destination, DestMax) upon entry to AsciiStrCatS.
1927 DestLen
= AsciiStrnLenS (Destination
, DestMax
);
1928 CopyLen
= DestMax
- DestLen
;
1931 // 1. Neither Destination nor Source shall be a null pointer.
1933 SAFE_STRING_CONSTRAINT_CHECK ((Destination
!= NULL
), RETURN_INVALID_PARAMETER
);
1934 SAFE_STRING_CONSTRAINT_CHECK ((Source
!= NULL
), RETURN_INVALID_PARAMETER
);
1937 // 2. DestMax shall not be greater than ASCII_RSIZE_MAX.
1939 if (ASCII_RSIZE_MAX
!= 0) {
1940 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
<= ASCII_RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
1944 // 3. DestMax shall not equal zero.
1946 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
!= 0), RETURN_INVALID_PARAMETER
);
1949 // 4. CopyLen shall not equal zero.
1951 SAFE_STRING_CONSTRAINT_CHECK ((CopyLen
!= 0), RETURN_BAD_BUFFER_SIZE
);
1954 // 5. CopyLen shall be greater than AsciiStrnLenS(Source, CopyLen).
1956 SourceLen
= AsciiStrnLenS (Source
, CopyLen
);
1957 SAFE_STRING_CONSTRAINT_CHECK ((CopyLen
> SourceLen
), RETURN_BUFFER_TOO_SMALL
);
1960 // 6. Copying shall not take place between objects that overlap.
1962 SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoAsciiStrOverlap (Destination
, DestMax
, (CHAR8
*)Source
, SourceLen
+ 1), RETURN_ACCESS_DENIED
);
1965 // The AsciiStrCatS function appends a copy of the string pointed to by Source (including the
1966 // terminating null character) to the end of the string pointed to by Destination. The initial character
1967 // from Source overwrites the null character at the end of Destination.
1969 Destination
= Destination
+ DestLen
;
1970 while (*Source
!= 0) {
1971 *(Destination
++) = *(Source
++);
1975 return RETURN_SUCCESS
;
1979 Appends not more than Length successive char from the string pointed to by
1980 Source to the end of the string pointed to by Destination. If no null char is
1981 copied from Source, then Destination[StrLen(Destination) + Length] is always
1984 This function is similar as strncat_s defined in C11.
1986 If an error is returned, then the Destination is unmodified.
1988 @param Destination A pointer to a Null-terminated Ascii string.
1989 @param DestMax The maximum number of Destination Ascii
1990 char, including terminating null char.
1991 @param Source A pointer to a Null-terminated Ascii string.
1992 @param Length The maximum number of Ascii characters to copy.
1994 @retval RETURN_SUCCESS String is appended.
1995 @retval RETURN_BAD_BUFFER_SIZE If DestMax is NOT greater than
1996 StrLen(Destination).
1997 @retval RETURN_BUFFER_TOO_SMALL If (DestMax - StrLen(Destination)) is NOT
1998 greater than MIN(StrLen(Source), Length).
1999 @retval RETURN_INVALID_PARAMETER If Destination is NULL.
2001 If PcdMaximumAsciiStringLength is not zero,
2002 and DestMax is greater than
2003 PcdMaximumAsciiStringLength.
2005 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.
2010 IN OUT CHAR8
*Destination
,
2012 IN CONST CHAR8
*Source
,
2021 // Let CopyLen denote the value DestMax - AsciiStrnLenS(Destination, DestMax) upon entry to AsciiStrnCatS.
2023 DestLen
= AsciiStrnLenS (Destination
, DestMax
);
2024 CopyLen
= DestMax
- DestLen
;
2027 // 1. Neither Destination nor Source shall be a null pointer.
2029 SAFE_STRING_CONSTRAINT_CHECK ((Destination
!= NULL
), RETURN_INVALID_PARAMETER
);
2030 SAFE_STRING_CONSTRAINT_CHECK ((Source
!= NULL
), RETURN_INVALID_PARAMETER
);
2033 // 2. Neither DestMax nor Length shall be greater than ASCII_RSIZE_MAX.
2035 if (ASCII_RSIZE_MAX
!= 0) {
2036 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
<= ASCII_RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
2037 SAFE_STRING_CONSTRAINT_CHECK ((Length
<= ASCII_RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
2041 // 3. DestMax shall not equal zero.
2043 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
!= 0), RETURN_INVALID_PARAMETER
);
2046 // 4. CopyLen shall not equal zero.
2048 SAFE_STRING_CONSTRAINT_CHECK ((CopyLen
!= 0), RETURN_BAD_BUFFER_SIZE
);
2051 // 5. If Length is not less than CopyLen, then CopyLen shall be greater than AsciiStrnLenS(Source, CopyLen).
2053 SourceLen
= AsciiStrnLenS (Source
, MIN (CopyLen
, Length
));
2054 if (Length
>= CopyLen
) {
2055 SAFE_STRING_CONSTRAINT_CHECK ((CopyLen
> SourceLen
), RETURN_BUFFER_TOO_SMALL
);
2059 // 6. Copying shall not take place between objects that overlap.
2061 if (SourceLen
> Length
) {
2064 SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoAsciiStrOverlap (Destination
, DestMax
, (CHAR8
*)Source
, SourceLen
+ 1), RETURN_ACCESS_DENIED
);
2067 // The AsciiStrnCatS function appends not more than Length successive characters (characters
2068 // that follow a null character are not copied) from the array pointed to by Source to the end of
2069 // the string pointed to by Destination. The initial character from Source overwrites the null character at
2070 // the end of Destination. If no null character was copied from Source, then Destination[DestMax-CopyLen+Length] is set to
2071 // a null character.
2073 Destination
= Destination
+ DestLen
;
2074 while ((SourceLen
> 0) && (*Source
!= 0)) {
2075 *(Destination
++) = *(Source
++);
2080 return RETURN_SUCCESS
;
2084 Convert a Null-terminated Ascii decimal string to a value of type UINTN.
2086 This function outputs a value of type UINTN by interpreting the contents of
2087 the Ascii string specified by String as a decimal number. The format of the
2088 input Ascii string String is:
2090 [spaces] [decimal digits].
2092 The valid decimal digit character is in the range [0-9]. The function will
2093 ignore the pad space, which includes spaces or tab characters, before
2094 [decimal digits]. The running zero in the beginning of [decimal digits] will
2095 be ignored. Then, the function stops at the first character that is a not a
2096 valid decimal character or a Null-terminator, whichever one comes first.
2098 If String has no valid decimal digits in the above format, then 0 is stored
2099 at the location pointed to by Data.
2100 If the number represented by String exceeds the range defined by UINTN, then
2101 MAX_UINTN is stored at the location pointed to by Data.
2103 If EndPointer is not NULL, a pointer to the character that stopped the scan
2104 is stored at the location pointed to by EndPointer. If String has no valid
2105 decimal digits right after the optional pad spaces, the value of String is
2106 stored at the location pointed to by EndPointer.
2108 @param String Pointer to a Null-terminated Ascii string.
2109 @param EndPointer Pointer to character that stops scan.
2110 @param Data Pointer to the converted value.
2112 @retval RETURN_SUCCESS Value is translated from String.
2113 @retval RETURN_INVALID_PARAMETER If String is NULL.
2115 If PcdMaximumAsciiStringLength is not zero,
2116 and String contains more than
2117 PcdMaximumAsciiStringLength Ascii
2118 characters, not including the
2120 @retval RETURN_UNSUPPORTED If the number represented by String exceeds
2121 the range defined by UINTN.
2126 AsciiStrDecimalToUintnS (
2127 IN CONST CHAR8
*String
,
2128 OUT CHAR8
**EndPointer
, OPTIONAL
2133 // 1. Neither String nor Data shall be a null pointer.
2135 SAFE_STRING_CONSTRAINT_CHECK ((String
!= NULL
), RETURN_INVALID_PARAMETER
);
2136 SAFE_STRING_CONSTRAINT_CHECK ((Data
!= NULL
), RETURN_INVALID_PARAMETER
);
2139 // 2. The length of String shall not be greater than ASCII_RSIZE_MAX.
2141 if (ASCII_RSIZE_MAX
!= 0) {
2142 SAFE_STRING_CONSTRAINT_CHECK ((AsciiStrnLenS (String
, ASCII_RSIZE_MAX
+ 1) <= ASCII_RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
2145 if (EndPointer
!= NULL
) {
2146 *EndPointer
= (CHAR8
*) String
;
2150 // Ignore the pad spaces (space or tab)
2152 while ((*String
== ' ') || (*String
== '\t')) {
2157 // Ignore leading Zeros after the spaces
2159 while (*String
== '0') {
2165 while (InternalAsciiIsDecimalDigitCharacter (*String
)) {
2167 // If the number represented by String overflows according to the range
2168 // defined by UINTN, then MAX_UINTN is stored in *Data and
2169 // RETURN_UNSUPPORTED is returned.
2171 if (*Data
> ((MAX_UINTN
- (*String
- '0')) / 10)) {
2173 if (EndPointer
!= NULL
) {
2174 *EndPointer
= (CHAR8
*) String
;
2176 return RETURN_UNSUPPORTED
;
2179 *Data
= *Data
* 10 + (*String
- '0');
2183 if (EndPointer
!= NULL
) {
2184 *EndPointer
= (CHAR8
*) String
;
2186 return RETURN_SUCCESS
;
2190 Convert a Null-terminated Ascii decimal string to a value of type UINT64.
2192 This function outputs a value of type UINT64 by interpreting the contents of
2193 the Ascii string specified by String as a decimal number. The format of the
2194 input Ascii string String is:
2196 [spaces] [decimal digits].
2198 The valid decimal digit character is in the range [0-9]. The function will
2199 ignore the pad space, which includes spaces or tab characters, before
2200 [decimal digits]. The running zero in the beginning of [decimal digits] will
2201 be ignored. Then, the function stops at the first character that is a not a
2202 valid decimal character or a Null-terminator, whichever one comes first.
2204 If String has no valid decimal digits in the above format, then 0 is stored
2205 at the location pointed to by Data.
2206 If the number represented by String exceeds the range defined by UINT64, then
2207 MAX_UINT64 is stored at the location pointed to by Data.
2209 If EndPointer is not NULL, a pointer to the character that stopped the scan
2210 is stored at the location pointed to by EndPointer. If String has no valid
2211 decimal digits right after the optional pad spaces, the value of String is
2212 stored at the location pointed to by EndPointer.
2214 @param String Pointer to a Null-terminated Ascii string.
2215 @param EndPointer Pointer to character that stops scan.
2216 @param Data Pointer to the converted value.
2218 @retval RETURN_SUCCESS Value is translated from String.
2219 @retval RETURN_INVALID_PARAMETER If String is NULL.
2221 If PcdMaximumAsciiStringLength is not zero,
2222 and String contains more than
2223 PcdMaximumAsciiStringLength Ascii
2224 characters, not including the
2226 @retval RETURN_UNSUPPORTED If the number represented by String exceeds
2227 the range defined by UINT64.
2232 AsciiStrDecimalToUint64S (
2233 IN CONST CHAR8
*String
,
2234 OUT CHAR8
**EndPointer
, OPTIONAL
2239 // 1. Neither String nor Data shall be a null pointer.
2241 SAFE_STRING_CONSTRAINT_CHECK ((String
!= NULL
), RETURN_INVALID_PARAMETER
);
2242 SAFE_STRING_CONSTRAINT_CHECK ((Data
!= NULL
), RETURN_INVALID_PARAMETER
);
2245 // 2. The length of String shall not be greater than ASCII_RSIZE_MAX.
2247 if (ASCII_RSIZE_MAX
!= 0) {
2248 SAFE_STRING_CONSTRAINT_CHECK ((AsciiStrnLenS (String
, ASCII_RSIZE_MAX
+ 1) <= ASCII_RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
2251 if (EndPointer
!= NULL
) {
2252 *EndPointer
= (CHAR8
*) String
;
2256 // Ignore the pad spaces (space or tab)
2258 while ((*String
== ' ') || (*String
== '\t')) {
2263 // Ignore leading Zeros after the spaces
2265 while (*String
== '0') {
2271 while (InternalAsciiIsDecimalDigitCharacter (*String
)) {
2273 // If the number represented by String overflows according to the range
2274 // defined by UINT64, then MAX_UINT64 is stored in *Data and
2275 // RETURN_UNSUPPORTED is returned.
2277 if (*Data
> DivU64x32 (MAX_UINT64
- (*String
- '0'), 10)) {
2279 if (EndPointer
!= NULL
) {
2280 *EndPointer
= (CHAR8
*) String
;
2282 return RETURN_UNSUPPORTED
;
2285 *Data
= MultU64x32 (*Data
, 10) + (*String
- '0');
2289 if (EndPointer
!= NULL
) {
2290 *EndPointer
= (CHAR8
*) String
;
2292 return RETURN_SUCCESS
;
2296 Convert a Null-terminated Ascii hexadecimal string to a value of type UINTN.
2298 This function outputs a value of type UINTN by interpreting the contents of
2299 the Ascii string specified by String as a hexadecimal number. The format of
2300 the input Ascii string String is:
2302 [spaces][zeros][x][hexadecimal digits].
2304 The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].
2305 The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix. If
2306 "x" appears in the input string, it must be prefixed with at least one 0. The
2307 function will ignore the pad space, which includes spaces or tab characters,
2308 before [zeros], [x] or [hexadecimal digits]. The running zero before [x] or
2309 [hexadecimal digits] will be ignored. Then, the decoding starts after [x] or
2310 the first valid hexadecimal digit. Then, the function stops at the first
2311 character that is a not a valid hexadecimal character or Null-terminator,
2312 whichever on comes first.
2314 If String has no valid hexadecimal digits in the above format, then 0 is
2315 stored at the location pointed to by Data.
2316 If the number represented by String exceeds the range defined by UINTN, then
2317 MAX_UINTN is stored at the location pointed to by Data.
2319 If EndPointer is not NULL, a pointer to the character that stopped the scan
2320 is stored at the location pointed to by EndPointer. If String has no valid
2321 hexadecimal digits right after the optional pad spaces, the value of String
2322 is stored at the location pointed to by EndPointer.
2324 @param String Pointer to a Null-terminated Ascii string.
2325 @param EndPointer Pointer to character that stops scan.
2326 @param Data Pointer to the converted value.
2328 @retval RETURN_SUCCESS Value is translated from String.
2329 @retval RETURN_INVALID_PARAMETER If String is NULL.
2331 If PcdMaximumAsciiStringLength is not zero,
2332 and String contains more than
2333 PcdMaximumAsciiStringLength Ascii
2334 characters, not including the
2336 @retval RETURN_UNSUPPORTED If the number represented by String exceeds
2337 the range defined by UINTN.
2342 AsciiStrHexToUintnS (
2343 IN CONST CHAR8
*String
,
2344 OUT CHAR8
**EndPointer
, OPTIONAL
2349 // 1. Neither String nor Data shall be a null pointer.
2351 SAFE_STRING_CONSTRAINT_CHECK ((String
!= NULL
), RETURN_INVALID_PARAMETER
);
2352 SAFE_STRING_CONSTRAINT_CHECK ((Data
!= NULL
), RETURN_INVALID_PARAMETER
);
2355 // 2. The length of String shall not be greater than ASCII_RSIZE_MAX.
2357 if (ASCII_RSIZE_MAX
!= 0) {
2358 SAFE_STRING_CONSTRAINT_CHECK ((AsciiStrnLenS (String
, ASCII_RSIZE_MAX
+ 1) <= ASCII_RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
2361 if (EndPointer
!= NULL
) {
2362 *EndPointer
= (CHAR8
*) String
;
2366 // Ignore the pad spaces (space or tab)
2368 while ((*String
== ' ') || (*String
== '\t')) {
2373 // Ignore leading Zeros after the spaces
2375 while (*String
== '0') {
2379 if (AsciiCharToUpper (*String
) == 'X') {
2380 if (*(String
- 1) != '0') {
2382 return RETURN_SUCCESS
;
2392 while (InternalAsciiIsHexaDecimalDigitCharacter (*String
)) {
2394 // If the number represented by String overflows according to the range
2395 // defined by UINTN, then MAX_UINTN is stored in *Data and
2396 // RETURN_UNSUPPORTED is returned.
2398 if (*Data
> ((MAX_UINTN
- InternalAsciiHexCharToUintn (*String
)) >> 4)) {
2400 if (EndPointer
!= NULL
) {
2401 *EndPointer
= (CHAR8
*) String
;
2403 return RETURN_UNSUPPORTED
;
2406 *Data
= (*Data
<< 4) + InternalAsciiHexCharToUintn (*String
);
2410 if (EndPointer
!= NULL
) {
2411 *EndPointer
= (CHAR8
*) String
;
2413 return RETURN_SUCCESS
;
2417 Convert a Null-terminated Ascii hexadecimal string to a value of type UINT64.
2419 This function outputs a value of type UINT64 by interpreting the contents of
2420 the Ascii string specified by String as a hexadecimal number. The format of
2421 the input Ascii string String is:
2423 [spaces][zeros][x][hexadecimal digits].
2425 The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].
2426 The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix. If
2427 "x" appears in the input string, it must be prefixed with at least one 0. The
2428 function will ignore the pad space, which includes spaces or tab characters,
2429 before [zeros], [x] or [hexadecimal digits]. The running zero before [x] or
2430 [hexadecimal digits] will be ignored. Then, the decoding starts after [x] or
2431 the first valid hexadecimal digit. Then, the function stops at the first
2432 character that is a not a valid hexadecimal character or Null-terminator,
2433 whichever on comes first.
2435 If String has no valid hexadecimal digits in the above format, then 0 is
2436 stored at the location pointed to by Data.
2437 If the number represented by String exceeds the range defined by UINT64, then
2438 MAX_UINT64 is stored at the location pointed to by Data.
2440 If EndPointer is not NULL, a pointer to the character that stopped the scan
2441 is stored at the location pointed to by EndPointer. If String has no valid
2442 hexadecimal digits right after the optional pad spaces, the value of String
2443 is stored at the location pointed to by EndPointer.
2445 @param String Pointer to a Null-terminated Ascii string.
2446 @param EndPointer Pointer to character that stops scan.
2447 @param Data Pointer to the converted value.
2449 @retval RETURN_SUCCESS Value is translated from String.
2450 @retval RETURN_INVALID_PARAMETER If String is NULL.
2452 If PcdMaximumAsciiStringLength is not zero,
2453 and String contains more than
2454 PcdMaximumAsciiStringLength Ascii
2455 characters, not including the
2457 @retval RETURN_UNSUPPORTED If the number represented by String exceeds
2458 the range defined by UINT64.
2463 AsciiStrHexToUint64S (
2464 IN CONST CHAR8
*String
,
2465 OUT CHAR8
**EndPointer
, OPTIONAL
2470 // 1. Neither String nor Data shall be a null pointer.
2472 SAFE_STRING_CONSTRAINT_CHECK ((String
!= NULL
), RETURN_INVALID_PARAMETER
);
2473 SAFE_STRING_CONSTRAINT_CHECK ((Data
!= NULL
), RETURN_INVALID_PARAMETER
);
2476 // 2. The length of String shall not be greater than ASCII_RSIZE_MAX.
2478 if (ASCII_RSIZE_MAX
!= 0) {
2479 SAFE_STRING_CONSTRAINT_CHECK ((AsciiStrnLenS (String
, ASCII_RSIZE_MAX
+ 1) <= ASCII_RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
2482 if (EndPointer
!= NULL
) {
2483 *EndPointer
= (CHAR8
*) String
;
2487 // Ignore the pad spaces (space or tab)
2489 while ((*String
== ' ') || (*String
== '\t')) {
2494 // Ignore leading Zeros after the spaces
2496 while (*String
== '0') {
2500 if (AsciiCharToUpper (*String
) == 'X') {
2501 if (*(String
- 1) != '0') {
2503 return RETURN_SUCCESS
;
2513 while (InternalAsciiIsHexaDecimalDigitCharacter (*String
)) {
2515 // If the number represented by String overflows according to the range
2516 // defined by UINT64, then MAX_UINT64 is stored in *Data and
2517 // RETURN_UNSUPPORTED is returned.
2519 if (*Data
> RShiftU64 (MAX_UINT64
- InternalAsciiHexCharToUintn (*String
), 4)) {
2521 if (EndPointer
!= NULL
) {
2522 *EndPointer
= (CHAR8
*) String
;
2524 return RETURN_UNSUPPORTED
;
2527 *Data
= LShiftU64 (*Data
, 4) + InternalAsciiHexCharToUintn (*String
);
2531 if (EndPointer
!= NULL
) {
2532 *EndPointer
= (CHAR8
*) String
;
2534 return RETURN_SUCCESS
;
2538 Convert a Null-terminated Unicode string to a Null-terminated
2541 This function is similar to AsciiStrCpyS.
2543 This function converts the content of the Unicode string Source
2544 to the ASCII string Destination by copying the lower 8 bits of
2545 each Unicode character. The function terminates the ASCII string
2546 Destination by appending a Null-terminator character at the end.
2548 The caller is responsible to make sure Destination points to a buffer with size
2549 equal or greater than ((StrLen (Source) + 1) * sizeof (CHAR8)) in bytes.
2551 If any Unicode characters in Source contain non-zero value in
2552 the upper 8 bits, then ASSERT().
2554 If Source is not aligned on a 16-bit boundary, then ASSERT().
2556 If an error is returned, then the Destination is unmodified.
2558 @param Source The pointer to a Null-terminated Unicode string.
2559 @param Destination The pointer to a Null-terminated ASCII string.
2560 @param DestMax The maximum number of Destination Ascii
2561 char, including terminating null char.
2563 @retval RETURN_SUCCESS String is converted.
2564 @retval RETURN_BUFFER_TOO_SMALL If DestMax is NOT greater than StrLen(Source).
2565 @retval RETURN_INVALID_PARAMETER If Destination is NULL.
2567 If PcdMaximumAsciiStringLength is not zero,
2568 and DestMax is greater than
2569 PcdMaximumAsciiStringLength.
2570 If PcdMaximumUnicodeStringLength is not zero,
2571 and DestMax is greater than
2572 PcdMaximumUnicodeStringLength.
2574 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.
2579 UnicodeStrToAsciiStrS (
2580 IN CONST CHAR16
*Source
,
2581 OUT CHAR8
*Destination
,
2587 ASSERT (((UINTN
) Source
& BIT0
) == 0);
2590 // 1. Neither Destination nor Source shall be a null pointer.
2592 SAFE_STRING_CONSTRAINT_CHECK ((Destination
!= NULL
), RETURN_INVALID_PARAMETER
);
2593 SAFE_STRING_CONSTRAINT_CHECK ((Source
!= NULL
), RETURN_INVALID_PARAMETER
);
2596 // 2. DestMax shall not be greater than ASCII_RSIZE_MAX or RSIZE_MAX.
2598 if (ASCII_RSIZE_MAX
!= 0) {
2599 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
<= ASCII_RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
2601 if (RSIZE_MAX
!= 0) {
2602 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
<= RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
2606 // 3. DestMax shall not equal zero.
2608 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
!= 0), RETURN_INVALID_PARAMETER
);
2611 // 4. DestMax shall be greater than StrnLenS (Source, DestMax).
2613 SourceLen
= StrnLenS (Source
, DestMax
);
2614 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
> SourceLen
), RETURN_BUFFER_TOO_SMALL
);
2617 // 5. Copying shall not take place between objects that overlap.
2619 SAFE_STRING_CONSTRAINT_CHECK (!InternalSafeStringIsOverlap (Destination
, DestMax
, (VOID
*)Source
, (SourceLen
+ 1) * sizeof(CHAR16
)), RETURN_ACCESS_DENIED
);
2624 while (*Source
!= '\0') {
2626 // If any Unicode characters in Source contain
2627 // non-zero value in the upper 8 bits, then ASSERT().
2629 ASSERT (*Source
< 0x100);
2630 *(Destination
++) = (CHAR8
) *(Source
++);
2632 *Destination
= '\0';
2634 return RETURN_SUCCESS
;
2638 Convert not more than Length successive characters from a Null-terminated
2639 Unicode string to a Null-terminated Ascii string. If no null char is copied
2640 from Source, then Destination[Length] is always set to null.
2642 This function converts not more than Length successive characters from the
2643 Unicode string Source to the Ascii string Destination by copying the lower 8
2644 bits of each Unicode character. The function terminates the Ascii string
2645 Destination by appending a Null-terminator character at the end.
2647 The caller is responsible to make sure Destination points to a buffer with
2648 size not smaller than ((MIN(StrLen(Source), Length) + 1) * sizeof (CHAR8))
2651 If any Unicode characters in Source contain non-zero value in the upper 8
2652 bits, then ASSERT().
2653 If Source is not aligned on a 16-bit boundary, then ASSERT().
2655 If an error is returned, then Destination and DestinationLength are
2658 @param Source The pointer to a Null-terminated Unicode string.
2659 @param Length The maximum number of Unicode characters to
2661 @param Destination The pointer to a Null-terminated Ascii string.
2662 @param DestMax The maximum number of Destination Ascii char,
2663 including terminating null char.
2664 @param DestinationLength The number of Unicode characters converted.
2666 @retval RETURN_SUCCESS String is converted.
2667 @retval RETURN_INVALID_PARAMETER If Destination is NULL.
2669 If DestinationLength is NULL.
2670 If PcdMaximumAsciiStringLength is not zero,
2671 and Length or DestMax is greater than
2672 PcdMaximumAsciiStringLength.
2673 If PcdMaximumUnicodeStringLength is not
2674 zero, and Length or DestMax is greater than
2675 PcdMaximumUnicodeStringLength.
2677 @retval RETURN_BUFFER_TOO_SMALL If DestMax is NOT greater than
2678 MIN(StrLen(Source), Length).
2679 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.
2684 UnicodeStrnToAsciiStrS (
2685 IN CONST CHAR16
*Source
,
2687 OUT CHAR8
*Destination
,
2689 OUT UINTN
*DestinationLength
2694 ASSERT (((UINTN
) Source
& BIT0
) == 0);
2697 // 1. None of Destination, Source or DestinationLength shall be a null
2700 SAFE_STRING_CONSTRAINT_CHECK ((Destination
!= NULL
), RETURN_INVALID_PARAMETER
);
2701 SAFE_STRING_CONSTRAINT_CHECK ((Source
!= NULL
), RETURN_INVALID_PARAMETER
);
2702 SAFE_STRING_CONSTRAINT_CHECK ((DestinationLength
!= NULL
), RETURN_INVALID_PARAMETER
);
2705 // 2. Neither Length nor DestMax shall be greater than ASCII_RSIZE_MAX or
2708 if (ASCII_RSIZE_MAX
!= 0) {
2709 SAFE_STRING_CONSTRAINT_CHECK ((Length
<= ASCII_RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
2710 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
<= ASCII_RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
2712 if (RSIZE_MAX
!= 0) {
2713 SAFE_STRING_CONSTRAINT_CHECK ((Length
<= RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
2714 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
<= RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
2718 // 3. DestMax shall not equal zero.
2720 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
!= 0), RETURN_INVALID_PARAMETER
);
2723 // 4. If Length is not less than DestMax, then DestMax shall be greater than
2724 // StrnLenS(Source, DestMax).
2726 SourceLen
= StrnLenS (Source
, DestMax
);
2727 if (Length
>= DestMax
) {
2728 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
> SourceLen
), RETURN_BUFFER_TOO_SMALL
);
2732 // 5. Copying shall not take place between objects that overlap.
2734 if (SourceLen
> Length
) {
2737 SAFE_STRING_CONSTRAINT_CHECK (!InternalSafeStringIsOverlap (Destination
, DestMax
, (VOID
*)Source
, (SourceLen
+ 1) * sizeof(CHAR16
)), RETURN_ACCESS_DENIED
);
2739 *DestinationLength
= 0;
2744 while ((*Source
!= 0) && (SourceLen
> 0)) {
2746 // If any Unicode characters in Source contain non-zero value in the upper
2747 // 8 bits, then ASSERT().
2749 ASSERT (*Source
< 0x100);
2750 *(Destination
++) = (CHAR8
) *(Source
++);
2752 (*DestinationLength
)++;
2756 return RETURN_SUCCESS
;
2760 Convert one Null-terminated ASCII string to a Null-terminated
2763 This function is similar to StrCpyS.
2765 This function converts the contents of the ASCII string Source to the Unicode
2766 string Destination. The function terminates the Unicode string Destination by
2767 appending a Null-terminator character at the end.
2769 The caller is responsible to make sure Destination points to a buffer with size
2770 equal or greater than ((AsciiStrLen (Source) + 1) * sizeof (CHAR16)) in bytes.
2772 If Destination is not aligned on a 16-bit boundary, then ASSERT().
2774 If an error is returned, then the Destination is unmodified.
2776 @param Source The pointer to a Null-terminated ASCII string.
2777 @param Destination The pointer to a Null-terminated Unicode string.
2778 @param DestMax The maximum number of Destination Unicode
2779 char, including terminating null char.
2781 @retval RETURN_SUCCESS String is converted.
2782 @retval RETURN_BUFFER_TOO_SMALL If DestMax is NOT greater than StrLen(Source).
2783 @retval RETURN_INVALID_PARAMETER If Destination is NULL.
2785 If PcdMaximumUnicodeStringLength is not zero,
2786 and DestMax is greater than
2787 PcdMaximumUnicodeStringLength.
2788 If PcdMaximumAsciiStringLength is not zero,
2789 and DestMax is greater than
2790 PcdMaximumAsciiStringLength.
2792 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.
2797 AsciiStrToUnicodeStrS (
2798 IN CONST CHAR8
*Source
,
2799 OUT CHAR16
*Destination
,
2805 ASSERT (((UINTN
) Destination
& BIT0
) == 0);
2808 // 1. Neither Destination nor Source shall be a null pointer.
2810 SAFE_STRING_CONSTRAINT_CHECK ((Destination
!= NULL
), RETURN_INVALID_PARAMETER
);
2811 SAFE_STRING_CONSTRAINT_CHECK ((Source
!= NULL
), RETURN_INVALID_PARAMETER
);
2814 // 2. DestMax shall not be greater than RSIZE_MAX or ASCII_RSIZE_MAX.
2816 if (RSIZE_MAX
!= 0) {
2817 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
<= RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
2819 if (ASCII_RSIZE_MAX
!= 0) {
2820 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
<= ASCII_RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
2824 // 3. DestMax shall not equal zero.
2826 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
!= 0), RETURN_INVALID_PARAMETER
);
2829 // 4. DestMax shall be greater than AsciiStrnLenS(Source, DestMax).
2831 SourceLen
= AsciiStrnLenS (Source
, DestMax
);
2832 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
> SourceLen
), RETURN_BUFFER_TOO_SMALL
);
2835 // 5. Copying shall not take place between objects that overlap.
2837 SAFE_STRING_CONSTRAINT_CHECK (!InternalSafeStringIsOverlap (Destination
, DestMax
* sizeof(CHAR16
), (VOID
*)Source
, SourceLen
+ 1), RETURN_ACCESS_DENIED
);
2842 while (*Source
!= '\0') {
2843 *(Destination
++) = (CHAR16
)(UINT8
)*(Source
++);
2845 *Destination
= '\0';
2847 return RETURN_SUCCESS
;
2851 Convert not more than Length successive characters from a Null-terminated
2852 Ascii string to a Null-terminated Unicode string. If no null char is copied
2853 from Source, then Destination[Length] is always set to null.
2855 This function converts not more than Length successive characters from the
2856 Ascii string Source to the Unicode string Destination. The function
2857 terminates the Unicode string Destination by appending a Null-terminator
2858 character at the end.
2860 The caller is responsible to make sure Destination points to a buffer with
2861 size not smaller than
2862 ((MIN(AsciiStrLen(Source), Length) + 1) * sizeof (CHAR8)) in bytes.
2864 If Destination is not aligned on a 16-bit boundary, then ASSERT().
2866 If an error is returned, then Destination and DestinationLength are
2869 @param Source The pointer to a Null-terminated Ascii string.
2870 @param Length The maximum number of Ascii characters to convert.
2871 @param Destination The pointer to a Null-terminated Unicode string.
2872 @param DestMax The maximum number of Destination Unicode char,
2873 including terminating null char.
2874 @param DestinationLength The number of Ascii characters converted.
2876 @retval RETURN_SUCCESS String is converted.
2877 @retval RETURN_INVALID_PARAMETER If Destination is NULL.
2879 If DestinationLength is NULL.
2880 If PcdMaximumUnicodeStringLength is not
2881 zero, and Length or DestMax is greater than
2882 PcdMaximumUnicodeStringLength.
2883 If PcdMaximumAsciiStringLength is not zero,
2884 and Length or DestMax is greater than
2885 PcdMaximumAsciiStringLength.
2887 @retval RETURN_BUFFER_TOO_SMALL If DestMax is NOT greater than
2888 MIN(AsciiStrLen(Source), Length).
2889 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.
2894 AsciiStrnToUnicodeStrS (
2895 IN CONST CHAR8
*Source
,
2897 OUT CHAR16
*Destination
,
2899 OUT UINTN
*DestinationLength
2904 ASSERT (((UINTN
) Destination
& BIT0
) == 0);
2907 // 1. None of Destination, Source or DestinationLength shall be a null
2910 SAFE_STRING_CONSTRAINT_CHECK ((Destination
!= NULL
), RETURN_INVALID_PARAMETER
);
2911 SAFE_STRING_CONSTRAINT_CHECK ((Source
!= NULL
), RETURN_INVALID_PARAMETER
);
2912 SAFE_STRING_CONSTRAINT_CHECK ((DestinationLength
!= NULL
), RETURN_INVALID_PARAMETER
);
2915 // 2. Neither Length nor DestMax shall be greater than ASCII_RSIZE_MAX or
2918 if (RSIZE_MAX
!= 0) {
2919 SAFE_STRING_CONSTRAINT_CHECK ((Length
<= RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
2920 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
<= RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
2922 if (ASCII_RSIZE_MAX
!= 0) {
2923 SAFE_STRING_CONSTRAINT_CHECK ((Length
<= ASCII_RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
2924 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
<= ASCII_RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
2928 // 3. DestMax shall not equal zero.
2930 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
!= 0), RETURN_INVALID_PARAMETER
);
2933 // 4. If Length is not less than DestMax, then DestMax shall be greater than
2934 // AsciiStrnLenS(Source, DestMax).
2936 SourceLen
= AsciiStrnLenS (Source
, DestMax
);
2937 if (Length
>= DestMax
) {
2938 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
> SourceLen
), RETURN_BUFFER_TOO_SMALL
);
2942 // 5. Copying shall not take place between objects that overlap.
2944 if (SourceLen
> Length
) {
2947 SAFE_STRING_CONSTRAINT_CHECK (!InternalSafeStringIsOverlap (Destination
, DestMax
* sizeof(CHAR16
), (VOID
*)Source
, SourceLen
+ 1), RETURN_ACCESS_DENIED
);
2949 *DestinationLength
= 0;
2954 while ((*Source
!= 0) && (SourceLen
> 0)) {
2955 *(Destination
++) = (CHAR16
)(UINT8
)*(Source
++);
2957 (*DestinationLength
)++;
2961 return RETURN_SUCCESS
;
2965 Convert a Null-terminated ASCII string to IPv6 address and prefix length.
2967 This function outputs a value of type IPv6_ADDRESS and may output a value
2968 of type UINT8 by interpreting the contents of the ASCII string specified
2969 by String. The format of the input ASCII string String is as follows:
2973 X contains one to four hexadecimal digit characters in the range [0-9], [a-f] and
2974 [A-F]. X is converted to a value of type UINT16, whose low byte is stored in low
2975 memory address and high byte is stored in high memory address. P contains decimal
2976 digit characters in the range [0-9]. The running zero in the beginning of P will
2977 be ignored. /P is optional.
2979 When /P is not in the String, the function stops at the first character that is
2980 not a valid hexadecimal digit character after eight X's are converted.
2982 When /P is in the String, the function stops at the first character that is not
2983 a valid decimal digit character after P is converted.
2985 "::" can be used to compress one or more groups of X when X contains only 0.
2986 The "::" can only appear once in the String.
2988 If EndPointer is not NULL and Address is translated from String, a pointer
2989 to the character that stopped the scan is stored at the location pointed to
2992 @param String Pointer to a Null-terminated ASCII string.
2993 @param EndPointer Pointer to character that stops scan.
2994 @param Address Pointer to the converted IPv6 address.
2995 @param PrefixLength Pointer to the converted IPv6 address prefix
2996 length. MAX_UINT8 is returned when /P is
2999 @retval RETURN_SUCCESS Address is translated from String.
3000 @retval RETURN_INVALID_PARAMETER If String is NULL.
3002 @retval RETURN_UNSUPPORTED If X contains more than four hexadecimal
3004 If String contains "::" and number of X
3006 If P starts with character that is not a
3007 valid decimal digit character.
3008 If the decimal number converted from P
3014 AsciiStrToIpv6Address (
3015 IN CONST CHAR8
*String
,
3016 OUT CHAR8
**EndPointer
, OPTIONAL
3017 OUT IPv6_ADDRESS
*Address
,
3018 OUT UINT8
*PrefixLength OPTIONAL
3021 RETURN_STATUS Status
;
3024 IPv6_ADDRESS LocalAddress
;
3025 UINT8 LocalPrefixLength
;
3026 CONST CHAR8
*Pointer
;
3028 UINTN CompressStart
;
3029 BOOLEAN ExpectPrefix
;
3031 LocalPrefixLength
= MAX_UINT8
;
3032 CompressStart
= ARRAY_SIZE (Address
->Addr
);
3033 ExpectPrefix
= FALSE
;
3036 // None of String or Address shall be a null pointer.
3038 SAFE_STRING_CONSTRAINT_CHECK ((String
!= NULL
), RETURN_INVALID_PARAMETER
);
3039 SAFE_STRING_CONSTRAINT_CHECK ((Address
!= NULL
), RETURN_INVALID_PARAMETER
);
3041 for (Pointer
= String
, AddressIndex
= 0; AddressIndex
< ARRAY_SIZE (Address
->Addr
) + 1;) {
3042 if (!InternalAsciiIsHexaDecimalDigitCharacter (*Pointer
)) {
3043 if (*Pointer
!= ':') {
3045 // ":" or "/" should be followed by digit characters.
3047 return RETURN_UNSUPPORTED
;
3051 // Meet second ":" after previous ":" or "/"
3052 // or meet first ":" in the beginning of String.
3056 // ":" shall not be after "/"
3058 return RETURN_UNSUPPORTED
;
3061 if (CompressStart
!= ARRAY_SIZE (Address
->Addr
) || AddressIndex
== ARRAY_SIZE (Address
->Addr
)) {
3063 // "::" can only appear once.
3064 // "::" can only appear when address is not full length.
3066 return RETURN_UNSUPPORTED
;
3069 // Remember the start of zero compressing.
3071 CompressStart
= AddressIndex
;
3074 if (CompressStart
== 0) {
3075 if (*Pointer
!= ':') {
3077 // Single ":" shall not be in the beginning of String.
3079 return RETURN_UNSUPPORTED
;
3086 if (!InternalAsciiIsHexaDecimalDigitCharacter (*Pointer
)) {
3087 if (*Pointer
== '/') {
3089 // Might be optional "/P" after "::".
3091 if (CompressStart
!= AddressIndex
) {
3092 return RETURN_UNSUPPORTED
;
3098 if (!ExpectPrefix
) {
3102 Status
= AsciiStrHexToUintnS (Pointer
, &End
, &Uintn
);
3103 if (RETURN_ERROR (Status
) || End
- Pointer
> 4) {
3105 // Number of hexadecimal digit characters is no more than 4.
3107 return RETURN_UNSUPPORTED
;
3111 // Uintn won't exceed MAX_UINT16 if number of hexadecimal digit characters is no more than 4.
3113 ASSERT (AddressIndex
+ 1 < ARRAY_SIZE (Address
->Addr
));
3114 LocalAddress
.Addr
[AddressIndex
] = (UINT8
) ((UINT16
) Uintn
>> 8);
3115 LocalAddress
.Addr
[AddressIndex
+ 1] = (UINT8
) Uintn
;
3119 // Get P, then exit the loop.
3121 Status
= AsciiStrDecimalToUintnS (Pointer
, &End
, &Uintn
);
3122 if (RETURN_ERROR (Status
) || End
== Pointer
|| Uintn
> 128) {
3124 // Prefix length should not exceed 128.
3126 return RETURN_UNSUPPORTED
;
3128 LocalPrefixLength
= (UINT8
) Uintn
;
3137 if (*Pointer
== '/') {
3138 ExpectPrefix
= TRUE
;
3139 } else if (*Pointer
== ':') {
3140 if (AddressIndex
== ARRAY_SIZE (Address
->Addr
)) {
3142 // Meet additional ":" after all 8 16-bit address
3148 // Meet other character that is not "/" or ":" after all 8 16-bit address
3155 if ((AddressIndex
== ARRAY_SIZE (Address
->Addr
) && CompressStart
!= ARRAY_SIZE (Address
->Addr
)) ||
3156 (AddressIndex
!= ARRAY_SIZE (Address
->Addr
) && CompressStart
== ARRAY_SIZE (Address
->Addr
))
3159 // Full length of address shall not have compressing zeros.
3160 // Non-full length of address shall have compressing zeros.
3162 return RETURN_UNSUPPORTED
;
3164 CopyMem (&Address
->Addr
[0], &LocalAddress
.Addr
[0], CompressStart
);
3165 ZeroMem (&Address
->Addr
[CompressStart
], ARRAY_SIZE (Address
->Addr
) - AddressIndex
);
3166 if (AddressIndex
> CompressStart
) {
3168 &Address
->Addr
[CompressStart
+ ARRAY_SIZE (Address
->Addr
) - AddressIndex
],
3169 &LocalAddress
.Addr
[CompressStart
],
3170 AddressIndex
- CompressStart
3175 if (PrefixLength
!= NULL
) {
3176 *PrefixLength
= LocalPrefixLength
;
3178 if (EndPointer
!= NULL
) {
3179 *EndPointer
= (CHAR8
*) Pointer
;
3182 return RETURN_SUCCESS
;
3186 Convert a Null-terminated ASCII string to IPv4 address and prefix length.
3188 This function outputs a value of type IPv4_ADDRESS and may output a value
3189 of type UINT8 by interpreting the contents of the ASCII string specified
3190 by String. The format of the input ASCII string String is as follows:
3194 D and P are decimal digit characters in the range [0-9]. The running zero in
3195 the beginning of D and P will be ignored. /P is optional.
3197 When /P is not in the String, the function stops at the first character that is
3198 not a valid decimal digit character after four D's are converted.
3200 When /P is in the String, the function stops at the first character that is not
3201 a valid decimal digit character after P is converted.
3203 If EndPointer is not NULL and Address is translated from String, a pointer
3204 to the character that stopped the scan is stored at the location pointed to
3207 @param String Pointer to a Null-terminated ASCII string.
3208 @param EndPointer Pointer to character that stops scan.
3209 @param Address Pointer to the converted IPv4 address.
3210 @param PrefixLength Pointer to the converted IPv4 address prefix
3211 length. MAX_UINT8 is returned when /P is
3214 @retval RETURN_SUCCESS Address is translated from String.
3215 @retval RETURN_INVALID_PARAMETER If String is NULL.
3217 @retval RETURN_UNSUPPORTED If String is not in the correct format.
3218 If any decimal number converted from D
3220 If the decimal number converted from P
3226 AsciiStrToIpv4Address (
3227 IN CONST CHAR8
*String
,
3228 OUT CHAR8
**EndPointer
, OPTIONAL
3229 OUT IPv4_ADDRESS
*Address
,
3230 OUT UINT8
*PrefixLength OPTIONAL
3233 RETURN_STATUS Status
;
3236 IPv4_ADDRESS LocalAddress
;
3237 UINT8 LocalPrefixLength
;
3240 LocalPrefixLength
= MAX_UINT8
;
3243 // None of String or Address shall be a null pointer.
3245 SAFE_STRING_CONSTRAINT_CHECK ((String
!= NULL
), RETURN_INVALID_PARAMETER
);
3246 SAFE_STRING_CONSTRAINT_CHECK ((Address
!= NULL
), RETURN_INVALID_PARAMETER
);
3248 for (Pointer
= (CHAR8
*) String
, AddressIndex
= 0; AddressIndex
< ARRAY_SIZE (Address
->Addr
) + 1;) {
3249 if (!InternalAsciiIsDecimalDigitCharacter (*Pointer
)) {
3251 // D or P contains invalid characters.
3259 Status
= AsciiStrDecimalToUintnS ((CONST CHAR8
*) Pointer
, &Pointer
, &Uintn
);
3260 if (RETURN_ERROR (Status
)) {
3261 return RETURN_UNSUPPORTED
;
3263 if (AddressIndex
== ARRAY_SIZE (Address
->Addr
)) {
3268 return RETURN_UNSUPPORTED
;
3270 LocalPrefixLength
= (UINT8
) Uintn
;
3275 if (Uintn
> MAX_UINT8
) {
3276 return RETURN_UNSUPPORTED
;
3278 LocalAddress
.Addr
[AddressIndex
] = (UINT8
) Uintn
;
3283 // Check the '.' or '/', depending on the AddressIndex.
3285 if (AddressIndex
== ARRAY_SIZE (Address
->Addr
)) {
3286 if (*Pointer
== '/') {
3288 // '/P' is in the String.
3289 // Skip "/" and get P in next loop.
3294 // '/P' is not in the String.
3298 } else if (AddressIndex
< ARRAY_SIZE (Address
->Addr
)) {
3299 if (*Pointer
== '.') {
3301 // D should be followed by '.'
3305 return RETURN_UNSUPPORTED
;
3310 if (AddressIndex
< ARRAY_SIZE (Address
->Addr
)) {
3311 return RETURN_UNSUPPORTED
;
3314 CopyMem (Address
, &LocalAddress
, sizeof (*Address
));
3315 if (PrefixLength
!= NULL
) {
3316 *PrefixLength
= LocalPrefixLength
;
3318 if (EndPointer
!= NULL
) {
3319 *EndPointer
= Pointer
;
3322 return RETURN_SUCCESS
;
3326 Convert a Null-terminated ASCII GUID string to a value of type
3329 This function outputs a GUID value by interpreting the contents of
3330 the ASCII string specified by String. The format of the input
3331 ASCII string String consists of 36 characters, as follows:
3333 aabbccdd-eeff-gghh-iijj-kkllmmnnoopp
3335 The pairs aa - pp are two characters in the range [0-9], [a-f] and
3336 [A-F], with each pair representing a single byte hexadecimal value.
3338 The mapping between String and the EFI_GUID structure is as follows:
3356 @param String Pointer to a Null-terminated ASCII string.
3357 @param Guid Pointer to the converted GUID.
3359 @retval RETURN_SUCCESS Guid is translated from String.
3360 @retval RETURN_INVALID_PARAMETER If String is NULL.
3362 @retval RETURN_UNSUPPORTED If String is not as the above format.
3368 IN CONST CHAR8
*String
,
3372 RETURN_STATUS Status
;
3376 // None of String or Guid shall be a null pointer.
3378 SAFE_STRING_CONSTRAINT_CHECK ((String
!= NULL
), RETURN_INVALID_PARAMETER
);
3379 SAFE_STRING_CONSTRAINT_CHECK ((Guid
!= NULL
), RETURN_INVALID_PARAMETER
);
3382 // Get aabbccdd in big-endian.
3384 Status
= AsciiStrHexToBytes (String
, 2 * sizeof (LocalGuid
.Data1
), (UINT8
*) &LocalGuid
.Data1
, sizeof (LocalGuid
.Data1
));
3385 if (RETURN_ERROR (Status
) || String
[2 * sizeof (LocalGuid
.Data1
)] != '-') {
3386 return RETURN_UNSUPPORTED
;
3389 // Convert big-endian to little-endian.
3391 LocalGuid
.Data1
= SwapBytes32 (LocalGuid
.Data1
);
3392 String
+= 2 * sizeof (LocalGuid
.Data1
) + 1;
3395 // Get eeff in big-endian.
3397 Status
= AsciiStrHexToBytes (String
, 2 * sizeof (LocalGuid
.Data2
), (UINT8
*) &LocalGuid
.Data2
, sizeof (LocalGuid
.Data2
));
3398 if (RETURN_ERROR (Status
) || String
[2 * sizeof (LocalGuid
.Data2
)] != '-') {
3399 return RETURN_UNSUPPORTED
;
3402 // Convert big-endian to little-endian.
3404 LocalGuid
.Data2
= SwapBytes16 (LocalGuid
.Data2
);
3405 String
+= 2 * sizeof (LocalGuid
.Data2
) + 1;
3408 // Get gghh in big-endian.
3410 Status
= AsciiStrHexToBytes (String
, 2 * sizeof (LocalGuid
.Data3
), (UINT8
*) &LocalGuid
.Data3
, sizeof (LocalGuid
.Data3
));
3411 if (RETURN_ERROR (Status
) || String
[2 * sizeof (LocalGuid
.Data3
)] != '-') {
3412 return RETURN_UNSUPPORTED
;
3415 // Convert big-endian to little-endian.
3417 LocalGuid
.Data3
= SwapBytes16 (LocalGuid
.Data3
);
3418 String
+= 2 * sizeof (LocalGuid
.Data3
) + 1;
3423 Status
= AsciiStrHexToBytes (String
, 2 * 2, &LocalGuid
.Data4
[0], 2);
3424 if (RETURN_ERROR (Status
) || String
[2 * 2] != '-') {
3425 return RETURN_UNSUPPORTED
;
3427 String
+= 2 * 2 + 1;
3430 // Get kkllmmnnoopp.
3432 Status
= AsciiStrHexToBytes (String
, 2 * 6, &LocalGuid
.Data4
[2], 6);
3433 if (RETURN_ERROR (Status
)) {
3434 return RETURN_UNSUPPORTED
;
3437 CopyGuid (Guid
, &LocalGuid
);
3438 return RETURN_SUCCESS
;
3442 Convert a Null-terminated ASCII hexadecimal string to a byte array.
3444 This function outputs a byte array by interpreting the contents of
3445 the ASCII string specified by String in hexadecimal format. The format of
3446 the input ASCII string String is:
3450 X is a hexadecimal digit character in the range [0-9], [a-f] and [A-F].
3451 The function decodes every two hexadecimal digit characters as one byte. The
3452 decoding stops after Length of characters and outputs Buffer containing
3455 @param String Pointer to a Null-terminated ASCII string.
3456 @param Length The number of ASCII characters to decode.
3457 @param Buffer Pointer to the converted bytes array.
3458 @param MaxBufferSize The maximum size of Buffer.
3460 @retval RETURN_SUCCESS Buffer is translated from String.
3461 @retval RETURN_INVALID_PARAMETER If String is NULL.
3463 If Length is not multiple of 2.
3464 If PcdMaximumAsciiStringLength is not zero,
3465 and Length is greater than
3466 PcdMaximumAsciiStringLength.
3467 @retval RETURN_UNSUPPORTED If Length of characters from String contain
3468 a character that is not valid hexadecimal
3469 digit characters, or a Null-terminator.
3470 @retval RETURN_BUFFER_TOO_SMALL If MaxBufferSize is less than (Length / 2).
3474 AsciiStrHexToBytes (
3475 IN CONST CHAR8
*String
,
3478 IN UINTN MaxBufferSize
3484 // 1. None of String or Buffer shall be a null pointer.
3486 SAFE_STRING_CONSTRAINT_CHECK ((String
!= NULL
), RETURN_INVALID_PARAMETER
);
3487 SAFE_STRING_CONSTRAINT_CHECK ((Buffer
!= NULL
), RETURN_INVALID_PARAMETER
);
3490 // 2. Length shall not be greater than ASCII_RSIZE_MAX.
3492 if (ASCII_RSIZE_MAX
!= 0) {
3493 SAFE_STRING_CONSTRAINT_CHECK ((Length
<= ASCII_RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
3497 // 3. Length shall not be odd.
3499 SAFE_STRING_CONSTRAINT_CHECK (((Length
& BIT0
) == 0), RETURN_INVALID_PARAMETER
);
3502 // 4. MaxBufferSize shall equal to or greater than Length / 2.
3504 SAFE_STRING_CONSTRAINT_CHECK ((MaxBufferSize
>= Length
/ 2), RETURN_BUFFER_TOO_SMALL
);
3507 // 5. String shall not contains invalid hexadecimal digits.
3509 for (Index
= 0; Index
< Length
; Index
++) {
3510 if (!InternalAsciiIsHexaDecimalDigitCharacter (String
[Index
])) {
3514 if (Index
!= Length
) {
3515 return RETURN_UNSUPPORTED
;
3519 // Convert the hex string to bytes.
3521 for(Index
= 0; Index
< Length
; Index
++) {
3524 // For even characters, write the upper nibble for each buffer byte,
3525 // and for even characters, the lower nibble.
3527 if ((Index
& BIT0
) == 0) {
3528 Buffer
[Index
/ 2] = (UINT8
) InternalAsciiHexCharToUintn (String
[Index
]) << 4;
3530 Buffer
[Index
/ 2] |= (UINT8
) InternalAsciiHexCharToUintn (String
[Index
]);
3533 return RETURN_SUCCESS
;