2 Common basic Library Functions
4 Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
18 #include "CommonLib.h"
19 #include "EfiUtilityMsgs.h"
21 #define SAFE_STRING_CONSTRAINT_CHECK(Expression, Status) \
23 ASSERT (Expression); \
24 if (!(Expression)) { \
38 Set Buffer to zero for Size bytes.
42 Buffer - Memory to set.
44 Size - Number of bytes to set
70 Copy Length bytes from Source to Destination.
74 Destination - Target of copy
76 Source - Place to copy from
78 Length - Number of bytes to copy
89 Destination8
= Destination
;
92 *(Destination8
++) = *(Source8
++);
102 PeiZeroMem (Buffer
, Size
);
107 IN VOID
*Destination
,
112 PeiCopyMem (Destination
, Source
, Length
);
128 Guid1 - guid to compare
129 Guid2 - guid to compare
132 = 0 if Guid1 == Guid2
133 != 0 if Guid1 != Guid2
142 // Compare 32 bits at a time
144 g1
= (INT32
*) Guid1
;
145 g2
= (INT32
*) Guid2
;
158 IN CHAR8
*InputFileName
,
159 OUT CHAR8
**InputFileImage
,
160 OUT UINT32
*BytesRead
166 This function opens a file and reads it into a memory buffer. The function
167 will allocate the memory buffer and returns the size of the buffer.
171 InputFileName The name of the file to read.
172 InputFileImage A pointer to the memory buffer.
173 BytesRead The size of the memory buffer.
177 EFI_SUCCESS The function completed successfully.
178 EFI_INVALID_PARAMETER One of the input parameters was invalid.
179 EFI_ABORTED An error occurred.
180 EFI_OUT_OF_RESOURCES No resource to complete operations.
188 // Verify input parameters.
190 if (InputFileName
== NULL
|| strlen (InputFileName
) == 0 || InputFileImage
== NULL
) {
191 return EFI_INVALID_PARAMETER
;
194 // Open the file and copy contents into a memory buffer.
199 InputFile
= fopen (LongFilePath (InputFileName
), "rb");
200 if (InputFile
== NULL
) {
201 Error (NULL
, 0, 0001, "Error opening the input file", InputFileName
);
205 // Go to the end so that we can determine the file size
207 if (fseek (InputFile
, 0, SEEK_END
)) {
208 Error (NULL
, 0, 0004, "Error reading the input file", InputFileName
);
215 FileSize
= ftell (InputFile
);
216 if (FileSize
== -1) {
217 Error (NULL
, 0, 0003, "Error parsing the input file", InputFileName
);
224 *InputFileImage
= malloc (FileSize
);
225 if (*InputFileImage
== NULL
) {
227 return EFI_OUT_OF_RESOURCES
;
230 // Reset to the beginning of the file
232 if (fseek (InputFile
, 0, SEEK_SET
)) {
233 Error (NULL
, 0, 0004, "Error reading the input file", InputFileName
);
235 free (*InputFileImage
);
236 *InputFileImage
= NULL
;
240 // Read all of the file contents.
242 *BytesRead
= fread (*InputFileImage
, sizeof (UINT8
), FileSize
, InputFile
);
243 if (*BytesRead
!= sizeof (UINT8
) * FileSize
) {
244 Error (NULL
, 0, 0004, "Error reading the input file", InputFileName
);
246 free (*InputFileImage
);
247 *InputFileImage
= NULL
;
260 IN CHAR8
*OutputFileName
,
261 IN CHAR8
*OutputFileImage
,
262 IN UINT32 BytesToWrite
268 This function opens a file and writes OutputFileImage into the file.
272 OutputFileName The name of the file to write.
273 OutputFileImage A pointer to the memory buffer.
274 BytesToWrite The size of the memory buffer.
278 EFI_SUCCESS The function completed successfully.
279 EFI_INVALID_PARAMETER One of the input parameters was invalid.
280 EFI_ABORTED An error occurred.
281 EFI_OUT_OF_RESOURCES No resource to complete operations.
289 // Verify input parameters.
291 if (OutputFileName
== NULL
|| strlen (OutputFileName
) == 0 || OutputFileImage
== NULL
) {
292 return EFI_INVALID_PARAMETER
;
295 // Open the file and copy contents into a memory buffer.
300 OutputFile
= fopen (LongFilePath (OutputFileName
), "wb");
301 if (OutputFile
== NULL
) {
302 Error (NULL
, 0, 0001, "Error opening the output file", OutputFileName
);
307 // Write all of the file contents.
309 BytesWrote
= fwrite (OutputFileImage
, sizeof (UINT8
), BytesToWrite
, OutputFile
);
310 if (BytesWrote
!= sizeof (UINT8
) * BytesToWrite
) {
311 Error (NULL
, 0, 0002, "Error writing the output file", OutputFileName
);
332 This function calculates the value needed for a valid UINT8 checksum
336 Buffer Pointer to buffer containing byte data of component.
337 Size Size of the buffer
341 The 8 bit checksum value needed.
345 return (UINT8
) (0x100 - CalculateSum8 (Buffer
, Size
));
355 Routine Description::
357 This function calculates the UINT8 sum for the requested region.
361 Buffer Pointer to buffer containing byte data of component.
362 Size Size of the buffer
366 The 8 bit checksum value needed.
376 // Perform the byte sum for buffer
378 for (Index
= 0; Index
< Size
; Index
++) {
379 Sum
= (UINT8
) (Sum
+ Buffer
[Index
]);
386 CalculateChecksum16 (
392 Routine Description::
394 This function calculates the value needed for a valid UINT16 checksum
398 Buffer Pointer to buffer containing byte data of component.
399 Size Size of the buffer
403 The 16 bit checksum value needed.
407 return (UINT16
) (0x10000 - CalculateSum16 (Buffer
, Size
));
419 This function calculates the UINT16 sum for the requested region.
423 Buffer Pointer to buffer containing byte data of component.
424 Size Size of the buffer
438 // Perform the word sum for buffer
440 for (Index
= 0; Index
< Size
; Index
++) {
441 Sum
= (UINT16
) (Sum
+ Buffer
[Index
]);
455 This function prints a GUID to STDOUT.
459 Guid Pointer to a GUID to print.
463 EFI_SUCCESS The GUID was printed.
464 EFI_INVALID_PARAMETER The input was NULL.
469 Error (NULL
, 0, 2000, "Invalid parameter", "PrintGuidToBuffer() called with a NULL value");
470 return EFI_INVALID_PARAMETER
;
474 "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x\n",
475 (unsigned) Guid
->Data1
,
493 IN OUT UINT8
*Buffer
,
501 This function prints a GUID to a buffer
505 Guid - Pointer to a GUID to print.
506 Buffer - Pointer to a user-provided buffer to print to
507 BufferLen - Size of the Buffer
508 Uppercase - If use upper case.
512 EFI_SUCCESS The GUID was printed.
513 EFI_INVALID_PARAMETER The input was NULL.
514 EFI_BUFFER_TOO_SMALL The input buffer was not big enough
519 Error (NULL
, 0, 2000, "Invalid parameter", "PrintGuidToBuffer() called with a NULL value");
520 return EFI_INVALID_PARAMETER
;
523 if (BufferLen
< PRINTED_GUID_BUFFER_SIZE
) {
524 Error (NULL
, 0, 2000, "Invalid parameter", "PrintGuidToBuffer() called with invalid buffer size");
525 return EFI_BUFFER_TOO_SMALL
;
531 "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X",
532 (unsigned) Guid
->Data1
,
547 "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
548 (unsigned) Guid
->Data1
,
567 size_t _filelength(int fd
)
569 struct stat stat_buf
;
570 fstat(fd
, &stat_buf
);
571 return stat_buf
.st_size
;
575 char *strlwr(char *s
)
586 #define WINDOWS_EXTENSION_PATH "\\\\?\\"
587 #define WINDOWS_UNC_EXTENSION_PATH "\\\\?\\UNC"
590 // Global data to store full file path. It is not required to be free.
592 CHAR8 mCommonLibFullPath
[MAX_LONG_FILE_PATH
];
601 Convert FileName to the long file path, which can support larger than 260 length.
607 LongFilePath A pointer to the converted long file path.
613 // __GNUC__ may not be good way to differentiate unix and windows. Need more investigation here.
614 // unix has no limitation on file path. Just return FileName.
622 PathPointer
= (CHAR8
*) FileName
;
624 if (FileName
!= NULL
) {
626 // Add the extension string first to support long file path.
628 mCommonLibFullPath
[0] = 0;
629 strcpy (mCommonLibFullPath
, WINDOWS_EXTENSION_PATH
);
631 if (strlen (FileName
) > 1 && FileName
[0] == '\\' && FileName
[1] == '\\') {
633 // network path like \\server\share to \\?\UNC\server\share
635 strcpy (mCommonLibFullPath
, WINDOWS_UNC_EXTENSION_PATH
);
637 } else if (strlen (FileName
) < 3 || FileName
[1] != ':' || (FileName
[2] != '\\' && FileName
[2] != '/')) {
639 // Relative file path. Convert it to absolute path.
641 RootPath
= getcwd (NULL
, 0);
642 if (RootPath
!= NULL
) {
643 if (strlen (mCommonLibFullPath
) + strlen (RootPath
) > MAX_LONG_FILE_PATH
- 1) {
644 Error (NULL
, 0, 2000, "Invalid parameter", "RootPath is too long!");
648 strncat (mCommonLibFullPath
, RootPath
, MAX_LONG_FILE_PATH
- strlen (mCommonLibFullPath
) - 1);
649 if (FileName
[0] != '\\' && FileName
[0] != '/') {
650 if (strlen (mCommonLibFullPath
) + 1 > MAX_LONG_FILE_PATH
- 1) {
651 Error (NULL
, 0, 2000, "Invalid parameter", "RootPath is too long!");
656 // Attach directory separator
658 strncat (mCommonLibFullPath
, "\\", MAX_LONG_FILE_PATH
- strlen (mCommonLibFullPath
) - 1);
665 // Construct the full file path
667 if (strlen (mCommonLibFullPath
) + strlen (FileName
) > MAX_LONG_FILE_PATH
- 1) {
668 Error (NULL
, 0, 2000, "Invalid parameter", "FileName %s is too long!", FileName
);
671 strncat (mCommonLibFullPath
, FileName
, MAX_LONG_FILE_PATH
- strlen (mCommonLibFullPath
) - 1);
674 // Convert directory separator '/' to '\\'
676 PathPointer
= (CHAR8
*) mCommonLibFullPath
;
678 if (*PathPointer
== '/') {
681 } while (*PathPointer
++ != '\0');
684 // Convert ":\\\\" to ":\\", because it doesn't work with WINDOWS_EXTENSION_PATH.
686 if ((PathPointer
= strstr (mCommonLibFullPath
, ":\\\\")) != NULL
) {
687 *(PathPointer
+ 2) = '\0';
688 strncat (mCommonLibFullPath
, PathPointer
+ 3, MAX_LONG_FILE_PATH
- strlen (mCommonLibFullPath
) - 1);
692 // Convert ".\\" to "", because it doesn't work with WINDOWS_EXTENSION_PATH.
694 while ((PathPointer
= strstr (mCommonLibFullPath
, ".\\")) != NULL
) {
696 strncat (mCommonLibFullPath
, PathPointer
+ 2, MAX_LONG_FILE_PATH
- strlen (mCommonLibFullPath
) - 1);
700 // Convert "\\.\\" to "\\", because it doesn't work with WINDOWS_EXTENSION_PATH.
702 while ((PathPointer
= strstr (mCommonLibFullPath
, "\\.\\")) != NULL
) {
704 strncat (mCommonLibFullPath
, PathPointer
+ 2, MAX_LONG_FILE_PATH
- strlen (mCommonLibFullPath
) - 1);
708 // Convert "\\..\\" to last directory, because it doesn't work with WINDOWS_EXTENSION_PATH.
710 while ((PathPointer
= strstr (mCommonLibFullPath
, "\\..\\")) != NULL
) {
711 NextPointer
= PathPointer
+ 3;
714 } while (PathPointer
> mCommonLibFullPath
&& *PathPointer
!= ':' && *PathPointer
!= '\\');
716 if (*PathPointer
== '\\') {
718 // Skip one directory
721 strncat (mCommonLibFullPath
, NextPointer
, MAX_LONG_FILE_PATH
- strlen (mCommonLibFullPath
) - 1);
724 // No directory is found. Just break.
730 PathPointer
= mCommonLibFullPath
;
738 InternalCharToUpper (
742 if (Char
>= L
'a' && Char
<= L
'z') {
743 return (CHAR16
) (Char
- (L
'a' - L
'A'));
751 CONST CHAR16
*String
,
757 ASSERT (((UINTN
) String
& BIT0
) == 0);
760 // If String is a null pointer or MaxSize is 0, then the StrnLenS function returns zero.
762 if ((String
== NULL
) || (MaxSize
== 0)) {
767 while (String
[Length
] != 0) {
768 if (Length
>= MaxSize
- 1) {
778 InternalAllocatePool (
784 Memory
= malloc(AllocationSize
);
785 ASSERT(Memory
!= NULL
);
791 InternalReallocatePool (
794 VOID
*OldBuffer OPTIONAL
799 NewBuffer
= AllocateZeroPool (NewSize
);
800 if (NewBuffer
!= NULL
&& OldBuffer
!= NULL
) {
801 memcpy (NewBuffer
, OldBuffer
, MIN (OldSize
, NewSize
));
811 VOID
*OldBuffer OPTIONAL
814 return InternalReallocatePool (OldSize
, NewSize
, OldBuffer
);
818 Returns the length of a Null-terminated Unicode string.
820 This function returns the number of Unicode characters in the Null-terminated
821 Unicode string specified by String.
823 If String is NULL, then ASSERT().
824 If String is not aligned on a 16-bit boundary, then ASSERT().
825 If PcdMaximumUnicodeStringLength is not zero, and String contains more than
826 PcdMaximumUnicodeStringLength Unicode characters, not including the
827 Null-terminator, then ASSERT().
829 @param String A pointer to a Null-terminated Unicode string.
831 @return The length of String.
841 ASSERT (String
!= NULL
);
842 ASSERT (((UINTN
) String
& BIT0
) == 0);
844 for (Length
= 0; *String
!= L
'\0'; String
++, Length
++) {
846 // If PcdMaximumUnicodeStringLength is not zero,
847 // length should not more than PcdMaximumUnicodeStringLength
854 InternalSafeStringIsOverlap (
861 if ((((UINTN
)Base1
>= (UINTN
)Base2
) && ((UINTN
)Base1
< (UINTN
)Base2
+ Size2
)) ||
862 (((UINTN
)Base2
>= (UINTN
)Base1
) && ((UINTN
)Base2
< (UINTN
)Base1
+ Size1
))) {
869 InternalSafeStringNoStrOverlap (
876 return !InternalSafeStringIsOverlap (Str1
, Size1
* sizeof(CHAR16
), Str2
, Size2
* sizeof(CHAR16
));
880 Convert a Null-terminated Unicode decimal string to a value of type UINT64.
882 This function outputs a value of type UINT64 by interpreting the contents of
883 the Unicode string specified by String as a decimal number. The format of the
884 input Unicode string String is:
886 [spaces] [decimal digits].
888 The valid decimal digit character is in the range [0-9]. The function will
889 ignore the pad space, which includes spaces or tab characters, before
890 [decimal digits]. The running zero in the beginning of [decimal digits] will
891 be ignored. Then, the function stops at the first character that is a not a
892 valid decimal character or a Null-terminator, whichever one comes first.
894 If String is NULL, then ASSERT().
895 If Data is NULL, then ASSERT().
896 If String is not aligned in a 16-bit boundary, then ASSERT().
897 If PcdMaximumUnicodeStringLength is not zero, and String contains more than
898 PcdMaximumUnicodeStringLength Unicode characters, not including the
899 Null-terminator, then ASSERT().
901 If String has no valid decimal digits in the above format, then 0 is stored
902 at the location pointed to by Data.
903 If the number represented by String exceeds the range defined by UINT64, then
904 MAX_UINT64 is stored at the location pointed to by Data.
906 If EndPointer is not NULL, a pointer to the character that stopped the scan
907 is stored at the location pointed to by EndPointer. If String has no valid
908 decimal digits right after the optional pad spaces, the value of String is
909 stored at the location pointed to by EndPointer.
911 @param String Pointer to a Null-terminated Unicode string.
912 @param EndPointer Pointer to character that stops scan.
913 @param Data Pointer to the converted value.
915 @retval RETURN_SUCCESS Value is translated from String.
916 @retval RETURN_INVALID_PARAMETER If String is NULL.
918 If PcdMaximumUnicodeStringLength is not
919 zero, and String contains more than
920 PcdMaximumUnicodeStringLength Unicode
921 characters, not including the
923 @retval RETURN_UNSUPPORTED If the number represented by String exceeds
924 the range defined by UINT64.
928 StrDecimalToUint64S (
929 CONST CHAR16
*String
,
930 CHAR16
**EndPointer
, OPTIONAL
934 ASSERT (((UINTN
) String
& BIT0
) == 0);
937 // 1. Neither String nor Data shall be a null pointer.
939 SAFE_STRING_CONSTRAINT_CHECK ((String
!= NULL
), RETURN_INVALID_PARAMETER
);
940 SAFE_STRING_CONSTRAINT_CHECK ((Data
!= NULL
), RETURN_INVALID_PARAMETER
);
943 // 2. The length of String shall not be greater than RSIZE_MAX.
945 if (RSIZE_MAX
!= 0) {
946 SAFE_STRING_CONSTRAINT_CHECK ((StrnLenS (String
, RSIZE_MAX
+ 1) <= RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
949 if (EndPointer
!= NULL
) {
950 *EndPointer
= (CHAR16
*) String
;
954 // Ignore the pad spaces (space or tab)
956 while ((*String
== L
' ') || (*String
== L
'\t')) {
961 // Ignore leading Zeros after the spaces
963 while (*String
== L
'0') {
969 while (InternalIsDecimalDigitCharacter (*String
)) {
971 // If the number represented by String overflows according to the range
972 // defined by UINT64, then MAX_UINT64 is stored in *Data and
973 // RETURN_UNSUPPORTED is returned.
975 if (*Data
> ((MAX_UINT64
- (*String
- L
'0'))/10)) {
977 if (EndPointer
!= NULL
) {
978 *EndPointer
= (CHAR16
*) String
;
980 return RETURN_UNSUPPORTED
;
983 *Data
= (*Data
) * 10 + (*String
- L
'0');
987 if (EndPointer
!= NULL
) {
988 *EndPointer
= (CHAR16
*) String
;
990 return RETURN_SUCCESS
;
994 Convert a Null-terminated Unicode hexadecimal string to a value of type
997 This function outputs a value of type UINT64 by interpreting the contents of
998 the Unicode string specified by String as a hexadecimal number. The format of
999 the input Unicode string String is:
1001 [spaces][zeros][x][hexadecimal digits].
1003 The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].
1004 The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix.
1005 If "x" appears in the input string, it must be prefixed with at least one 0.
1006 The function will ignore the pad space, which includes spaces or tab
1007 characters, before [zeros], [x] or [hexadecimal digit]. The running zero
1008 before [x] or [hexadecimal digit] will be ignored. Then, the decoding starts
1009 after [x] or the first valid hexadecimal digit. Then, the function stops at
1010 the first character that is a not a valid hexadecimal character or NULL,
1011 whichever one comes first.
1013 If String is NULL, then ASSERT().
1014 If Data is NULL, then ASSERT().
1015 If String is not aligned in a 16-bit boundary, then ASSERT().
1016 If PcdMaximumUnicodeStringLength is not zero, and String contains more than
1017 PcdMaximumUnicodeStringLength Unicode characters, not including the
1018 Null-terminator, then ASSERT().
1020 If String has no valid hexadecimal digits in the above format, then 0 is
1021 stored at the location pointed to by Data.
1022 If the number represented by String exceeds the range defined by UINT64, then
1023 MAX_UINT64 is stored at the location pointed to by Data.
1025 If EndPointer is not NULL, a pointer to the character that stopped the scan
1026 is stored at the location pointed to by EndPointer. If String has no valid
1027 hexadecimal digits right after the optional pad spaces, the value of String
1028 is stored at the location pointed to by EndPointer.
1030 @param String Pointer to a Null-terminated Unicode string.
1031 @param EndPointer Pointer to character that stops scan.
1032 @param Data Pointer to the converted value.
1034 @retval RETURN_SUCCESS Value is translated from String.
1035 @retval RETURN_INVALID_PARAMETER If String is NULL.
1037 If PcdMaximumUnicodeStringLength is not
1038 zero, and String contains more than
1039 PcdMaximumUnicodeStringLength Unicode
1040 characters, not including the
1042 @retval RETURN_UNSUPPORTED If the number represented by String exceeds
1043 the range defined by UINT64.
1048 CONST CHAR16
*String
,
1049 CHAR16
**EndPointer
, OPTIONAL
1053 ASSERT (((UINTN
) String
& BIT0
) == 0);
1056 // 1. Neither String nor Data shall be a null pointer.
1058 SAFE_STRING_CONSTRAINT_CHECK ((String
!= NULL
), RETURN_INVALID_PARAMETER
);
1059 SAFE_STRING_CONSTRAINT_CHECK ((Data
!= NULL
), RETURN_INVALID_PARAMETER
);
1062 // 2. The length of String shall not be greater than RSIZE_MAX.
1064 if (RSIZE_MAX
!= 0) {
1065 SAFE_STRING_CONSTRAINT_CHECK ((StrnLenS (String
, RSIZE_MAX
+ 1) <= RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
1068 if (EndPointer
!= NULL
) {
1069 *EndPointer
= (CHAR16
*) String
;
1073 // Ignore the pad spaces (space or tab)
1075 while ((*String
== L
' ') || (*String
== L
'\t')) {
1080 // Ignore leading Zeros after the spaces
1082 while (*String
== L
'0') {
1086 if (InternalCharToUpper (*String
) == L
'X') {
1087 if (*(String
- 1) != L
'0') {
1089 return RETURN_SUCCESS
;
1099 while (InternalIsHexaDecimalDigitCharacter (*String
)) {
1101 // If the number represented by String overflows according to the range
1102 // defined by UINT64, then MAX_UINT64 is stored in *Data and
1103 // RETURN_UNSUPPORTED is returned.
1105 if (*Data
> ((MAX_UINT64
- InternalHexCharToUintn (*String
))>>4)) {
1107 if (EndPointer
!= NULL
) {
1108 *EndPointer
= (CHAR16
*) String
;
1110 return RETURN_UNSUPPORTED
;
1113 *Data
= ((*Data
) << 4) + InternalHexCharToUintn (*String
);
1117 if (EndPointer
!= NULL
) {
1118 *EndPointer
= (CHAR16
*) String
;
1120 return RETURN_SUCCESS
;
1124 StrDecimalToUint64 (
1125 CONST CHAR16
*String
1130 StrDecimalToUint64S (String
, (CHAR16
**) NULL
, &Result
);
1137 CONST CHAR16
*String
1142 StrHexToUint64S (String
, (CHAR16
**) NULL
, &Result
);
1148 CONST CHAR16
*String
1151 return (StrLen (String
) + 1) * sizeof (*String
);
1157 CONST UINT64
*Buffer
1160 ASSERT (Buffer
!= NULL
);
1171 ASSERT (Buffer
!= NULL
);
1173 return *Buffer
= Value
;
1179 EFI_GUID
*DestinationGuid
,
1180 CONST EFI_GUID
*SourceGuid
1184 (UINT64
*)DestinationGuid
,
1185 ReadUnaligned64 ((CONST UINT64
*)SourceGuid
)
1188 (UINT64
*)DestinationGuid
+ 1,
1189 ReadUnaligned64 ((CONST UINT64
*)SourceGuid
+ 1)
1191 return DestinationGuid
;
1199 return (UINT16
) ((Value
<< 8) | (Value
>> 8));
1211 LowerBytes
= (UINT32
) SwapBytes16 ((UINT16
) Value
);
1212 HigherBytes
= (UINT32
) SwapBytes16 ((UINT16
) (Value
>> 16));
1213 return (LowerBytes
<< 16 | HigherBytes
);
1217 InternalIsDecimalDigitCharacter (
1221 return (BOOLEAN
) (Char
>= L
'0' && Char
<= L
'9');
1225 InternalAllocateCopyPool (
1226 UINTN AllocationSize
,
1232 ASSERT (Buffer
!= NULL
);
1234 Memory
= malloc (AllocationSize
);
1235 if (Memory
!= NULL
) {
1236 Memory
= memcpy (Memory
, Buffer
, AllocationSize
);
1242 InternalIsHexaDecimalDigitCharacter (
1247 return (BOOLEAN
) (InternalIsDecimalDigitCharacter (Char
) ||
1248 (Char
>= L
'A' && Char
<= L
'F') ||
1249 (Char
>= L
'a' && Char
<= L
'f'));
1253 InternalHexCharToUintn (
1257 if (InternalIsDecimalDigitCharacter (Char
)) {
1261 return (10 + InternalCharToUpper (Char
) - L
'A');
1266 Convert a Null-terminated Unicode hexadecimal string to a byte array.
1268 This function outputs a byte array by interpreting the contents of
1269 the Unicode string specified by String in hexadecimal format. The format of
1270 the input Unicode string String is:
1274 X is a hexadecimal digit character in the range [0-9], [a-f] and [A-F].
1275 The function decodes every two hexadecimal digit characters as one byte. The
1276 decoding stops after Length of characters and outputs Buffer containing
1279 If String is not aligned in a 16-bit boundary, then ASSERT().
1281 If String is NULL, then ASSERT().
1283 If Buffer is NULL, then ASSERT().
1285 If Length is not multiple of 2, then ASSERT().
1287 If PcdMaximumUnicodeStringLength is not zero and Length is greater than
1288 PcdMaximumUnicodeStringLength, then ASSERT().
1290 If MaxBufferSize is less than (Length / 2), then ASSERT().
1292 @param String Pointer to a Null-terminated Unicode string.
1293 @param Length The number of Unicode characters to decode.
1294 @param Buffer Pointer to the converted bytes array.
1295 @param MaxBufferSize The maximum size of Buffer.
1297 @retval RETURN_SUCCESS Buffer is translated from String.
1298 @retval RETURN_INVALID_PARAMETER If String is NULL.
1300 If Length is not multiple of 2.
1301 If PcdMaximumUnicodeStringLength is not zero,
1302 and Length is greater than
1303 PcdMaximumUnicodeStringLength.
1304 @retval RETURN_UNSUPPORTED If Length of characters from String contain
1305 a character that is not valid hexadecimal
1306 digit characters, or a Null-terminator.
1307 @retval RETURN_BUFFER_TOO_SMALL If MaxBufferSize is less than (Length / 2).
1311 CONST CHAR16
*String
,
1319 ASSERT (((UINTN
) String
& BIT0
) == 0);
1322 // 1. None of String or Buffer shall be a null pointer.
1324 SAFE_STRING_CONSTRAINT_CHECK ((String
!= NULL
), RETURN_INVALID_PARAMETER
);
1325 SAFE_STRING_CONSTRAINT_CHECK ((Buffer
!= NULL
), RETURN_INVALID_PARAMETER
);
1328 // 2. Length shall not be greater than RSIZE_MAX.
1330 if (RSIZE_MAX
!= 0) {
1331 SAFE_STRING_CONSTRAINT_CHECK ((Length
<= RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
1335 // 3. Length shall not be odd.
1337 SAFE_STRING_CONSTRAINT_CHECK (((Length
& BIT0
) == 0), RETURN_INVALID_PARAMETER
);
1340 // 4. MaxBufferSize shall equal to or greater than Length / 2.
1342 SAFE_STRING_CONSTRAINT_CHECK ((MaxBufferSize
>= Length
/ 2), RETURN_BUFFER_TOO_SMALL
);
1345 // 5. String shall not contains invalid hexadecimal digits.
1347 for (Index
= 0; Index
< Length
; Index
++) {
1348 if (!InternalIsHexaDecimalDigitCharacter (String
[Index
])) {
1352 if (Index
!= Length
) {
1353 return RETURN_UNSUPPORTED
;
1357 // Convert the hex string to bytes.
1359 for(Index
= 0; Index
< Length
; Index
++) {
1362 // For even characters, write the upper nibble for each buffer byte,
1363 // and for even characters, the lower nibble.
1365 if ((Index
& BIT0
) == 0) {
1366 Buffer
[Index
/ 2] = (UINT8
) InternalHexCharToUintn (String
[Index
]) << 4;
1368 Buffer
[Index
/ 2] |= (UINT8
) InternalHexCharToUintn (String
[Index
]);
1371 return RETURN_SUCCESS
;
1375 Convert a Null-terminated Unicode GUID string to a value of type
1378 This function outputs a GUID value by interpreting the contents of
1379 the Unicode string specified by String. The format of the input
1380 Unicode string String consists of 36 characters, as follows:
1382 aabbccdd-eeff-gghh-iijj-kkllmmnnoopp
1384 The pairs aa - pp are two characters in the range [0-9], [a-f] and
1385 [A-F], with each pair representing a single byte hexadecimal value.
1387 The mapping between String and the EFI_GUID structure is as follows:
1405 If String is NULL, then ASSERT().
1406 If Guid is NULL, then ASSERT().
1407 If String is not aligned in a 16-bit boundary, then ASSERT().
1409 @param String Pointer to a Null-terminated Unicode string.
1410 @param Guid Pointer to the converted GUID.
1412 @retval RETURN_SUCCESS Guid is translated from String.
1413 @retval RETURN_INVALID_PARAMETER If String is NULL.
1415 @retval RETURN_UNSUPPORTED If String is not as the above format.
1420 CONST CHAR16
*String
,
1424 RETURN_STATUS Status
;
1427 ASSERT (((UINTN
) String
& BIT0
) == 0);
1430 // 1. None of String or Guid shall be a null pointer.
1432 SAFE_STRING_CONSTRAINT_CHECK ((String
!= NULL
), RETURN_INVALID_PARAMETER
);
1433 SAFE_STRING_CONSTRAINT_CHECK ((Guid
!= NULL
), RETURN_INVALID_PARAMETER
);
1436 // Get aabbccdd in big-endian.
1438 Status
= StrHexToBytes (String
, 2 * sizeof (LocalGuid
.Data1
), (UINT8
*) &LocalGuid
.Data1
, sizeof (LocalGuid
.Data1
));
1439 if (RETURN_ERROR (Status
) || String
[2 * sizeof (LocalGuid
.Data1
)] != L
'-') {
1440 return RETURN_UNSUPPORTED
;
1443 // Convert big-endian to little-endian.
1445 LocalGuid
.Data1
= SwapBytes32 (LocalGuid
.Data1
);
1446 String
+= 2 * sizeof (LocalGuid
.Data1
) + 1;
1449 // Get eeff in big-endian.
1451 Status
= StrHexToBytes (String
, 2 * sizeof (LocalGuid
.Data2
), (UINT8
*) &LocalGuid
.Data2
, sizeof (LocalGuid
.Data2
));
1452 if (RETURN_ERROR (Status
) || String
[2 * sizeof (LocalGuid
.Data2
)] != L
'-') {
1453 return RETURN_UNSUPPORTED
;
1456 // Convert big-endian to little-endian.
1458 LocalGuid
.Data2
= SwapBytes16 (LocalGuid
.Data2
);
1459 String
+= 2 * sizeof (LocalGuid
.Data2
) + 1;
1462 // Get gghh in big-endian.
1464 Status
= StrHexToBytes (String
, 2 * sizeof (LocalGuid
.Data3
), (UINT8
*) &LocalGuid
.Data3
, sizeof (LocalGuid
.Data3
));
1465 if (RETURN_ERROR (Status
) || String
[2 * sizeof (LocalGuid
.Data3
)] != L
'-') {
1466 return RETURN_UNSUPPORTED
;
1469 // Convert big-endian to little-endian.
1471 LocalGuid
.Data3
= SwapBytes16 (LocalGuid
.Data3
);
1472 String
+= 2 * sizeof (LocalGuid
.Data3
) + 1;
1477 Status
= StrHexToBytes (String
, 2 * 2, &LocalGuid
.Data4
[0], 2);
1478 if (RETURN_ERROR (Status
) || String
[2 * 2] != L
'-') {
1479 return RETURN_UNSUPPORTED
;
1481 String
+= 2 * 2 + 1;
1484 // Get kkllmmnnoopp.
1486 Status
= StrHexToBytes (String
, 2 * 6, &LocalGuid
.Data4
[2], 6);
1487 if (RETURN_ERROR (Status
)) {
1488 return RETURN_UNSUPPORTED
;
1491 CopyGuid (Guid
, &LocalGuid
);
1492 return RETURN_SUCCESS
;
1496 Compares up to a specified length the contents of two Null-terminated Unicode strings,
1497 and returns the difference between the first mismatched Unicode characters.
1499 This function compares the Null-terminated Unicode string FirstString to the
1500 Null-terminated Unicode string SecondString. At most, Length Unicode
1501 characters will be compared. If Length is 0, then 0 is returned. If
1502 FirstString is identical to SecondString, then 0 is returned. Otherwise, the
1503 value returned is the first mismatched Unicode character in SecondString
1504 subtracted from the first mismatched Unicode character in FirstString.
1506 If Length > 0 and FirstString is NULL, then ASSERT().
1507 If Length > 0 and FirstString is not aligned on a 16-bit boundary, then ASSERT().
1508 If Length > 0 and SecondString is NULL, then ASSERT().
1509 If Length > 0 and SecondString is not aligned on a 16-bit boundary, then ASSERT().
1510 If PcdMaximumUnicodeStringLength is not zero, and Length is greater than
1511 PcdMaximumUnicodeStringLength, then ASSERT().
1512 If PcdMaximumUnicodeStringLength is not zero, and FirstString contains more than
1513 PcdMaximumUnicodeStringLength Unicode characters, not including the Null-terminator,
1515 If PcdMaximumUnicodeStringLength is not zero, and SecondString contains more than
1516 PcdMaximumUnicodeStringLength Unicode characters, not including the Null-terminator,
1519 @param FirstString A pointer to a Null-terminated Unicode string.
1520 @param SecondString A pointer to a Null-terminated Unicode string.
1521 @param Length The maximum number of Unicode characters to compare.
1523 @retval 0 FirstString is identical to SecondString.
1524 @return others FirstString is not identical to SecondString.
1529 CONST CHAR16
*FirstString
,
1530 CONST CHAR16
*SecondString
,
1539 // ASSERT both strings are less long than PcdMaximumUnicodeStringLength.
1540 // Length tests are performed inside StrLen().
1542 ASSERT (StrSize (FirstString
) != 0);
1543 ASSERT (StrSize (SecondString
) != 0);
1545 while ((*FirstString
!= L
'\0') &&
1546 (*SecondString
!= L
'\0') &&
1547 (*FirstString
== *SecondString
) &&
1554 return *FirstString
- *SecondString
;
1559 UINTN AllocationSize
,
1563 return InternalAllocateCopyPool (AllocationSize
, Buffer
);
1568 CONST CHAR16
*FirstString
,
1569 CONST CHAR16
*SecondString
1573 // ASSERT both strings are less long than PcdMaximumUnicodeStringLength
1575 ASSERT (StrSize (FirstString
) != 0);
1576 ASSERT (StrSize (SecondString
) != 0);
1578 while ((*FirstString
!= L
'\0') && (*FirstString
== *SecondString
)) {
1582 return *FirstString
- *SecondString
;
1590 return InternalMathSwapBytes64 (Value
);
1594 InternalMathSwapBytes64 (
1601 LowerBytes
= (UINT64
) SwapBytes32 ((UINT32
) Operand
);
1602 HigherBytes
= (UINT64
) SwapBytes32 ((UINT32
) (Operand
>> 32));
1604 return (LowerBytes
<< 32 | HigherBytes
);
1609 CONST CHAR16
*String
,
1610 CHAR16
**EndPointer
,
1611 EFI_IPv4_ADDRESS
*Address
,
1615 RETURN_STATUS Status
;
1618 EFI_IPv4_ADDRESS LocalAddress
;
1619 UINT8 LocalPrefixLength
;
1622 LocalPrefixLength
= MAX_UINT8
;
1623 LocalAddress
.Addr
[0] = 0;
1625 ASSERT (((UINTN
) String
& BIT0
) == 0);
1628 // 1. None of String or Guid shall be a null pointer.
1630 SAFE_STRING_CONSTRAINT_CHECK ((String
!= NULL
), RETURN_INVALID_PARAMETER
);
1631 SAFE_STRING_CONSTRAINT_CHECK ((Address
!= NULL
), RETURN_INVALID_PARAMETER
);
1633 for (Pointer
= (CHAR16
*) String
, AddressIndex
= 0; AddressIndex
< ARRAY_SIZE (Address
->Addr
) + 1;) {
1634 if (!InternalIsDecimalDigitCharacter (*Pointer
)) {
1636 // D or P contains invalid characters.
1644 Status
= StrDecimalToUint64S ((CONST CHAR16
*) Pointer
, &Pointer
, &Uint64
);
1645 if (RETURN_ERROR (Status
)) {
1646 return RETURN_UNSUPPORTED
;
1648 if (AddressIndex
== ARRAY_SIZE (Address
->Addr
)) {
1653 return RETURN_UNSUPPORTED
;
1655 LocalPrefixLength
= (UINT8
) Uint64
;
1660 if (Uint64
> MAX_UINT8
) {
1661 return RETURN_UNSUPPORTED
;
1663 LocalAddress
.Addr
[AddressIndex
] = (UINT8
) Uint64
;
1668 // Check the '.' or '/', depending on the AddressIndex.
1670 if (AddressIndex
== ARRAY_SIZE (Address
->Addr
)) {
1671 if (*Pointer
== L
'/') {
1673 // '/P' is in the String.
1674 // Skip "/" and get P in next loop.
1679 // '/P' is not in the String.
1683 } else if (AddressIndex
< ARRAY_SIZE (Address
->Addr
)) {
1684 if (*Pointer
== L
'.') {
1686 // D should be followed by '.'
1690 return RETURN_UNSUPPORTED
;
1695 if (AddressIndex
< ARRAY_SIZE (Address
->Addr
)) {
1696 return RETURN_UNSUPPORTED
;
1699 memcpy (Address
, &LocalAddress
, sizeof (*Address
));
1700 if (PrefixLength
!= NULL
) {
1701 *PrefixLength
= LocalPrefixLength
;
1703 if (EndPointer
!= NULL
) {
1704 *EndPointer
= Pointer
;
1707 return RETURN_SUCCESS
;
1712 CONST CHAR16
*String
,
1713 CHAR16
**EndPointer
,
1714 EFI_IPv6_ADDRESS
*Address
,
1718 RETURN_STATUS Status
;
1721 EFI_IPv6_ADDRESS LocalAddress
;
1722 UINT8 LocalPrefixLength
;
1723 CONST CHAR16
*Pointer
;
1725 UINTN CompressStart
;
1726 BOOLEAN ExpectPrefix
;
1728 LocalPrefixLength
= MAX_UINT8
;
1729 CompressStart
= ARRAY_SIZE (Address
->Addr
);
1730 ExpectPrefix
= FALSE
;
1732 ASSERT (((UINTN
) String
& BIT0
) == 0);
1735 // 1. None of String or Guid shall be a null pointer.
1737 SAFE_STRING_CONSTRAINT_CHECK ((String
!= NULL
), RETURN_INVALID_PARAMETER
);
1738 SAFE_STRING_CONSTRAINT_CHECK ((Address
!= NULL
), RETURN_INVALID_PARAMETER
);
1740 for (Pointer
= String
, AddressIndex
= 0; AddressIndex
< ARRAY_SIZE (Address
->Addr
) + 1;) {
1741 if (!InternalIsHexaDecimalDigitCharacter (*Pointer
)) {
1742 if (*Pointer
!= L
':') {
1744 // ":" or "/" should be followed by digit characters.
1746 return RETURN_UNSUPPORTED
;
1750 // Meet second ":" after previous ":" or "/"
1751 // or meet first ":" in the beginning of String.
1755 // ":" shall not be after "/"
1757 return RETURN_UNSUPPORTED
;
1760 if (CompressStart
!= ARRAY_SIZE (Address
->Addr
) || AddressIndex
== ARRAY_SIZE (Address
->Addr
)) {
1762 // "::" can only appear once.
1763 // "::" can only appear when address is not full length.
1765 return RETURN_UNSUPPORTED
;
1768 // Remember the start of zero compressing.
1770 CompressStart
= AddressIndex
;
1773 if (CompressStart
== 0) {
1774 if (*Pointer
!= L
':') {
1776 // Single ":" shall not be in the beginning of String.
1778 return RETURN_UNSUPPORTED
;
1785 if (!InternalIsHexaDecimalDigitCharacter (*Pointer
)) {
1786 if (*Pointer
== L
'/') {
1788 // Might be optional "/P" after "::".
1790 if (CompressStart
!= AddressIndex
) {
1791 return RETURN_UNSUPPORTED
;
1797 if (!ExpectPrefix
) {
1801 Status
= StrHexToUint64S (Pointer
, &End
, &Uint64
);
1802 if (RETURN_ERROR (Status
) || End
- Pointer
> 4) {
1804 // Number of hexadecimal digit characters is no more than 4.
1806 return RETURN_UNSUPPORTED
;
1810 // Uint64 won't exceed MAX_UINT16 if number of hexadecimal digit characters is no more than 4.
1812 ASSERT (AddressIndex
+ 1 < ARRAY_SIZE (Address
->Addr
));
1813 LocalAddress
.Addr
[AddressIndex
] = (UINT8
) ((UINT16
) Uint64
>> 8);
1814 LocalAddress
.Addr
[AddressIndex
+ 1] = (UINT8
) Uint64
;
1818 // Get P, then exit the loop.
1820 Status
= StrDecimalToUint64S (Pointer
, &End
, &Uint64
);
1821 if (RETURN_ERROR (Status
) || End
== Pointer
|| Uint64
> 128) {
1823 // Prefix length should not exceed 128.
1825 return RETURN_UNSUPPORTED
;
1827 LocalPrefixLength
= (UINT8
) Uint64
;
1836 if (*Pointer
== L
'/') {
1837 ExpectPrefix
= TRUE
;
1838 } else if (*Pointer
== L
':') {
1839 if (AddressIndex
== ARRAY_SIZE (Address
->Addr
)) {
1841 // Meet additional ":" after all 8 16-bit address
1847 // Meet other character that is not "/" or ":" after all 8 16-bit address
1854 if ((AddressIndex
== ARRAY_SIZE (Address
->Addr
) && CompressStart
!= ARRAY_SIZE (Address
->Addr
)) ||
1855 (AddressIndex
!= ARRAY_SIZE (Address
->Addr
) && CompressStart
== ARRAY_SIZE (Address
->Addr
))
1858 // Full length of address shall not have compressing zeros.
1859 // Non-full length of address shall have compressing zeros.
1861 return RETURN_UNSUPPORTED
;
1863 memcpy (&Address
->Addr
[0], &LocalAddress
.Addr
[0], CompressStart
);
1864 if (AddressIndex
> CompressStart
) {
1865 memset (&Address
->Addr
[CompressStart
], 0, ARRAY_SIZE (Address
->Addr
) - AddressIndex
);
1867 &Address
->Addr
[CompressStart
+ ARRAY_SIZE (Address
->Addr
) - AddressIndex
],
1868 &LocalAddress
.Addr
[CompressStart
],
1869 AddressIndex
- CompressStart
1873 if (PrefixLength
!= NULL
) {
1874 *PrefixLength
= LocalPrefixLength
;
1876 if (EndPointer
!= NULL
) {
1877 *EndPointer
= (CHAR16
*) Pointer
;
1880 return RETURN_SUCCESS
;
1885 UnicodeStrToAsciiStrS (
1886 CONST CHAR16
*Source
,
1893 ASSERT (((UINTN
) Source
& BIT0
) == 0);
1896 // 1. Neither Destination nor Source shall be a null pointer.
1898 SAFE_STRING_CONSTRAINT_CHECK ((Destination
!= NULL
), RETURN_INVALID_PARAMETER
);
1899 SAFE_STRING_CONSTRAINT_CHECK ((Source
!= NULL
), RETURN_INVALID_PARAMETER
);
1902 // 2. DestMax shall not be greater than ASCII_RSIZE_MAX or RSIZE_MAX.
1904 if (ASCII_RSIZE_MAX
!= 0) {
1905 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
<= ASCII_RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
1907 if (RSIZE_MAX
!= 0) {
1908 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
<= RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
1912 // 3. DestMax shall not equal zero.
1914 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
!= 0), RETURN_INVALID_PARAMETER
);
1917 // 4. DestMax shall be greater than StrnLenS (Source, DestMax).
1919 SourceLen
= StrnLenS (Source
, DestMax
);
1920 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
> SourceLen
), RETURN_BUFFER_TOO_SMALL
);
1923 // 5. Copying shall not take place between objects that overlap.
1925 SAFE_STRING_CONSTRAINT_CHECK (!InternalSafeStringIsOverlap (Destination
, DestMax
, (VOID
*)Source
, (SourceLen
+ 1) * sizeof(CHAR16
)), RETURN_ACCESS_DENIED
);
1930 while (*Source
!= '\0') {
1932 // If any Unicode characters in Source contain
1933 // non-zero value in the upper 8 bits, then ASSERT().
1935 ASSERT (*Source
< 0x100);
1936 *(Destination
++) = (CHAR8
) *(Source
++);
1938 *Destination
= '\0';
1940 return RETURN_SUCCESS
;
1945 CHAR16
*Destination
,
1947 CONST CHAR16
*Source
1952 ASSERT (((UINTN
) Destination
& BIT0
) == 0);
1953 ASSERT (((UINTN
) Source
& BIT0
) == 0);
1956 // 1. Neither Destination nor Source shall be a null pointer.
1958 SAFE_STRING_CONSTRAINT_CHECK ((Destination
!= NULL
), RETURN_INVALID_PARAMETER
);
1959 SAFE_STRING_CONSTRAINT_CHECK ((Source
!= NULL
), RETURN_INVALID_PARAMETER
);
1962 // 2. DestMax shall not be greater than RSIZE_MAX.
1964 if (RSIZE_MAX
!= 0) {
1965 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
<= RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
1969 // 3. DestMax shall not equal zero.
1971 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
!= 0), RETURN_INVALID_PARAMETER
);
1974 // 4. DestMax shall be greater than StrnLenS(Source, DestMax).
1976 SourceLen
= StrnLenS (Source
, DestMax
);
1977 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
> SourceLen
), RETURN_BUFFER_TOO_SMALL
);
1980 // 5. Copying shall not take place between objects that overlap.
1982 SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoStrOverlap (Destination
, DestMax
, (CHAR16
*)Source
, SourceLen
+ 1), RETURN_ACCESS_DENIED
);
1985 // The StrCpyS function copies the string pointed to by Source (including the terminating
1986 // null character) into the array pointed to by Destination.
1988 while (*Source
!= 0) {
1989 *(Destination
++) = *(Source
++);
1993 return RETURN_SUCCESS
;
1998 UINTN AllocationSize
2002 Memory
= malloc(AllocationSize
);
2003 ASSERT (Memory
!= NULL
);
2004 if (Memory
== NULL
) {
2005 fprintf(stderr
, "Not memory for malloc\n");
2007 memset(Memory
, 0, AllocationSize
);
2013 UINTN AllocationSize
2016 return InternalAllocatePool (AllocationSize
);
2025 ASSERT (Buffer
!= NULL
);
2027 return *Buffer
= Value
;
2032 CONST UINT16
*Buffer
2035 ASSERT (Buffer
!= NULL
);
2040 Return whether the integer string is a hex string.
2042 @param Str The integer string
2044 @retval TRUE Hex string
2045 @retval FALSE Decimal string
2054 // skip preceding white space
2056 while ((*Str
!= 0) && *Str
== L
' ') {
2060 // skip preceding zeros
2062 while ((*Str
!= 0) && *Str
== L
'0') {
2066 return (BOOLEAN
) (*Str
== L
'x' || *Str
== L
'X');
2071 Convert integer string to uint.
2073 @param Str The integer string. If leading with "0x" or "0X", it's hexadecimal.
2075 @return A UINTN value represented by Str
2083 if (IsHexStr (Str
)) {
2084 return (UINTN
)StrHexToUint64 (Str
);
2086 return (UINTN
)StrDecimalToUint64 (Str
);
2092 Convert integer string to 64 bit data.
2094 @param Str The integer string. If leading with "0x" or "0X", it's hexadecimal.
2095 @param Data A pointer to the UINT64 value represented by Str
2104 if (IsHexStr (Str
)) {
2105 *Data
= StrHexToUint64 (Str
);
2107 *Data
= StrDecimalToUint64 (Str
);
2112 Converts a Unicode string to ASCII string.
2114 @param Str The equivalent Unicode string
2115 @param AsciiStr On input, it points to destination ASCII string buffer; on output, it points
2116 to the next ASCII string next to it
2128 while (!IS_NULL (*Str
)) {
2129 *(Dest
++) = (CHAR8
) *(Str
++);
2134 // Return the string next to it
2136 *AsciiStr
= Dest
+ 1;
2140 Gets current sub-string from a string list, before return
2141 the list header is moved to next sub-string. The sub-string is separated
2142 by the specified character. For example, the separator is ',', the string
2143 list is "2,0,3", it returns "2", the remain list move to "0,3"
2145 @param List A string list separated by the specified separator
2146 @param Separator The separator character
2148 @return A pointer to the current sub-string
2163 if (IS_NULL (*Str
)) {
2168 // Find first occurrence of the separator
2170 while (!IS_NULL (*Str
)) {
2171 if (*Str
== Separator
) {
2177 if (*Str
== Separator
) {
2179 // Find a sub-string, terminate it
2186 // Move to next sub-string