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 ASSERT (Expression); \
18 if (!(Expression)) { \
24 Returns if 2 memory blocks are overlapped.
26 @param Base1 Base address of 1st memory block.
27 @param Size1 Size of 1st memory block.
28 @param Base2 Base address of 2nd memory block.
29 @param Size2 Size of 2nd memory block.
31 @retval TRUE 2 memory blocks are overlapped.
32 @retval FALSE 2 memory blocks are not overlapped.
35 InternalSafeStringIsOverlap (
42 if ((((UINTN
)Base1
>= (UINTN
)Base2
) && ((UINTN
)Base1
< (UINTN
)Base2
+ Size2
)) ||
43 (((UINTN
)Base2
>= (UINTN
)Base1
) && ((UINTN
)Base2
< (UINTN
)Base1
+ Size1
))) {
50 Returns if 2 Unicode strings are not overlapped.
52 @param Str1 Start address of 1st Unicode string.
53 @param Size1 The number of char in 1st Unicode string,
54 including terminating null char.
55 @param Str2 Start address of 2nd Unicode string.
56 @param Size2 The number of char in 2nd Unicode string,
57 including terminating null char.
59 @retval TRUE 2 Unicode strings are NOT overlapped.
60 @retval FALSE 2 Unicode strings are overlapped.
63 InternalSafeStringNoStrOverlap (
70 return !InternalSafeStringIsOverlap (Str1
, Size1
* sizeof(CHAR16
), Str2
, Size2
* sizeof(CHAR16
));
74 Returns if 2 Ascii strings are not overlapped.
76 @param Str1 Start address of 1st Ascii string.
77 @param Size1 The number of char in 1st Ascii string,
78 including terminating null char.
79 @param Str2 Start address of 2nd Ascii string.
80 @param Size2 The number of char in 2nd Ascii string,
81 including terminating null char.
83 @retval TRUE 2 Ascii strings are NOT overlapped.
84 @retval FALSE 2 Ascii strings are overlapped.
87 InternalSafeStringNoAsciiStrOverlap (
94 return !InternalSafeStringIsOverlap (Str1
, Size1
, Str2
, Size2
);
98 Returns the length of a Null-terminated Unicode string.
100 This function is similar as strlen_s defined in C11.
102 If String is not aligned on a 16-bit boundary, then ASSERT().
104 @param String A pointer to a Null-terminated Unicode string.
105 @param MaxSize The maximum number of Destination Unicode
106 char, including terminating null char.
108 @retval 0 If String is NULL.
109 @retval MaxSize If there is no null character in the first MaxSize characters of String.
110 @return The number of characters that percede the terminating null character.
116 IN CONST CHAR16
*String
,
122 ASSERT (((UINTN
) String
& BIT0
) == 0);
125 // If String is a null pointer or MaxSize is 0, then the StrnLenS function returns zero.
127 if ((String
== NULL
) || (MaxSize
== 0)) {
132 // Otherwise, the StrnLenS function returns the number of characters that precede the
133 // terminating null character. If there is no null character in the first MaxSize characters of
134 // String then StrnLenS returns MaxSize. At most the first MaxSize characters of String shall
135 // be accessed by StrnLenS.
138 while (String
[Length
] != 0) {
139 if (Length
>= MaxSize
- 1) {
148 Returns the size of a Null-terminated Unicode string in bytes, including the
151 This function returns the size of the Null-terminated Unicode string
152 specified by String in bytes, including the Null terminator.
154 If String is not aligned on a 16-bit boundary, then ASSERT().
156 @param String A pointer to a Null-terminated Unicode string.
157 @param MaxSize The maximum number of Destination Unicode
158 char, including the Null terminator.
160 @retval 0 If String is NULL.
161 @retval (sizeof (CHAR16) * (MaxSize + 1))
162 If there is no Null terminator in the first MaxSize characters of
164 @return The size of the Null-terminated Unicode string in bytes, including
171 IN CONST CHAR16
*String
,
176 // If String is a null pointer, then the StrnSizeS function returns zero.
178 if (String
== NULL
) {
183 // Otherwise, the StrnSizeS function returns the size of the Null-terminated
184 // Unicode string in bytes, including the Null terminator. If there is no
185 // Null terminator in the first MaxSize characters of String, then StrnSizeS
186 // returns (sizeof (CHAR16) * (MaxSize + 1)) to keep a consistent map with
187 // the StrnLenS function.
189 return (StrnLenS (String
, MaxSize
) + 1) * sizeof (*String
);
193 Copies the string pointed to by Source (including the terminating null char)
194 to the array pointed to by Destination.
196 This function is similar as strcpy_s defined in C11.
198 If Destination is not aligned on a 16-bit boundary, then ASSERT().
199 If Source is not aligned on a 16-bit boundary, then ASSERT().
200 If an error would be returned, then the function will also ASSERT().
202 If an error is returned, then the Destination is unmodified.
204 @param Destination A pointer to a Null-terminated Unicode string.
205 @param DestMax The maximum number of Destination Unicode
206 char, including terminating null char.
207 @param Source A pointer to a Null-terminated Unicode string.
209 @retval RETURN_SUCCESS String is copied.
210 @retval RETURN_BUFFER_TOO_SMALL If DestMax is NOT greater than StrLen(Source).
211 @retval RETURN_INVALID_PARAMETER If Destination is NULL.
213 If PcdMaximumUnicodeStringLength is not zero,
214 and DestMax is greater than
215 PcdMaximumUnicodeStringLength.
217 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.
222 OUT CHAR16
*Destination
,
224 IN CONST CHAR16
*Source
229 ASSERT (((UINTN
) Destination
& BIT0
) == 0);
230 ASSERT (((UINTN
) Source
& BIT0
) == 0);
233 // 1. Neither Destination nor Source shall be a null pointer.
235 SAFE_STRING_CONSTRAINT_CHECK ((Destination
!= NULL
), RETURN_INVALID_PARAMETER
);
236 SAFE_STRING_CONSTRAINT_CHECK ((Source
!= NULL
), RETURN_INVALID_PARAMETER
);
239 // 2. DestMax shall not be greater than RSIZE_MAX.
241 if (RSIZE_MAX
!= 0) {
242 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
<= RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
246 // 3. DestMax shall not equal zero.
248 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
!= 0), RETURN_INVALID_PARAMETER
);
251 // 4. DestMax shall be greater than StrnLenS(Source, DestMax).
253 SourceLen
= StrnLenS (Source
, DestMax
);
254 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
> SourceLen
), RETURN_BUFFER_TOO_SMALL
);
257 // 5. Copying shall not take place between objects that overlap.
259 SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoStrOverlap (Destination
, DestMax
, (CHAR16
*)Source
, SourceLen
+ 1), RETURN_ACCESS_DENIED
);
262 // The StrCpyS function copies the string pointed to by Source (including the terminating
263 // null character) into the array pointed to by Destination.
265 while (*Source
!= 0) {
266 *(Destination
++) = *(Source
++);
270 return RETURN_SUCCESS
;
274 Copies not more than Length successive char from the string pointed to by
275 Source to the array pointed to by Destination. If no null char is copied from
276 Source, then Destination[Length] is always set to null.
278 This function is similar as strncpy_s defined in C11.
280 If Length > 0 and Destination is not aligned on a 16-bit boundary, then ASSERT().
281 If Length > 0 and Source is not aligned on a 16-bit boundary, then ASSERT().
282 If an error would be returned, then the function will also 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().
375 If an error would be returned, then the function will also ASSERT().
377 If an error is returned, then the Destination is unmodified.
379 @param Destination A pointer to a Null-terminated Unicode string.
380 @param DestMax The maximum number of Destination Unicode
381 char, including terminating null char.
382 @param Source A pointer to a Null-terminated Unicode string.
384 @retval RETURN_SUCCESS String is appended.
385 @retval RETURN_BAD_BUFFER_SIZE If DestMax is NOT greater than
387 @retval RETURN_BUFFER_TOO_SMALL If (DestMax - StrLen(Destination)) is NOT
388 greater than StrLen(Source).
389 @retval RETURN_INVALID_PARAMETER If Destination is NULL.
391 If PcdMaximumUnicodeStringLength is not zero,
392 and DestMax is greater than
393 PcdMaximumUnicodeStringLength.
395 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.
400 IN OUT CHAR16
*Destination
,
402 IN CONST CHAR16
*Source
409 ASSERT (((UINTN
) Destination
& BIT0
) == 0);
410 ASSERT (((UINTN
) Source
& BIT0
) == 0);
413 // Let CopyLen denote the value DestMax - StrnLenS(Destination, DestMax) upon entry to StrCatS.
415 DestLen
= StrnLenS (Destination
, DestMax
);
416 CopyLen
= DestMax
- DestLen
;
419 // 1. Neither Destination nor Source shall be a null pointer.
421 SAFE_STRING_CONSTRAINT_CHECK ((Destination
!= NULL
), RETURN_INVALID_PARAMETER
);
422 SAFE_STRING_CONSTRAINT_CHECK ((Source
!= NULL
), RETURN_INVALID_PARAMETER
);
425 // 2. DestMax shall not be greater than RSIZE_MAX.
427 if (RSIZE_MAX
!= 0) {
428 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
<= RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
432 // 3. DestMax shall not equal zero.
434 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
!= 0), RETURN_INVALID_PARAMETER
);
437 // 4. CopyLen shall not equal zero.
439 SAFE_STRING_CONSTRAINT_CHECK ((CopyLen
!= 0), RETURN_BAD_BUFFER_SIZE
);
442 // 5. CopyLen shall be greater than StrnLenS(Source, CopyLen).
444 SourceLen
= StrnLenS (Source
, CopyLen
);
445 SAFE_STRING_CONSTRAINT_CHECK ((CopyLen
> SourceLen
), RETURN_BUFFER_TOO_SMALL
);
448 // 6. Copying shall not take place between objects that overlap.
450 SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoStrOverlap (Destination
, DestMax
, (CHAR16
*)Source
, SourceLen
+ 1), RETURN_ACCESS_DENIED
);
453 // The StrCatS function appends a copy of the string pointed to by Source (including the
454 // terminating null character) to the end of the string pointed to by Destination. The initial character
455 // from Source overwrites the null character at the end of Destination.
457 Destination
= Destination
+ DestLen
;
458 while (*Source
!= 0) {
459 *(Destination
++) = *(Source
++);
463 return RETURN_SUCCESS
;
467 Appends not more than Length successive char from the string pointed to by
468 Source to the end of the string pointed to by Destination. If no null char is
469 copied from Source, then Destination[StrLen(Destination) + Length] is always
472 This function is similar as strncat_s defined in C11.
474 If Destination is not aligned on a 16-bit boundary, then ASSERT().
475 If Source is not aligned on a 16-bit boundary, then ASSERT().
476 If an error would be returned, then the function will also ASSERT().
478 If an error is returned, then the Destination is unmodified.
480 @param Destination A pointer to a Null-terminated Unicode string.
481 @param DestMax The maximum number of Destination Unicode
482 char, including terminating null char.
483 @param Source A pointer to a Null-terminated Unicode string.
484 @param Length The maximum number of Unicode characters to copy.
486 @retval RETURN_SUCCESS String is appended.
487 @retval RETURN_BAD_BUFFER_SIZE If DestMax is NOT greater than
489 @retval RETURN_BUFFER_TOO_SMALL If (DestMax - StrLen(Destination)) is NOT
490 greater than MIN(StrLen(Source), Length).
491 @retval RETURN_INVALID_PARAMETER If Destination is NULL.
493 If PcdMaximumUnicodeStringLength is not zero,
494 and DestMax is greater than
495 PcdMaximumUnicodeStringLength.
497 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.
502 IN OUT CHAR16
*Destination
,
504 IN CONST CHAR16
*Source
,
512 ASSERT (((UINTN
) Destination
& BIT0
) == 0);
513 ASSERT (((UINTN
) Source
& BIT0
) == 0);
516 // Let CopyLen denote the value DestMax - StrnLenS(Destination, DestMax) upon entry to StrnCatS.
518 DestLen
= StrnLenS (Destination
, DestMax
);
519 CopyLen
= DestMax
- DestLen
;
522 // 1. Neither Destination nor Source shall be a null pointer.
524 SAFE_STRING_CONSTRAINT_CHECK ((Destination
!= NULL
), RETURN_INVALID_PARAMETER
);
525 SAFE_STRING_CONSTRAINT_CHECK ((Source
!= NULL
), RETURN_INVALID_PARAMETER
);
528 // 2. Neither DestMax nor Length shall be greater than RSIZE_MAX.
530 if (RSIZE_MAX
!= 0) {
531 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
<= RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
532 SAFE_STRING_CONSTRAINT_CHECK ((Length
<= RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
536 // 3. DestMax shall not equal zero.
538 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
!= 0), RETURN_INVALID_PARAMETER
);
541 // 4. CopyLen shall not equal zero.
543 SAFE_STRING_CONSTRAINT_CHECK ((CopyLen
!= 0), RETURN_BAD_BUFFER_SIZE
);
546 // 5. If Length is not less than CopyLen, then CopyLen shall be greater than StrnLenS(Source, CopyLen).
548 SourceLen
= StrnLenS (Source
, MIN (CopyLen
, Length
));
549 if (Length
>= CopyLen
) {
550 SAFE_STRING_CONSTRAINT_CHECK ((CopyLen
> SourceLen
), RETURN_BUFFER_TOO_SMALL
);
554 // 6. Copying shall not take place between objects that overlap.
556 if (SourceLen
> Length
) {
559 SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoStrOverlap (Destination
, DestMax
, (CHAR16
*)Source
, SourceLen
+ 1), RETURN_ACCESS_DENIED
);
562 // The StrnCatS function appends not more than Length successive characters (characters
563 // that follow a null character are not copied) from the array pointed to by Source to the end of
564 // the string pointed to by Destination. The initial character from Source overwrites the null character at
565 // the end of Destination. If no null character was copied from Source, then Destination[DestMax-CopyLen+Length] is set to
568 Destination
= Destination
+ DestLen
;
569 while ((SourceLen
> 0) && (*Source
!= 0)) {
570 *(Destination
++) = *(Source
++);
575 return RETURN_SUCCESS
;
579 Convert a Null-terminated Unicode decimal string to a value of type UINTN.
581 This function outputs a value of type UINTN by interpreting the contents of
582 the Unicode string specified by String as a decimal number. The format of the
583 input Unicode string String is:
585 [spaces] [decimal digits].
587 The valid decimal digit character is in the range [0-9]. The function will
588 ignore the pad space, which includes spaces or tab characters, before
589 [decimal digits]. The running zero in the beginning of [decimal digits] will
590 be ignored. Then, the function stops at the first character that is a not a
591 valid decimal character or a Null-terminator, whichever one comes first.
593 If String is NULL, then ASSERT().
594 If Data is NULL, then ASSERT().
595 If String is not aligned in a 16-bit boundary, then ASSERT().
596 If PcdMaximumUnicodeStringLength is not zero, and String contains more than
597 PcdMaximumUnicodeStringLength Unicode characters, not including the
598 Null-terminator, then ASSERT().
600 If String has no valid decimal digits in the above format, then 0 is stored
601 at the location pointed to by Data.
602 If the number represented by String exceeds the range defined by UINTN, then
603 MAX_UINTN is stored at the location pointed to by Data.
605 If EndPointer is not NULL, a pointer to the character that stopped the scan
606 is stored at the location pointed to by EndPointer. If String has no valid
607 decimal digits right after the optional pad spaces, the value of String is
608 stored at the location pointed to by EndPointer.
610 @param String Pointer to a Null-terminated Unicode string.
611 @param EndPointer Pointer to character that stops scan.
612 @param Data Pointer to the converted value.
614 @retval RETURN_SUCCESS Value is translated from String.
615 @retval RETURN_INVALID_PARAMETER If String is NULL.
617 If PcdMaximumUnicodeStringLength is not
618 zero, and String contains more than
619 PcdMaximumUnicodeStringLength Unicode
620 characters, not including the
622 @retval RETURN_UNSUPPORTED If the number represented by String exceeds
623 the range defined by UINTN.
629 IN CONST CHAR16
*String
,
630 OUT CHAR16
**EndPointer
, OPTIONAL
634 ASSERT (((UINTN
) String
& BIT0
) == 0);
637 // 1. Neither String nor Data shall be a null pointer.
639 SAFE_STRING_CONSTRAINT_CHECK ((String
!= NULL
), RETURN_INVALID_PARAMETER
);
640 SAFE_STRING_CONSTRAINT_CHECK ((Data
!= NULL
), RETURN_INVALID_PARAMETER
);
643 // 2. The length of String shall not be greater than RSIZE_MAX.
645 if (RSIZE_MAX
!= 0) {
646 SAFE_STRING_CONSTRAINT_CHECK ((StrnLenS (String
, RSIZE_MAX
+ 1) <= RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
649 if (EndPointer
!= NULL
) {
650 *EndPointer
= (CHAR16
*) String
;
654 // Ignore the pad spaces (space or tab)
656 while ((*String
== L
' ') || (*String
== L
'\t')) {
661 // Ignore leading Zeros after the spaces
663 while (*String
== L
'0') {
669 while (InternalIsDecimalDigitCharacter (*String
)) {
671 // If the number represented by String overflows according to the range
672 // defined by UINTN, then MAX_UINTN is stored in *Data and
673 // RETURN_UNSUPPORTED is returned.
675 if (*Data
> ((MAX_UINTN
- (*String
- L
'0')) / 10)) {
677 if (EndPointer
!= NULL
) {
678 *EndPointer
= (CHAR16
*) String
;
680 return RETURN_UNSUPPORTED
;
683 *Data
= *Data
* 10 + (*String
- L
'0');
687 if (EndPointer
!= NULL
) {
688 *EndPointer
= (CHAR16
*) String
;
690 return RETURN_SUCCESS
;
694 Convert a Null-terminated Unicode decimal string to a value of type UINT64.
696 This function outputs a value of type UINT64 by interpreting the contents of
697 the Unicode string specified by String as a decimal number. The format of the
698 input Unicode string String is:
700 [spaces] [decimal digits].
702 The valid decimal digit character is in the range [0-9]. The function will
703 ignore the pad space, which includes spaces or tab characters, before
704 [decimal digits]. The running zero in the beginning of [decimal digits] will
705 be ignored. Then, the function stops at the first character that is a not a
706 valid decimal character or a Null-terminator, whichever one comes first.
708 If String is NULL, then ASSERT().
709 If Data is NULL, then ASSERT().
710 If String is not aligned in a 16-bit boundary, then ASSERT().
711 If PcdMaximumUnicodeStringLength is not zero, and String contains more than
712 PcdMaximumUnicodeStringLength Unicode characters, not including the
713 Null-terminator, then ASSERT().
715 If String has no valid decimal digits in the above format, then 0 is stored
716 at the location pointed to by Data.
717 If the number represented by String exceeds the range defined by UINT64, then
718 MAX_UINT64 is stored at the location pointed to by Data.
720 If EndPointer is not NULL, a pointer to the character that stopped the scan
721 is stored at the location pointed to by EndPointer. If String has no valid
722 decimal digits right after the optional pad spaces, the value of String is
723 stored at the location pointed to by EndPointer.
725 @param String Pointer to a Null-terminated Unicode string.
726 @param EndPointer Pointer to character that stops scan.
727 @param Data Pointer to the converted value.
729 @retval RETURN_SUCCESS Value is translated from String.
730 @retval RETURN_INVALID_PARAMETER If String is NULL.
732 If PcdMaximumUnicodeStringLength is not
733 zero, and String contains more than
734 PcdMaximumUnicodeStringLength Unicode
735 characters, not including the
737 @retval RETURN_UNSUPPORTED If the number represented by String exceeds
738 the range defined by UINT64.
743 StrDecimalToUint64S (
744 IN CONST CHAR16
*String
,
745 OUT CHAR16
**EndPointer
, OPTIONAL
749 ASSERT (((UINTN
) String
& BIT0
) == 0);
752 // 1. Neither String nor Data shall be a null pointer.
754 SAFE_STRING_CONSTRAINT_CHECK ((String
!= NULL
), RETURN_INVALID_PARAMETER
);
755 SAFE_STRING_CONSTRAINT_CHECK ((Data
!= NULL
), RETURN_INVALID_PARAMETER
);
758 // 2. The length of String shall not be greater than RSIZE_MAX.
760 if (RSIZE_MAX
!= 0) {
761 SAFE_STRING_CONSTRAINT_CHECK ((StrnLenS (String
, RSIZE_MAX
+ 1) <= RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
764 if (EndPointer
!= NULL
) {
765 *EndPointer
= (CHAR16
*) String
;
769 // Ignore the pad spaces (space or tab)
771 while ((*String
== L
' ') || (*String
== L
'\t')) {
776 // Ignore leading Zeros after the spaces
778 while (*String
== L
'0') {
784 while (InternalIsDecimalDigitCharacter (*String
)) {
786 // If the number represented by String overflows according to the range
787 // defined by UINT64, then MAX_UINT64 is stored in *Data and
788 // RETURN_UNSUPPORTED is returned.
790 if (*Data
> DivU64x32 (MAX_UINT64
- (*String
- L
'0'), 10)) {
792 if (EndPointer
!= NULL
) {
793 *EndPointer
= (CHAR16
*) String
;
795 return RETURN_UNSUPPORTED
;
798 *Data
= MultU64x32 (*Data
, 10) + (*String
- L
'0');
802 if (EndPointer
!= NULL
) {
803 *EndPointer
= (CHAR16
*) String
;
805 return RETURN_SUCCESS
;
809 Convert a Null-terminated Unicode hexadecimal string to a value of type
812 This function outputs a value of type UINTN by interpreting the contents of
813 the Unicode string specified by String as a hexadecimal number. The format of
814 the input Unicode string String is:
816 [spaces][zeros][x][hexadecimal digits].
818 The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].
819 The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix.
820 If "x" appears in the input string, it must be prefixed with at least one 0.
821 The function will ignore the pad space, which includes spaces or tab
822 characters, before [zeros], [x] or [hexadecimal digit]. The running zero
823 before [x] or [hexadecimal digit] will be ignored. Then, the decoding starts
824 after [x] or the first valid hexadecimal digit. Then, the function stops at
825 the first character that is a not a valid hexadecimal character or NULL,
826 whichever one comes first.
828 If String is NULL, then ASSERT().
829 If Data is NULL, then ASSERT().
830 If String is not aligned in a 16-bit boundary, then ASSERT().
831 If PcdMaximumUnicodeStringLength is not zero, and String contains more than
832 PcdMaximumUnicodeStringLength Unicode characters, not including the
833 Null-terminator, then ASSERT().
835 If String has no valid hexadecimal digits in the above format, then 0 is
836 stored at the location pointed to by Data.
837 If the number represented by String exceeds the range defined by UINTN, then
838 MAX_UINTN is stored at the location pointed to by Data.
840 If EndPointer is not NULL, a pointer to the character that stopped the scan
841 is stored at the location pointed to by EndPointer. If String has no valid
842 hexadecimal digits right after the optional pad spaces, the value of String
843 is stored at the location pointed to by EndPointer.
845 @param String Pointer to a Null-terminated Unicode string.
846 @param EndPointer Pointer to character that stops scan.
847 @param Data Pointer to the converted value.
849 @retval RETURN_SUCCESS Value is translated from String.
850 @retval RETURN_INVALID_PARAMETER If String is NULL.
852 If PcdMaximumUnicodeStringLength is not
853 zero, and String contains more than
854 PcdMaximumUnicodeStringLength Unicode
855 characters, not including the
857 @retval RETURN_UNSUPPORTED If the number represented by String exceeds
858 the range defined by UINTN.
864 IN CONST CHAR16
*String
,
865 OUT CHAR16
**EndPointer
, OPTIONAL
869 ASSERT (((UINTN
) String
& BIT0
) == 0);
872 // 1. Neither String nor Data shall be a null pointer.
874 SAFE_STRING_CONSTRAINT_CHECK ((String
!= NULL
), RETURN_INVALID_PARAMETER
);
875 SAFE_STRING_CONSTRAINT_CHECK ((Data
!= NULL
), RETURN_INVALID_PARAMETER
);
878 // 2. The length of String shall not be greater than RSIZE_MAX.
880 if (RSIZE_MAX
!= 0) {
881 SAFE_STRING_CONSTRAINT_CHECK ((StrnLenS (String
, RSIZE_MAX
+ 1) <= RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
884 if (EndPointer
!= NULL
) {
885 *EndPointer
= (CHAR16
*) String
;
889 // Ignore the pad spaces (space or tab)
891 while ((*String
== L
' ') || (*String
== L
'\t')) {
896 // Ignore leading Zeros after the spaces
898 while (*String
== L
'0') {
902 if (CharToUpper (*String
) == L
'X') {
903 if (*(String
- 1) != L
'0') {
905 return RETURN_SUCCESS
;
915 while (InternalIsHexaDecimalDigitCharacter (*String
)) {
917 // If the number represented by String overflows according to the range
918 // defined by UINTN, then MAX_UINTN is stored in *Data and
919 // RETURN_UNSUPPORTED is returned.
921 if (*Data
> ((MAX_UINTN
- InternalHexCharToUintn (*String
)) >> 4)) {
923 if (EndPointer
!= NULL
) {
924 *EndPointer
= (CHAR16
*) String
;
926 return RETURN_UNSUPPORTED
;
929 *Data
= (*Data
<< 4) + InternalHexCharToUintn (*String
);
933 if (EndPointer
!= NULL
) {
934 *EndPointer
= (CHAR16
*) String
;
936 return RETURN_SUCCESS
;
940 Convert a Null-terminated Unicode hexadecimal string to a value of type
943 This function outputs a value of type UINT64 by interpreting the contents of
944 the Unicode string specified by String as a hexadecimal number. The format of
945 the input Unicode string String is:
947 [spaces][zeros][x][hexadecimal digits].
949 The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].
950 The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix.
951 If "x" appears in the input string, it must be prefixed with at least one 0.
952 The function will ignore the pad space, which includes spaces or tab
953 characters, before [zeros], [x] or [hexadecimal digit]. The running zero
954 before [x] or [hexadecimal digit] will be ignored. Then, the decoding starts
955 after [x] or the first valid hexadecimal digit. Then, the function stops at
956 the first character that is a not a valid hexadecimal character or NULL,
957 whichever one comes first.
959 If String is NULL, then ASSERT().
960 If Data is NULL, then ASSERT().
961 If String is not aligned in a 16-bit boundary, then ASSERT().
962 If PcdMaximumUnicodeStringLength is not zero, and String contains more than
963 PcdMaximumUnicodeStringLength Unicode characters, not including the
964 Null-terminator, then ASSERT().
966 If String has no valid hexadecimal digits in the above format, then 0 is
967 stored at the location pointed to by Data.
968 If the number represented by String exceeds the range defined by UINT64, then
969 MAX_UINT64 is stored at the location pointed to by Data.
971 If EndPointer is not NULL, a pointer to the character that stopped the scan
972 is stored at the location pointed to by EndPointer. If String has no valid
973 hexadecimal digits right after the optional pad spaces, the value of String
974 is stored at the location pointed to by EndPointer.
976 @param String Pointer to a Null-terminated Unicode string.
977 @param EndPointer Pointer to character that stops scan.
978 @param Data Pointer to the converted value.
980 @retval RETURN_SUCCESS Value is translated from String.
981 @retval RETURN_INVALID_PARAMETER If String is NULL.
983 If PcdMaximumUnicodeStringLength is not
984 zero, and String contains more than
985 PcdMaximumUnicodeStringLength Unicode
986 characters, not including the
988 @retval RETURN_UNSUPPORTED If the number represented by String exceeds
989 the range defined by UINT64.
995 IN CONST CHAR16
*String
,
996 OUT CHAR16
**EndPointer
, OPTIONAL
1000 ASSERT (((UINTN
) String
& BIT0
) == 0);
1003 // 1. Neither String nor Data shall be a null pointer.
1005 SAFE_STRING_CONSTRAINT_CHECK ((String
!= NULL
), RETURN_INVALID_PARAMETER
);
1006 SAFE_STRING_CONSTRAINT_CHECK ((Data
!= NULL
), RETURN_INVALID_PARAMETER
);
1009 // 2. The length of String shall not be greater than RSIZE_MAX.
1011 if (RSIZE_MAX
!= 0) {
1012 SAFE_STRING_CONSTRAINT_CHECK ((StrnLenS (String
, RSIZE_MAX
+ 1) <= RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
1015 if (EndPointer
!= NULL
) {
1016 *EndPointer
= (CHAR16
*) String
;
1020 // Ignore the pad spaces (space or tab)
1022 while ((*String
== L
' ') || (*String
== L
'\t')) {
1027 // Ignore leading Zeros after the spaces
1029 while (*String
== L
'0') {
1033 if (CharToUpper (*String
) == L
'X') {
1034 if (*(String
- 1) != L
'0') {
1036 return RETURN_SUCCESS
;
1046 while (InternalIsHexaDecimalDigitCharacter (*String
)) {
1048 // If the number represented by String overflows according to the range
1049 // defined by UINT64, then MAX_UINT64 is stored in *Data and
1050 // RETURN_UNSUPPORTED is returned.
1052 if (*Data
> RShiftU64 (MAX_UINT64
- InternalHexCharToUintn (*String
), 4)) {
1054 if (EndPointer
!= NULL
) {
1055 *EndPointer
= (CHAR16
*) String
;
1057 return RETURN_UNSUPPORTED
;
1060 *Data
= LShiftU64 (*Data
, 4) + InternalHexCharToUintn (*String
);
1064 if (EndPointer
!= NULL
) {
1065 *EndPointer
= (CHAR16
*) String
;
1067 return RETURN_SUCCESS
;
1071 Convert a Null-terminated Unicode string to IPv6 address and prefix length.
1073 This function outputs a value of type IPv6_ADDRESS and may output a value
1074 of type UINT8 by interpreting the contents of the Unicode string specified
1075 by String. The format of the input Unicode string String is as follows:
1079 X contains one to four hexadecimal digit characters in the range [0-9], [a-f] and
1080 [A-F]. X is converted to a value of type UINT16, whose low byte is stored in low
1081 memory address and high byte is stored in high memory address. P contains decimal
1082 digit characters in the range [0-9]. The running zero in the beginning of P will
1083 be ignored. /P is optional.
1085 When /P is not in the String, the function stops at the first character that is
1086 not a valid hexadecimal digit character after eight X's are converted.
1088 When /P is in the String, the function stops at the first character that is not
1089 a valid decimal digit character after P is converted.
1091 "::" can be used to compress one or more groups of X when X contains only 0.
1092 The "::" can only appear once in the String.
1094 If String is NULL, then ASSERT().
1096 If Address is NULL, then ASSERT().
1098 If String is not aligned in a 16-bit boundary, then ASSERT().
1100 If PcdMaximumUnicodeStringLength is not zero, and String contains more than
1101 PcdMaximumUnicodeStringLength Unicode characters, not including the
1102 Null-terminator, then ASSERT().
1104 If EndPointer is not NULL and Address is translated from String, a pointer
1105 to the character that stopped the scan is stored at the location pointed to
1108 @param String Pointer to a Null-terminated Unicode string.
1109 @param EndPointer Pointer to character that stops scan.
1110 @param Address Pointer to the converted IPv6 address.
1111 @param PrefixLength Pointer to the converted IPv6 address prefix
1112 length. MAX_UINT8 is returned when /P is
1115 @retval RETURN_SUCCESS Address is translated from String.
1116 @retval RETURN_INVALID_PARAMETER If String is NULL.
1118 @retval RETURN_UNSUPPORTED If X contains more than four hexadecimal
1120 If String contains "::" and number of X
1122 If P starts with character that is not a
1123 valid decimal digit character.
1124 If the decimal number converted from P
1131 IN CONST CHAR16
*String
,
1132 OUT CHAR16
**EndPointer
, OPTIONAL
1133 OUT IPv6_ADDRESS
*Address
,
1134 OUT UINT8
*PrefixLength OPTIONAL
1137 RETURN_STATUS Status
;
1140 IPv6_ADDRESS LocalAddress
;
1141 UINT8 LocalPrefixLength
;
1142 CONST CHAR16
*Pointer
;
1144 UINTN CompressStart
;
1145 BOOLEAN ExpectPrefix
;
1147 LocalPrefixLength
= MAX_UINT8
;
1148 CompressStart
= ARRAY_SIZE (Address
->Addr
);
1149 ExpectPrefix
= FALSE
;
1151 ASSERT (((UINTN
) String
& BIT0
) == 0);
1154 // 1. None of String or Guid shall be a null pointer.
1156 SAFE_STRING_CONSTRAINT_CHECK ((String
!= NULL
), RETURN_INVALID_PARAMETER
);
1157 SAFE_STRING_CONSTRAINT_CHECK ((Address
!= NULL
), RETURN_INVALID_PARAMETER
);
1159 for (Pointer
= String
, AddressIndex
= 0; AddressIndex
< ARRAY_SIZE (Address
->Addr
) + 1;) {
1160 if (!InternalIsHexaDecimalDigitCharacter (*Pointer
)) {
1161 if (*Pointer
!= L
':') {
1163 // ":" or "/" should be followed by digit characters.
1165 return RETURN_UNSUPPORTED
;
1169 // Meet second ":" after previous ":" or "/"
1170 // or meet first ":" in the beginning of String.
1174 // ":" shall not be after "/"
1176 return RETURN_UNSUPPORTED
;
1179 if (CompressStart
!= ARRAY_SIZE (Address
->Addr
) || AddressIndex
== ARRAY_SIZE (Address
->Addr
)) {
1181 // "::" can only appear once.
1182 // "::" can only appear when address is not full length.
1184 return RETURN_UNSUPPORTED
;
1187 // Remember the start of zero compressing.
1189 CompressStart
= AddressIndex
;
1192 if (CompressStart
== 0) {
1193 if (*Pointer
!= L
':') {
1195 // Single ":" shall not be in the beginning of String.
1197 return RETURN_UNSUPPORTED
;
1204 if (!InternalIsHexaDecimalDigitCharacter (*Pointer
)) {
1205 if (*Pointer
== L
'/') {
1207 // Might be optional "/P" after "::".
1209 if (CompressStart
!= AddressIndex
) {
1210 return RETURN_UNSUPPORTED
;
1216 if (!ExpectPrefix
) {
1220 Status
= StrHexToUintnS (Pointer
, &End
, &Uintn
);
1221 if (RETURN_ERROR (Status
) || End
- Pointer
> 4) {
1223 // Number of hexadecimal digit characters is no more than 4.
1225 return RETURN_UNSUPPORTED
;
1229 // Uintn won't exceed MAX_UINT16 if number of hexadecimal digit characters is no more than 4.
1231 ASSERT (AddressIndex
+ 1 < ARRAY_SIZE (Address
->Addr
));
1232 LocalAddress
.Addr
[AddressIndex
] = (UINT8
) ((UINT16
) Uintn
>> 8);
1233 LocalAddress
.Addr
[AddressIndex
+ 1] = (UINT8
) Uintn
;
1237 // Get P, then exit the loop.
1239 Status
= StrDecimalToUintnS (Pointer
, &End
, &Uintn
);
1240 if (RETURN_ERROR (Status
) || End
== Pointer
|| Uintn
> 128) {
1242 // Prefix length should not exceed 128.
1244 return RETURN_UNSUPPORTED
;
1246 LocalPrefixLength
= (UINT8
) Uintn
;
1255 if (*Pointer
== L
'/') {
1256 ExpectPrefix
= TRUE
;
1257 } else if (*Pointer
== L
':') {
1258 if (AddressIndex
== ARRAY_SIZE (Address
->Addr
)) {
1260 // Meet additional ":" after all 8 16-bit address
1266 // Meet other character that is not "/" or ":" after all 8 16-bit address
1273 if ((AddressIndex
== ARRAY_SIZE (Address
->Addr
) && CompressStart
!= ARRAY_SIZE (Address
->Addr
)) ||
1274 (AddressIndex
!= ARRAY_SIZE (Address
->Addr
) && CompressStart
== ARRAY_SIZE (Address
->Addr
))
1277 // Full length of address shall not have compressing zeros.
1278 // Non-full length of address shall have compressing zeros.
1280 return RETURN_UNSUPPORTED
;
1282 CopyMem (&Address
->Addr
[0], &LocalAddress
.Addr
[0], CompressStart
);
1283 ZeroMem (&Address
->Addr
[CompressStart
], ARRAY_SIZE (Address
->Addr
) - AddressIndex
);
1284 if (AddressIndex
> CompressStart
) {
1286 &Address
->Addr
[CompressStart
+ ARRAY_SIZE (Address
->Addr
) - AddressIndex
],
1287 &LocalAddress
.Addr
[CompressStart
],
1288 AddressIndex
- CompressStart
1292 if (PrefixLength
!= NULL
) {
1293 *PrefixLength
= LocalPrefixLength
;
1295 if (EndPointer
!= NULL
) {
1296 *EndPointer
= (CHAR16
*) Pointer
;
1299 return RETURN_SUCCESS
;
1303 Convert a Null-terminated Unicode string to IPv4 address and prefix length.
1305 This function outputs a value of type IPv4_ADDRESS and may output a value
1306 of type UINT8 by interpreting the contents of the Unicode string specified
1307 by String. The format of the input Unicode string String is as follows:
1311 D and P are decimal digit characters in the range [0-9]. The running zero in
1312 the beginning of D and P will be ignored. /P is optional.
1314 When /P is not in the String, the function stops at the first character that is
1315 not a valid decimal digit character after four D's are converted.
1317 When /P is in the String, the function stops at the first character that is not
1318 a valid decimal digit character after P is converted.
1320 If String is NULL, then ASSERT().
1322 If Address is NULL, then ASSERT().
1324 If String is not aligned in a 16-bit boundary, then ASSERT().
1326 If PcdMaximumUnicodeStringLength is not zero, and String contains more than
1327 PcdMaximumUnicodeStringLength Unicode characters, not including the
1328 Null-terminator, then ASSERT().
1330 If EndPointer is not NULL and Address is translated from String, a pointer
1331 to the character that stopped the scan is stored at the location pointed to
1334 @param String Pointer to a Null-terminated Unicode string.
1335 @param EndPointer Pointer to character that stops scan.
1336 @param Address Pointer to the converted IPv4 address.
1337 @param PrefixLength Pointer to the converted IPv4 address prefix
1338 length. MAX_UINT8 is returned when /P is
1341 @retval RETURN_SUCCESS Address is translated from String.
1342 @retval RETURN_INVALID_PARAMETER If String is NULL.
1344 @retval RETURN_UNSUPPORTED If String is not in the correct format.
1345 If any decimal number converted from D
1347 If the decimal number converted from P
1354 IN CONST CHAR16
*String
,
1355 OUT CHAR16
**EndPointer
, OPTIONAL
1356 OUT IPv4_ADDRESS
*Address
,
1357 OUT UINT8
*PrefixLength OPTIONAL
1360 RETURN_STATUS Status
;
1363 IPv4_ADDRESS LocalAddress
;
1364 UINT8 LocalPrefixLength
;
1367 LocalPrefixLength
= MAX_UINT8
;
1369 ASSERT (((UINTN
) String
& BIT0
) == 0);
1372 // 1. None of String or Guid shall be a null pointer.
1374 SAFE_STRING_CONSTRAINT_CHECK ((String
!= NULL
), RETURN_INVALID_PARAMETER
);
1375 SAFE_STRING_CONSTRAINT_CHECK ((Address
!= NULL
), RETURN_INVALID_PARAMETER
);
1377 for (Pointer
= (CHAR16
*) String
, AddressIndex
= 0; AddressIndex
< ARRAY_SIZE (Address
->Addr
) + 1;) {
1378 if (!InternalIsDecimalDigitCharacter (*Pointer
)) {
1380 // D or P contains invalid characters.
1388 Status
= StrDecimalToUintnS ((CONST CHAR16
*) Pointer
, &Pointer
, &Uintn
);
1389 if (RETURN_ERROR (Status
)) {
1390 return RETURN_UNSUPPORTED
;
1392 if (AddressIndex
== ARRAY_SIZE (Address
->Addr
)) {
1397 return RETURN_UNSUPPORTED
;
1399 LocalPrefixLength
= (UINT8
) Uintn
;
1404 if (Uintn
> MAX_UINT8
) {
1405 return RETURN_UNSUPPORTED
;
1407 LocalAddress
.Addr
[AddressIndex
] = (UINT8
) Uintn
;
1412 // Check the '.' or '/', depending on the AddressIndex.
1414 if (AddressIndex
== ARRAY_SIZE (Address
->Addr
)) {
1415 if (*Pointer
== L
'/') {
1417 // '/P' is in the String.
1418 // Skip "/" and get P in next loop.
1423 // '/P' is not in the String.
1427 } else if (AddressIndex
< ARRAY_SIZE (Address
->Addr
)) {
1428 if (*Pointer
== L
'.') {
1430 // D should be followed by '.'
1434 return RETURN_UNSUPPORTED
;
1439 if (AddressIndex
< ARRAY_SIZE (Address
->Addr
)) {
1440 return RETURN_UNSUPPORTED
;
1443 CopyMem (Address
, &LocalAddress
, sizeof (*Address
));
1444 if (PrefixLength
!= NULL
) {
1445 *PrefixLength
= LocalPrefixLength
;
1447 if (EndPointer
!= NULL
) {
1448 *EndPointer
= Pointer
;
1451 return RETURN_SUCCESS
;
1455 Convert a Null-terminated Unicode GUID string to a value of type
1458 This function outputs a GUID value by interpreting the contents of
1459 the Unicode string specified by String. The format of the input
1460 Unicode string String consists of 36 characters, as follows:
1462 aabbccdd-eeff-gghh-iijj-kkllmmnnoopp
1464 The pairs aa - pp are two characters in the range [0-9], [a-f] and
1465 [A-F], with each pair representing a single byte hexadecimal value.
1467 The mapping between String and the EFI_GUID structure is as follows:
1485 If String is NULL, then ASSERT().
1486 If Guid is NULL, then ASSERT().
1487 If String is not aligned in a 16-bit boundary, then ASSERT().
1489 @param String Pointer to a Null-terminated Unicode string.
1490 @param Guid Pointer to the converted GUID.
1492 @retval RETURN_SUCCESS Guid is translated from String.
1493 @retval RETURN_INVALID_PARAMETER If String is NULL.
1495 @retval RETURN_UNSUPPORTED If String is not as the above format.
1501 IN CONST CHAR16
*String
,
1505 RETURN_STATUS Status
;
1508 ASSERT (((UINTN
) String
& BIT0
) == 0);
1511 // 1. None of String or Guid shall be a null pointer.
1513 SAFE_STRING_CONSTRAINT_CHECK ((String
!= NULL
), RETURN_INVALID_PARAMETER
);
1514 SAFE_STRING_CONSTRAINT_CHECK ((Guid
!= NULL
), RETURN_INVALID_PARAMETER
);
1517 // Get aabbccdd in big-endian.
1519 Status
= StrHexToBytes (String
, 2 * sizeof (LocalGuid
.Data1
), (UINT8
*) &LocalGuid
.Data1
, sizeof (LocalGuid
.Data1
));
1520 if (RETURN_ERROR (Status
) || String
[2 * sizeof (LocalGuid
.Data1
)] != L
'-') {
1521 return RETURN_UNSUPPORTED
;
1524 // Convert big-endian to little-endian.
1526 LocalGuid
.Data1
= SwapBytes32 (LocalGuid
.Data1
);
1527 String
+= 2 * sizeof (LocalGuid
.Data1
) + 1;
1530 // Get eeff in big-endian.
1532 Status
= StrHexToBytes (String
, 2 * sizeof (LocalGuid
.Data2
), (UINT8
*) &LocalGuid
.Data2
, sizeof (LocalGuid
.Data2
));
1533 if (RETURN_ERROR (Status
) || String
[2 * sizeof (LocalGuid
.Data2
)] != L
'-') {
1534 return RETURN_UNSUPPORTED
;
1537 // Convert big-endian to little-endian.
1539 LocalGuid
.Data2
= SwapBytes16 (LocalGuid
.Data2
);
1540 String
+= 2 * sizeof (LocalGuid
.Data2
) + 1;
1543 // Get gghh in big-endian.
1545 Status
= StrHexToBytes (String
, 2 * sizeof (LocalGuid
.Data3
), (UINT8
*) &LocalGuid
.Data3
, sizeof (LocalGuid
.Data3
));
1546 if (RETURN_ERROR (Status
) || String
[2 * sizeof (LocalGuid
.Data3
)] != L
'-') {
1547 return RETURN_UNSUPPORTED
;
1550 // Convert big-endian to little-endian.
1552 LocalGuid
.Data3
= SwapBytes16 (LocalGuid
.Data3
);
1553 String
+= 2 * sizeof (LocalGuid
.Data3
) + 1;
1558 Status
= StrHexToBytes (String
, 2 * 2, &LocalGuid
.Data4
[0], 2);
1559 if (RETURN_ERROR (Status
) || String
[2 * 2] != L
'-') {
1560 return RETURN_UNSUPPORTED
;
1562 String
+= 2 * 2 + 1;
1565 // Get kkllmmnnoopp.
1567 Status
= StrHexToBytes (String
, 2 * 6, &LocalGuid
.Data4
[2], 6);
1568 if (RETURN_ERROR (Status
)) {
1569 return RETURN_UNSUPPORTED
;
1572 CopyGuid (Guid
, &LocalGuid
);
1573 return RETURN_SUCCESS
;
1577 Convert a Null-terminated Unicode hexadecimal string to a byte array.
1579 This function outputs a byte array by interpreting the contents of
1580 the Unicode string specified by String in hexadecimal format. The format of
1581 the input Unicode string String is:
1585 X is a hexadecimal digit character in the range [0-9], [a-f] and [A-F].
1586 The function decodes every two hexadecimal digit characters as one byte. The
1587 decoding stops after Length of characters and outputs Buffer containing
1590 If String is not aligned in a 16-bit boundary, then ASSERT().
1592 If String is NULL, then ASSERT().
1594 If Buffer is NULL, then ASSERT().
1596 If Length is not multiple of 2, then ASSERT().
1598 If PcdMaximumUnicodeStringLength is not zero and Length is greater than
1599 PcdMaximumUnicodeStringLength, then ASSERT().
1601 If MaxBufferSize is less than (Length / 2), then ASSERT().
1603 @param String Pointer to a Null-terminated Unicode string.
1604 @param Length The number of Unicode characters to decode.
1605 @param Buffer Pointer to the converted bytes array.
1606 @param MaxBufferSize The maximum size of Buffer.
1608 @retval RETURN_SUCCESS Buffer is translated from String.
1609 @retval RETURN_INVALID_PARAMETER If String is NULL.
1611 If Length is not multiple of 2.
1612 If PcdMaximumUnicodeStringLength is not zero,
1613 and Length is greater than
1614 PcdMaximumUnicodeStringLength.
1615 @retval RETURN_UNSUPPORTED If Length of characters from String contain
1616 a character that is not valid hexadecimal
1617 digit characters, or a Null-terminator.
1618 @retval RETURN_BUFFER_TOO_SMALL If MaxBufferSize is less than (Length / 2).
1623 IN CONST CHAR16
*String
,
1626 IN UINTN MaxBufferSize
1631 ASSERT (((UINTN
) String
& BIT0
) == 0);
1634 // 1. None of String or Buffer shall be a null pointer.
1636 SAFE_STRING_CONSTRAINT_CHECK ((String
!= NULL
), RETURN_INVALID_PARAMETER
);
1637 SAFE_STRING_CONSTRAINT_CHECK ((Buffer
!= NULL
), RETURN_INVALID_PARAMETER
);
1640 // 2. Length shall not be greater than RSIZE_MAX.
1642 if (RSIZE_MAX
!= 0) {
1643 SAFE_STRING_CONSTRAINT_CHECK ((Length
<= RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
1647 // 3. Length shall not be odd.
1649 SAFE_STRING_CONSTRAINT_CHECK (((Length
& BIT0
) == 0), RETURN_INVALID_PARAMETER
);
1652 // 4. MaxBufferSize shall equal to or greater than Length / 2.
1654 SAFE_STRING_CONSTRAINT_CHECK ((MaxBufferSize
>= Length
/ 2), RETURN_BUFFER_TOO_SMALL
);
1657 // 5. String shall not contains invalid hexadecimal digits.
1659 for (Index
= 0; Index
< Length
; Index
++) {
1660 if (!InternalIsHexaDecimalDigitCharacter (String
[Index
])) {
1664 if (Index
!= Length
) {
1665 return RETURN_UNSUPPORTED
;
1669 // Convert the hex string to bytes.
1671 for(Index
= 0; Index
< Length
; Index
++) {
1674 // For even characters, write the upper nibble for each buffer byte,
1675 // and for even characters, the lower nibble.
1677 if ((Index
& BIT0
) == 0) {
1678 Buffer
[Index
/ 2] = (UINT8
) InternalHexCharToUintn (String
[Index
]) << 4;
1680 Buffer
[Index
/ 2] |= (UINT8
) InternalHexCharToUintn (String
[Index
]);
1683 return RETURN_SUCCESS
;
1687 Returns the length of a Null-terminated Ascii string.
1689 This function is similar as strlen_s defined in C11.
1691 @param String A pointer to a Null-terminated Ascii string.
1692 @param MaxSize The maximum number of Destination Ascii
1693 char, including terminating null char.
1695 @retval 0 If String is NULL.
1696 @retval MaxSize If there is no null character in the first MaxSize characters of String.
1697 @return The number of characters that percede the terminating null character.
1703 IN CONST CHAR8
*String
,
1710 // If String is a null pointer or MaxSize is 0, then the AsciiStrnLenS function returns zero.
1712 if ((String
== NULL
) || (MaxSize
== 0)) {
1717 // Otherwise, the AsciiStrnLenS function returns the number of characters that precede the
1718 // terminating null character. If there is no null character in the first MaxSize characters of
1719 // String then AsciiStrnLenS returns MaxSize. At most the first MaxSize characters of String shall
1720 // be accessed by AsciiStrnLenS.
1723 while (String
[Length
] != 0) {
1724 if (Length
>= MaxSize
- 1) {
1733 Returns the size of a Null-terminated Ascii string in bytes, including the
1736 This function returns the size of the Null-terminated Ascii string specified
1737 by String in bytes, including the Null terminator.
1739 @param String A pointer to a Null-terminated Ascii string.
1740 @param MaxSize The maximum number of Destination Ascii
1741 char, including the Null terminator.
1743 @retval 0 If String is NULL.
1744 @retval (sizeof (CHAR8) * (MaxSize + 1))
1745 If there is no Null terminator in the first MaxSize characters of
1747 @return The size of the Null-terminated Ascii string in bytes, including the
1754 IN CONST CHAR8
*String
,
1759 // If String is a null pointer, then the AsciiStrnSizeS function returns
1762 if (String
== NULL
) {
1767 // Otherwise, the AsciiStrnSizeS function returns the size of the
1768 // Null-terminated Ascii string in bytes, including the Null terminator. If
1769 // there is no Null terminator in the first MaxSize characters of String,
1770 // then AsciiStrnSizeS returns (sizeof (CHAR8) * (MaxSize + 1)) to keep a
1771 // consistent map with the AsciiStrnLenS function.
1773 return (AsciiStrnLenS (String
, MaxSize
) + 1) * sizeof (*String
);
1777 Copies the string pointed to by Source (including the terminating null char)
1778 to the array pointed to by Destination.
1780 This function is similar as strcpy_s defined in C11.
1782 If an error would be returned, then the function will also ASSERT().
1784 If an error is returned, then the Destination is unmodified.
1786 @param Destination A pointer to a Null-terminated Ascii string.
1787 @param DestMax The maximum number of Destination Ascii
1788 char, including terminating null char.
1789 @param Source A pointer to a Null-terminated Ascii string.
1791 @retval RETURN_SUCCESS String is copied.
1792 @retval RETURN_BUFFER_TOO_SMALL If DestMax is NOT greater than StrLen(Source).
1793 @retval RETURN_INVALID_PARAMETER If Destination is NULL.
1795 If PcdMaximumAsciiStringLength is not zero,
1796 and DestMax is greater than
1797 PcdMaximumAsciiStringLength.
1799 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.
1804 OUT CHAR8
*Destination
,
1806 IN CONST CHAR8
*Source
1812 // 1. Neither Destination nor Source shall be a null pointer.
1814 SAFE_STRING_CONSTRAINT_CHECK ((Destination
!= NULL
), RETURN_INVALID_PARAMETER
);
1815 SAFE_STRING_CONSTRAINT_CHECK ((Source
!= NULL
), RETURN_INVALID_PARAMETER
);
1818 // 2. DestMax shall not be greater than ASCII_RSIZE_MAX.
1820 if (ASCII_RSIZE_MAX
!= 0) {
1821 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
<= ASCII_RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
1825 // 3. DestMax shall not equal zero.
1827 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
!= 0), RETURN_INVALID_PARAMETER
);
1830 // 4. DestMax shall be greater than AsciiStrnLenS(Source, DestMax).
1832 SourceLen
= AsciiStrnLenS (Source
, DestMax
);
1833 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
> SourceLen
), RETURN_BUFFER_TOO_SMALL
);
1836 // 5. Copying shall not take place between objects that overlap.
1838 SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoAsciiStrOverlap (Destination
, DestMax
, (CHAR8
*)Source
, SourceLen
+ 1), RETURN_ACCESS_DENIED
);
1841 // The AsciiStrCpyS function copies the string pointed to by Source (including the terminating
1842 // null character) into the array pointed to by Destination.
1844 while (*Source
!= 0) {
1845 *(Destination
++) = *(Source
++);
1849 return RETURN_SUCCESS
;
1853 Copies not more than Length successive char from the string pointed to by
1854 Source to the array pointed to by Destination. If no null char is copied from
1855 Source, then Destination[Length] is always set to null.
1857 This function is similar as strncpy_s defined in C11.
1859 If an error would be returned, then the function will also ASSERT().
1861 If an error is returned, then the Destination is unmodified.
1863 @param Destination A pointer to a Null-terminated Ascii string.
1864 @param DestMax The maximum number of Destination Ascii
1865 char, including terminating null char.
1866 @param Source A pointer to a Null-terminated Ascii string.
1867 @param Length The maximum number of Ascii characters to copy.
1869 @retval RETURN_SUCCESS String is copied.
1870 @retval RETURN_BUFFER_TOO_SMALL If DestMax is NOT greater than
1871 MIN(StrLen(Source), Length).
1872 @retval RETURN_INVALID_PARAMETER If Destination is NULL.
1874 If PcdMaximumAsciiStringLength is not zero,
1875 and DestMax is greater than
1876 PcdMaximumAsciiStringLength.
1878 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.
1883 OUT CHAR8
*Destination
,
1885 IN CONST CHAR8
*Source
,
1892 // 1. Neither Destination nor Source shall be a null pointer.
1894 SAFE_STRING_CONSTRAINT_CHECK ((Destination
!= NULL
), RETURN_INVALID_PARAMETER
);
1895 SAFE_STRING_CONSTRAINT_CHECK ((Source
!= NULL
), RETURN_INVALID_PARAMETER
);
1898 // 2. Neither DestMax nor Length shall be greater than ASCII_RSIZE_MAX
1900 if (ASCII_RSIZE_MAX
!= 0) {
1901 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
<= ASCII_RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
1902 SAFE_STRING_CONSTRAINT_CHECK ((Length
<= ASCII_RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
1906 // 3. DestMax shall not equal zero.
1908 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
!= 0), RETURN_INVALID_PARAMETER
);
1911 // 4. If Length is not less than DestMax, then DestMax shall be greater than AsciiStrnLenS(Source, DestMax).
1913 SourceLen
= AsciiStrnLenS (Source
, MIN (DestMax
, Length
));
1914 if (Length
>= DestMax
) {
1915 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
> SourceLen
), RETURN_BUFFER_TOO_SMALL
);
1919 // 5. Copying shall not take place between objects that overlap.
1921 if (SourceLen
> Length
) {
1924 SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoAsciiStrOverlap (Destination
, DestMax
, (CHAR8
*)Source
, SourceLen
+ 1), RETURN_ACCESS_DENIED
);
1927 // The AsciiStrnCpyS function copies not more than Length successive characters (characters that
1928 // follow a null character are not copied) from the array pointed to by Source to the array
1929 // pointed to by Destination. If no null character was copied from Source, then Destination[Length] is set to a null
1932 while ((SourceLen
> 0) && (*Source
!= 0)) {
1933 *(Destination
++) = *(Source
++);
1938 return RETURN_SUCCESS
;
1942 Appends a copy of the string pointed to by Source (including the terminating
1943 null char) to the end of the string pointed to by Destination.
1945 This function is similar as strcat_s defined in C11.
1947 If an error would be returned, then the function will also ASSERT().
1949 If an error is returned, then the Destination is unmodified.
1951 @param Destination A pointer to a Null-terminated Ascii string.
1952 @param DestMax The maximum number of Destination Ascii
1953 char, including terminating null char.
1954 @param Source A pointer to a Null-terminated Ascii string.
1956 @retval RETURN_SUCCESS String is appended.
1957 @retval RETURN_BAD_BUFFER_SIZE If DestMax is NOT greater than
1958 StrLen(Destination).
1959 @retval RETURN_BUFFER_TOO_SMALL If (DestMax - StrLen(Destination)) is NOT
1960 greater than StrLen(Source).
1961 @retval RETURN_INVALID_PARAMETER If Destination is NULL.
1963 If PcdMaximumAsciiStringLength is not zero,
1964 and DestMax is greater than
1965 PcdMaximumAsciiStringLength.
1967 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.
1972 IN OUT CHAR8
*Destination
,
1974 IN CONST CHAR8
*Source
1982 // Let CopyLen denote the value DestMax - AsciiStrnLenS(Destination, DestMax) upon entry to AsciiStrCatS.
1984 DestLen
= AsciiStrnLenS (Destination
, DestMax
);
1985 CopyLen
= DestMax
- DestLen
;
1988 // 1. Neither Destination nor Source shall be a null pointer.
1990 SAFE_STRING_CONSTRAINT_CHECK ((Destination
!= NULL
), RETURN_INVALID_PARAMETER
);
1991 SAFE_STRING_CONSTRAINT_CHECK ((Source
!= NULL
), RETURN_INVALID_PARAMETER
);
1994 // 2. DestMax shall not be greater than ASCII_RSIZE_MAX.
1996 if (ASCII_RSIZE_MAX
!= 0) {
1997 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
<= ASCII_RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
2001 // 3. DestMax shall not equal zero.
2003 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
!= 0), RETURN_INVALID_PARAMETER
);
2006 // 4. CopyLen shall not equal zero.
2008 SAFE_STRING_CONSTRAINT_CHECK ((CopyLen
!= 0), RETURN_BAD_BUFFER_SIZE
);
2011 // 5. CopyLen shall be greater than AsciiStrnLenS(Source, CopyLen).
2013 SourceLen
= AsciiStrnLenS (Source
, CopyLen
);
2014 SAFE_STRING_CONSTRAINT_CHECK ((CopyLen
> SourceLen
), RETURN_BUFFER_TOO_SMALL
);
2017 // 6. Copying shall not take place between objects that overlap.
2019 SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoAsciiStrOverlap (Destination
, DestMax
, (CHAR8
*)Source
, SourceLen
+ 1), RETURN_ACCESS_DENIED
);
2022 // The AsciiStrCatS function appends a copy of the string pointed to by Source (including the
2023 // terminating null character) to the end of the string pointed to by Destination. The initial character
2024 // from Source overwrites the null character at the end of Destination.
2026 Destination
= Destination
+ DestLen
;
2027 while (*Source
!= 0) {
2028 *(Destination
++) = *(Source
++);
2032 return RETURN_SUCCESS
;
2036 Appends not more than Length successive char from the string pointed to by
2037 Source to the end of the string pointed to by Destination. If no null char is
2038 copied from Source, then Destination[StrLen(Destination) + Length] is always
2041 This function is similar as strncat_s defined in C11.
2043 If an error would be returned, then the function will also ASSERT().
2045 If an error is returned, then the Destination is unmodified.
2047 @param Destination A pointer to a Null-terminated Ascii string.
2048 @param DestMax The maximum number of Destination Ascii
2049 char, including terminating null char.
2050 @param Source A pointer to a Null-terminated Ascii string.
2051 @param Length The maximum number of Ascii characters to copy.
2053 @retval RETURN_SUCCESS String is appended.
2054 @retval RETURN_BAD_BUFFER_SIZE If DestMax is NOT greater than
2055 StrLen(Destination).
2056 @retval RETURN_BUFFER_TOO_SMALL If (DestMax - StrLen(Destination)) is NOT
2057 greater than MIN(StrLen(Source), Length).
2058 @retval RETURN_INVALID_PARAMETER If Destination is NULL.
2060 If PcdMaximumAsciiStringLength is not zero,
2061 and DestMax is greater than
2062 PcdMaximumAsciiStringLength.
2064 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.
2069 IN OUT CHAR8
*Destination
,
2071 IN CONST CHAR8
*Source
,
2080 // Let CopyLen denote the value DestMax - AsciiStrnLenS(Destination, DestMax) upon entry to AsciiStrnCatS.
2082 DestLen
= AsciiStrnLenS (Destination
, DestMax
);
2083 CopyLen
= DestMax
- DestLen
;
2086 // 1. Neither Destination nor Source shall be a null pointer.
2088 SAFE_STRING_CONSTRAINT_CHECK ((Destination
!= NULL
), RETURN_INVALID_PARAMETER
);
2089 SAFE_STRING_CONSTRAINT_CHECK ((Source
!= NULL
), RETURN_INVALID_PARAMETER
);
2092 // 2. Neither DestMax nor Length shall be greater than ASCII_RSIZE_MAX.
2094 if (ASCII_RSIZE_MAX
!= 0) {
2095 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
<= ASCII_RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
2096 SAFE_STRING_CONSTRAINT_CHECK ((Length
<= ASCII_RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
2100 // 3. DestMax shall not equal zero.
2102 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
!= 0), RETURN_INVALID_PARAMETER
);
2105 // 4. CopyLen shall not equal zero.
2107 SAFE_STRING_CONSTRAINT_CHECK ((CopyLen
!= 0), RETURN_BAD_BUFFER_SIZE
);
2110 // 5. If Length is not less than CopyLen, then CopyLen shall be greater than AsciiStrnLenS(Source, CopyLen).
2112 SourceLen
= AsciiStrnLenS (Source
, MIN (CopyLen
, Length
));
2113 if (Length
>= CopyLen
) {
2114 SAFE_STRING_CONSTRAINT_CHECK ((CopyLen
> SourceLen
), RETURN_BUFFER_TOO_SMALL
);
2118 // 6. Copying shall not take place between objects that overlap.
2120 if (SourceLen
> Length
) {
2123 SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoAsciiStrOverlap (Destination
, DestMax
, (CHAR8
*)Source
, SourceLen
+ 1), RETURN_ACCESS_DENIED
);
2126 // The AsciiStrnCatS function appends not more than Length successive characters (characters
2127 // that follow a null character are not copied) from the array pointed to by Source to the end of
2128 // the string pointed to by Destination. The initial character from Source overwrites the null character at
2129 // the end of Destination. If no null character was copied from Source, then Destination[DestMax-CopyLen+Length] is set to
2130 // a null character.
2132 Destination
= Destination
+ DestLen
;
2133 while ((SourceLen
> 0) && (*Source
!= 0)) {
2134 *(Destination
++) = *(Source
++);
2139 return RETURN_SUCCESS
;
2143 Convert a Null-terminated Ascii decimal string to a value of type UINTN.
2145 This function outputs a value of type UINTN by interpreting the contents of
2146 the Ascii string specified by String as a decimal number. The format of the
2147 input Ascii string String is:
2149 [spaces] [decimal digits].
2151 The valid decimal digit character is in the range [0-9]. The function will
2152 ignore the pad space, which includes spaces or tab characters, before
2153 [decimal digits]. The running zero in the beginning of [decimal digits] will
2154 be ignored. Then, the function stops at the first character that is a not a
2155 valid decimal character or a Null-terminator, whichever one comes first.
2157 If String is NULL, then ASSERT().
2158 If Data is NULL, then ASSERT().
2159 If PcdMaximumAsciiStringLength is not zero, and String contains more than
2160 PcdMaximumAsciiStringLength Ascii characters, not including the
2161 Null-terminator, then ASSERT().
2163 If String has no valid decimal digits in the above format, then 0 is stored
2164 at the location pointed to by Data.
2165 If the number represented by String exceeds the range defined by UINTN, then
2166 MAX_UINTN is stored at the location pointed to by Data.
2168 If EndPointer is not NULL, a pointer to the character that stopped the scan
2169 is stored at the location pointed to by EndPointer. If String has no valid
2170 decimal digits right after the optional pad spaces, the value of String is
2171 stored at the location pointed to by EndPointer.
2173 @param String Pointer to a Null-terminated Ascii string.
2174 @param EndPointer Pointer to character that stops scan.
2175 @param Data Pointer to the converted value.
2177 @retval RETURN_SUCCESS Value is translated from String.
2178 @retval RETURN_INVALID_PARAMETER If String is NULL.
2180 If PcdMaximumAsciiStringLength is not zero,
2181 and String contains more than
2182 PcdMaximumAsciiStringLength Ascii
2183 characters, not including the
2185 @retval RETURN_UNSUPPORTED If the number represented by String exceeds
2186 the range defined by UINTN.
2191 AsciiStrDecimalToUintnS (
2192 IN CONST CHAR8
*String
,
2193 OUT CHAR8
**EndPointer
, OPTIONAL
2198 // 1. Neither String nor Data shall be a null pointer.
2200 SAFE_STRING_CONSTRAINT_CHECK ((String
!= NULL
), RETURN_INVALID_PARAMETER
);
2201 SAFE_STRING_CONSTRAINT_CHECK ((Data
!= NULL
), RETURN_INVALID_PARAMETER
);
2204 // 2. The length of String shall not be greater than ASCII_RSIZE_MAX.
2206 if (ASCII_RSIZE_MAX
!= 0) {
2207 SAFE_STRING_CONSTRAINT_CHECK ((AsciiStrnLenS (String
, ASCII_RSIZE_MAX
+ 1) <= ASCII_RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
2210 if (EndPointer
!= NULL
) {
2211 *EndPointer
= (CHAR8
*) String
;
2215 // Ignore the pad spaces (space or tab)
2217 while ((*String
== ' ') || (*String
== '\t')) {
2222 // Ignore leading Zeros after the spaces
2224 while (*String
== '0') {
2230 while (InternalAsciiIsDecimalDigitCharacter (*String
)) {
2232 // If the number represented by String overflows according to the range
2233 // defined by UINTN, then MAX_UINTN is stored in *Data and
2234 // RETURN_UNSUPPORTED is returned.
2236 if (*Data
> ((MAX_UINTN
- (*String
- '0')) / 10)) {
2238 if (EndPointer
!= NULL
) {
2239 *EndPointer
= (CHAR8
*) String
;
2241 return RETURN_UNSUPPORTED
;
2244 *Data
= *Data
* 10 + (*String
- '0');
2248 if (EndPointer
!= NULL
) {
2249 *EndPointer
= (CHAR8
*) String
;
2251 return RETURN_SUCCESS
;
2255 Convert a Null-terminated Ascii decimal string to a value of type UINT64.
2257 This function outputs a value of type UINT64 by interpreting the contents of
2258 the Ascii string specified by String as a decimal number. The format of the
2259 input Ascii string String is:
2261 [spaces] [decimal digits].
2263 The valid decimal digit character is in the range [0-9]. The function will
2264 ignore the pad space, which includes spaces or tab characters, before
2265 [decimal digits]. The running zero in the beginning of [decimal digits] will
2266 be ignored. Then, the function stops at the first character that is a not a
2267 valid decimal character or a Null-terminator, whichever one comes first.
2269 If String is NULL, then ASSERT().
2270 If Data is NULL, then ASSERT().
2271 If PcdMaximumAsciiStringLength is not zero, and String contains more than
2272 PcdMaximumAsciiStringLength Ascii characters, not including the
2273 Null-terminator, then ASSERT().
2275 If String has no valid decimal digits in the above format, then 0 is stored
2276 at the location pointed to by Data.
2277 If the number represented by String exceeds the range defined by UINT64, then
2278 MAX_UINT64 is stored at the location pointed to by Data.
2280 If EndPointer is not NULL, a pointer to the character that stopped the scan
2281 is stored at the location pointed to by EndPointer. If String has no valid
2282 decimal digits right after the optional pad spaces, the value of String is
2283 stored at the location pointed to by EndPointer.
2285 @param String Pointer to a Null-terminated Ascii string.
2286 @param EndPointer Pointer to character that stops scan.
2287 @param Data Pointer to the converted value.
2289 @retval RETURN_SUCCESS Value is translated from String.
2290 @retval RETURN_INVALID_PARAMETER If String is NULL.
2292 If PcdMaximumAsciiStringLength is not zero,
2293 and String contains more than
2294 PcdMaximumAsciiStringLength Ascii
2295 characters, not including the
2297 @retval RETURN_UNSUPPORTED If the number represented by String exceeds
2298 the range defined by UINT64.
2303 AsciiStrDecimalToUint64S (
2304 IN CONST CHAR8
*String
,
2305 OUT CHAR8
**EndPointer
, OPTIONAL
2310 // 1. Neither String nor Data shall be a null pointer.
2312 SAFE_STRING_CONSTRAINT_CHECK ((String
!= NULL
), RETURN_INVALID_PARAMETER
);
2313 SAFE_STRING_CONSTRAINT_CHECK ((Data
!= NULL
), RETURN_INVALID_PARAMETER
);
2316 // 2. The length of String shall not be greater than ASCII_RSIZE_MAX.
2318 if (ASCII_RSIZE_MAX
!= 0) {
2319 SAFE_STRING_CONSTRAINT_CHECK ((AsciiStrnLenS (String
, ASCII_RSIZE_MAX
+ 1) <= ASCII_RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
2322 if (EndPointer
!= NULL
) {
2323 *EndPointer
= (CHAR8
*) String
;
2327 // Ignore the pad spaces (space or tab)
2329 while ((*String
== ' ') || (*String
== '\t')) {
2334 // Ignore leading Zeros after the spaces
2336 while (*String
== '0') {
2342 while (InternalAsciiIsDecimalDigitCharacter (*String
)) {
2344 // If the number represented by String overflows according to the range
2345 // defined by UINT64, then MAX_UINT64 is stored in *Data and
2346 // RETURN_UNSUPPORTED is returned.
2348 if (*Data
> DivU64x32 (MAX_UINT64
- (*String
- '0'), 10)) {
2350 if (EndPointer
!= NULL
) {
2351 *EndPointer
= (CHAR8
*) String
;
2353 return RETURN_UNSUPPORTED
;
2356 *Data
= MultU64x32 (*Data
, 10) + (*String
- '0');
2360 if (EndPointer
!= NULL
) {
2361 *EndPointer
= (CHAR8
*) String
;
2363 return RETURN_SUCCESS
;
2367 Convert a Null-terminated Ascii hexadecimal string to a value of type UINTN.
2369 This function outputs a value of type UINTN by interpreting the contents of
2370 the Ascii string specified by String as a hexadecimal number. The format of
2371 the input Ascii string String is:
2373 [spaces][zeros][x][hexadecimal digits].
2375 The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].
2376 The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix. If
2377 "x" appears in the input string, it must be prefixed with at least one 0. The
2378 function will ignore the pad space, which includes spaces or tab characters,
2379 before [zeros], [x] or [hexadecimal digits]. The running zero before [x] or
2380 [hexadecimal digits] will be ignored. Then, the decoding starts after [x] or
2381 the first valid hexadecimal digit. Then, the function stops at the first
2382 character that is a not a valid hexadecimal character or Null-terminator,
2383 whichever on comes first.
2385 If String is NULL, then ASSERT().
2386 If Data is NULL, then ASSERT().
2387 If PcdMaximumAsciiStringLength is not zero, and String contains more than
2388 PcdMaximumAsciiStringLength Ascii characters, not including the
2389 Null-terminator, then ASSERT().
2391 If String has no valid hexadecimal digits in the above format, then 0 is
2392 stored at the location pointed to by Data.
2393 If the number represented by String exceeds the range defined by UINTN, then
2394 MAX_UINTN is stored at the location pointed to by Data.
2396 If EndPointer is not NULL, a pointer to the character that stopped the scan
2397 is stored at the location pointed to by EndPointer. If String has no valid
2398 hexadecimal digits right after the optional pad spaces, the value of String
2399 is stored at the location pointed to by EndPointer.
2401 @param String Pointer to a Null-terminated Ascii string.
2402 @param EndPointer Pointer to character that stops scan.
2403 @param Data Pointer to the converted value.
2405 @retval RETURN_SUCCESS Value is translated from String.
2406 @retval RETURN_INVALID_PARAMETER If String is NULL.
2408 If PcdMaximumAsciiStringLength is not zero,
2409 and String contains more than
2410 PcdMaximumAsciiStringLength Ascii
2411 characters, not including the
2413 @retval RETURN_UNSUPPORTED If the number represented by String exceeds
2414 the range defined by UINTN.
2419 AsciiStrHexToUintnS (
2420 IN CONST CHAR8
*String
,
2421 OUT CHAR8
**EndPointer
, OPTIONAL
2426 // 1. Neither String nor Data shall be a null pointer.
2428 SAFE_STRING_CONSTRAINT_CHECK ((String
!= NULL
), RETURN_INVALID_PARAMETER
);
2429 SAFE_STRING_CONSTRAINT_CHECK ((Data
!= NULL
), RETURN_INVALID_PARAMETER
);
2432 // 2. The length of String shall not be greater than ASCII_RSIZE_MAX.
2434 if (ASCII_RSIZE_MAX
!= 0) {
2435 SAFE_STRING_CONSTRAINT_CHECK ((AsciiStrnLenS (String
, ASCII_RSIZE_MAX
+ 1) <= ASCII_RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
2438 if (EndPointer
!= NULL
) {
2439 *EndPointer
= (CHAR8
*) String
;
2443 // Ignore the pad spaces (space or tab)
2445 while ((*String
== ' ') || (*String
== '\t')) {
2450 // Ignore leading Zeros after the spaces
2452 while (*String
== '0') {
2456 if (AsciiCharToUpper (*String
) == 'X') {
2457 if (*(String
- 1) != '0') {
2459 return RETURN_SUCCESS
;
2469 while (InternalAsciiIsHexaDecimalDigitCharacter (*String
)) {
2471 // If the number represented by String overflows according to the range
2472 // defined by UINTN, then MAX_UINTN is stored in *Data and
2473 // RETURN_UNSUPPORTED is returned.
2475 if (*Data
> ((MAX_UINTN
- InternalAsciiHexCharToUintn (*String
)) >> 4)) {
2477 if (EndPointer
!= NULL
) {
2478 *EndPointer
= (CHAR8
*) String
;
2480 return RETURN_UNSUPPORTED
;
2483 *Data
= (*Data
<< 4) + InternalAsciiHexCharToUintn (*String
);
2487 if (EndPointer
!= NULL
) {
2488 *EndPointer
= (CHAR8
*) String
;
2490 return RETURN_SUCCESS
;
2494 Convert a Null-terminated Ascii hexadecimal string to a value of type UINT64.
2496 This function outputs a value of type UINT64 by interpreting the contents of
2497 the Ascii string specified by String as a hexadecimal number. The format of
2498 the input Ascii string String is:
2500 [spaces][zeros][x][hexadecimal digits].
2502 The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].
2503 The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix. If
2504 "x" appears in the input string, it must be prefixed with at least one 0. The
2505 function will ignore the pad space, which includes spaces or tab characters,
2506 before [zeros], [x] or [hexadecimal digits]. The running zero before [x] or
2507 [hexadecimal digits] will be ignored. Then, the decoding starts after [x] or
2508 the first valid hexadecimal digit. Then, the function stops at the first
2509 character that is a not a valid hexadecimal character or Null-terminator,
2510 whichever on comes first.
2512 If String is NULL, then ASSERT().
2513 If Data is NULL, then ASSERT().
2514 If PcdMaximumAsciiStringLength is not zero, and String contains more than
2515 PcdMaximumAsciiStringLength Ascii characters, not including the
2516 Null-terminator, then ASSERT().
2518 If String has no valid hexadecimal digits in the above format, then 0 is
2519 stored at the location pointed to by Data.
2520 If the number represented by String exceeds the range defined by UINT64, then
2521 MAX_UINT64 is stored at the location pointed to by Data.
2523 If EndPointer is not NULL, a pointer to the character that stopped the scan
2524 is stored at the location pointed to by EndPointer. If String has no valid
2525 hexadecimal digits right after the optional pad spaces, the value of String
2526 is stored at the location pointed to by EndPointer.
2528 @param String Pointer to a Null-terminated Ascii string.
2529 @param EndPointer Pointer to character that stops scan.
2530 @param Data Pointer to the converted value.
2532 @retval RETURN_SUCCESS Value is translated from String.
2533 @retval RETURN_INVALID_PARAMETER If String is NULL.
2535 If PcdMaximumAsciiStringLength is not zero,
2536 and String contains more than
2537 PcdMaximumAsciiStringLength Ascii
2538 characters, not including the
2540 @retval RETURN_UNSUPPORTED If the number represented by String exceeds
2541 the range defined by UINT64.
2546 AsciiStrHexToUint64S (
2547 IN CONST CHAR8
*String
,
2548 OUT CHAR8
**EndPointer
, OPTIONAL
2553 // 1. Neither String nor Data shall be a null pointer.
2555 SAFE_STRING_CONSTRAINT_CHECK ((String
!= NULL
), RETURN_INVALID_PARAMETER
);
2556 SAFE_STRING_CONSTRAINT_CHECK ((Data
!= NULL
), RETURN_INVALID_PARAMETER
);
2559 // 2. The length of String shall not be greater than ASCII_RSIZE_MAX.
2561 if (ASCII_RSIZE_MAX
!= 0) {
2562 SAFE_STRING_CONSTRAINT_CHECK ((AsciiStrnLenS (String
, ASCII_RSIZE_MAX
+ 1) <= ASCII_RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
2565 if (EndPointer
!= NULL
) {
2566 *EndPointer
= (CHAR8
*) String
;
2570 // Ignore the pad spaces (space or tab)
2572 while ((*String
== ' ') || (*String
== '\t')) {
2577 // Ignore leading Zeros after the spaces
2579 while (*String
== '0') {
2583 if (AsciiCharToUpper (*String
) == 'X') {
2584 if (*(String
- 1) != '0') {
2586 return RETURN_SUCCESS
;
2596 while (InternalAsciiIsHexaDecimalDigitCharacter (*String
)) {
2598 // If the number represented by String overflows according to the range
2599 // defined by UINT64, then MAX_UINT64 is stored in *Data and
2600 // RETURN_UNSUPPORTED is returned.
2602 if (*Data
> RShiftU64 (MAX_UINT64
- InternalAsciiHexCharToUintn (*String
), 4)) {
2604 if (EndPointer
!= NULL
) {
2605 *EndPointer
= (CHAR8
*) String
;
2607 return RETURN_UNSUPPORTED
;
2610 *Data
= LShiftU64 (*Data
, 4) + InternalAsciiHexCharToUintn (*String
);
2614 if (EndPointer
!= NULL
) {
2615 *EndPointer
= (CHAR8
*) String
;
2617 return RETURN_SUCCESS
;
2621 Convert a Null-terminated Unicode string to a Null-terminated
2624 This function is similar to AsciiStrCpyS.
2626 This function converts the content of the Unicode string Source
2627 to the ASCII string Destination by copying the lower 8 bits of
2628 each Unicode character. The function terminates the ASCII string
2629 Destination by appending a Null-terminator character at the end.
2631 The caller is responsible to make sure Destination points to a buffer with size
2632 equal or greater than ((StrLen (Source) + 1) * sizeof (CHAR8)) in bytes.
2634 If any Unicode characters in Source contain non-zero value in
2635 the upper 8 bits, then ASSERT().
2637 If Source is not aligned on a 16-bit boundary, then ASSERT().
2638 If an error would be returned, then the function will also ASSERT().
2640 If an error is returned, then the Destination is unmodified.
2642 @param Source The pointer to a Null-terminated Unicode string.
2643 @param Destination The pointer to a Null-terminated ASCII string.
2644 @param DestMax The maximum number of Destination Ascii
2645 char, including terminating null char.
2647 @retval RETURN_SUCCESS String is converted.
2648 @retval RETURN_BUFFER_TOO_SMALL If DestMax is NOT greater than StrLen(Source).
2649 @retval RETURN_INVALID_PARAMETER If Destination is NULL.
2651 If PcdMaximumAsciiStringLength is not zero,
2652 and DestMax is greater than
2653 PcdMaximumAsciiStringLength.
2654 If PcdMaximumUnicodeStringLength is not zero,
2655 and DestMax is greater than
2656 PcdMaximumUnicodeStringLength.
2658 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.
2663 UnicodeStrToAsciiStrS (
2664 IN CONST CHAR16
*Source
,
2665 OUT CHAR8
*Destination
,
2671 ASSERT (((UINTN
) Source
& BIT0
) == 0);
2674 // 1. Neither Destination nor Source shall be a null pointer.
2676 SAFE_STRING_CONSTRAINT_CHECK ((Destination
!= NULL
), RETURN_INVALID_PARAMETER
);
2677 SAFE_STRING_CONSTRAINT_CHECK ((Source
!= NULL
), RETURN_INVALID_PARAMETER
);
2680 // 2. DestMax shall not be greater than ASCII_RSIZE_MAX or RSIZE_MAX.
2682 if (ASCII_RSIZE_MAX
!= 0) {
2683 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
<= ASCII_RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
2685 if (RSIZE_MAX
!= 0) {
2686 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
<= RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
2690 // 3. DestMax shall not equal zero.
2692 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
!= 0), RETURN_INVALID_PARAMETER
);
2695 // 4. DestMax shall be greater than StrnLenS (Source, DestMax).
2697 SourceLen
= StrnLenS (Source
, DestMax
);
2698 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
> SourceLen
), RETURN_BUFFER_TOO_SMALL
);
2701 // 5. Copying shall not take place between objects that overlap.
2703 SAFE_STRING_CONSTRAINT_CHECK (!InternalSafeStringIsOverlap (Destination
, DestMax
, (VOID
*)Source
, (SourceLen
+ 1) * sizeof(CHAR16
)), RETURN_ACCESS_DENIED
);
2708 while (*Source
!= '\0') {
2710 // If any Unicode characters in Source contain
2711 // non-zero value in the upper 8 bits, then ASSERT().
2713 ASSERT (*Source
< 0x100);
2714 *(Destination
++) = (CHAR8
) *(Source
++);
2716 *Destination
= '\0';
2718 return RETURN_SUCCESS
;
2722 Convert not more than Length successive characters from a Null-terminated
2723 Unicode string to a Null-terminated Ascii string. If no null char is copied
2724 from Source, then Destination[Length] is always set to null.
2726 This function converts not more than Length successive characters from the
2727 Unicode string Source to the Ascii string Destination by copying the lower 8
2728 bits of each Unicode character. The function terminates the Ascii string
2729 Destination by appending a Null-terminator character at the end.
2731 The caller is responsible to make sure Destination points to a buffer with
2732 size not smaller than ((MIN(StrLen(Source), Length) + 1) * sizeof (CHAR8))
2735 If any Unicode characters in Source contain non-zero value in the upper 8
2736 bits, then ASSERT().
2737 If Source is not aligned on a 16-bit boundary, then ASSERT().
2738 If an error would be returned, then the function will also ASSERT().
2740 If an error is returned, then Destination and DestinationLength are
2743 @param Source The pointer to a Null-terminated Unicode string.
2744 @param Length The maximum number of Unicode characters to
2746 @param Destination The pointer to a Null-terminated Ascii string.
2747 @param DestMax The maximum number of Destination Ascii char,
2748 including terminating null char.
2749 @param DestinationLength The number of Unicode characters converted.
2751 @retval RETURN_SUCCESS String is converted.
2752 @retval RETURN_INVALID_PARAMETER If Destination is NULL.
2754 If DestinationLength is NULL.
2755 If PcdMaximumAsciiStringLength is not zero,
2756 and Length or DestMax is greater than
2757 PcdMaximumAsciiStringLength.
2758 If PcdMaximumUnicodeStringLength is not
2759 zero, and Length or DestMax is greater than
2760 PcdMaximumUnicodeStringLength.
2762 @retval RETURN_BUFFER_TOO_SMALL If DestMax is NOT greater than
2763 MIN(StrLen(Source), Length).
2764 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.
2769 UnicodeStrnToAsciiStrS (
2770 IN CONST CHAR16
*Source
,
2772 OUT CHAR8
*Destination
,
2774 OUT UINTN
*DestinationLength
2779 ASSERT (((UINTN
) Source
& BIT0
) == 0);
2782 // 1. None of Destination, Source or DestinationLength shall be a null
2785 SAFE_STRING_CONSTRAINT_CHECK ((Destination
!= NULL
), RETURN_INVALID_PARAMETER
);
2786 SAFE_STRING_CONSTRAINT_CHECK ((Source
!= NULL
), RETURN_INVALID_PARAMETER
);
2787 SAFE_STRING_CONSTRAINT_CHECK ((DestinationLength
!= NULL
), RETURN_INVALID_PARAMETER
);
2790 // 2. Neither Length nor DestMax shall be greater than ASCII_RSIZE_MAX or
2793 if (ASCII_RSIZE_MAX
!= 0) {
2794 SAFE_STRING_CONSTRAINT_CHECK ((Length
<= ASCII_RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
2795 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
<= ASCII_RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
2797 if (RSIZE_MAX
!= 0) {
2798 SAFE_STRING_CONSTRAINT_CHECK ((Length
<= RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
2799 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
<= RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
2803 // 3. DestMax shall not equal zero.
2805 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
!= 0), RETURN_INVALID_PARAMETER
);
2808 // 4. If Length is not less than DestMax, then DestMax shall be greater than
2809 // StrnLenS(Source, DestMax).
2811 SourceLen
= StrnLenS (Source
, DestMax
);
2812 if (Length
>= DestMax
) {
2813 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
> SourceLen
), RETURN_BUFFER_TOO_SMALL
);
2817 // 5. Copying shall not take place between objects that overlap.
2819 if (SourceLen
> Length
) {
2822 SAFE_STRING_CONSTRAINT_CHECK (!InternalSafeStringIsOverlap (Destination
, DestMax
, (VOID
*)Source
, (SourceLen
+ 1) * sizeof(CHAR16
)), RETURN_ACCESS_DENIED
);
2824 *DestinationLength
= 0;
2829 while ((*Source
!= 0) && (SourceLen
> 0)) {
2831 // If any Unicode characters in Source contain non-zero value in the upper
2832 // 8 bits, then ASSERT().
2834 ASSERT (*Source
< 0x100);
2835 *(Destination
++) = (CHAR8
) *(Source
++);
2837 (*DestinationLength
)++;
2841 return RETURN_SUCCESS
;
2845 Convert one Null-terminated ASCII string to a Null-terminated
2848 This function is similar to StrCpyS.
2850 This function converts the contents of the ASCII string Source to the Unicode
2851 string Destination. The function terminates the Unicode string Destination by
2852 appending a Null-terminator character at the end.
2854 The caller is responsible to make sure Destination points to a buffer with size
2855 equal or greater than ((AsciiStrLen (Source) + 1) * sizeof (CHAR16)) in bytes.
2857 If Destination is not aligned on a 16-bit boundary, then ASSERT().
2858 If an error would be returned, then the function will also ASSERT().
2860 If an error is returned, then the Destination is unmodified.
2862 @param Source The pointer to a Null-terminated ASCII string.
2863 @param Destination The pointer to a Null-terminated Unicode string.
2864 @param DestMax The maximum number of Destination Unicode
2865 char, including terminating null char.
2867 @retval RETURN_SUCCESS String is converted.
2868 @retval RETURN_BUFFER_TOO_SMALL If DestMax is NOT greater than StrLen(Source).
2869 @retval RETURN_INVALID_PARAMETER If Destination is NULL.
2871 If PcdMaximumUnicodeStringLength is not zero,
2872 and DestMax is greater than
2873 PcdMaximumUnicodeStringLength.
2874 If PcdMaximumAsciiStringLength is not zero,
2875 and DestMax is greater than
2876 PcdMaximumAsciiStringLength.
2878 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.
2883 AsciiStrToUnicodeStrS (
2884 IN CONST CHAR8
*Source
,
2885 OUT CHAR16
*Destination
,
2891 ASSERT (((UINTN
) Destination
& BIT0
) == 0);
2894 // 1. Neither Destination nor Source shall be a null pointer.
2896 SAFE_STRING_CONSTRAINT_CHECK ((Destination
!= NULL
), RETURN_INVALID_PARAMETER
);
2897 SAFE_STRING_CONSTRAINT_CHECK ((Source
!= NULL
), RETURN_INVALID_PARAMETER
);
2900 // 2. DestMax shall not be greater than RSIZE_MAX or ASCII_RSIZE_MAX.
2902 if (RSIZE_MAX
!= 0) {
2903 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
<= RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
2905 if (ASCII_RSIZE_MAX
!= 0) {
2906 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
<= ASCII_RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
2910 // 3. DestMax shall not equal zero.
2912 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
!= 0), RETURN_INVALID_PARAMETER
);
2915 // 4. DestMax shall be greater than AsciiStrnLenS(Source, DestMax).
2917 SourceLen
= AsciiStrnLenS (Source
, DestMax
);
2918 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
> SourceLen
), RETURN_BUFFER_TOO_SMALL
);
2921 // 5. Copying shall not take place between objects that overlap.
2923 SAFE_STRING_CONSTRAINT_CHECK (!InternalSafeStringIsOverlap (Destination
, DestMax
* sizeof(CHAR16
), (VOID
*)Source
, SourceLen
+ 1), RETURN_ACCESS_DENIED
);
2928 while (*Source
!= '\0') {
2929 *(Destination
++) = (CHAR16
)(UINT8
)*(Source
++);
2931 *Destination
= '\0';
2933 return RETURN_SUCCESS
;
2937 Convert not more than Length successive characters from a Null-terminated
2938 Ascii string to a Null-terminated Unicode string. If no null char is copied
2939 from Source, then Destination[Length] is always set to null.
2941 This function converts not more than Length successive characters from the
2942 Ascii string Source to the Unicode string Destination. The function
2943 terminates the Unicode string Destination by appending a Null-terminator
2944 character at the end.
2946 The caller is responsible to make sure Destination points to a buffer with
2947 size not smaller than
2948 ((MIN(AsciiStrLen(Source), Length) + 1) * sizeof (CHAR8)) in bytes.
2950 If Destination is not aligned on a 16-bit boundary, then ASSERT().
2951 If an error would be returned, then the function will also ASSERT().
2953 If an error is returned, then Destination and DestinationLength are
2956 @param Source The pointer to a Null-terminated Ascii string.
2957 @param Length The maximum number of Ascii characters to convert.
2958 @param Destination The pointer to a Null-terminated Unicode string.
2959 @param DestMax The maximum number of Destination Unicode char,
2960 including terminating null char.
2961 @param DestinationLength The number of Ascii characters converted.
2963 @retval RETURN_SUCCESS String is converted.
2964 @retval RETURN_INVALID_PARAMETER If Destination is NULL.
2966 If DestinationLength is NULL.
2967 If PcdMaximumUnicodeStringLength is not
2968 zero, and Length or DestMax is greater than
2969 PcdMaximumUnicodeStringLength.
2970 If PcdMaximumAsciiStringLength is not zero,
2971 and Length or DestMax is greater than
2972 PcdMaximumAsciiStringLength.
2974 @retval RETURN_BUFFER_TOO_SMALL If DestMax is NOT greater than
2975 MIN(AsciiStrLen(Source), Length).
2976 @retval RETURN_ACCESS_DENIED If Source and Destination overlap.
2981 AsciiStrnToUnicodeStrS (
2982 IN CONST CHAR8
*Source
,
2984 OUT CHAR16
*Destination
,
2986 OUT UINTN
*DestinationLength
2991 ASSERT (((UINTN
) Destination
& BIT0
) == 0);
2994 // 1. None of Destination, Source or DestinationLength shall be a null
2997 SAFE_STRING_CONSTRAINT_CHECK ((Destination
!= NULL
), RETURN_INVALID_PARAMETER
);
2998 SAFE_STRING_CONSTRAINT_CHECK ((Source
!= NULL
), RETURN_INVALID_PARAMETER
);
2999 SAFE_STRING_CONSTRAINT_CHECK ((DestinationLength
!= NULL
), RETURN_INVALID_PARAMETER
);
3002 // 2. Neither Length nor DestMax shall be greater than ASCII_RSIZE_MAX or
3005 if (RSIZE_MAX
!= 0) {
3006 SAFE_STRING_CONSTRAINT_CHECK ((Length
<= RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
3007 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
<= RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
3009 if (ASCII_RSIZE_MAX
!= 0) {
3010 SAFE_STRING_CONSTRAINT_CHECK ((Length
<= ASCII_RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
3011 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
<= ASCII_RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
3015 // 3. DestMax shall not equal zero.
3017 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
!= 0), RETURN_INVALID_PARAMETER
);
3020 // 4. If Length is not less than DestMax, then DestMax shall be greater than
3021 // AsciiStrnLenS(Source, DestMax).
3023 SourceLen
= AsciiStrnLenS (Source
, DestMax
);
3024 if (Length
>= DestMax
) {
3025 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
> SourceLen
), RETURN_BUFFER_TOO_SMALL
);
3029 // 5. Copying shall not take place between objects that overlap.
3031 if (SourceLen
> Length
) {
3034 SAFE_STRING_CONSTRAINT_CHECK (!InternalSafeStringIsOverlap (Destination
, DestMax
* sizeof(CHAR16
), (VOID
*)Source
, SourceLen
+ 1), RETURN_ACCESS_DENIED
);
3036 *DestinationLength
= 0;
3041 while ((*Source
!= 0) && (SourceLen
> 0)) {
3042 *(Destination
++) = (CHAR16
)(UINT8
)*(Source
++);
3044 (*DestinationLength
)++;
3048 return RETURN_SUCCESS
;
3052 Convert a Null-terminated ASCII string to IPv6 address and prefix length.
3054 This function outputs a value of type IPv6_ADDRESS and may output a value
3055 of type UINT8 by interpreting the contents of the ASCII string specified
3056 by String. The format of the input ASCII string String is as follows:
3060 X contains one to four hexadecimal digit characters in the range [0-9], [a-f] and
3061 [A-F]. X is converted to a value of type UINT16, whose low byte is stored in low
3062 memory address and high byte is stored in high memory address. P contains decimal
3063 digit characters in the range [0-9]. The running zero in the beginning of P will
3064 be ignored. /P is optional.
3066 When /P is not in the String, the function stops at the first character that is
3067 not a valid hexadecimal digit character after eight X's are converted.
3069 When /P is in the String, the function stops at the first character that is not
3070 a valid decimal digit character after P is converted.
3072 "::" can be used to compress one or more groups of X when X contains only 0.
3073 The "::" can only appear once in the String.
3075 If String is NULL, then ASSERT().
3077 If Address is NULL, then ASSERT().
3079 If EndPointer is not NULL and Address is translated from String, a pointer
3080 to the character that stopped the scan is stored at the location pointed to
3083 @param String Pointer to a Null-terminated ASCII string.
3084 @param EndPointer Pointer to character that stops scan.
3085 @param Address Pointer to the converted IPv6 address.
3086 @param PrefixLength Pointer to the converted IPv6 address prefix
3087 length. MAX_UINT8 is returned when /P is
3090 @retval RETURN_SUCCESS Address is translated from String.
3091 @retval RETURN_INVALID_PARAMETER If String is NULL.
3093 @retval RETURN_UNSUPPORTED If X contains more than four hexadecimal
3095 If String contains "::" and number of X
3097 If P starts with character that is not a
3098 valid decimal digit character.
3099 If the decimal number converted from P
3105 AsciiStrToIpv6Address (
3106 IN CONST CHAR8
*String
,
3107 OUT CHAR8
**EndPointer
, OPTIONAL
3108 OUT IPv6_ADDRESS
*Address
,
3109 OUT UINT8
*PrefixLength OPTIONAL
3112 RETURN_STATUS Status
;
3115 IPv6_ADDRESS LocalAddress
;
3116 UINT8 LocalPrefixLength
;
3117 CONST CHAR8
*Pointer
;
3119 UINTN CompressStart
;
3120 BOOLEAN ExpectPrefix
;
3122 LocalPrefixLength
= MAX_UINT8
;
3123 CompressStart
= ARRAY_SIZE (Address
->Addr
);
3124 ExpectPrefix
= FALSE
;
3127 // None of String or Address shall be a null pointer.
3129 SAFE_STRING_CONSTRAINT_CHECK ((String
!= NULL
), RETURN_INVALID_PARAMETER
);
3130 SAFE_STRING_CONSTRAINT_CHECK ((Address
!= NULL
), RETURN_INVALID_PARAMETER
);
3132 for (Pointer
= String
, AddressIndex
= 0; AddressIndex
< ARRAY_SIZE (Address
->Addr
) + 1;) {
3133 if (!InternalAsciiIsHexaDecimalDigitCharacter (*Pointer
)) {
3134 if (*Pointer
!= ':') {
3136 // ":" or "/" should be followed by digit characters.
3138 return RETURN_UNSUPPORTED
;
3142 // Meet second ":" after previous ":" or "/"
3143 // or meet first ":" in the beginning of String.
3147 // ":" shall not be after "/"
3149 return RETURN_UNSUPPORTED
;
3152 if (CompressStart
!= ARRAY_SIZE (Address
->Addr
) || AddressIndex
== ARRAY_SIZE (Address
->Addr
)) {
3154 // "::" can only appear once.
3155 // "::" can only appear when address is not full length.
3157 return RETURN_UNSUPPORTED
;
3160 // Remember the start of zero compressing.
3162 CompressStart
= AddressIndex
;
3165 if (CompressStart
== 0) {
3166 if (*Pointer
!= ':') {
3168 // Single ":" shall not be in the beginning of String.
3170 return RETURN_UNSUPPORTED
;
3177 if (!InternalAsciiIsHexaDecimalDigitCharacter (*Pointer
)) {
3178 if (*Pointer
== '/') {
3180 // Might be optional "/P" after "::".
3182 if (CompressStart
!= AddressIndex
) {
3183 return RETURN_UNSUPPORTED
;
3189 if (!ExpectPrefix
) {
3193 Status
= AsciiStrHexToUintnS (Pointer
, &End
, &Uintn
);
3194 if (RETURN_ERROR (Status
) || End
- Pointer
> 4) {
3196 // Number of hexadecimal digit characters is no more than 4.
3198 return RETURN_UNSUPPORTED
;
3202 // Uintn won't exceed MAX_UINT16 if number of hexadecimal digit characters is no more than 4.
3204 ASSERT (AddressIndex
+ 1 < ARRAY_SIZE (Address
->Addr
));
3205 LocalAddress
.Addr
[AddressIndex
] = (UINT8
) ((UINT16
) Uintn
>> 8);
3206 LocalAddress
.Addr
[AddressIndex
+ 1] = (UINT8
) Uintn
;
3210 // Get P, then exit the loop.
3212 Status
= AsciiStrDecimalToUintnS (Pointer
, &End
, &Uintn
);
3213 if (RETURN_ERROR (Status
) || End
== Pointer
|| Uintn
> 128) {
3215 // Prefix length should not exceed 128.
3217 return RETURN_UNSUPPORTED
;
3219 LocalPrefixLength
= (UINT8
) Uintn
;
3228 if (*Pointer
== '/') {
3229 ExpectPrefix
= TRUE
;
3230 } else if (*Pointer
== ':') {
3231 if (AddressIndex
== ARRAY_SIZE (Address
->Addr
)) {
3233 // Meet additional ":" after all 8 16-bit address
3239 // Meet other character that is not "/" or ":" after all 8 16-bit address
3246 if ((AddressIndex
== ARRAY_SIZE (Address
->Addr
) && CompressStart
!= ARRAY_SIZE (Address
->Addr
)) ||
3247 (AddressIndex
!= ARRAY_SIZE (Address
->Addr
) && CompressStart
== ARRAY_SIZE (Address
->Addr
))
3250 // Full length of address shall not have compressing zeros.
3251 // Non-full length of address shall have compressing zeros.
3253 return RETURN_UNSUPPORTED
;
3255 CopyMem (&Address
->Addr
[0], &LocalAddress
.Addr
[0], CompressStart
);
3256 ZeroMem (&Address
->Addr
[CompressStart
], ARRAY_SIZE (Address
->Addr
) - AddressIndex
);
3257 if (AddressIndex
> CompressStart
) {
3259 &Address
->Addr
[CompressStart
+ ARRAY_SIZE (Address
->Addr
) - AddressIndex
],
3260 &LocalAddress
.Addr
[CompressStart
],
3261 AddressIndex
- CompressStart
3266 if (PrefixLength
!= NULL
) {
3267 *PrefixLength
= LocalPrefixLength
;
3269 if (EndPointer
!= NULL
) {
3270 *EndPointer
= (CHAR8
*) Pointer
;
3273 return RETURN_SUCCESS
;
3277 Convert a Null-terminated ASCII string to IPv4 address and prefix length.
3279 This function outputs a value of type IPv4_ADDRESS and may output a value
3280 of type UINT8 by interpreting the contents of the ASCII string specified
3281 by String. The format of the input ASCII string String is as follows:
3285 D and P are decimal digit characters in the range [0-9]. The running zero in
3286 the beginning of D and P will be ignored. /P is optional.
3288 When /P is not in the String, the function stops at the first character that is
3289 not a valid decimal digit character after four D's are converted.
3291 When /P is in the String, the function stops at the first character that is not
3292 a valid decimal digit character after P is converted.
3294 If String is NULL, then ASSERT().
3296 If Address is NULL, then ASSERT().
3298 If EndPointer is not NULL and Address is translated from String, a pointer
3299 to the character that stopped the scan is stored at the location pointed to
3302 @param String Pointer to a Null-terminated ASCII string.
3303 @param EndPointer Pointer to character that stops scan.
3304 @param Address Pointer to the converted IPv4 address.
3305 @param PrefixLength Pointer to the converted IPv4 address prefix
3306 length. MAX_UINT8 is returned when /P is
3309 @retval RETURN_SUCCESS Address is translated from String.
3310 @retval RETURN_INVALID_PARAMETER If String is NULL.
3312 @retval RETURN_UNSUPPORTED If String is not in the correct format.
3313 If any decimal number converted from D
3315 If the decimal number converted from P
3321 AsciiStrToIpv4Address (
3322 IN CONST CHAR8
*String
,
3323 OUT CHAR8
**EndPointer
, OPTIONAL
3324 OUT IPv4_ADDRESS
*Address
,
3325 OUT UINT8
*PrefixLength OPTIONAL
3328 RETURN_STATUS Status
;
3331 IPv4_ADDRESS LocalAddress
;
3332 UINT8 LocalPrefixLength
;
3335 LocalPrefixLength
= MAX_UINT8
;
3338 // None of String or Address shall be a null pointer.
3340 SAFE_STRING_CONSTRAINT_CHECK ((String
!= NULL
), RETURN_INVALID_PARAMETER
);
3341 SAFE_STRING_CONSTRAINT_CHECK ((Address
!= NULL
), RETURN_INVALID_PARAMETER
);
3343 for (Pointer
= (CHAR8
*) String
, AddressIndex
= 0; AddressIndex
< ARRAY_SIZE (Address
->Addr
) + 1;) {
3344 if (!InternalAsciiIsDecimalDigitCharacter (*Pointer
)) {
3346 // D or P contains invalid characters.
3354 Status
= AsciiStrDecimalToUintnS ((CONST CHAR8
*) Pointer
, &Pointer
, &Uintn
);
3355 if (RETURN_ERROR (Status
)) {
3356 return RETURN_UNSUPPORTED
;
3358 if (AddressIndex
== ARRAY_SIZE (Address
->Addr
)) {
3363 return RETURN_UNSUPPORTED
;
3365 LocalPrefixLength
= (UINT8
) Uintn
;
3370 if (Uintn
> MAX_UINT8
) {
3371 return RETURN_UNSUPPORTED
;
3373 LocalAddress
.Addr
[AddressIndex
] = (UINT8
) Uintn
;
3378 // Check the '.' or '/', depending on the AddressIndex.
3380 if (AddressIndex
== ARRAY_SIZE (Address
->Addr
)) {
3381 if (*Pointer
== '/') {
3383 // '/P' is in the String.
3384 // Skip "/" and get P in next loop.
3389 // '/P' is not in the String.
3393 } else if (AddressIndex
< ARRAY_SIZE (Address
->Addr
)) {
3394 if (*Pointer
== '.') {
3396 // D should be followed by '.'
3400 return RETURN_UNSUPPORTED
;
3405 if (AddressIndex
< ARRAY_SIZE (Address
->Addr
)) {
3406 return RETURN_UNSUPPORTED
;
3409 CopyMem (Address
, &LocalAddress
, sizeof (*Address
));
3410 if (PrefixLength
!= NULL
) {
3411 *PrefixLength
= LocalPrefixLength
;
3413 if (EndPointer
!= NULL
) {
3414 *EndPointer
= Pointer
;
3417 return RETURN_SUCCESS
;
3421 Convert a Null-terminated ASCII GUID string to a value of type
3424 This function outputs a GUID value by interpreting the contents of
3425 the ASCII string specified by String. The format of the input
3426 ASCII string String consists of 36 characters, as follows:
3428 aabbccdd-eeff-gghh-iijj-kkllmmnnoopp
3430 The pairs aa - pp are two characters in the range [0-9], [a-f] and
3431 [A-F], with each pair representing a single byte hexadecimal value.
3433 The mapping between String and the EFI_GUID structure is as follows:
3451 If String is NULL, then ASSERT().
3452 If Guid is NULL, then ASSERT().
3454 @param String Pointer to a Null-terminated ASCII string.
3455 @param Guid Pointer to the converted GUID.
3457 @retval RETURN_SUCCESS Guid is translated from String.
3458 @retval RETURN_INVALID_PARAMETER If String is NULL.
3460 @retval RETURN_UNSUPPORTED If String is not as the above format.
3466 IN CONST CHAR8
*String
,
3470 RETURN_STATUS Status
;
3474 // None of String or Guid shall be a null pointer.
3476 SAFE_STRING_CONSTRAINT_CHECK ((String
!= NULL
), RETURN_INVALID_PARAMETER
);
3477 SAFE_STRING_CONSTRAINT_CHECK ((Guid
!= NULL
), RETURN_INVALID_PARAMETER
);
3480 // Get aabbccdd in big-endian.
3482 Status
= AsciiStrHexToBytes (String
, 2 * sizeof (LocalGuid
.Data1
), (UINT8
*) &LocalGuid
.Data1
, sizeof (LocalGuid
.Data1
));
3483 if (RETURN_ERROR (Status
) || String
[2 * sizeof (LocalGuid
.Data1
)] != '-') {
3484 return RETURN_UNSUPPORTED
;
3487 // Convert big-endian to little-endian.
3489 LocalGuid
.Data1
= SwapBytes32 (LocalGuid
.Data1
);
3490 String
+= 2 * sizeof (LocalGuid
.Data1
) + 1;
3493 // Get eeff in big-endian.
3495 Status
= AsciiStrHexToBytes (String
, 2 * sizeof (LocalGuid
.Data2
), (UINT8
*) &LocalGuid
.Data2
, sizeof (LocalGuid
.Data2
));
3496 if (RETURN_ERROR (Status
) || String
[2 * sizeof (LocalGuid
.Data2
)] != '-') {
3497 return RETURN_UNSUPPORTED
;
3500 // Convert big-endian to little-endian.
3502 LocalGuid
.Data2
= SwapBytes16 (LocalGuid
.Data2
);
3503 String
+= 2 * sizeof (LocalGuid
.Data2
) + 1;
3506 // Get gghh in big-endian.
3508 Status
= AsciiStrHexToBytes (String
, 2 * sizeof (LocalGuid
.Data3
), (UINT8
*) &LocalGuid
.Data3
, sizeof (LocalGuid
.Data3
));
3509 if (RETURN_ERROR (Status
) || String
[2 * sizeof (LocalGuid
.Data3
)] != '-') {
3510 return RETURN_UNSUPPORTED
;
3513 // Convert big-endian to little-endian.
3515 LocalGuid
.Data3
= SwapBytes16 (LocalGuid
.Data3
);
3516 String
+= 2 * sizeof (LocalGuid
.Data3
) + 1;
3521 Status
= AsciiStrHexToBytes (String
, 2 * 2, &LocalGuid
.Data4
[0], 2);
3522 if (RETURN_ERROR (Status
) || String
[2 * 2] != '-') {
3523 return RETURN_UNSUPPORTED
;
3525 String
+= 2 * 2 + 1;
3528 // Get kkllmmnnoopp.
3530 Status
= AsciiStrHexToBytes (String
, 2 * 6, &LocalGuid
.Data4
[2], 6);
3531 if (RETURN_ERROR (Status
)) {
3532 return RETURN_UNSUPPORTED
;
3535 CopyGuid (Guid
, &LocalGuid
);
3536 return RETURN_SUCCESS
;
3540 Convert a Null-terminated ASCII hexadecimal string to a byte array.
3542 This function outputs a byte array by interpreting the contents of
3543 the ASCII string specified by String in hexadecimal format. The format of
3544 the input ASCII string String is:
3548 X is a hexadecimal digit character in the range [0-9], [a-f] and [A-F].
3549 The function decodes every two hexadecimal digit characters as one byte. The
3550 decoding stops after Length of characters and outputs Buffer containing
3553 If String is NULL, then ASSERT().
3555 If Buffer is NULL, then ASSERT().
3557 If Length is not multiple of 2, then ASSERT().
3559 If PcdMaximumAsciiStringLength is not zero and Length is greater than
3560 PcdMaximumAsciiStringLength, then ASSERT().
3562 If MaxBufferSize is less than (Length / 2), then ASSERT().
3564 @param String Pointer to a Null-terminated ASCII string.
3565 @param Length The number of ASCII characters to decode.
3566 @param Buffer Pointer to the converted bytes array.
3567 @param MaxBufferSize The maximum size of Buffer.
3569 @retval RETURN_SUCCESS Buffer is translated from String.
3570 @retval RETURN_INVALID_PARAMETER If String is NULL.
3572 If Length is not multiple of 2.
3573 If PcdMaximumAsciiStringLength is not zero,
3574 and Length is greater than
3575 PcdMaximumAsciiStringLength.
3576 @retval RETURN_UNSUPPORTED If Length of characters from String contain
3577 a character that is not valid hexadecimal
3578 digit characters, or a Null-terminator.
3579 @retval RETURN_BUFFER_TOO_SMALL If MaxBufferSize is less than (Length / 2).
3583 AsciiStrHexToBytes (
3584 IN CONST CHAR8
*String
,
3587 IN UINTN MaxBufferSize
3593 // 1. None of String or Buffer shall be a null pointer.
3595 SAFE_STRING_CONSTRAINT_CHECK ((String
!= NULL
), RETURN_INVALID_PARAMETER
);
3596 SAFE_STRING_CONSTRAINT_CHECK ((Buffer
!= NULL
), RETURN_INVALID_PARAMETER
);
3599 // 2. Length shall not be greater than ASCII_RSIZE_MAX.
3601 if (ASCII_RSIZE_MAX
!= 0) {
3602 SAFE_STRING_CONSTRAINT_CHECK ((Length
<= ASCII_RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
3606 // 3. Length shall not be odd.
3608 SAFE_STRING_CONSTRAINT_CHECK (((Length
& BIT0
) == 0), RETURN_INVALID_PARAMETER
);
3611 // 4. MaxBufferSize shall equal to or greater than Length / 2.
3613 SAFE_STRING_CONSTRAINT_CHECK ((MaxBufferSize
>= Length
/ 2), RETURN_BUFFER_TOO_SMALL
);
3616 // 5. String shall not contains invalid hexadecimal digits.
3618 for (Index
= 0; Index
< Length
; Index
++) {
3619 if (!InternalAsciiIsHexaDecimalDigitCharacter (String
[Index
])) {
3623 if (Index
!= Length
) {
3624 return RETURN_UNSUPPORTED
;
3628 // Convert the hex string to bytes.
3630 for(Index
= 0; Index
< Length
; Index
++) {
3633 // For even characters, write the upper nibble for each buffer byte,
3634 // and for even characters, the lower nibble.
3636 if ((Index
& BIT0
) == 0) {
3637 Buffer
[Index
/ 2] = (UINT8
) InternalAsciiHexCharToUintn (String
[Index
]) << 4;
3639 Buffer
[Index
/ 2] |= (UINT8
) InternalAsciiHexCharToUintn (String
[Index
]);
3642 return RETURN_SUCCESS
;