2 Common basic Library Functions
4 Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
24 #include "CommonLib.h"
25 #include "EfiUtilityMsgs.h"
27 #define SAFE_STRING_CONSTRAINT_CHECK(Expression, Status) \
29 ASSERT (Expression); \
30 if (!(Expression)) { \
44 Set Buffer to zero for Size bytes.
48 Buffer - Memory to set.
50 Size - Number of bytes to set
76 Copy Length bytes from Source to Destination.
80 Destination - Target of copy
82 Source - Place to copy from
84 Length - Number of bytes to copy
95 Destination8
= Destination
;
98 *(Destination8
++) = *(Source8
++);
108 PeiZeroMem (Buffer
, Size
);
113 IN VOID
*Destination
,
118 PeiCopyMem (Destination
, Source
, Length
);
134 Guid1 - guid to compare
135 Guid2 - guid to compare
138 = 0 if Guid1 == Guid2
139 != 0 if Guid1 != Guid2
148 // Compare 32 bits at a time
150 g1
= (INT32
*) Guid1
;
151 g2
= (INT32
*) Guid2
;
164 IN CHAR8
*InputFileName
,
165 OUT CHAR8
**InputFileImage
,
166 OUT UINT32
*BytesRead
172 This function opens a file and reads it into a memory buffer. The function
173 will allocate the memory buffer and returns the size of the buffer.
177 InputFileName The name of the file to read.
178 InputFileImage A pointer to the memory buffer.
179 BytesRead The size of the memory buffer.
183 EFI_SUCCESS The function completed successfully.
184 EFI_INVALID_PARAMETER One of the input parameters was invalid.
185 EFI_ABORTED An error occurred.
186 EFI_OUT_OF_RESOURCES No resource to complete operations.
194 // Verify input parameters.
196 if (InputFileName
== NULL
|| strlen (InputFileName
) == 0 || InputFileImage
== NULL
) {
197 return EFI_INVALID_PARAMETER
;
200 // Open the file and copy contents into a memory buffer.
205 InputFile
= fopen (LongFilePath (InputFileName
), "rb");
206 if (InputFile
== NULL
) {
207 Error (NULL
, 0, 0001, "Error opening the input file", InputFileName
);
211 // Go to the end so that we can determine the file size
213 if (fseek (InputFile
, 0, SEEK_END
)) {
214 Error (NULL
, 0, 0004, "Error reading the input file", InputFileName
);
221 FileSize
= ftell (InputFile
);
222 if (FileSize
== -1) {
223 Error (NULL
, 0, 0003, "Error parsing the input file", InputFileName
);
230 *InputFileImage
= malloc (FileSize
);
231 if (*InputFileImage
== NULL
) {
233 return EFI_OUT_OF_RESOURCES
;
236 // Reset to the beginning of the file
238 if (fseek (InputFile
, 0, SEEK_SET
)) {
239 Error (NULL
, 0, 0004, "Error reading the input file", InputFileName
);
241 free (*InputFileImage
);
242 *InputFileImage
= NULL
;
246 // Read all of the file contents.
248 *BytesRead
= fread (*InputFileImage
, sizeof (UINT8
), FileSize
, InputFile
);
249 if (*BytesRead
!= sizeof (UINT8
) * FileSize
) {
250 Error (NULL
, 0, 0004, "Error reading the input file", InputFileName
);
252 free (*InputFileImage
);
253 *InputFileImage
= NULL
;
266 IN CHAR8
*OutputFileName
,
267 IN CHAR8
*OutputFileImage
,
268 IN UINT32 BytesToWrite
274 This function opens a file and writes OutputFileImage into the file.
278 OutputFileName The name of the file to write.
279 OutputFileImage A pointer to the memory buffer.
280 BytesToWrite The size of the memory buffer.
284 EFI_SUCCESS The function completed successfully.
285 EFI_INVALID_PARAMETER One of the input parameters was invalid.
286 EFI_ABORTED An error occurred.
287 EFI_OUT_OF_RESOURCES No resource to complete operations.
295 // Verify input parameters.
297 if (OutputFileName
== NULL
|| strlen (OutputFileName
) == 0 || OutputFileImage
== NULL
) {
298 return EFI_INVALID_PARAMETER
;
301 // Open the file and copy contents into a memory buffer.
306 OutputFile
= fopen (LongFilePath (OutputFileName
), "wb");
307 if (OutputFile
== NULL
) {
308 Error (NULL
, 0, 0001, "Error opening the output file", OutputFileName
);
313 // Write all of the file contents.
315 BytesWrote
= fwrite (OutputFileImage
, sizeof (UINT8
), BytesToWrite
, OutputFile
);
316 if (BytesWrote
!= sizeof (UINT8
) * BytesToWrite
) {
317 Error (NULL
, 0, 0002, "Error writing the output file", OutputFileName
);
338 This function calculates the value needed for a valid UINT8 checksum
342 Buffer Pointer to buffer containing byte data of component.
343 Size Size of the buffer
347 The 8 bit checksum value needed.
351 return (UINT8
) (0x100 - CalculateSum8 (Buffer
, Size
));
361 Routine Description::
363 This function calculates the UINT8 sum for the requested region.
367 Buffer Pointer to buffer containing byte data of component.
368 Size Size of the buffer
372 The 8 bit checksum value needed.
382 // Perform the byte sum for buffer
384 for (Index
= 0; Index
< Size
; Index
++) {
385 Sum
= (UINT8
) (Sum
+ Buffer
[Index
]);
392 CalculateChecksum16 (
398 Routine Description::
400 This function calculates the value needed for a valid UINT16 checksum
404 Buffer Pointer to buffer containing byte data of component.
405 Size Size of the buffer
409 The 16 bit checksum value needed.
413 return (UINT16
) (0x10000 - CalculateSum16 (Buffer
, Size
));
425 This function calculates the UINT16 sum for the requested region.
429 Buffer Pointer to buffer containing byte data of component.
430 Size Size of the buffer
444 // Perform the word sum for buffer
446 for (Index
= 0; Index
< Size
; Index
++) {
447 Sum
= (UINT16
) (Sum
+ Buffer
[Index
]);
461 This function prints a GUID to STDOUT.
465 Guid Pointer to a GUID to print.
469 EFI_SUCCESS The GUID was printed.
470 EFI_INVALID_PARAMETER The input was NULL.
475 Error (NULL
, 0, 2000, "Invalid parameter", "PrintGuidToBuffer() called with a NULL value");
476 return EFI_INVALID_PARAMETER
;
480 "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x\n",
481 (unsigned) Guid
->Data1
,
499 IN OUT UINT8
*Buffer
,
507 This function prints a GUID to a buffer
511 Guid - Pointer to a GUID to print.
512 Buffer - Pointer to a user-provided buffer to print to
513 BufferLen - Size of the Buffer
514 Uppercase - If use upper case.
518 EFI_SUCCESS The GUID was printed.
519 EFI_INVALID_PARAMETER The input was NULL.
520 EFI_BUFFER_TOO_SMALL The input buffer was not big enough
525 Error (NULL
, 0, 2000, "Invalid parameter", "PrintGuidToBuffer() called with a NULL value");
526 return EFI_INVALID_PARAMETER
;
529 if (BufferLen
< PRINTED_GUID_BUFFER_SIZE
) {
530 Error (NULL
, 0, 2000, "Invalid parameter", "PrintGuidToBuffer() called with invalid buffer size");
531 return EFI_BUFFER_TOO_SMALL
;
537 "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X",
538 (unsigned) Guid
->Data1
,
553 "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
554 (unsigned) Guid
->Data1
,
573 size_t _filelength(int fd
)
575 struct stat stat_buf
;
576 fstat(fd
, &stat_buf
);
577 return stat_buf
.st_size
;
581 char *strlwr(char *s
)
592 #define WINDOWS_EXTENSION_PATH "\\\\?\\"
593 #define WINDOWS_UNC_EXTENSION_PATH "\\\\?\\UNC"
596 // Global data to store full file path. It is not required to be free.
598 CHAR8 mCommonLibFullPath
[MAX_LONG_FILE_PATH
];
607 Convert FileName to the long file path, which can support larger than 260 length.
613 LongFilePath A pointer to the converted long file path.
619 // __GNUC__ may not be good way to differentiate unix and windows. Need more investigation here.
620 // unix has no limitation on file path. Just return FileName.
628 PathPointer
= (CHAR8
*) FileName
;
630 if (FileName
!= NULL
) {
632 // Add the extension string first to support long file path.
634 mCommonLibFullPath
[0] = 0;
635 strcpy (mCommonLibFullPath
, WINDOWS_EXTENSION_PATH
);
637 if (strlen (FileName
) > 1 && FileName
[0] == '\\' && FileName
[1] == '\\') {
639 // network path like \\server\share to \\?\UNC\server\share
641 strcpy (mCommonLibFullPath
, WINDOWS_UNC_EXTENSION_PATH
);
643 } else if (strlen (FileName
) < 3 || FileName
[1] != ':' || (FileName
[2] != '\\' && FileName
[2] != '/')) {
645 // Relative file path. Convert it to absolute path.
647 RootPath
= getcwd (NULL
, 0);
648 if (RootPath
!= NULL
) {
649 if (strlen (mCommonLibFullPath
) + strlen (RootPath
) > MAX_LONG_FILE_PATH
- 1) {
650 Error (NULL
, 0, 2000, "Invalid parameter", "RootPath is too long!");
654 strncat (mCommonLibFullPath
, RootPath
, MAX_LONG_FILE_PATH
- strlen (mCommonLibFullPath
) - 1);
655 if (FileName
[0] != '\\' && FileName
[0] != '/') {
656 if (strlen (mCommonLibFullPath
) + 1 > MAX_LONG_FILE_PATH
- 1) {
657 Error (NULL
, 0, 2000, "Invalid parameter", "RootPath is too long!");
662 // Attach directory separator
664 strncat (mCommonLibFullPath
, "\\", MAX_LONG_FILE_PATH
- strlen (mCommonLibFullPath
) - 1);
671 // Construct the full file path
673 if (strlen (mCommonLibFullPath
) + strlen (FileName
) > MAX_LONG_FILE_PATH
- 1) {
674 Error (NULL
, 0, 2000, "Invalid parameter", "FileName %s is too long!", FileName
);
677 strncat (mCommonLibFullPath
, FileName
, MAX_LONG_FILE_PATH
- strlen (mCommonLibFullPath
) - 1);
680 // Convert directory separator '/' to '\\'
682 PathPointer
= (CHAR8
*) mCommonLibFullPath
;
684 if (*PathPointer
== '/') {
687 } while (*PathPointer
++ != '\0');
690 // Convert ":\\\\" to ":\\", because it doesn't work with WINDOWS_EXTENSION_PATH.
692 if ((PathPointer
= strstr (mCommonLibFullPath
, ":\\\\")) != NULL
) {
693 *(PathPointer
+ 2) = '\0';
694 strncat (mCommonLibFullPath
, PathPointer
+ 3, MAX_LONG_FILE_PATH
- strlen (mCommonLibFullPath
) - 1);
698 // Convert ".\\" to "", because it doesn't work with WINDOWS_EXTENSION_PATH.
700 while ((PathPointer
= strstr (mCommonLibFullPath
, ".\\")) != NULL
) {
702 strncat (mCommonLibFullPath
, PathPointer
+ 2, MAX_LONG_FILE_PATH
- strlen (mCommonLibFullPath
) - 1);
706 // Convert "\\.\\" to "\\", because it doesn't work with WINDOWS_EXTENSION_PATH.
708 while ((PathPointer
= strstr (mCommonLibFullPath
, "\\.\\")) != NULL
) {
710 strncat (mCommonLibFullPath
, PathPointer
+ 2, MAX_LONG_FILE_PATH
- strlen (mCommonLibFullPath
) - 1);
714 // Convert "\\..\\" to last directory, because it doesn't work with WINDOWS_EXTENSION_PATH.
716 while ((PathPointer
= strstr (mCommonLibFullPath
, "\\..\\")) != NULL
) {
717 NextPointer
= PathPointer
+ 3;
720 } while (PathPointer
> mCommonLibFullPath
&& *PathPointer
!= ':' && *PathPointer
!= '\\');
722 if (*PathPointer
== '\\') {
724 // Skip one directory
727 strncat (mCommonLibFullPath
, NextPointer
, MAX_LONG_FILE_PATH
- strlen (mCommonLibFullPath
) - 1);
730 // No directory is found. Just break.
736 PathPointer
= mCommonLibFullPath
;
744 InternalCharToUpper (
748 if (Char
>= L
'a' && Char
<= L
'z') {
749 return (CHAR16
) (Char
- (L
'a' - L
'A'));
757 CONST CHAR16
*String
,
763 ASSERT (((UINTN
) String
& BIT0
) == 0);
766 // If String is a null pointer or MaxSize is 0, then the StrnLenS function returns zero.
768 if ((String
== NULL
) || (MaxSize
== 0)) {
773 while (String
[Length
] != 0) {
774 if (Length
>= MaxSize
- 1) {
784 InternalAllocatePool (
790 Memory
= malloc(AllocationSize
);
791 ASSERT(Memory
!= NULL
);
797 InternalReallocatePool (
800 VOID
*OldBuffer OPTIONAL
805 NewBuffer
= AllocateZeroPool (NewSize
);
806 if (NewBuffer
!= NULL
&& OldBuffer
!= NULL
) {
807 memcpy (NewBuffer
, OldBuffer
, MIN (OldSize
, NewSize
));
817 VOID
*OldBuffer OPTIONAL
820 return InternalReallocatePool (OldSize
, NewSize
, OldBuffer
);
824 Returns the length of a Null-terminated Unicode string.
826 This function returns the number of Unicode characters in the Null-terminated
827 Unicode string specified by String.
829 If String is NULL, then ASSERT().
830 If String is not aligned on 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 @param String A pointer to a Null-terminated Unicode string.
837 @return The length of String.
847 ASSERT (String
!= NULL
);
848 ASSERT (((UINTN
) String
& BIT0
) == 0);
850 for (Length
= 0; *String
!= L
'\0'; String
++, Length
++) {
852 // If PcdMaximumUnicodeStringLength is not zero,
853 // length should not more than PcdMaximumUnicodeStringLength
860 InternalSafeStringIsOverlap (
867 if ((((UINTN
)Base1
>= (UINTN
)Base2
) && ((UINTN
)Base1
< (UINTN
)Base2
+ Size2
)) ||
868 (((UINTN
)Base2
>= (UINTN
)Base1
) && ((UINTN
)Base2
< (UINTN
)Base1
+ Size1
))) {
875 InternalSafeStringNoStrOverlap (
882 return !InternalSafeStringIsOverlap (Str1
, Size1
* sizeof(CHAR16
), Str2
, Size2
* sizeof(CHAR16
));
886 Convert a Null-terminated Unicode decimal string to a value of type UINT64.
888 This function outputs a value of type UINT64 by interpreting the contents of
889 the Unicode string specified by String as a decimal number. The format of the
890 input Unicode string String is:
892 [spaces] [decimal digits].
894 The valid decimal digit character is in the range [0-9]. The function will
895 ignore the pad space, which includes spaces or tab characters, before
896 [decimal digits]. The running zero in the beginning of [decimal digits] will
897 be ignored. Then, the function stops at the first character that is a not a
898 valid decimal character or a Null-terminator, whichever one comes first.
900 If String is NULL, then ASSERT().
901 If Data is NULL, then ASSERT().
902 If String is not aligned in a 16-bit boundary, then ASSERT().
903 If PcdMaximumUnicodeStringLength is not zero, and String contains more than
904 PcdMaximumUnicodeStringLength Unicode characters, not including the
905 Null-terminator, then ASSERT().
907 If String has no valid decimal digits in the above format, then 0 is stored
908 at the location pointed to by Data.
909 If the number represented by String exceeds the range defined by UINT64, then
910 MAX_UINT64 is stored at the location pointed to by Data.
912 If EndPointer is not NULL, a pointer to the character that stopped the scan
913 is stored at the location pointed to by EndPointer. If String has no valid
914 decimal digits right after the optional pad spaces, the value of String is
915 stored at the location pointed to by EndPointer.
917 @param String Pointer to a Null-terminated Unicode string.
918 @param EndPointer Pointer to character that stops scan.
919 @param Data Pointer to the converted value.
921 @retval RETURN_SUCCESS Value is translated from String.
922 @retval RETURN_INVALID_PARAMETER If String is NULL.
924 If PcdMaximumUnicodeStringLength is not
925 zero, and String contains more than
926 PcdMaximumUnicodeStringLength Unicode
927 characters, not including the
929 @retval RETURN_UNSUPPORTED If the number represented by String exceeds
930 the range defined by UINT64.
934 StrDecimalToUint64S (
935 CONST CHAR16
*String
,
936 CHAR16
**EndPointer
, OPTIONAL
940 ASSERT (((UINTN
) String
& BIT0
) == 0);
943 // 1. Neither String nor Data shall be a null pointer.
945 SAFE_STRING_CONSTRAINT_CHECK ((String
!= NULL
), RETURN_INVALID_PARAMETER
);
946 SAFE_STRING_CONSTRAINT_CHECK ((Data
!= NULL
), RETURN_INVALID_PARAMETER
);
949 // 2. The length of String shall not be greater than RSIZE_MAX.
951 if (RSIZE_MAX
!= 0) {
952 SAFE_STRING_CONSTRAINT_CHECK ((StrnLenS (String
, RSIZE_MAX
+ 1) <= RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
955 if (EndPointer
!= NULL
) {
956 *EndPointer
= (CHAR16
*) String
;
960 // Ignore the pad spaces (space or tab)
962 while ((*String
== L
' ') || (*String
== L
'\t')) {
967 // Ignore leading Zeros after the spaces
969 while (*String
== L
'0') {
975 while (InternalIsDecimalDigitCharacter (*String
)) {
977 // If the number represented by String overflows according to the range
978 // defined by UINT64, then MAX_UINT64 is stored in *Data and
979 // RETURN_UNSUPPORTED is returned.
981 if (*Data
> ((MAX_UINT64
- (*String
- L
'0'))/10)) {
983 if (EndPointer
!= NULL
) {
984 *EndPointer
= (CHAR16
*) String
;
986 return RETURN_UNSUPPORTED
;
989 *Data
= (*Data
) * 10 + (*String
- L
'0');
993 if (EndPointer
!= NULL
) {
994 *EndPointer
= (CHAR16
*) String
;
996 return RETURN_SUCCESS
;
1000 Convert a Null-terminated Unicode hexadecimal string to a value of type
1003 This function outputs a value of type UINT64 by interpreting the contents of
1004 the Unicode string specified by String as a hexadecimal number. The format of
1005 the input Unicode string String is:
1007 [spaces][zeros][x][hexadecimal digits].
1009 The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].
1010 The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix.
1011 If "x" appears in the input string, it must be prefixed with at least one 0.
1012 The function will ignore the pad space, which includes spaces or tab
1013 characters, before [zeros], [x] or [hexadecimal digit]. The running zero
1014 before [x] or [hexadecimal digit] will be ignored. Then, the decoding starts
1015 after [x] or the first valid hexadecimal digit. Then, the function stops at
1016 the first character that is a not a valid hexadecimal character or NULL,
1017 whichever one comes first.
1019 If String is NULL, then ASSERT().
1020 If Data is NULL, then ASSERT().
1021 If String is not aligned in a 16-bit boundary, then ASSERT().
1022 If PcdMaximumUnicodeStringLength is not zero, and String contains more than
1023 PcdMaximumUnicodeStringLength Unicode characters, not including the
1024 Null-terminator, then ASSERT().
1026 If String has no valid hexadecimal digits in the above format, then 0 is
1027 stored at the location pointed to by Data.
1028 If the number represented by String exceeds the range defined by UINT64, then
1029 MAX_UINT64 is stored at the location pointed to by Data.
1031 If EndPointer is not NULL, a pointer to the character that stopped the scan
1032 is stored at the location pointed to by EndPointer. If String has no valid
1033 hexadecimal digits right after the optional pad spaces, the value of String
1034 is stored at the location pointed to by EndPointer.
1036 @param String Pointer to a Null-terminated Unicode string.
1037 @param EndPointer Pointer to character that stops scan.
1038 @param Data Pointer to the converted value.
1040 @retval RETURN_SUCCESS Value is translated from String.
1041 @retval RETURN_INVALID_PARAMETER If String is NULL.
1043 If PcdMaximumUnicodeStringLength is not
1044 zero, and String contains more than
1045 PcdMaximumUnicodeStringLength Unicode
1046 characters, not including the
1048 @retval RETURN_UNSUPPORTED If the number represented by String exceeds
1049 the range defined by UINT64.
1054 CONST CHAR16
*String
,
1055 CHAR16
**EndPointer
, OPTIONAL
1059 ASSERT (((UINTN
) String
& BIT0
) == 0);
1062 // 1. Neither String nor Data shall be a null pointer.
1064 SAFE_STRING_CONSTRAINT_CHECK ((String
!= NULL
), RETURN_INVALID_PARAMETER
);
1065 SAFE_STRING_CONSTRAINT_CHECK ((Data
!= NULL
), RETURN_INVALID_PARAMETER
);
1068 // 2. The length of String shall not be greater than RSIZE_MAX.
1070 if (RSIZE_MAX
!= 0) {
1071 SAFE_STRING_CONSTRAINT_CHECK ((StrnLenS (String
, RSIZE_MAX
+ 1) <= RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
1074 if (EndPointer
!= NULL
) {
1075 *EndPointer
= (CHAR16
*) String
;
1079 // Ignore the pad spaces (space or tab)
1081 while ((*String
== L
' ') || (*String
== L
'\t')) {
1086 // Ignore leading Zeros after the spaces
1088 while (*String
== L
'0') {
1092 if (InternalCharToUpper (*String
) == L
'X') {
1093 if (*(String
- 1) != L
'0') {
1095 return RETURN_SUCCESS
;
1105 while (InternalIsHexaDecimalDigitCharacter (*String
)) {
1107 // If the number represented by String overflows according to the range
1108 // defined by UINT64, then MAX_UINT64 is stored in *Data and
1109 // RETURN_UNSUPPORTED is returned.
1111 if (*Data
> ((MAX_UINT64
- InternalHexCharToUintn (*String
))>>4)) {
1113 if (EndPointer
!= NULL
) {
1114 *EndPointer
= (CHAR16
*) String
;
1116 return RETURN_UNSUPPORTED
;
1119 *Data
= ((*Data
) << 4) + InternalHexCharToUintn (*String
);
1123 if (EndPointer
!= NULL
) {
1124 *EndPointer
= (CHAR16
*) String
;
1126 return RETURN_SUCCESS
;
1130 StrDecimalToUint64 (
1131 CONST CHAR16
*String
1136 StrDecimalToUint64S (String
, (CHAR16
**) NULL
, &Result
);
1143 CONST CHAR16
*String
1148 StrHexToUint64S (String
, (CHAR16
**) NULL
, &Result
);
1154 CONST CHAR16
*String
1157 return (StrLen (String
) + 1) * sizeof (*String
);
1163 CONST UINT64
*Buffer
1166 ASSERT (Buffer
!= NULL
);
1177 ASSERT (Buffer
!= NULL
);
1179 return *Buffer
= Value
;
1185 EFI_GUID
*DestinationGuid
,
1186 CONST EFI_GUID
*SourceGuid
1190 (UINT64
*)DestinationGuid
,
1191 ReadUnaligned64 ((CONST UINT64
*)SourceGuid
)
1194 (UINT64
*)DestinationGuid
+ 1,
1195 ReadUnaligned64 ((CONST UINT64
*)SourceGuid
+ 1)
1197 return DestinationGuid
;
1205 return (UINT16
) ((Value
<< 8) | (Value
>> 8));
1217 LowerBytes
= (UINT32
) SwapBytes16 ((UINT16
) Value
);
1218 HigherBytes
= (UINT32
) SwapBytes16 ((UINT16
) (Value
>> 16));
1219 return (LowerBytes
<< 16 | HigherBytes
);
1223 InternalIsDecimalDigitCharacter (
1227 return (BOOLEAN
) (Char
>= L
'0' && Char
<= L
'9');
1231 InternalAllocateCopyPool (
1232 UINTN AllocationSize
,
1238 ASSERT (Buffer
!= NULL
);
1239 ASSERT (AllocationSize
<= (MAX_ADDRESS
- (UINTN
) Buffer
+ 1));
1241 Memory
= malloc (AllocationSize
);
1242 if (Memory
!= NULL
) {
1243 Memory
= memcpy (Memory
, Buffer
, AllocationSize
);
1249 InternalIsHexaDecimalDigitCharacter (
1254 return (BOOLEAN
) (InternalIsDecimalDigitCharacter (Char
) ||
1255 (Char
>= L
'A' && Char
<= L
'F') ||
1256 (Char
>= L
'a' && Char
<= L
'f'));
1260 InternalHexCharToUintn (
1264 if (InternalIsDecimalDigitCharacter (Char
)) {
1268 return (10 + InternalCharToUpper (Char
) - L
'A');
1273 Convert a Null-terminated Unicode hexadecimal string to a byte array.
1275 This function outputs a byte array by interpreting the contents of
1276 the Unicode string specified by String in hexadecimal format. The format of
1277 the input Unicode string String is:
1281 X is a hexadecimal digit character in the range [0-9], [a-f] and [A-F].
1282 The function decodes every two hexadecimal digit characters as one byte. The
1283 decoding stops after Length of characters and outputs Buffer containing
1286 If String is not aligned in a 16-bit boundary, then ASSERT().
1288 If String is NULL, then ASSERT().
1290 If Buffer is NULL, then ASSERT().
1292 If Length is not multiple of 2, then ASSERT().
1294 If PcdMaximumUnicodeStringLength is not zero and Length is greater than
1295 PcdMaximumUnicodeStringLength, then ASSERT().
1297 If MaxBufferSize is less than (Length / 2), then ASSERT().
1299 @param String Pointer to a Null-terminated Unicode string.
1300 @param Length The number of Unicode characters to decode.
1301 @param Buffer Pointer to the converted bytes array.
1302 @param MaxBufferSize The maximum size of Buffer.
1304 @retval RETURN_SUCCESS Buffer is translated from String.
1305 @retval RETURN_INVALID_PARAMETER If String is NULL.
1307 If Length is not multiple of 2.
1308 If PcdMaximumUnicodeStringLength is not zero,
1309 and Length is greater than
1310 PcdMaximumUnicodeStringLength.
1311 @retval RETURN_UNSUPPORTED If Length of characters from String contain
1312 a character that is not valid hexadecimal
1313 digit characters, or a Null-terminator.
1314 @retval RETURN_BUFFER_TOO_SMALL If MaxBufferSize is less than (Length / 2).
1318 CONST CHAR16
*String
,
1326 ASSERT (((UINTN
) String
& BIT0
) == 0);
1329 // 1. None of String or Buffer shall be a null pointer.
1331 SAFE_STRING_CONSTRAINT_CHECK ((String
!= NULL
), RETURN_INVALID_PARAMETER
);
1332 SAFE_STRING_CONSTRAINT_CHECK ((Buffer
!= NULL
), RETURN_INVALID_PARAMETER
);
1335 // 2. Length shall not be greater than RSIZE_MAX.
1337 if (RSIZE_MAX
!= 0) {
1338 SAFE_STRING_CONSTRAINT_CHECK ((Length
<= RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
1342 // 3. Length shall not be odd.
1344 SAFE_STRING_CONSTRAINT_CHECK (((Length
& BIT0
) == 0), RETURN_INVALID_PARAMETER
);
1347 // 4. MaxBufferSize shall equal to or greater than Length / 2.
1349 SAFE_STRING_CONSTRAINT_CHECK ((MaxBufferSize
>= Length
/ 2), RETURN_BUFFER_TOO_SMALL
);
1352 // 5. String shall not contains invalid hexadecimal digits.
1354 for (Index
= 0; Index
< Length
; Index
++) {
1355 if (!InternalIsHexaDecimalDigitCharacter (String
[Index
])) {
1359 if (Index
!= Length
) {
1360 return RETURN_UNSUPPORTED
;
1364 // Convert the hex string to bytes.
1366 for(Index
= 0; Index
< Length
; Index
++) {
1369 // For even characters, write the upper nibble for each buffer byte,
1370 // and for even characters, the lower nibble.
1372 if ((Index
& BIT0
) == 0) {
1373 Buffer
[Index
/ 2] = (UINT8
) InternalHexCharToUintn (String
[Index
]) << 4;
1375 Buffer
[Index
/ 2] |= (UINT8
) InternalHexCharToUintn (String
[Index
]);
1378 return RETURN_SUCCESS
;
1382 Convert a Null-terminated Unicode GUID string to a value of type
1385 This function outputs a GUID value by interpreting the contents of
1386 the Unicode string specified by String. The format of the input
1387 Unicode string String consists of 36 characters, as follows:
1389 aabbccdd-eeff-gghh-iijj-kkllmmnnoopp
1391 The pairs aa - pp are two characters in the range [0-9], [a-f] and
1392 [A-F], with each pair representing a single byte hexadecimal value.
1394 The mapping between String and the EFI_GUID structure is as follows:
1412 If String is NULL, then ASSERT().
1413 If Guid is NULL, then ASSERT().
1414 If String is not aligned in a 16-bit boundary, then ASSERT().
1416 @param String Pointer to a Null-terminated Unicode string.
1417 @param Guid Pointer to the converted GUID.
1419 @retval RETURN_SUCCESS Guid is translated from String.
1420 @retval RETURN_INVALID_PARAMETER If String is NULL.
1422 @retval RETURN_UNSUPPORTED If String is not as the above format.
1427 CONST CHAR16
*String
,
1431 RETURN_STATUS Status
;
1434 ASSERT (((UINTN
) String
& BIT0
) == 0);
1437 // 1. None of String or Guid shall be a null pointer.
1439 SAFE_STRING_CONSTRAINT_CHECK ((String
!= NULL
), RETURN_INVALID_PARAMETER
);
1440 SAFE_STRING_CONSTRAINT_CHECK ((Guid
!= NULL
), RETURN_INVALID_PARAMETER
);
1443 // Get aabbccdd in big-endian.
1445 Status
= StrHexToBytes (String
, 2 * sizeof (LocalGuid
.Data1
), (UINT8
*) &LocalGuid
.Data1
, sizeof (LocalGuid
.Data1
));
1446 if (RETURN_ERROR (Status
) || String
[2 * sizeof (LocalGuid
.Data1
)] != L
'-') {
1447 return RETURN_UNSUPPORTED
;
1450 // Convert big-endian to little-endian.
1452 LocalGuid
.Data1
= SwapBytes32 (LocalGuid
.Data1
);
1453 String
+= 2 * sizeof (LocalGuid
.Data1
) + 1;
1456 // Get eeff in big-endian.
1458 Status
= StrHexToBytes (String
, 2 * sizeof (LocalGuid
.Data2
), (UINT8
*) &LocalGuid
.Data2
, sizeof (LocalGuid
.Data2
));
1459 if (RETURN_ERROR (Status
) || String
[2 * sizeof (LocalGuid
.Data2
)] != L
'-') {
1460 return RETURN_UNSUPPORTED
;
1463 // Convert big-endian to little-endian.
1465 LocalGuid
.Data2
= SwapBytes16 (LocalGuid
.Data2
);
1466 String
+= 2 * sizeof (LocalGuid
.Data2
) + 1;
1469 // Get gghh in big-endian.
1471 Status
= StrHexToBytes (String
, 2 * sizeof (LocalGuid
.Data3
), (UINT8
*) &LocalGuid
.Data3
, sizeof (LocalGuid
.Data3
));
1472 if (RETURN_ERROR (Status
) || String
[2 * sizeof (LocalGuid
.Data3
)] != L
'-') {
1473 return RETURN_UNSUPPORTED
;
1476 // Convert big-endian to little-endian.
1478 LocalGuid
.Data3
= SwapBytes16 (LocalGuid
.Data3
);
1479 String
+= 2 * sizeof (LocalGuid
.Data3
) + 1;
1484 Status
= StrHexToBytes (String
, 2 * 2, &LocalGuid
.Data4
[0], 2);
1485 if (RETURN_ERROR (Status
) || String
[2 * 2] != L
'-') {
1486 return RETURN_UNSUPPORTED
;
1488 String
+= 2 * 2 + 1;
1491 // Get kkllmmnnoopp.
1493 Status
= StrHexToBytes (String
, 2 * 6, &LocalGuid
.Data4
[2], 6);
1494 if (RETURN_ERROR (Status
)) {
1495 return RETURN_UNSUPPORTED
;
1498 CopyGuid (Guid
, &LocalGuid
);
1499 return RETURN_SUCCESS
;
1503 Compares up to a specified length the contents of two Null-terminated Unicode strings,
1504 and returns the difference between the first mismatched Unicode characters.
1506 This function compares the Null-terminated Unicode string FirstString to the
1507 Null-terminated Unicode string SecondString. At most, Length Unicode
1508 characters will be compared. If Length is 0, then 0 is returned. If
1509 FirstString is identical to SecondString, then 0 is returned. Otherwise, the
1510 value returned is the first mismatched Unicode character in SecondString
1511 subtracted from the first mismatched Unicode character in FirstString.
1513 If Length > 0 and FirstString is NULL, then ASSERT().
1514 If Length > 0 and FirstString is not aligned on a 16-bit boundary, then ASSERT().
1515 If Length > 0 and SecondString is NULL, then ASSERT().
1516 If Length > 0 and SecondString is not aligned on a 16-bit boundary, then ASSERT().
1517 If PcdMaximumUnicodeStringLength is not zero, and Length is greater than
1518 PcdMaximumUnicodeStringLength, then ASSERT().
1519 If PcdMaximumUnicodeStringLength is not zero, and FirstString contains more than
1520 PcdMaximumUnicodeStringLength Unicode characters, not including the Null-terminator,
1522 If PcdMaximumUnicodeStringLength is not zero, and SecondString contains more than
1523 PcdMaximumUnicodeStringLength Unicode characters, not including the Null-terminator,
1526 @param FirstString A pointer to a Null-terminated Unicode string.
1527 @param SecondString A pointer to a Null-terminated Unicode string.
1528 @param Length The maximum number of Unicode characters to compare.
1530 @retval 0 FirstString is identical to SecondString.
1531 @return others FirstString is not identical to SecondString.
1536 CONST CHAR16
*FirstString
,
1537 CONST CHAR16
*SecondString
,
1546 // ASSERT both strings are less long than PcdMaximumUnicodeStringLength.
1547 // Length tests are performed inside StrLen().
1549 ASSERT (StrSize (FirstString
) != 0);
1550 ASSERT (StrSize (SecondString
) != 0);
1552 while ((*FirstString
!= L
'\0') &&
1553 (*SecondString
!= L
'\0') &&
1554 (*FirstString
== *SecondString
) &&
1561 return *FirstString
- *SecondString
;
1566 UINTN AllocationSize
,
1570 return InternalAllocateCopyPool (AllocationSize
, Buffer
);
1575 CONST CHAR16
*FirstString
,
1576 CONST CHAR16
*SecondString
1580 // ASSERT both strings are less long than PcdMaximumUnicodeStringLength
1582 ASSERT (StrSize (FirstString
) != 0);
1583 ASSERT (StrSize (SecondString
) != 0);
1585 while ((*FirstString
!= L
'\0') && (*FirstString
== *SecondString
)) {
1589 return *FirstString
- *SecondString
;
1597 return InternalMathSwapBytes64 (Value
);
1601 InternalMathSwapBytes64 (
1608 LowerBytes
= (UINT64
) SwapBytes32 ((UINT32
) Operand
);
1609 HigherBytes
= (UINT64
) SwapBytes32 ((UINT32
) (Operand
>> 32));
1611 return (LowerBytes
<< 32 | HigherBytes
);
1616 CONST CHAR16
*String
,
1617 CHAR16
**EndPointer
,
1618 EFI_IPv4_ADDRESS
*Address
,
1622 RETURN_STATUS Status
;
1625 EFI_IPv4_ADDRESS LocalAddress
;
1626 UINT8 LocalPrefixLength
;
1629 LocalPrefixLength
= MAX_UINT8
;
1630 LocalAddress
.Addr
[0] = 0;
1632 ASSERT (((UINTN
) String
& BIT0
) == 0);
1635 // 1. None of String or Guid shall be a null pointer.
1637 SAFE_STRING_CONSTRAINT_CHECK ((String
!= NULL
), RETURN_INVALID_PARAMETER
);
1638 SAFE_STRING_CONSTRAINT_CHECK ((Address
!= NULL
), RETURN_INVALID_PARAMETER
);
1640 for (Pointer
= (CHAR16
*) String
, AddressIndex
= 0; AddressIndex
< ARRAY_SIZE (Address
->Addr
) + 1;) {
1641 if (!InternalIsDecimalDigitCharacter (*Pointer
)) {
1643 // D or P contains invalid characters.
1651 Status
= StrDecimalToUint64S ((CONST CHAR16
*) Pointer
, &Pointer
, &Uint64
);
1652 if (RETURN_ERROR (Status
)) {
1653 return RETURN_UNSUPPORTED
;
1655 if (AddressIndex
== ARRAY_SIZE (Address
->Addr
)) {
1660 return RETURN_UNSUPPORTED
;
1662 LocalPrefixLength
= (UINT8
) Uint64
;
1667 if (Uint64
> MAX_UINT8
) {
1668 return RETURN_UNSUPPORTED
;
1670 LocalAddress
.Addr
[AddressIndex
] = (UINT8
) Uint64
;
1675 // Check the '.' or '/', depending on the AddressIndex.
1677 if (AddressIndex
== ARRAY_SIZE (Address
->Addr
)) {
1678 if (*Pointer
== L
'/') {
1680 // '/P' is in the String.
1681 // Skip "/" and get P in next loop.
1686 // '/P' is not in the String.
1690 } else if (AddressIndex
< ARRAY_SIZE (Address
->Addr
)) {
1691 if (*Pointer
== L
'.') {
1693 // D should be followed by '.'
1697 return RETURN_UNSUPPORTED
;
1702 if (AddressIndex
< ARRAY_SIZE (Address
->Addr
)) {
1703 return RETURN_UNSUPPORTED
;
1706 memcpy (Address
, &LocalAddress
, sizeof (*Address
));
1707 if (PrefixLength
!= NULL
) {
1708 *PrefixLength
= LocalPrefixLength
;
1710 if (EndPointer
!= NULL
) {
1711 *EndPointer
= Pointer
;
1714 return RETURN_SUCCESS
;
1719 CONST CHAR16
*String
,
1720 CHAR16
**EndPointer
,
1721 EFI_IPv6_ADDRESS
*Address
,
1725 RETURN_STATUS Status
;
1728 EFI_IPv6_ADDRESS LocalAddress
;
1729 UINT8 LocalPrefixLength
;
1730 CONST CHAR16
*Pointer
;
1732 UINTN CompressStart
;
1733 BOOLEAN ExpectPrefix
;
1735 LocalPrefixLength
= MAX_UINT8
;
1736 CompressStart
= ARRAY_SIZE (Address
->Addr
);
1737 ExpectPrefix
= FALSE
;
1739 ASSERT (((UINTN
) String
& BIT0
) == 0);
1742 // 1. None of String or Guid shall be a null pointer.
1744 SAFE_STRING_CONSTRAINT_CHECK ((String
!= NULL
), RETURN_INVALID_PARAMETER
);
1745 SAFE_STRING_CONSTRAINT_CHECK ((Address
!= NULL
), RETURN_INVALID_PARAMETER
);
1747 for (Pointer
= String
, AddressIndex
= 0; AddressIndex
< ARRAY_SIZE (Address
->Addr
) + 1;) {
1748 if (!InternalIsHexaDecimalDigitCharacter (*Pointer
)) {
1749 if (*Pointer
!= L
':') {
1751 // ":" or "/" should be followed by digit characters.
1753 return RETURN_UNSUPPORTED
;
1757 // Meet second ":" after previous ":" or "/"
1758 // or meet first ":" in the beginning of String.
1762 // ":" shall not be after "/"
1764 return RETURN_UNSUPPORTED
;
1767 if (CompressStart
!= ARRAY_SIZE (Address
->Addr
) || AddressIndex
== ARRAY_SIZE (Address
->Addr
)) {
1769 // "::" can only appear once.
1770 // "::" can only appear when address is not full length.
1772 return RETURN_UNSUPPORTED
;
1775 // Remember the start of zero compressing.
1777 CompressStart
= AddressIndex
;
1780 if (CompressStart
== 0) {
1781 if (*Pointer
!= L
':') {
1783 // Single ":" shall not be in the beginning of String.
1785 return RETURN_UNSUPPORTED
;
1792 if (!InternalIsHexaDecimalDigitCharacter (*Pointer
)) {
1793 if (*Pointer
== L
'/') {
1795 // Might be optional "/P" after "::".
1797 if (CompressStart
!= AddressIndex
) {
1798 return RETURN_UNSUPPORTED
;
1804 if (!ExpectPrefix
) {
1808 Status
= StrHexToUint64S (Pointer
, &End
, &Uint64
);
1809 if (RETURN_ERROR (Status
) || End
- Pointer
> 4) {
1811 // Number of hexadecimal digit characters is no more than 4.
1813 return RETURN_UNSUPPORTED
;
1817 // Uint64 won't exceed MAX_UINT16 if number of hexadecimal digit characters is no more than 4.
1819 ASSERT (AddressIndex
+ 1 < ARRAY_SIZE (Address
->Addr
));
1820 LocalAddress
.Addr
[AddressIndex
] = (UINT8
) ((UINT16
) Uint64
>> 8);
1821 LocalAddress
.Addr
[AddressIndex
+ 1] = (UINT8
) Uint64
;
1825 // Get P, then exit the loop.
1827 Status
= StrDecimalToUint64S (Pointer
, &End
, &Uint64
);
1828 if (RETURN_ERROR (Status
) || End
== Pointer
|| Uint64
> 128) {
1830 // Prefix length should not exceed 128.
1832 return RETURN_UNSUPPORTED
;
1834 LocalPrefixLength
= (UINT8
) Uint64
;
1843 if (*Pointer
== L
'/') {
1844 ExpectPrefix
= TRUE
;
1845 } else if (*Pointer
== L
':') {
1846 if (AddressIndex
== ARRAY_SIZE (Address
->Addr
)) {
1848 // Meet additional ":" after all 8 16-bit address
1854 // Meet other character that is not "/" or ":" after all 8 16-bit address
1861 if ((AddressIndex
== ARRAY_SIZE (Address
->Addr
) && CompressStart
!= ARRAY_SIZE (Address
->Addr
)) ||
1862 (AddressIndex
!= ARRAY_SIZE (Address
->Addr
) && CompressStart
== ARRAY_SIZE (Address
->Addr
))
1865 // Full length of address shall not have compressing zeros.
1866 // Non-full length of address shall have compressing zeros.
1868 return RETURN_UNSUPPORTED
;
1870 memcpy (&Address
->Addr
[0], &LocalAddress
.Addr
[0], CompressStart
);
1871 if (AddressIndex
> CompressStart
) {
1872 memset (&Address
->Addr
[CompressStart
], 0, ARRAY_SIZE (Address
->Addr
) - AddressIndex
);
1874 &Address
->Addr
[CompressStart
+ ARRAY_SIZE (Address
->Addr
) - AddressIndex
],
1875 &LocalAddress
.Addr
[CompressStart
],
1876 AddressIndex
- CompressStart
1880 if (PrefixLength
!= NULL
) {
1881 *PrefixLength
= LocalPrefixLength
;
1883 if (EndPointer
!= NULL
) {
1884 *EndPointer
= (CHAR16
*) Pointer
;
1887 return RETURN_SUCCESS
;
1892 UnicodeStrToAsciiStrS (
1893 CONST CHAR16
*Source
,
1900 ASSERT (((UINTN
) Source
& BIT0
) == 0);
1903 // 1. Neither Destination nor Source shall be a null pointer.
1905 SAFE_STRING_CONSTRAINT_CHECK ((Destination
!= NULL
), RETURN_INVALID_PARAMETER
);
1906 SAFE_STRING_CONSTRAINT_CHECK ((Source
!= NULL
), RETURN_INVALID_PARAMETER
);
1909 // 2. DestMax shall not be greater than ASCII_RSIZE_MAX or RSIZE_MAX.
1911 if (ASCII_RSIZE_MAX
!= 0) {
1912 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
<= ASCII_RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
1914 if (RSIZE_MAX
!= 0) {
1915 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
<= RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
1919 // 3. DestMax shall not equal zero.
1921 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
!= 0), RETURN_INVALID_PARAMETER
);
1924 // 4. DestMax shall be greater than StrnLenS (Source, DestMax).
1926 SourceLen
= StrnLenS (Source
, DestMax
);
1927 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
> SourceLen
), RETURN_BUFFER_TOO_SMALL
);
1930 // 5. Copying shall not take place between objects that overlap.
1932 SAFE_STRING_CONSTRAINT_CHECK (!InternalSafeStringIsOverlap (Destination
, DestMax
, (VOID
*)Source
, (SourceLen
+ 1) * sizeof(CHAR16
)), RETURN_ACCESS_DENIED
);
1937 while (*Source
!= '\0') {
1939 // If any Unicode characters in Source contain
1940 // non-zero value in the upper 8 bits, then ASSERT().
1942 ASSERT (*Source
< 0x100);
1943 *(Destination
++) = (CHAR8
) *(Source
++);
1945 *Destination
= '\0';
1947 return RETURN_SUCCESS
;
1952 CHAR16
*Destination
,
1954 CONST CHAR16
*Source
1959 ASSERT (((UINTN
) Destination
& BIT0
) == 0);
1960 ASSERT (((UINTN
) Source
& BIT0
) == 0);
1963 // 1. Neither Destination nor Source shall be a null pointer.
1965 SAFE_STRING_CONSTRAINT_CHECK ((Destination
!= NULL
), RETURN_INVALID_PARAMETER
);
1966 SAFE_STRING_CONSTRAINT_CHECK ((Source
!= NULL
), RETURN_INVALID_PARAMETER
);
1969 // 2. DestMax shall not be greater than RSIZE_MAX.
1971 if (RSIZE_MAX
!= 0) {
1972 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
<= RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
1976 // 3. DestMax shall not equal zero.
1978 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
!= 0), RETURN_INVALID_PARAMETER
);
1981 // 4. DestMax shall be greater than StrnLenS(Source, DestMax).
1983 SourceLen
= StrnLenS (Source
, DestMax
);
1984 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
> SourceLen
), RETURN_BUFFER_TOO_SMALL
);
1987 // 5. Copying shall not take place between objects that overlap.
1989 SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoStrOverlap (Destination
, DestMax
, (CHAR16
*)Source
, SourceLen
+ 1), RETURN_ACCESS_DENIED
);
1992 // The StrCpyS function copies the string pointed to by Source (including the terminating
1993 // null character) into the array pointed to by Destination.
1995 while (*Source
!= 0) {
1996 *(Destination
++) = *(Source
++);
2000 return RETURN_SUCCESS
;
2005 UINTN AllocationSize
2009 Memory
= malloc(AllocationSize
);
2010 ASSERT (Memory
!= NULL
);
2011 if (Memory
== NULL
) {
2012 fprintf(stderr
, "Not memory for malloc\n");
2014 memset(Memory
, 0, AllocationSize
);
2020 UINTN AllocationSize
2023 return InternalAllocatePool (AllocationSize
);
2032 ASSERT (Buffer
!= NULL
);
2034 return *Buffer
= Value
;
2039 CONST UINT16
*Buffer
2042 ASSERT (Buffer
!= NULL
);
2047 Return whether the integer string is a hex string.
2049 @param Str The integer string
2051 @retval TRUE Hex string
2052 @retval FALSE Decimal string
2061 // skip preceeding white space
2063 while ((*Str
!= 0) && *Str
== L
' ') {
2067 // skip preceeding zeros
2069 while ((*Str
!= 0) && *Str
== L
'0') {
2073 return (BOOLEAN
) (*Str
== L
'x' || *Str
== L
'X');
2078 Convert integer string to uint.
2080 @param Str The integer string. If leading with "0x" or "0X", it's hexadecimal.
2082 @return A UINTN value represented by Str
2090 if (IsHexStr (Str
)) {
2091 return (UINTN
)StrHexToUint64 (Str
);
2093 return (UINTN
)StrDecimalToUint64 (Str
);
2099 Convert integer string to 64 bit data.
2101 @param Str The integer string. If leading with "0x" or "0X", it's hexadecimal.
2102 @param Data A pointer to the UINT64 value represented by Str
2111 if (IsHexStr (Str
)) {
2112 *Data
= StrHexToUint64 (Str
);
2114 *Data
= StrDecimalToUint64 (Str
);
2119 Converts a Unicode string to ASCII string.
2121 @param Str The equivalent Unicode string
2122 @param AsciiStr On input, it points to destination ASCII string buffer; on output, it points
2123 to the next ASCII string next to it
2135 while (!IS_NULL (*Str
)) {
2136 *(Dest
++) = (CHAR8
) *(Str
++);
2141 // Return the string next to it
2143 *AsciiStr
= Dest
+ 1;
2147 Gets current sub-string from a string list, before return
2148 the list header is moved to next sub-string. The sub-string is separated
2149 by the specified character. For example, the separator is ',', the string
2150 list is "2,0,3", it returns "2", the remain list move to "0,3"
2152 @param List A string list separated by the specified separator
2153 @param Separator The separator character
2155 @return A pointer to the current sub-string
2170 if (IS_NULL (*Str
)) {
2175 // Find first occurrence of the separator
2177 while (!IS_NULL (*Str
)) {
2178 if (*Str
== Separator
) {
2184 if (*Str
== Separator
) {
2186 // Find a sub-string, terminate it
2193 // Move to next sub-string