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
);
1240 Memory
= malloc (AllocationSize
);
1241 if (Memory
!= NULL
) {
1242 Memory
= memcpy (Memory
, Buffer
, AllocationSize
);
1248 InternalIsHexaDecimalDigitCharacter (
1253 return (BOOLEAN
) (InternalIsDecimalDigitCharacter (Char
) ||
1254 (Char
>= L
'A' && Char
<= L
'F') ||
1255 (Char
>= L
'a' && Char
<= L
'f'));
1259 InternalHexCharToUintn (
1263 if (InternalIsDecimalDigitCharacter (Char
)) {
1267 return (10 + InternalCharToUpper (Char
) - L
'A');
1272 Convert a Null-terminated Unicode hexadecimal string to a byte array.
1274 This function outputs a byte array by interpreting the contents of
1275 the Unicode string specified by String in hexadecimal format. The format of
1276 the input Unicode string String is:
1280 X is a hexadecimal digit character in the range [0-9], [a-f] and [A-F].
1281 The function decodes every two hexadecimal digit characters as one byte. The
1282 decoding stops after Length of characters and outputs Buffer containing
1285 If String is not aligned in a 16-bit boundary, then ASSERT().
1287 If String is NULL, then ASSERT().
1289 If Buffer is NULL, then ASSERT().
1291 If Length is not multiple of 2, then ASSERT().
1293 If PcdMaximumUnicodeStringLength is not zero and Length is greater than
1294 PcdMaximumUnicodeStringLength, then ASSERT().
1296 If MaxBufferSize is less than (Length / 2), then ASSERT().
1298 @param String Pointer to a Null-terminated Unicode string.
1299 @param Length The number of Unicode characters to decode.
1300 @param Buffer Pointer to the converted bytes array.
1301 @param MaxBufferSize The maximum size of Buffer.
1303 @retval RETURN_SUCCESS Buffer is translated from String.
1304 @retval RETURN_INVALID_PARAMETER If String is NULL.
1306 If Length is not multiple of 2.
1307 If PcdMaximumUnicodeStringLength is not zero,
1308 and Length is greater than
1309 PcdMaximumUnicodeStringLength.
1310 @retval RETURN_UNSUPPORTED If Length of characters from String contain
1311 a character that is not valid hexadecimal
1312 digit characters, or a Null-terminator.
1313 @retval RETURN_BUFFER_TOO_SMALL If MaxBufferSize is less than (Length / 2).
1317 CONST CHAR16
*String
,
1325 ASSERT (((UINTN
) String
& BIT0
) == 0);
1328 // 1. None of String or Buffer shall be a null pointer.
1330 SAFE_STRING_CONSTRAINT_CHECK ((String
!= NULL
), RETURN_INVALID_PARAMETER
);
1331 SAFE_STRING_CONSTRAINT_CHECK ((Buffer
!= NULL
), RETURN_INVALID_PARAMETER
);
1334 // 2. Length shall not be greater than RSIZE_MAX.
1336 if (RSIZE_MAX
!= 0) {
1337 SAFE_STRING_CONSTRAINT_CHECK ((Length
<= RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
1341 // 3. Length shall not be odd.
1343 SAFE_STRING_CONSTRAINT_CHECK (((Length
& BIT0
) == 0), RETURN_INVALID_PARAMETER
);
1346 // 4. MaxBufferSize shall equal to or greater than Length / 2.
1348 SAFE_STRING_CONSTRAINT_CHECK ((MaxBufferSize
>= Length
/ 2), RETURN_BUFFER_TOO_SMALL
);
1351 // 5. String shall not contains invalid hexadecimal digits.
1353 for (Index
= 0; Index
< Length
; Index
++) {
1354 if (!InternalIsHexaDecimalDigitCharacter (String
[Index
])) {
1358 if (Index
!= Length
) {
1359 return RETURN_UNSUPPORTED
;
1363 // Convert the hex string to bytes.
1365 for(Index
= 0; Index
< Length
; Index
++) {
1368 // For even characters, write the upper nibble for each buffer byte,
1369 // and for even characters, the lower nibble.
1371 if ((Index
& BIT0
) == 0) {
1372 Buffer
[Index
/ 2] = (UINT8
) InternalHexCharToUintn (String
[Index
]) << 4;
1374 Buffer
[Index
/ 2] |= (UINT8
) InternalHexCharToUintn (String
[Index
]);
1377 return RETURN_SUCCESS
;
1381 Convert a Null-terminated Unicode GUID string to a value of type
1384 This function outputs a GUID value by interpreting the contents of
1385 the Unicode string specified by String. The format of the input
1386 Unicode string String consists of 36 characters, as follows:
1388 aabbccdd-eeff-gghh-iijj-kkllmmnnoopp
1390 The pairs aa - pp are two characters in the range [0-9], [a-f] and
1391 [A-F], with each pair representing a single byte hexadecimal value.
1393 The mapping between String and the EFI_GUID structure is as follows:
1411 If String is NULL, then ASSERT().
1412 If Guid is NULL, then ASSERT().
1413 If String is not aligned in a 16-bit boundary, then ASSERT().
1415 @param String Pointer to a Null-terminated Unicode string.
1416 @param Guid Pointer to the converted GUID.
1418 @retval RETURN_SUCCESS Guid is translated from String.
1419 @retval RETURN_INVALID_PARAMETER If String is NULL.
1421 @retval RETURN_UNSUPPORTED If String is not as the above format.
1426 CONST CHAR16
*String
,
1430 RETURN_STATUS Status
;
1433 ASSERT (((UINTN
) String
& BIT0
) == 0);
1436 // 1. None of String or Guid shall be a null pointer.
1438 SAFE_STRING_CONSTRAINT_CHECK ((String
!= NULL
), RETURN_INVALID_PARAMETER
);
1439 SAFE_STRING_CONSTRAINT_CHECK ((Guid
!= NULL
), RETURN_INVALID_PARAMETER
);
1442 // Get aabbccdd in big-endian.
1444 Status
= StrHexToBytes (String
, 2 * sizeof (LocalGuid
.Data1
), (UINT8
*) &LocalGuid
.Data1
, sizeof (LocalGuid
.Data1
));
1445 if (RETURN_ERROR (Status
) || String
[2 * sizeof (LocalGuid
.Data1
)] != L
'-') {
1446 return RETURN_UNSUPPORTED
;
1449 // Convert big-endian to little-endian.
1451 LocalGuid
.Data1
= SwapBytes32 (LocalGuid
.Data1
);
1452 String
+= 2 * sizeof (LocalGuid
.Data1
) + 1;
1455 // Get eeff in big-endian.
1457 Status
= StrHexToBytes (String
, 2 * sizeof (LocalGuid
.Data2
), (UINT8
*) &LocalGuid
.Data2
, sizeof (LocalGuid
.Data2
));
1458 if (RETURN_ERROR (Status
) || String
[2 * sizeof (LocalGuid
.Data2
)] != L
'-') {
1459 return RETURN_UNSUPPORTED
;
1462 // Convert big-endian to little-endian.
1464 LocalGuid
.Data2
= SwapBytes16 (LocalGuid
.Data2
);
1465 String
+= 2 * sizeof (LocalGuid
.Data2
) + 1;
1468 // Get gghh in big-endian.
1470 Status
= StrHexToBytes (String
, 2 * sizeof (LocalGuid
.Data3
), (UINT8
*) &LocalGuid
.Data3
, sizeof (LocalGuid
.Data3
));
1471 if (RETURN_ERROR (Status
) || String
[2 * sizeof (LocalGuid
.Data3
)] != L
'-') {
1472 return RETURN_UNSUPPORTED
;
1475 // Convert big-endian to little-endian.
1477 LocalGuid
.Data3
= SwapBytes16 (LocalGuid
.Data3
);
1478 String
+= 2 * sizeof (LocalGuid
.Data3
) + 1;
1483 Status
= StrHexToBytes (String
, 2 * 2, &LocalGuid
.Data4
[0], 2);
1484 if (RETURN_ERROR (Status
) || String
[2 * 2] != L
'-') {
1485 return RETURN_UNSUPPORTED
;
1487 String
+= 2 * 2 + 1;
1490 // Get kkllmmnnoopp.
1492 Status
= StrHexToBytes (String
, 2 * 6, &LocalGuid
.Data4
[2], 6);
1493 if (RETURN_ERROR (Status
)) {
1494 return RETURN_UNSUPPORTED
;
1497 CopyGuid (Guid
, &LocalGuid
);
1498 return RETURN_SUCCESS
;
1502 Compares up to a specified length the contents of two Null-terminated Unicode strings,
1503 and returns the difference between the first mismatched Unicode characters.
1505 This function compares the Null-terminated Unicode string FirstString to the
1506 Null-terminated Unicode string SecondString. At most, Length Unicode
1507 characters will be compared. If Length is 0, then 0 is returned. If
1508 FirstString is identical to SecondString, then 0 is returned. Otherwise, the
1509 value returned is the first mismatched Unicode character in SecondString
1510 subtracted from the first mismatched Unicode character in FirstString.
1512 If Length > 0 and FirstString is NULL, then ASSERT().
1513 If Length > 0 and FirstString is not aligned on a 16-bit boundary, then ASSERT().
1514 If Length > 0 and SecondString is NULL, then ASSERT().
1515 If Length > 0 and SecondString is not aligned on a 16-bit boundary, then ASSERT().
1516 If PcdMaximumUnicodeStringLength is not zero, and Length is greater than
1517 PcdMaximumUnicodeStringLength, then ASSERT().
1518 If PcdMaximumUnicodeStringLength is not zero, and FirstString contains more than
1519 PcdMaximumUnicodeStringLength Unicode characters, not including the Null-terminator,
1521 If PcdMaximumUnicodeStringLength is not zero, and SecondString contains more than
1522 PcdMaximumUnicodeStringLength Unicode characters, not including the Null-terminator,
1525 @param FirstString A pointer to a Null-terminated Unicode string.
1526 @param SecondString A pointer to a Null-terminated Unicode string.
1527 @param Length The maximum number of Unicode characters to compare.
1529 @retval 0 FirstString is identical to SecondString.
1530 @return others FirstString is not identical to SecondString.
1535 CONST CHAR16
*FirstString
,
1536 CONST CHAR16
*SecondString
,
1545 // ASSERT both strings are less long than PcdMaximumUnicodeStringLength.
1546 // Length tests are performed inside StrLen().
1548 ASSERT (StrSize (FirstString
) != 0);
1549 ASSERT (StrSize (SecondString
) != 0);
1551 while ((*FirstString
!= L
'\0') &&
1552 (*SecondString
!= L
'\0') &&
1553 (*FirstString
== *SecondString
) &&
1560 return *FirstString
- *SecondString
;
1565 UINTN AllocationSize
,
1569 return InternalAllocateCopyPool (AllocationSize
, Buffer
);
1574 CONST CHAR16
*FirstString
,
1575 CONST CHAR16
*SecondString
1579 // ASSERT both strings are less long than PcdMaximumUnicodeStringLength
1581 ASSERT (StrSize (FirstString
) != 0);
1582 ASSERT (StrSize (SecondString
) != 0);
1584 while ((*FirstString
!= L
'\0') && (*FirstString
== *SecondString
)) {
1588 return *FirstString
- *SecondString
;
1596 return InternalMathSwapBytes64 (Value
);
1600 InternalMathSwapBytes64 (
1607 LowerBytes
= (UINT64
) SwapBytes32 ((UINT32
) Operand
);
1608 HigherBytes
= (UINT64
) SwapBytes32 ((UINT32
) (Operand
>> 32));
1610 return (LowerBytes
<< 32 | HigherBytes
);
1615 CONST CHAR16
*String
,
1616 CHAR16
**EndPointer
,
1617 EFI_IPv4_ADDRESS
*Address
,
1621 RETURN_STATUS Status
;
1624 EFI_IPv4_ADDRESS LocalAddress
;
1625 UINT8 LocalPrefixLength
;
1628 LocalPrefixLength
= MAX_UINT8
;
1629 LocalAddress
.Addr
[0] = 0;
1631 ASSERT (((UINTN
) String
& BIT0
) == 0);
1634 // 1. None of String or Guid shall be a null pointer.
1636 SAFE_STRING_CONSTRAINT_CHECK ((String
!= NULL
), RETURN_INVALID_PARAMETER
);
1637 SAFE_STRING_CONSTRAINT_CHECK ((Address
!= NULL
), RETURN_INVALID_PARAMETER
);
1639 for (Pointer
= (CHAR16
*) String
, AddressIndex
= 0; AddressIndex
< ARRAY_SIZE (Address
->Addr
) + 1;) {
1640 if (!InternalIsDecimalDigitCharacter (*Pointer
)) {
1642 // D or P contains invalid characters.
1650 Status
= StrDecimalToUint64S ((CONST CHAR16
*) Pointer
, &Pointer
, &Uint64
);
1651 if (RETURN_ERROR (Status
)) {
1652 return RETURN_UNSUPPORTED
;
1654 if (AddressIndex
== ARRAY_SIZE (Address
->Addr
)) {
1659 return RETURN_UNSUPPORTED
;
1661 LocalPrefixLength
= (UINT8
) Uint64
;
1666 if (Uint64
> MAX_UINT8
) {
1667 return RETURN_UNSUPPORTED
;
1669 LocalAddress
.Addr
[AddressIndex
] = (UINT8
) Uint64
;
1674 // Check the '.' or '/', depending on the AddressIndex.
1676 if (AddressIndex
== ARRAY_SIZE (Address
->Addr
)) {
1677 if (*Pointer
== L
'/') {
1679 // '/P' is in the String.
1680 // Skip "/" and get P in next loop.
1685 // '/P' is not in the String.
1689 } else if (AddressIndex
< ARRAY_SIZE (Address
->Addr
)) {
1690 if (*Pointer
== L
'.') {
1692 // D should be followed by '.'
1696 return RETURN_UNSUPPORTED
;
1701 if (AddressIndex
< ARRAY_SIZE (Address
->Addr
)) {
1702 return RETURN_UNSUPPORTED
;
1705 memcpy (Address
, &LocalAddress
, sizeof (*Address
));
1706 if (PrefixLength
!= NULL
) {
1707 *PrefixLength
= LocalPrefixLength
;
1709 if (EndPointer
!= NULL
) {
1710 *EndPointer
= Pointer
;
1713 return RETURN_SUCCESS
;
1718 CONST CHAR16
*String
,
1719 CHAR16
**EndPointer
,
1720 EFI_IPv6_ADDRESS
*Address
,
1724 RETURN_STATUS Status
;
1727 EFI_IPv6_ADDRESS LocalAddress
;
1728 UINT8 LocalPrefixLength
;
1729 CONST CHAR16
*Pointer
;
1731 UINTN CompressStart
;
1732 BOOLEAN ExpectPrefix
;
1734 LocalPrefixLength
= MAX_UINT8
;
1735 CompressStart
= ARRAY_SIZE (Address
->Addr
);
1736 ExpectPrefix
= FALSE
;
1738 ASSERT (((UINTN
) String
& BIT0
) == 0);
1741 // 1. None of String or Guid shall be a null pointer.
1743 SAFE_STRING_CONSTRAINT_CHECK ((String
!= NULL
), RETURN_INVALID_PARAMETER
);
1744 SAFE_STRING_CONSTRAINT_CHECK ((Address
!= NULL
), RETURN_INVALID_PARAMETER
);
1746 for (Pointer
= String
, AddressIndex
= 0; AddressIndex
< ARRAY_SIZE (Address
->Addr
) + 1;) {
1747 if (!InternalIsHexaDecimalDigitCharacter (*Pointer
)) {
1748 if (*Pointer
!= L
':') {
1750 // ":" or "/" should be followed by digit characters.
1752 return RETURN_UNSUPPORTED
;
1756 // Meet second ":" after previous ":" or "/"
1757 // or meet first ":" in the beginning of String.
1761 // ":" shall not be after "/"
1763 return RETURN_UNSUPPORTED
;
1766 if (CompressStart
!= ARRAY_SIZE (Address
->Addr
) || AddressIndex
== ARRAY_SIZE (Address
->Addr
)) {
1768 // "::" can only appear once.
1769 // "::" can only appear when address is not full length.
1771 return RETURN_UNSUPPORTED
;
1774 // Remember the start of zero compressing.
1776 CompressStart
= AddressIndex
;
1779 if (CompressStart
== 0) {
1780 if (*Pointer
!= L
':') {
1782 // Single ":" shall not be in the beginning of String.
1784 return RETURN_UNSUPPORTED
;
1791 if (!InternalIsHexaDecimalDigitCharacter (*Pointer
)) {
1792 if (*Pointer
== L
'/') {
1794 // Might be optional "/P" after "::".
1796 if (CompressStart
!= AddressIndex
) {
1797 return RETURN_UNSUPPORTED
;
1803 if (!ExpectPrefix
) {
1807 Status
= StrHexToUint64S (Pointer
, &End
, &Uint64
);
1808 if (RETURN_ERROR (Status
) || End
- Pointer
> 4) {
1810 // Number of hexadecimal digit characters is no more than 4.
1812 return RETURN_UNSUPPORTED
;
1816 // Uint64 won't exceed MAX_UINT16 if number of hexadecimal digit characters is no more than 4.
1818 ASSERT (AddressIndex
+ 1 < ARRAY_SIZE (Address
->Addr
));
1819 LocalAddress
.Addr
[AddressIndex
] = (UINT8
) ((UINT16
) Uint64
>> 8);
1820 LocalAddress
.Addr
[AddressIndex
+ 1] = (UINT8
) Uint64
;
1824 // Get P, then exit the loop.
1826 Status
= StrDecimalToUint64S (Pointer
, &End
, &Uint64
);
1827 if (RETURN_ERROR (Status
) || End
== Pointer
|| Uint64
> 128) {
1829 // Prefix length should not exceed 128.
1831 return RETURN_UNSUPPORTED
;
1833 LocalPrefixLength
= (UINT8
) Uint64
;
1842 if (*Pointer
== L
'/') {
1843 ExpectPrefix
= TRUE
;
1844 } else if (*Pointer
== L
':') {
1845 if (AddressIndex
== ARRAY_SIZE (Address
->Addr
)) {
1847 // Meet additional ":" after all 8 16-bit address
1853 // Meet other character that is not "/" or ":" after all 8 16-bit address
1860 if ((AddressIndex
== ARRAY_SIZE (Address
->Addr
) && CompressStart
!= ARRAY_SIZE (Address
->Addr
)) ||
1861 (AddressIndex
!= ARRAY_SIZE (Address
->Addr
) && CompressStart
== ARRAY_SIZE (Address
->Addr
))
1864 // Full length of address shall not have compressing zeros.
1865 // Non-full length of address shall have compressing zeros.
1867 return RETURN_UNSUPPORTED
;
1869 memcpy (&Address
->Addr
[0], &LocalAddress
.Addr
[0], CompressStart
);
1870 if (AddressIndex
> CompressStart
) {
1871 memset (&Address
->Addr
[CompressStart
], 0, ARRAY_SIZE (Address
->Addr
) - AddressIndex
);
1873 &Address
->Addr
[CompressStart
+ ARRAY_SIZE (Address
->Addr
) - AddressIndex
],
1874 &LocalAddress
.Addr
[CompressStart
],
1875 AddressIndex
- CompressStart
1879 if (PrefixLength
!= NULL
) {
1880 *PrefixLength
= LocalPrefixLength
;
1882 if (EndPointer
!= NULL
) {
1883 *EndPointer
= (CHAR16
*) Pointer
;
1886 return RETURN_SUCCESS
;
1891 UnicodeStrToAsciiStrS (
1892 CONST CHAR16
*Source
,
1899 ASSERT (((UINTN
) Source
& BIT0
) == 0);
1902 // 1. Neither Destination nor Source shall be a null pointer.
1904 SAFE_STRING_CONSTRAINT_CHECK ((Destination
!= NULL
), RETURN_INVALID_PARAMETER
);
1905 SAFE_STRING_CONSTRAINT_CHECK ((Source
!= NULL
), RETURN_INVALID_PARAMETER
);
1908 // 2. DestMax shall not be greater than ASCII_RSIZE_MAX or RSIZE_MAX.
1910 if (ASCII_RSIZE_MAX
!= 0) {
1911 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
<= ASCII_RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
1913 if (RSIZE_MAX
!= 0) {
1914 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
<= RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
1918 // 3. DestMax shall not equal zero.
1920 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
!= 0), RETURN_INVALID_PARAMETER
);
1923 // 4. DestMax shall be greater than StrnLenS (Source, DestMax).
1925 SourceLen
= StrnLenS (Source
, DestMax
);
1926 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
> SourceLen
), RETURN_BUFFER_TOO_SMALL
);
1929 // 5. Copying shall not take place between objects that overlap.
1931 SAFE_STRING_CONSTRAINT_CHECK (!InternalSafeStringIsOverlap (Destination
, DestMax
, (VOID
*)Source
, (SourceLen
+ 1) * sizeof(CHAR16
)), RETURN_ACCESS_DENIED
);
1936 while (*Source
!= '\0') {
1938 // If any Unicode characters in Source contain
1939 // non-zero value in the upper 8 bits, then ASSERT().
1941 ASSERT (*Source
< 0x100);
1942 *(Destination
++) = (CHAR8
) *(Source
++);
1944 *Destination
= '\0';
1946 return RETURN_SUCCESS
;
1951 CHAR16
*Destination
,
1953 CONST CHAR16
*Source
1958 ASSERT (((UINTN
) Destination
& BIT0
) == 0);
1959 ASSERT (((UINTN
) Source
& BIT0
) == 0);
1962 // 1. Neither Destination nor Source shall be a null pointer.
1964 SAFE_STRING_CONSTRAINT_CHECK ((Destination
!= NULL
), RETURN_INVALID_PARAMETER
);
1965 SAFE_STRING_CONSTRAINT_CHECK ((Source
!= NULL
), RETURN_INVALID_PARAMETER
);
1968 // 2. DestMax shall not be greater than RSIZE_MAX.
1970 if (RSIZE_MAX
!= 0) {
1971 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
<= RSIZE_MAX
), RETURN_INVALID_PARAMETER
);
1975 // 3. DestMax shall not equal zero.
1977 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
!= 0), RETURN_INVALID_PARAMETER
);
1980 // 4. DestMax shall be greater than StrnLenS(Source, DestMax).
1982 SourceLen
= StrnLenS (Source
, DestMax
);
1983 SAFE_STRING_CONSTRAINT_CHECK ((DestMax
> SourceLen
), RETURN_BUFFER_TOO_SMALL
);
1986 // 5. Copying shall not take place between objects that overlap.
1988 SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoStrOverlap (Destination
, DestMax
, (CHAR16
*)Source
, SourceLen
+ 1), RETURN_ACCESS_DENIED
);
1991 // The StrCpyS function copies the string pointed to by Source (including the terminating
1992 // null character) into the array pointed to by Destination.
1994 while (*Source
!= 0) {
1995 *(Destination
++) = *(Source
++);
1999 return RETURN_SUCCESS
;
2004 UINTN AllocationSize
2008 Memory
= malloc(AllocationSize
);
2009 ASSERT (Memory
!= NULL
);
2010 if (Memory
== NULL
) {
2011 fprintf(stderr
, "Not memory for malloc\n");
2013 memset(Memory
, 0, AllocationSize
);
2019 UINTN AllocationSize
2022 return InternalAllocatePool (AllocationSize
);
2031 ASSERT (Buffer
!= NULL
);
2033 return *Buffer
= Value
;
2038 CONST UINT16
*Buffer
2041 ASSERT (Buffer
!= NULL
);
2046 Return whether the integer string is a hex string.
2048 @param Str The integer string
2050 @retval TRUE Hex string
2051 @retval FALSE Decimal string
2060 // skip preceeding white space
2062 while ((*Str
!= 0) && *Str
== L
' ') {
2066 // skip preceeding zeros
2068 while ((*Str
!= 0) && *Str
== L
'0') {
2072 return (BOOLEAN
) (*Str
== L
'x' || *Str
== L
'X');
2077 Convert integer string to uint.
2079 @param Str The integer string. If leading with "0x" or "0X", it's hexadecimal.
2081 @return A UINTN value represented by Str
2089 if (IsHexStr (Str
)) {
2090 return (UINTN
)StrHexToUint64 (Str
);
2092 return (UINTN
)StrDecimalToUint64 (Str
);
2098 Convert integer string to 64 bit data.
2100 @param Str The integer string. If leading with "0x" or "0X", it's hexadecimal.
2101 @param Data A pointer to the UINT64 value represented by Str
2110 if (IsHexStr (Str
)) {
2111 *Data
= StrHexToUint64 (Str
);
2113 *Data
= StrDecimalToUint64 (Str
);
2118 Converts a Unicode string to ASCII string.
2120 @param Str The equivalent Unicode string
2121 @param AsciiStr On input, it points to destination ASCII string buffer; on output, it points
2122 to the next ASCII string next to it
2134 while (!IS_NULL (*Str
)) {
2135 *(Dest
++) = (CHAR8
) *(Str
++);
2140 // Return the string next to it
2142 *AsciiStr
= Dest
+ 1;
2146 Gets current sub-string from a string list, before return
2147 the list header is moved to next sub-string. The sub-string is separated
2148 by the specified character. For example, the separator is ',', the string
2149 list is "2,0,3", it returns "2", the remain list move to "0,3"
2151 @param List A string list separated by the specified separator
2152 @param Separator The separator character
2154 @return A pointer to the current sub-string
2169 if (IS_NULL (*Str
)) {
2174 // Find first occurrence of the separator
2176 while (!IS_NULL (*Str
)) {
2177 if (*Str
== Separator
) {
2183 if (*Str
== Separator
) {
2185 // Find a sub-string, terminate it
2192 // Move to next sub-string