5 Copyright (c) 2011-2019, Intel Corporation. All rights reserved.<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
11 #define WARNING_STATUS_NUMBER 4
12 #define ERROR_STATUS_NUMBER 24
14 CONST CHAR8 mHexStr
[] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
16 CONST CHAR8
*mStatusString
[] = {
17 "Success", // RETURN_SUCCESS = 0
18 "Warning Unknown Glyph", // RETURN_WARN_UNKNOWN_GLYPH = 1
19 "Warning Delete Failure", // RETURN_WARN_DELETE_FAILURE = 2
20 "Warning Write Failure", // RETURN_WARN_WRITE_FAILURE = 3
21 "Warning Buffer Too Small", // RETURN_WARN_BUFFER_TOO_SMALL = 4
22 "Load Error", // RETURN_LOAD_ERROR = 1 | MAX_BIT
23 "Invalid Parameter", // RETURN_INVALID_PARAMETER = 2 | MAX_BIT
24 "Unsupported", // RETURN_UNSUPPORTED = 3 | MAX_BIT
25 "Bad Buffer Size", // RETURN_BAD_BUFFER_SIZE = 4 | MAX_BIT
26 "Buffer Too Small", // RETURN_BUFFER_TOO_SMALL, = 5 | MAX_BIT
27 "Not Ready", // RETURN_NOT_READY = 6 | MAX_BIT
28 "Device Error", // RETURN_DEVICE_ERROR = 7 | MAX_BIT
29 "Write Protected", // RETURN_WRITE_PROTECTED = 8 | MAX_BIT
30 "Out of Resources", // RETURN_OUT_OF_RESOURCES = 9 | MAX_BIT
31 "Volume Corrupt", // RETURN_VOLUME_CORRUPTED = 10 | MAX_BIT
32 "Volume Full", // RETURN_VOLUME_FULL = 11 | MAX_BIT
33 "No Media", // RETURN_NO_MEDIA = 12 | MAX_BIT
34 "Media changed", // RETURN_MEDIA_CHANGED = 13 | MAX_BIT
35 "Not Found", // RETURN_NOT_FOUND = 14 | MAX_BIT
36 "Access Denied", // RETURN_ACCESS_DENIED = 15 | MAX_BIT
37 "No Response", // RETURN_NO_RESPONSE = 16 | MAX_BIT
38 "No mapping", // RETURN_NO_MAPPING = 17 | MAX_BIT
39 "Time out", // RETURN_TIMEOUT = 18 | MAX_BIT
40 "Not started", // RETURN_NOT_STARTED = 19 | MAX_BIT
41 "Already started", // RETURN_ALREADY_STARTED = 20 | MAX_BIT
42 "Aborted", // RETURN_ABORTED = 21 | MAX_BIT
43 "ICMP Error", // RETURN_ICMP_ERROR = 22 | MAX_BIT
44 "TFTP Error", // RETURN_TFTP_ERROR = 23 | MAX_BIT
45 "Protocol Error" // RETURN_PROTOCOL_ERROR = 24 | MAX_BIT
49 Copies one Null-terminated Unicode string to another Null-terminated Unicode
50 string and returns the new Unicode string.
52 This function copies the contents of the Unicode string Source to the Unicode
53 string Destination, and returns Destination. If Source and Destination
54 overlap, then the results are undefined.
56 If Destination is NULL, then return NULL.
57 If Destination is not aligned on a 16-bit boundary, then return NULL.
59 @param Destination A pointer to a Null-terminated Unicode string.
60 @param Source A pointer to a Null-terminated Unicode string.
67 OUT CHAR16
*Destination
,
68 IN CONST CHAR16
*Source
75 if ((Destination
== NULL
) || ((UINTN
) Destination
% 2 != 0)) {
79 ReturnValue
= Destination
;
80 while (*Source
!= 0) {
81 *(Destination
++) = *(Source
++);
88 Returns the length of a Null-terminated Unicode string.
90 This function returns the number of Unicode characters in the Null-terminated
91 Unicode string specified by String.
93 If String is NULL, then return 0.
95 @param String A pointer to a Null-terminated Unicode string.
97 @return The length of String.
102 IN CONST CHAR16
*String
107 if (String
== NULL
) {
110 for (Length
= 0; *String
!= L
'\0'; String
++, Length
++) {
117 Returns the size of a Null-terminated Unicode string in bytes, including the
120 This function returns the size, in bytes, of the Null-terminated Unicode string
123 If String is NULL, then ASSERT().
124 If String is not aligned on a 16-bit boundary, then ASSERT().
125 If PcdMaximumUnicodeStringLength is not zero, and String contains more than
126 PcdMaximumUnicodeStringLength Unicode characters, not including the
127 Null-terminator, then ASSERT().
129 @param String A pointer to a Null-terminated Unicode string.
131 @return The size of String.
136 IN CONST CHAR16
*String
139 return (FceStrLen (String
) + 1) * sizeof (*String
);
143 Compares two Null-terminated Unicode strings, and returns the difference
144 between the first mismatched Unicode characters.
146 This function compares the Null-terminated Unicode string FirstString to the
147 Null-terminated Unicode string SecondString. If FirstString is identical to
148 SecondString, then 0 is returned. Otherwise, the value returned is the first
149 mismatched Unicode character in SecondString subtracted from the first
150 mismatched Unicode character in FirstString.
152 @param FirstString A pointer to a Null-terminated Unicode string.
153 @param SecondString A pointer to a Null-terminated Unicode string.
155 @retval 0 FirstString is identical to SecondString.
156 @return others FirstString is not identical to SecondString.
161 IN CONST CHAR16
*FirstString
,
162 IN CONST CHAR16
*SecondString
165 while ((*FirstString
!= L
'\0') && (*FirstString
== *SecondString
)) {
169 return *FirstString
- *SecondString
;
173 Concatenates one Null-terminated Unicode string to another Null-terminated
174 Unicode string, and returns the concatenated Unicode string.
176 This function concatenates two Null-terminated Unicode strings. The contents
177 of Null-terminated Unicode string Source are concatenated to the end of
178 Null-terminated Unicode string Destination. The Null-terminated concatenated
179 Unicode String is returned. If Source and Destination overlap, then the
180 results are undefined.
182 If Destination is NULL, then ASSERT().
183 If Destination is not aligned on a 16-bit boundary, then ASSERT().
184 If Source is NULL, then ASSERT().
185 If Source is not aligned on a 16-bit boundary, then ASSERT().
186 If Source and Destination overlap, then ASSERT().
187 If PcdMaximumUnicodeStringLength is not zero, and Destination contains more
188 than PcdMaximumUnicodeStringLength Unicode characters, not including the
189 Null-terminator, then ASSERT().
190 If PcdMaximumUnicodeStringLength is not zero, and Source contains more than
191 PcdMaximumUnicodeStringLength Unicode characters, not including the
192 Null-terminator, then ASSERT().
193 If PcdMaximumUnicodeStringLength is not zero, and concatenating Destination
194 and Source results in a Unicode string with more than
195 PcdMaximumUnicodeStringLength Unicode characters, not including the
196 Null-terminator, then ASSERT().
198 @param Destination A pointer to a Null-terminated Unicode string.
199 @param Source A pointer to a Null-terminated Unicode string.
206 IN OUT CHAR16
*Destination
,
207 IN CONST CHAR16
*Source
210 StrCpy (Destination
+ FceStrLen (Destination
), Source
);
213 // Size of the resulting string should never be zero.
214 // PcdMaximumUnicodeStringLength is tested inside FceStrLen().
216 ASSERT (FceStrSize (Destination
) != 0);
221 Returns the first occurrence of a Null-terminated Unicode sub-string
222 in a Null-terminated Unicode string.
224 This function scans the contents of the Null-terminated Unicode string
225 specified by String and returns the first occurrence of SearchString.
226 If SearchString is not found in String, then NULL is returned. If
227 the length of SearchString is zero, then String is
230 If String is NULL, then ASSERT().
231 If String is not aligned on a 16-bit boundary, then ASSERT().
232 If SearchString is NULL, then ASSERT().
233 If SearchString is not aligned on a 16-bit boundary, then ASSERT().
235 If PcdMaximumUnicodeStringLength is not zero, and SearchString
236 or String contains more than PcdMaximumUnicodeStringLength Unicode
237 characters, not including the Null-terminator, then ASSERT().
239 @param String A pointer to a Null-terminated Unicode string.
240 @param SearchString A pointer to a Null-terminated Unicode string to search for.
242 @retval NULL If the SearchString does not appear in String.
243 @return others If there is a match.
248 IN CONST CHAR16
*String
,
249 IN CONST CHAR16
*SearchString
252 CONST CHAR16
*FirstMatch
;
253 CONST CHAR16
*SearchStringTmp
;
256 // ASSERT both strings are less long than PcdMaximumUnicodeStringLength.
257 // Length tests are performed inside FceStrLen().
259 ASSERT (FceStrSize (String
) != 0);
260 ASSERT (FceStrSize (SearchString
) != 0);
262 if (*SearchString
== L
'\0') {
263 return (CHAR16
*) String
;
266 while (*String
!= L
'\0') {
267 SearchStringTmp
= SearchString
;
270 while ((*String
== *SearchStringTmp
)
271 && (*String
!= L
'\0')) {
276 if (*SearchStringTmp
== L
'\0') {
277 return (CHAR16
*) FirstMatch
;
280 if (*String
== L
'\0') {
284 String
= FirstMatch
+ 1;
291 Convert one Null-terminated ASCII string to a Null-terminated
292 Unicode string and returns the Unicode string.
294 This function converts the contents of the ASCII string Source to the Unicode
295 string Destination, and returns Destination. The function terminates the
296 Unicode string Destination by appending a Null-terminator character at the end.
297 The caller is responsible to make sure Destination points to a buffer with size
298 equal or greater than ((AsciiStrLen (Source) + 1) * sizeof (CHAR16)) in bytes.
300 @param Source A pointer to a Null-terminated ASCII string.
301 @param Destination A pointer to a Null-terminated Unicode string.
304 @return NULL If Destination or Source is NULL, return NULL.
308 AsciiStrToUnicodeStr (
309 IN CONST CHAR8
*Source
,
310 OUT CHAR16
*Destination
317 if ((Destination
== NULL
) || (Source
== NULL
) || (strlen (Source
) == 0)) {
320 ReturnValue
= Destination
;
321 while (*Source
!= '\0') {
322 *(Destination
++) = (CHAR16
) *(Source
++);
325 // End the Destination with a NULL.
333 Internal function that convert a number to a string in Buffer.
335 Print worker function that converts a decimal or hexadecimal number to an ASCII string in Buffer.
337 @param Buffer Location to place the ASCII string of Value.
338 @param Value The value to convert to a Decimal or Hexadecimal string in Buffer.
339 @param Radix Radix of the value
341 @return A pointer to the end of buffer filled with ASCII string.
345 BasePrintLibValueToString (
346 IN OUT CHAR8
*Buffer
,
354 // Loop to convert one digit at a time in reverse order
358 Value
= (INT64
)DivU64x32Remainder ((UINT64
)Value
, (UINT32
)Radix
, &Remainder
);
359 *(++Buffer
) = mHexStr
[Remainder
];
360 } while (Value
!= 0);
363 // Return pointer of the end of filled buffer.
369 Reads a 16-bit value from memory that may be unaligned.
371 This function returns the 16-bit value pointed to by Buffer. The function
372 guarantees that the read operation does not produce an alignment fault.
374 If the Buffer is NULL, then ASSERT().
376 @param Buffer A pointer to a 16-bit value that may be unaligned.
378 @return The 16-bit value read from Buffer.
383 IN CONST UINT16
*Buffer
386 ASSERT (Buffer
!= NULL
);
392 Reads a 32-bit value from memory that may be unaligned.
394 This function returns the 32-bit value pointed to by Buffer. The function
395 guarantees that the read operation does not produce an alignment fault.
397 If the Buffer is NULL, then ASSERT().
399 @param Buffer A pointer to a 32-bit value that may be unaligned.
401 @return The 32-bit value read from Buffer.
406 IN CONST UINT32
*Buffer
409 ASSERT (Buffer
!= NULL
);
415 Internal function that places the character into the Buffer.
417 Internal function that places ASCII or Unicode character into the Buffer.
419 @param Buffer The buffer to place the Unicode or ASCII string.
420 @param EndBuffer The end of the input Buffer. No characters will be
422 @param Length The count of character to be placed into Buffer.
423 (Negative value indicates no buffer fill.)
424 @param Character The character to be placed into Buffer.
425 @param Increment The character increment in Buffer.
431 BasePrintLibFillBuffer (
441 for (Index
= 0; Index
< Length
&& Buffer
< EndBuffer
; Index
++) {
442 *Buffer
= (CHAR8
) Character
;
443 if (Increment
!= 1) {
444 *(Buffer
+ 1) = (CHAR8
)(Character
>> 8);
453 Worker function that produces a Null-terminated string in an output buffer
454 based on a Null-terminated format string and a VA_LIST argument list.
456 VSPrint function to process format and place the results in Buffer. Since a
457 VA_LIST is used this routine allows the nesting of Vararg routines. Thus
458 this is the main print working routine.
460 If COUNT_ONLY_NO_PRINT is set in Flags, Buffer will not be modified at all.
462 @param[out] Buffer The character buffer to print the results of the
463 parsing of Format into.
464 @param[in] BufferSize The maximum number of characters to put into
466 @param[in] Flags Initial flags value.
467 Can only have FORMAT_UNICODE, OUTPUT_UNICODE,
468 and COUNT_ONLY_NO_PRINT set.
469 @param[in] Format A Null-terminated format string.
470 @param[in] VaListMarker VA_LIST style variable argument list consumed by
472 @param[in] BaseListMarker BASE_LIST style variable argument list consumed
473 by processing Format.
475 @return The number of characters printed not including the Null-terminator.
476 If COUNT_ONLY_NO_PRINT was set returns the same, but without any
477 modification to Buffer.
481 BasePrintLibSPrintMarker (
485 IN CONST CHAR8
*Format
,
486 IN VA_LIST VaListMarker
, OPTIONAL
487 IN BASE_LIST BaseListMarker OPTIONAL
490 CHAR8
*OriginalBuffer
;
492 CHAR8 ValueBuffer
[MAXIMUM_VALUE_CHARACTERS
];
493 UINT32 BytesPerOutputCharacter
;
494 UINTN BytesPerFormatCharacter
;
496 UINTN FormatCharacter
;
500 CONST CHAR8
*ArgumentString
;
506 INTN BytesPerArgumentCharacter
;
507 UINTN ArgumentCharacter
;
515 RETURN_STATUS Status
;
519 UINTN LengthToReturn
;
522 // If you change this code be sure to match the 2 versions of this function.
523 // Nearly identical logic is found in the BasePrintLib and
524 // DxePrintLibPrint2Protocol (both PrintLib instances).
527 if ((Flags
& COUNT_ONLY_NO_PRINT
) != 0) {
528 if (BufferSize
== 0) {
533 // We can run without a Buffer for counting only.
535 if (BufferSize
== 0) {
538 ASSERT (Buffer
!= NULL
);
541 if ((Flags
& OUTPUT_UNICODE
) != 0) {
542 BytesPerOutputCharacter
= 2;
544 BytesPerOutputCharacter
= 1;
550 // Reserve space for the Null terminator.
553 OriginalBuffer
= Buffer
;
556 // Set the tag for the end of the input Buffer.
558 EndBuffer
= Buffer
+ BufferSize
* BytesPerOutputCharacter
;
560 if ((Flags
& FORMAT_UNICODE
) != 0) {
562 // Make sure format string cannot contain more than PcdMaximumUnicodeStringLength
563 // Unicode characters if PcdMaximumUnicodeStringLength is not zero.
565 ASSERT (FceStrSize ((CHAR16
*) Format
) != 0);
566 BytesPerFormatCharacter
= 2;
570 // Make sure format string cannot contain more than PcdMaximumAsciiStringLength
571 // Ascii characters if PcdMaximumAsciiStringLength is not zero.
573 ASSERT (strlen (Format
) + 1 != 0);
574 BytesPerFormatCharacter
= 1;
579 // Get the first character from the format string
581 FormatCharacter
= ((*Format
& 0xff) | (*(Format
+ 1) << 8)) & FormatMask
;
584 // Loop until the end of the format string is reached or the output buffer is full
586 while (FormatCharacter
!= 0 && Buffer
< EndBuffer
) {
588 // Clear all the flag bits except those that may have been passed in
590 Flags
&= (OUTPUT_UNICODE
| FORMAT_UNICODE
| COUNT_ONLY_NO_PRINT
);
593 // Set the default width to zero, and the default precision to 1
603 switch (FormatCharacter
) {
606 // Parse Flags and Width
608 for (Done
= FALSE
; !Done
; ) {
609 Format
+= BytesPerFormatCharacter
;
610 FormatCharacter
= ((*Format
& 0xff) | (*(Format
+ 1) << 8)) & FormatMask
;
611 switch (FormatCharacter
) {
616 Flags
|= LEFT_JUSTIFY
;
619 Flags
|= PREFIX_SIGN
;
622 Flags
|= PREFIX_BLANK
;
632 if ((Flags
& PRECISION
) == 0) {
633 Flags
|= PAD_TO_WIDTH
;
634 if (BaseListMarker
== NULL
) {
635 Width
= VA_ARG (VaListMarker
, UINTN
);
637 Width
= BASE_ARG (BaseListMarker
, UINTN
);
640 if (BaseListMarker
== NULL
) {
641 Precision
= VA_ARG (VaListMarker
, UINTN
);
643 Precision
= BASE_ARG (BaseListMarker
, UINTN
);
648 if ((Flags
& PRECISION
) == 0) {
649 Flags
|= PREFIX_ZERO
;
660 for (Count
= 0; ((FormatCharacter
>= '0') && (FormatCharacter
<= '9')); ){
661 Count
= (Count
* 10) + FormatCharacter
- '0';
662 Format
+= BytesPerFormatCharacter
;
663 FormatCharacter
= ((*Format
& 0xff) | (*(Format
+ 1) << 8)) & FormatMask
;
665 Format
-= BytesPerFormatCharacter
;
666 if ((Flags
& PRECISION
) == 0) {
667 Flags
|= PAD_TO_WIDTH
;
676 // Make no output if Format string terminates unexpectedly when
677 // looking up for flag, width, precision and type.
679 Format
-= BytesPerFormatCharacter
;
682 // break skipped on purpose.
691 // Handle each argument type
693 switch (FormatCharacter
) {
696 // Flag space, +, 0, L & l are invalid for type p.
698 Flags
&= ~(PREFIX_BLANK
| PREFIX_SIGN
| PREFIX_ZERO
| LONG_TYPE
);
699 if (sizeof (VOID
*) > 4) {
703 Flags
|= PREFIX_ZERO
;
705 // break skipped on purpose
710 // break skipped on purpose
713 if ((Flags
& LONG_TYPE
) == 0) {
715 // 'd','x', and 'X' that are not preceded by 'l' or 'L' are assumed to be type "int".
716 // This assumption is made so the format string definition is compatible with the ANSI C
717 // Specification for formatted strings. It is recommended that the Base Types be used
718 // everywhere, but in this one case, compliance with ANSI C is more important, and
719 // provides an implementation that is compatible with that largest possible set of CPU
720 // architectures. This is why the type "int" is used in this one case.
722 if (BaseListMarker
== NULL
) {
723 Value
= VA_ARG (VaListMarker
, int);
725 Value
= BASE_ARG (BaseListMarker
, int);
728 if (BaseListMarker
== NULL
) {
729 Value
= VA_ARG (VaListMarker
, INT64
);
731 Value
= BASE_ARG (BaseListMarker
, INT64
);
734 if ((Flags
& PREFIX_BLANK
) != 0) {
737 if ((Flags
& PREFIX_SIGN
) != 0) {
740 if ((Flags
& COMMA_TYPE
) != 0) {
743 if ((Flags
& RADIX_HEX
) == 0) {
746 Flags
&= (~PREFIX_ZERO
);
750 Flags
|= PREFIX_SIGN
;
757 if ((Flags
& LONG_TYPE
) == 0 && Value
< 0) {
759 // 'd','x', and 'X' that are not preceded by 'l' or 'L' are assumed to be type "int".
760 // This assumption is made so the format string definition is compatible with the ANSI C
761 // Specification for formatted strings. It is recommended that the Base Types be used
762 // everywhere, but in this one case, compliance with ANSI C is more important, and
763 // provides an implementation that is compatible with that largest possible set of CPU
764 // architectures. This is why the type "unsigned int" is used in this one case.
766 Value
= (unsigned int)Value
;
770 // Convert Value to a reversed string
772 Count
= BasePrintLibValueToString (ValueBuffer
, Value
, Radix
) - ValueBuffer
;
773 if (Value
== 0 && Precision
== 0) {
776 ArgumentString
= (CHAR8
*)ValueBuffer
+ Count
;
782 if (Comma
&& Count
!= 0) {
783 Count
+= ((Count
- 1) / 3);
789 Flags
|= ARGUMENT_REVERSED
;
791 if ((Flags
& PREFIX_ZERO
) != 0) {
792 if ((Flags
& LEFT_JUSTIFY
) == 0) {
793 if ((Flags
& PAD_TO_WIDTH
) != 0) {
794 if ((Flags
& PRECISION
) == 0) {
804 Flags
|= ARGUMENT_UNICODE
;
806 // break skipped on purpose
809 if (BaseListMarker
== NULL
) {
810 ArgumentString
= VA_ARG (VaListMarker
, CHAR8
*);
812 ArgumentString
= BASE_ARG (BaseListMarker
, CHAR8
*);
814 if (ArgumentString
== NULL
) {
815 Flags
&= (~ARGUMENT_UNICODE
);
816 ArgumentString
= "<null string>";
819 // Set the default precision for string to be zero if not specified.
821 if ((Flags
& PRECISION
) == 0) {
827 if (BaseListMarker
== NULL
) {
828 Character
= VA_ARG (VaListMarker
, UINTN
) & 0xffff;
830 Character
= BASE_ARG (BaseListMarker
, UINTN
) & 0xffff;
832 ArgumentString
= (CHAR8
*)&Character
;
833 Flags
|= ARGUMENT_UNICODE
;
837 if (BaseListMarker
== NULL
) {
838 TmpGuid
= VA_ARG (VaListMarker
, EFI_GUID
*);
840 TmpGuid
= BASE_ARG (BaseListMarker
, EFI_GUID
*);
842 if (TmpGuid
== NULL
) {
843 ArgumentString
= "<null guid>";
845 GuidData1
= ReadUnaligned32 (&(TmpGuid
->Data1
));
846 GuidData2
= FceReadUnaligned16 (&(TmpGuid
->Data2
));
847 GuidData3
= FceReadUnaligned16 (&(TmpGuid
->Data3
));
850 MAXIMUM_VALUE_CHARACTERS
,
852 "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
865 ArgumentString
= ValueBuffer
;
870 if (BaseListMarker
== NULL
) {
871 TmpTime
= VA_ARG (VaListMarker
, TIME
*);
873 TmpTime
= BASE_ARG (BaseListMarker
, TIME
*);
875 if (TmpTime
== NULL
) {
876 ArgumentString
= "<null time>";
880 MAXIMUM_VALUE_CHARACTERS
,
882 "%02d/%02d/%04d %02d:%02d",
889 ArgumentString
= ValueBuffer
;
894 if (BaseListMarker
== NULL
) {
895 Status
= VA_ARG (VaListMarker
, RETURN_STATUS
);
897 Status
= BASE_ARG (BaseListMarker
, RETURN_STATUS
);
899 ArgumentString
= ValueBuffer
;
900 if (RETURN_ERROR (Status
)) {
904 Index
= Status
& ~MAX_BIT
;
905 if (Index
> 0 && Index
<= ERROR_STATUS_NUMBER
) {
906 ArgumentString
= mStatusString
[Index
+ WARNING_STATUS_NUMBER
];
910 if (Index
<= WARNING_STATUS_NUMBER
) {
911 ArgumentString
= mStatusString
[Index
];
914 if (ArgumentString
== ValueBuffer
) {
915 BasePrintLibSPrint ((CHAR8
*) ValueBuffer
, MAXIMUM_VALUE_CHARACTERS
, 0, "%08X", Status
);
920 Format
+= BytesPerFormatCharacter
;
921 FormatCharacter
= ((*Format
& 0xff) | (*(Format
+ 1) << 8)) & FormatMask
;
922 if (FormatCharacter
== '\n') {
924 // Translate '\r\n' to '\r\n'
926 ArgumentString
= "\r\n";
929 // Translate '\r' to '\r'
931 ArgumentString
= "\r";
932 Format
-= BytesPerFormatCharacter
;
938 // Translate '\n' to '\r\n' and '\n\r' to '\r\n'
940 ArgumentString
= "\r\n";
941 Format
+= BytesPerFormatCharacter
;
942 FormatCharacter
= ((*Format
& 0xff) | (*(Format
+ 1) << 8)) & FormatMask
;
943 if (FormatCharacter
!= '\r') {
944 Format
-= BytesPerFormatCharacter
;
951 // if the type is '%' or unknown, then print it to the screen
953 ArgumentString
= (CHAR8
*)&FormatCharacter
;
954 Flags
|= ARGUMENT_UNICODE
;
960 Format
+= BytesPerFormatCharacter
;
961 FormatCharacter
= ((*Format
& 0xff) | (*(Format
+ 1) << 8)) & FormatMask
;
962 if (FormatCharacter
== '\n') {
964 // Translate '\r\n' to '\r\n'
966 ArgumentString
= "\r\n";
969 // Translate '\r' to '\r'
971 ArgumentString
= "\r";
972 Format
-= BytesPerFormatCharacter
;
978 // Translate '\n' to '\r\n' and '\n\r' to '\r\n'
980 ArgumentString
= "\r\n";
981 Format
+= BytesPerFormatCharacter
;
982 FormatCharacter
= ((*Format
& 0xff) | (*(Format
+ 1) << 8)) & FormatMask
;
983 if (FormatCharacter
!= '\r') {
984 Format
-= BytesPerFormatCharacter
;
989 ArgumentString
= (CHAR8
*)&FormatCharacter
;
990 Flags
|= ARGUMENT_UNICODE
;
995 // Retrieve the ArgumentString attriubutes
997 if ((Flags
& ARGUMENT_UNICODE
) != 0) {
998 ArgumentMask
= 0xffff;
999 BytesPerArgumentCharacter
= 2;
1001 ArgumentMask
= 0xff;
1002 BytesPerArgumentCharacter
= 1;
1004 if ((Flags
& ARGUMENT_REVERSED
) != 0) {
1005 BytesPerArgumentCharacter
= -BytesPerArgumentCharacter
;
1008 // Compute the number of characters in ArgumentString and store it in Count
1009 // ArgumentString is either null-terminated, or it contains Precision characters
1011 for (Count
= 0; Count
< Precision
|| ((Flags
& PRECISION
) == 0); Count
++) {
1012 ArgumentCharacter
= ((ArgumentString
[Count
* BytesPerArgumentCharacter
] & 0xff) | ((ArgumentString
[Count
* BytesPerArgumentCharacter
+ 1]) << 8)) & ArgumentMask
;
1013 if (ArgumentCharacter
== 0) {
1019 if (Precision
< Count
) {
1024 // Pad before the string
1026 if ((Flags
& (PAD_TO_WIDTH
| LEFT_JUSTIFY
)) == (PAD_TO_WIDTH
)) {
1027 LengthToReturn
+= ((Width
- Precision
) * BytesPerOutputCharacter
);
1028 if ((Flags
& COUNT_ONLY_NO_PRINT
) == 0 && Buffer
!= NULL
) {
1029 Buffer
= BasePrintLibFillBuffer (Buffer
, EndBuffer
, Width
- Precision
, ' ', BytesPerOutputCharacter
);
1035 LengthToReturn
+= (1 * BytesPerOutputCharacter
);
1036 if ((Flags
& COUNT_ONLY_NO_PRINT
) == 0 && Buffer
!= NULL
) {
1037 Buffer
= BasePrintLibFillBuffer (Buffer
, EndBuffer
, 1, Prefix
, BytesPerOutputCharacter
);
1040 LengthToReturn
+= ((Precision
- Count
) * BytesPerOutputCharacter
);
1041 if ((Flags
& COUNT_ONLY_NO_PRINT
) == 0 && Buffer
!= NULL
) {
1042 Buffer
= BasePrintLibFillBuffer (Buffer
, EndBuffer
, Precision
- Count
, '0', BytesPerOutputCharacter
);
1045 LengthToReturn
+= ((Precision
- Count
) * BytesPerOutputCharacter
);
1046 if ((Flags
& COUNT_ONLY_NO_PRINT
) == 0 && Buffer
!= NULL
) {
1047 Buffer
= BasePrintLibFillBuffer (Buffer
, EndBuffer
, Precision
- Count
, ' ', BytesPerOutputCharacter
);
1050 LengthToReturn
+= (1 * BytesPerOutputCharacter
);
1051 if ((Flags
& COUNT_ONLY_NO_PRINT
) == 0 && Buffer
!= NULL
) {
1052 Buffer
= BasePrintLibFillBuffer (Buffer
, EndBuffer
, 1, Prefix
, BytesPerOutputCharacter
);
1058 // Output the Prefix character if it is present
1066 // Copy the string into the output buffer performing the required type conversions
1068 while (Index
< Count
) {
1069 ArgumentCharacter
= ((*ArgumentString
& 0xff) | (*(ArgumentString
+ 1) << 8)) & ArgumentMask
;
1071 LengthToReturn
+= (1 * BytesPerOutputCharacter
);
1072 if ((Flags
& COUNT_ONLY_NO_PRINT
) == 0 && Buffer
!= NULL
) {
1073 Buffer
= BasePrintLibFillBuffer (Buffer
, EndBuffer
, 1, ArgumentCharacter
, BytesPerOutputCharacter
);
1075 ArgumentString
+= BytesPerArgumentCharacter
;
1082 if (Index
< Count
) {
1083 LengthToReturn
+= (1 * BytesPerOutputCharacter
);
1084 if ((Flags
& COUNT_ONLY_NO_PRINT
) == 0 && Buffer
!= NULL
) {
1085 Buffer
= BasePrintLibFillBuffer (Buffer
, EndBuffer
, 1, ',', BytesPerOutputCharacter
);
1093 // Pad after the string
1095 if ((Flags
& (PAD_TO_WIDTH
| LEFT_JUSTIFY
)) == (PAD_TO_WIDTH
| LEFT_JUSTIFY
)) {
1096 LengthToReturn
+= ((Width
- Precision
) * BytesPerOutputCharacter
);
1097 if ((Flags
& COUNT_ONLY_NO_PRINT
) == 0 && Buffer
!= NULL
) {
1098 Buffer
= BasePrintLibFillBuffer (Buffer
, EndBuffer
, Width
- Precision
, ' ', BytesPerOutputCharacter
);
1103 // Get the next character from the format string
1105 Format
+= BytesPerFormatCharacter
;
1108 // Get the next character from the format string
1110 FormatCharacter
= ((*Format
& 0xff) | (*(Format
+ 1) << 8)) & FormatMask
;
1113 if ((Flags
& COUNT_ONLY_NO_PRINT
) != 0) {
1114 return (LengthToReturn
/ BytesPerOutputCharacter
);
1117 ASSERT (Buffer
!= NULL
);
1119 // Null terminate the Unicode or ASCII string
1121 BasePrintLibFillBuffer (Buffer
, EndBuffer
+ BytesPerOutputCharacter
, 1, 0, BytesPerOutputCharacter
);
1123 // Make sure output buffer cannot contain more than PcdMaximumUnicodeStringLength
1124 // Unicode characters if PcdMaximumUnicodeStringLength is not zero.
1126 ASSERT ((((Flags
& OUTPUT_UNICODE
) == 0)) || (FceStrSize ((CHAR16
*) OriginalBuffer
) != 0));
1128 // Make sure output buffer cannot contain more than PcdMaximumAsciiStringLength
1129 // ASCII characters if PcdMaximumAsciiStringLength is not zero.
1131 ASSERT ((((Flags
& OUTPUT_UNICODE
) != 0)) || ((strlen (OriginalBuffer
) + 1) != 0));
1133 return ((Buffer
- OriginalBuffer
) / BytesPerOutputCharacter
);
1137 Worker function that produces a Null-terminated string in an output buffer
1138 based on a Null-terminated format string and variable argument list.
1140 VSPrint function to process format and place the results in Buffer. Since a
1141 VA_LIST is used this routine allows the nesting of Vararg routines. Thus
1142 this is the main print working routine
1144 @param StartOfBuffer The character buffer to print the results of the parsing
1146 @param BufferSize The maximum number of characters to put into buffer.
1147 Zero means no limit.
1148 @param Flags Initial flags value.
1149 Can only have FORMAT_UNICODE and OUTPUT_UNICODE set
1150 @param FormatString A Null-terminated format string.
1151 @param ... The variable argument list.
1153 @return The number of characters printed.
1157 BasePrintLibSPrint (
1158 OUT CHAR8
*StartOfBuffer
,
1159 IN UINTN BufferSize
,
1161 IN CONST CHAR8
*FormatString
,
1167 VA_START (Marker
, FormatString
);
1168 return BasePrintLibSPrintMarker (StartOfBuffer
, BufferSize
, Flags
, FormatString
, Marker
, NULL
);
1172 Produces a Null-terminated Unicode string in an output buffer based on
1173 a Null-terminated Unicode format string and a VA_LIST argument list
1175 Produces a Null-terminated Unicode string in the output buffer specified by StartOfBuffer
1177 The Unicode string is produced by parsing the format string specified by FormatString.
1178 Arguments are pulled from the variable argument list specified by Marker based on the
1179 contents of the format string.
1180 The number of Unicode characters in the produced output buffer is returned not including
1181 the Null-terminator.
1182 If BufferSize is 0 or 1, then no output buffer is produced and 0 is returned.
1184 If BufferSize > 1 and StartOfBuffer is NULL, then ASSERT().
1185 If BufferSize > 1 and StartOfBuffer is not aligned on a 16-bit boundary, then ASSERT().
1186 If BufferSize > 1 and FormatString is NULL, then ASSERT().
1187 If BufferSize > 1 and FormatString is not aligned on a 16-bit boundary, then ASSERT().
1188 If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than
1189 PcdMaximumUnicodeStringLength Unicode characters not including the Null-terminator, then
1191 If PcdMaximumUnicodeStringLength is not zero, and produced Null-terminated Unicode string
1192 contains more than PcdMaximumUnicodeStringLength Unicode characters not including the
1193 Null-terminator, then ASSERT().
1195 @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated
1197 @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer.
1198 @param FormatString A Null-terminated Unicode format string.
1199 @param Marker VA_LIST marker for the variable argument list.
1201 @return The number of Unicode characters in the produced output buffer not including the
1207 OUT CHAR16
*StartOfBuffer
,
1208 IN UINTN BufferSize
,
1209 IN CONST CHAR16
*FormatString
,
1213 ASSERT_UNICODE_BUFFER (StartOfBuffer
);
1214 ASSERT_UNICODE_BUFFER (FormatString
);
1215 return BasePrintLibSPrintMarker ((CHAR8
*)StartOfBuffer
, BufferSize
>> 1, FORMAT_UNICODE
| OUTPUT_UNICODE
, (CHAR8
*)FormatString
, Marker
, NULL
);
1219 Produces a Null-terminated Unicode string in an output buffer based on a Null-terminated
1220 Unicode format string and variable argument list.
1222 Produces a Null-terminated Unicode string in the output buffer specified by StartOfBuffer
1224 The Unicode string is produced by parsing the format string specified by FormatString.
1225 Arguments are pulled from the variable argument list based on the contents of the format string.
1226 The number of Unicode characters in the produced output buffer is returned not including
1227 the Null-terminator.
1228 If BufferSize is 0 or 1, then no output buffer is produced and 0 is returned.
1230 If BufferSize > 1 and StartOfBuffer is NULL, then ASSERT().
1231 If BufferSize > 1 and StartOfBuffer is not aligned on a 16-bit boundary, then ASSERT().
1232 If BufferSize > 1 and FormatString is NULL, then ASSERT().
1233 If BufferSize > 1 and FormatString is not aligned on a 16-bit boundary, then ASSERT().
1234 If PcdMaximumUnicodeStringLength is not zero, and FormatString contains more than
1235 PcdMaximumUnicodeStringLength Unicode characters not including the Null-terminator, then
1237 If PcdMaximumUnicodeStringLength is not zero, and produced Null-terminated Unicode string
1238 contains more than PcdMaximumUnicodeStringLength Unicode characters not including the
1239 Null-terminator, then ASSERT().
1241 @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated
1243 @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer.
1244 @param FormatString A Null-terminated Unicode format string.
1245 @param ... Variable argument list whose contents are accessed based on the
1246 format string specified by FormatString.
1248 @return The number of Unicode characters in the produced output buffer not including the
1254 OUT CHAR16
*StartOfBuffer
,
1255 IN UINTN BufferSize
,
1256 IN CONST CHAR16
*FormatString
,
1262 VA_START (Marker
, FormatString
);
1263 return UnicodeVSPrint (StartOfBuffer
, BufferSize
, FormatString
, Marker
);
1267 Convert a Null-terminated Unicode string to a Null-terminated
1268 ASCII string and returns the ASCII string.
1270 This function converts the content of the Unicode string Source
1271 to the ASCII string Destination by copying the lower 8 bits of
1272 each Unicode character. It returns Destination. The function terminates
1273 the ASCII string Destination by appending a Null-terminator character
1274 at the end. The caller is responsible to make sure Destination points
1275 to a buffer with size equal or greater than (FceStrLen (Source) + 1) in bytes.
1277 If Destination is NULL, then ASSERT().
1278 If Source is NULL, then ASSERT().
1279 If Source is not aligned on a 16-bit boundary, then ASSERT().
1280 If Source and Destination overlap, then ASSERT().
1282 If any Unicode characters in Source contain non-zero value in
1283 the upper 8 bits, then ASSERT().
1285 @param Source Pointer to a Null-terminated Unicode string.
1286 @param Destination Pointer to a Null-terminated ASCII string.
1292 UnicodeStrToAsciiStr (
1293 IN CONST CHAR16
*Source
,
1294 OUT CHAR8
*Destination
1299 ReturnValue
= Destination
;
1300 assert (Destination
!= NULL
);
1301 assert (Source
!= NULL
);
1302 assert (((UINTN
) Source
& 0x01) == 0);
1304 while (*Source
!= L
'\0') {
1306 // If any Unicode characters in Source contain
1307 // non-zero value in the upper 8 bits, then ASSERT().
1309 assert (*Source
< 0x100);
1310 *(ReturnValue
++) = (CHAR8
) *(Source
++);
1313 *ReturnValue
= '\0';
1319 Allocate new memory and then copy the Unicode string Source to Destination.
1321 @param Dest Location to copy string
1322 @param Src String to copy
1327 IN OUT CHAR16
**Dest
,
1331 if (*Dest
!= NULL
) {
1334 *Dest
= FceAllocateCopyPool (FceStrSize (Src
), Src
);
1335 ASSERT (*Dest
!= NULL
);
1339 Check if a Unicode character is a decimal character.
1341 This internal function checks if a Unicode character is a
1342 decimal character. The valid decimal character is from
1345 @param Char The character to check against.
1347 @retval TRUE If the Char is a decmial character.
1348 @retval FALSE If the Char is not a decmial character.
1352 FceInternalIsDecimalDigitCharacter (
1356 return (BOOLEAN
) ((Char
>= L
'0') && (Char
<= L
'9'));
1360 Convert a Unicode character to upper case only if
1361 it maps to a valid small-case ASCII character.
1363 This internal function only deal with Unicode character
1364 which maps to a valid small-case ASCII character, i.e.
1365 L'a' to L'z'. For other Unicode character, the input character
1366 is returned directly.
1368 @param Char The character to convert.
1370 @retval LowerCharacter If the Char is with range L'a' to L'z'.
1371 @retval Unchanged Otherwise.
1375 FceInternalCharToUpper (
1379 if ((Char
>= L
'a') && (Char
<= L
'z')) {
1380 return (CHAR16
) (Char
- (L
'a' - L
'A'));
1387 Convert a Unicode character to numerical value.
1389 This internal function only deal with Unicode character
1390 which maps to a valid hexadecimal ASII character, i.e.
1391 L'0' to L'9', L'a' to L'f' or L'A' to L'F'. For other
1392 Unicode character, the value returned does not make sense.
1394 @param Char The character to convert.
1396 @return The numerical value converted.
1400 FceInternalHexCharToUintn (
1404 if (FceInternalIsDecimalDigitCharacter (Char
)) {
1408 return (UINTN
) (10 + FceInternalCharToUpper (Char
) - L
'A');
1412 Check if a Unicode character is a hexadecimal character.
1414 This internal function checks if a Unicode character is a
1415 decimal character. The valid hexadecimal character is
1416 L'0' to L'9', L'a' to L'f', or L'A' to L'F'.
1419 @param Char The character to check against.
1421 @retval TRUE If the Char is a hexadecmial character.
1422 @retval FALSE If the Char is not a hexadecmial character.
1426 FceInternalIsHexaDecimalDigitCharacter (
1431 return (BOOLEAN
) (FceInternalIsDecimalDigitCharacter (Char
) ||
1432 ((Char
>= L
'A') && (Char
<= L
'F')) ||
1433 ((Char
>= L
'a') && (Char
<= L
'f')));
1438 Convert a Null-terminated Unicode decimal string to a value of
1441 This function returns a value of type UINT64 by interpreting the contents
1442 of the Unicode string specified by String as a decimal number. The format
1443 of the input Unicode string String is:
1445 [spaces] [decimal digits].
1447 The valid decimal digit character is in the range [0-9]. The
1448 function will ignore the pad space, which includes spaces or
1449 tab characters, before [decimal digits]. The running zero in the
1450 beginning of [decimal digits] will be ignored. Then, the function
1451 stops at the first character that is a not a valid decimal character
1452 or a Null-terminator, whichever one comes first.
1454 If String is NULL, then ASSERT().
1455 If String is not aligned in a 16-bit boundary, then ASSERT().
1456 If String has only pad spaces, then 0 is returned.
1457 If String has no pad spaces or valid decimal digits,
1459 If the number represented by String overflows according
1460 to the range defined by UINT64, then ASSERT().
1462 If PcdMaximumUnicodeStringLength is not zero, and String contains
1463 more than PcdMaximumUnicodeStringLength Unicode characters, not including
1464 the Null-terminator, then ASSERT().
1466 @param String A pointer to a Null-terminated Unicode string.
1468 @retval Value translated from String.
1472 FceStrDecimalToUint64 (
1473 IN CONST CHAR16
*String
1479 // ASSERT String is less long than PcdMaximumUnicodeStringLength.
1480 // Length tests are performed inside FceStrLen().
1482 ASSERT (FceStrSize (String
) != 0);
1485 // Ignore the pad spaces (space or tab)
1487 while ((*String
== L
' ') || (*String
== L
'\t')) {
1492 // Ignore leading Zeros after the spaces
1494 while (*String
== L
'0') {
1500 while (FceInternalIsDecimalDigitCharacter (*String
)) {
1502 // If the number represented by String overflows according
1503 // to the range defined by UINTN, then ASSERT().
1505 ASSERT (Result
<= DivU64x32 (((UINT64
) ~0) - (*String
- L
'0') , 10));
1507 Result
= MultU64x32 (Result
, 10) + (*String
- L
'0');
1516 Convert a Null-terminated Unicode hexadecimal string to a value of type UINT64.
1518 This function returns a value of type UINT64 by interpreting the contents
1519 of the Unicode string specified by String as a hexadecimal number.
1520 The format of the input Unicode string String is
1522 [spaces][zeros][x][hexadecimal digits].
1524 The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].
1525 The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix.
1526 If "x" appears in the input string, it must be prefixed with at least one 0.
1527 The function will ignore the pad space, which includes spaces or tab characters,
1528 before [zeros], [x] or [hexadecimal digit]. The running zero before [x] or
1529 [hexadecimal digit] will be ignored. Then, the decoding starts after [x] or the
1530 first valid hexadecimal digit. Then, the function stops at the first character that is
1531 a not a valid hexadecimal character or NULL, whichever one comes first.
1533 If String is NULL, then ASSERT().
1534 If String is not aligned in a 16-bit boundary, then ASSERT().
1535 If String has only pad spaces, then zero is returned.
1536 If String has no leading pad spaces, leading zeros or valid hexadecimal digits,
1537 then zero is returned.
1538 If the number represented by String overflows according to the range defined by
1539 UINT64, then ASSERT().
1541 If PcdMaximumUnicodeStringLength is not zero, and String contains more than
1542 PcdMaximumUnicodeStringLength Unicode characters, not including the Null-terminator,
1545 @param String A pointer to a Null-terminated Unicode string.
1547 @retval Value translated from String.
1552 IN CONST CHAR16
*String
1558 // ASSERT String is less long than PcdMaximumUnicodeStringLength.
1559 // Length tests are performed inside FceStrLen().
1561 ASSERT (FceStrSize (String
) != 0);
1564 // Ignore the pad spaces (space or tab)
1566 while ((*String
== L
' ') || (*String
== L
'\t')) {
1571 // Ignore leading Zeros after the spaces
1573 while (*String
== L
'0') {
1577 if (FceInternalCharToUpper (*String
) == L
'X') {
1578 ASSERT (*(String
- 1) == L
'0');
1579 if (*(String
- 1) != L
'0') {
1590 while (FceInternalIsHexaDecimalDigitCharacter (*String
)) {
1592 // If the Hex Number represented by String overflows according
1593 // to the range defined by UINTN, then ASSERT().
1595 ASSERT (Result
<= RShiftU64 (((UINT64
) ~0) - FceInternalHexCharToUintn (*String
) , 4));
1597 Result
= LShiftU64 (Result
, 4);
1598 Result
= Result
+ FceInternalHexCharToUintn (*String
);
1611 if (('a' <= a
) && (a
<= 'z')) {
1612 return (CHAR16
) (a
- 0x20);
1623 if (('A' <= a
) && (a
<= 'Z')) {
1624 return (CHAR16
) (a
+ 0x20);
1631 Performs a case-insensitive comparison between a Null-terminated
1632 Unicode pattern string and a Null-terminated Unicode string.
1634 @param String - A pointer to a Null-terminated Unicode string.
1635 @param Pattern - A pointer to a Null-terminated Unicode pattern string.
1638 @retval TRUE - Pattern was found in String.
1639 @retval FALSE - Pattern was not found in String.
1651 assert (String
!= NULL
);
1652 assert (Pattern
!= NULL
);
1660 // End of pattern. If end of string, TRUE match
1671 if (ToUpper (c
) != ToUpper (p
)) {
1683 Multiplies a 64-bit unsigned integer by a 32-bit unsigned integer and
1684 generates a 64-bit unsigned result.
1686 This function multiplies the 64-bit unsigned value Multiplicand by the 32-bit
1687 unsigned value Multiplier and generates a 64-bit unsigned result. This 64-
1688 bit unsigned result is returned.
1690 @param Multiplicand A 64-bit unsigned value.
1691 @param Multiplier A 32-bit unsigned value.
1693 @return Multiplicand * Multiplier.
1698 IN UINT64 Multiplicand
,
1699 IN UINT32 Multiplier
1702 return Multiplicand
* Multiplier
;
1706 Divides a 64-bit unsigned integer by a 32-bit unsigned integer and generates
1707 a 64-bit unsigned result.
1709 This function divides the 64-bit unsigned value Dividend by the 32-bit
1710 unsigned value Divisor and generates a 64-bit unsigned quotient. This
1711 function returns the 64-bit unsigned quotient.
1713 If Divisor is 0, then ASSERT().
1715 @param Dividend A 64-bit unsigned value.
1716 @param Divisor A 32-bit unsigned value.
1718 @return Dividend / Divisor
1727 ASSERT (Divisor
!= 0);
1728 return Dividend
/ Divisor
;
1732 Shifts a 64-bit integer left between 0 and 63 bits. The low bits are filled
1733 with zeros. The shifted value is returned.
1735 This function shifts the 64-bit value Operand to the left by Count bits. The
1736 low Count bits are set to zero. The shifted value is returned.
1738 If Count is greater than 63, then ASSERT().
1740 @param Operand The 64-bit operand to shift left.
1741 @param Count The number of bits to shift left.
1743 @return Operand << Count.
1752 ASSERT (Count
< 64);
1753 return Operand
<< Count
;
1757 Shifts a 64-bit integer right between 0 and 63 bits. This high bits are
1758 filled with zeros. The shifted value is returned.
1760 This function shifts the 64-bit value Operand to the right by Count bits. The
1761 high Count bits are set to zero. The shifted value is returned.
1763 If Count is greater than 63, then ASSERT().
1765 @param Operand The 64-bit operand to shift right.
1766 @param Count The number of bits to shift right.
1768 @return Operand >> Count.
1778 ASSERT (Count
< 64);
1779 return Operand
>> Count
;
1784 Divides a 64-bit unsigned integer by a 32-bit unsigned integer and generates
1785 a 64-bit unsigned result and an optional 32-bit unsigned remainder.
1787 This function divides the 64-bit unsigned value Dividend by the 32-bit
1788 unsigned value Divisor and generates a 64-bit unsigned quotient. If Remainder
1789 is not NULL, then the 32-bit unsigned remainder is returned in Remainder.
1790 This function returns the 64-bit unsigned quotient.
1792 If Divisor is 0, then ASSERT().
1794 @param Dividend A 64-bit unsigned value.
1795 @param Divisor A 32-bit unsigned value.
1796 @param Remainder A pointer to a 32-bit unsigned value. This parameter is
1797 optional and may be NULL.
1799 @return Dividend / Divisor
1803 DivU64x32Remainder (
1806 OUT UINT32
*Remainder
1809 ASSERT (Divisor
!= 0);
1811 if (Remainder
!= NULL
) {
1812 *Remainder
= (UINT32
)(Dividend
% Divisor
);
1814 return Dividend
/ Divisor
;
1818 Copies a buffer to an allocated buffer.
1820 Allocates the number bytes specified by AllocationSize, copies allocationSize bytes
1821 from Buffer to the newly allocated buffer, and returns a pointer to the allocated
1822 buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there
1823 is not enough memory remaining to satisfy the request, then NULL is returned.
1825 If Buffer is NULL, then ASSERT().
1827 @param AllocationSize The number of bytes to allocate and zero.
1828 @param Buffer The buffer to copy to the allocated buffer.
1830 @return A pointer to the allocated buffer or NULL if allocation fails.
1834 FceAllocateCopyPool (
1835 IN UINTN AllocationSize
,
1836 IN CONST VOID
*Buffer
1843 if ((Buffer
== NULL
) || (AllocationSize
== 0)) {
1847 Memory
= calloc (AllocationSize
, sizeof (CHAR8
));
1848 if (Memory
!= NULL
) {
1849 Memory
= memcpy (Memory
, Buffer
, AllocationSize
);
1855 Initializes the head node of a doubly-linked list, and returns the pointer to
1856 the head node of the doubly-linked list.
1858 Initializes the forward and backward links of a new linked list. After
1859 initializing a linked list with this function, the other linked list
1860 functions may be used to add and remove nodes from the linked list. It is up
1861 to the caller of this function to allocate the memory for ListHead.
1863 If ListHead is NULL, then ASSERT().
1865 @param ListHead A pointer to the head node of a new doubly-linked list.
1871 InitializeListHead (
1872 IN OUT LIST_ENTRY
*ListHead
1876 assert (ListHead
!= NULL
);
1878 ListHead
->ForwardLink
= ListHead
;
1879 ListHead
->BackLink
= ListHead
;
1884 Adds a node to the beginning of a doubly-linked list, and returns the pointer
1885 to the head node of the doubly-linked list.
1887 Adds the node Entry at the beginning of the doubly-linked list denoted by
1888 ListHead, and returns ListHead.
1890 If ListHead is NULL, then ASSERT().
1891 If Entry is NULL, then ASSERT().
1892 If ListHead was not initialized with INTIALIZE_LIST_HEAD_VARIABLE() or
1893 InitializeListHead(), then ASSERT().
1894 If PcdMaximumLinkedListLenth is not zero, and prior to insertion the number
1895 of nodes in ListHead, including the ListHead node, is greater than or
1896 equal to PcdMaximumLinkedListLength, then ASSERT().
1898 @param ListHead A pointer to the head node of a doubly-linked list.
1899 @param Entry A pointer to a node that is to be inserted at the beginning
1900 of a doubly-linked list.
1907 IN OUT LIST_ENTRY
*ListHead
,
1908 IN OUT LIST_ENTRY
*Entry
1911 assert ((ListHead
!= NULL
) && (Entry
!= NULL
));
1913 Entry
->ForwardLink
= ListHead
->ForwardLink
;
1914 Entry
->BackLink
= ListHead
;
1915 Entry
->ForwardLink
->BackLink
= Entry
;
1916 ListHead
->ForwardLink
= Entry
;
1921 Adds a node to the end of a doubly-linked list, and returns the pointer to
1922 the head node of the doubly-linked list.
1924 Adds the node Entry to the end of the doubly-linked list denoted by ListHead,
1925 and returns ListHead.
1927 If ListHead is NULL, then ASSERT().
1928 If Entry is NULL, then ASSERT().
1929 If ListHead was not initialized with INTIALIZE_LIST_HEAD_VARIABLE() or
1930 InitializeListHead(), then ASSERT().
1931 If PcdMaximumLinkedListLenth is not zero, and prior to insertion the number
1932 of nodes in ListHead, including the ListHead node, is greater than or
1933 equal to PcdMaximumLinkedListLength, then ASSERT().
1935 @param ListHead A pointer to the head node of a doubly-linked list.
1936 @param Entry A pointer to a node that is to be added at the end of the
1944 IN OUT LIST_ENTRY
*ListHead
,
1945 IN OUT LIST_ENTRY
*Entry
1948 assert ((ListHead
!= NULL
) && (Entry
!= NULL
));
1950 Entry
->ForwardLink
= ListHead
;
1951 Entry
->BackLink
= ListHead
->BackLink
;
1952 Entry
->BackLink
->ForwardLink
= Entry
;
1953 ListHead
->BackLink
= Entry
;
1958 Retrieves the first node of a doubly-linked list.
1960 Returns the first node of a doubly-linked list. List must have been
1961 initialized with INTIALIZE_LIST_HEAD_VARIABLE() or InitializeListHead().
1962 If List is empty, then List is returned.
1964 If List is NULL, then ASSERT().
1965 If List was not initialized with INTIALIZE_LIST_HEAD_VARIABLE() or
1966 InitializeListHead(), then ASSERT().
1967 If PcdMaximumLinkedListLenth is not zero, and the number of nodes
1968 in List, including the List node, is greater than or equal to
1969 PcdMaximumLinkedListLength, then ASSERT().
1971 @param List A pointer to the head node of a doubly-linked list.
1973 @return The first node of a doubly-linked list.
1974 @retval NULL The list is empty.
1979 IN CONST LIST_ENTRY
*List
1982 assert (List
!= NULL
);
1984 return List
->ForwardLink
;
1988 Retrieves the next node of a doubly-linked list.
1990 Returns the node of a doubly-linked list that follows Node.
1991 List must have been initialized with INTIALIZE_LIST_HEAD_VARIABLE()
1992 or InitializeListHead(). If List is empty, then List is returned.
1994 If List is NULL, then ASSERT().
1995 If Node is NULL, then ASSERT().
1996 If List was not initialized with INTIALIZE_LIST_HEAD_VARIABLE() or
1997 InitializeListHead(), then ASSERT().
1998 If PcdMaximumLinkedListLenth is not zero, and List contains more than
1999 PcdMaximumLinkedListLenth nodes, then ASSERT().
2000 If PcdVerifyNodeInList is TRUE and Node is not a node in List, then ASSERT().
2002 @param List A pointer to the head node of a doubly-linked list.
2003 @param Node A pointer to a node in the doubly-linked list.
2005 @return A pointer to the next node if one exists. Otherwise List is returned.
2010 IN CONST LIST_ENTRY
*List
,
2011 IN CONST LIST_ENTRY
*Node
2014 assert ((List
!= NULL
) && (Node
!= NULL
));
2016 return Node
->ForwardLink
;
2020 Retrieves the previous node of a doubly-linked list.
2022 Returns the node of a doubly-linked list that precedes Node.
2023 List must have been initialized with INTIALIZE_LIST_HEAD_VARIABLE()
2024 or InitializeListHead(). If List is empty, then List is returned.
2026 If List is NULL, then ASSERT().
2027 If Node is NULL, then ASSERT().
2028 If List was not initialized with INTIALIZE_LIST_HEAD_VARIABLE() or
2029 InitializeListHead(), then ASSERT().
2030 If PcdMaximumLinkedListLenth is not zero, and List contains more than
2031 PcdMaximumLinkedListLenth nodes, then ASSERT().
2032 If PcdVerifyNodeInList is TRUE and Node is not a node in List, then ASSERT().
2034 @param List A pointer to the head node of a doubly-linked list.
2035 @param Node A pointer to a node in the doubly-linked list.
2037 @return A pointer to the previous node if one exists. Otherwise List is returned.
2042 IN CONST LIST_ENTRY
*List
,
2043 IN CONST LIST_ENTRY
*Node
2046 assert ((List
!= NULL
) && (Node
!= NULL
));
2048 return Node
->BackLink
;
2052 Checks to see if a doubly-linked list is empty or not.
2054 Checks to see if the doubly-linked list is empty. If the linked list contains
2055 zero nodes, this function returns TRUE. Otherwise, it returns FALSE.
2057 If ListHead is NULL, then ASSERT().
2058 If ListHead was not initialized with INTIALIZE_LIST_HEAD_VARIABLE() or
2059 InitializeListHead(), then ASSERT().
2060 If PcdMaximumLinkedListLenth is not zero, and the number of nodes
2061 in List, including the List node, is greater than or equal to
2062 PcdMaximumLinkedListLength, then ASSERT().
2064 @param ListHead A pointer to the head node of a doubly-linked list.
2066 @retval TRUE The linked list is empty.
2067 @retval FALSE The linked list is not empty.
2072 IN CONST LIST_ENTRY
*ListHead
2075 assert (ListHead
!= NULL
);
2077 return (BOOLEAN
)(ListHead
->ForwardLink
== ListHead
);
2081 Determines if a node in a doubly-linked list is the head node of a the same
2082 doubly-linked list. This function is typically used to terminate a loop that
2083 traverses all the nodes in a doubly-linked list starting with the head node.
2085 Returns TRUE if Node is equal to List. Returns FALSE if Node is one of the
2086 nodes in the doubly-linked list specified by List. List must have been
2087 initialized with INTIALIZE_LIST_HEAD_VARIABLE() or InitializeListHead().
2089 If List is NULL, then ASSERT().
2090 If Node is NULL, then ASSERT().
2091 If List was not initialized with INTIALIZE_LIST_HEAD_VARIABLE() or InitializeListHead(),
2093 If PcdMaximumLinkedListLenth is not zero, and the number of nodes
2094 in List, including the List node, is greater than or equal to
2095 PcdMaximumLinkedListLength, then ASSERT().
2096 If PcdVerifyNodeInList is TRUE and Node is not a node in List and Node is not
2097 equal to List, then ASSERT().
2099 @param List A pointer to the head node of a doubly-linked list.
2100 @param Node A pointer to a node in the doubly-linked list.
2102 @retval TRUE Node is the head of the doubly-linked list pointed by List.
2103 @retval FALSE Node is not the head of the doubly-linked list pointed by List.
2108 IN CONST LIST_ENTRY
*List
,
2109 IN CONST LIST_ENTRY
*Node
2112 assert ((List
!= NULL
) && (Node
!= NULL
));
2114 return (BOOLEAN
)(Node
== List
);
2118 Determines if a node the last node in a doubly-linked list.
2120 Returns TRUE if Node is the last node in the doubly-linked list specified by
2121 List. Otherwise, FALSE is returned. List must have been initialized with
2122 INTIALIZE_LIST_HEAD_VARIABLE() or InitializeListHead().
2124 If List is NULL, then ASSERT().
2125 If Node is NULL, then ASSERT().
2126 If List was not initialized with INTIALIZE_LIST_HEAD_VARIABLE() or
2127 InitializeListHead(), then ASSERT().
2128 If PcdMaximumLinkedListLenth is not zero, and the number of nodes
2129 in List, including the List node, is greater than or equal to
2130 PcdMaximumLinkedListLength, then ASSERT().
2131 If PcdVerifyNodeInList is TRUE and Node is not a node in List, then ASSERT().
2133 @param List A pointer to the head node of a doubly-linked list.
2134 @param Node A pointer to a node in the doubly-linked list.
2136 @retval TRUE Node is the last node in the linked list.
2137 @retval FALSE Node is not the last node in the linked list.
2142 IN CONST LIST_ENTRY
*List
,
2143 IN CONST LIST_ENTRY
*Node
2146 assert ((List
!= NULL
) && (Node
!= NULL
));
2148 return (BOOLEAN
)(!IsNull (List
, Node
) && (List
->BackLink
== Node
));
2152 Removes a node from a doubly-linked list, and returns the node that follows
2155 Removes the node Entry from a doubly-linked list. It is up to the caller of
2156 this function to release the memory used by this node if that is required. On
2157 exit, the node following Entry in the doubly-linked list is returned. If
2158 Entry is the only node in the linked list, then the head node of the linked
2161 If Entry is NULL, then ASSERT().
2162 If Entry is the head node of an empty list, then ASSERT().
2163 If PcdMaximumLinkedListLength is not zero, and the number of nodes in the
2164 linked list containing Entry, including the Entry node, is greater than
2165 or equal to PcdMaximumLinkedListLength, then ASSERT().
2167 @param Entry A pointer to a node in a linked list.
2174 IN CONST LIST_ENTRY
*Entry
2177 assert (!IsListEmpty (Entry
));
2179 Entry
->ForwardLink
->BackLink
= Entry
->BackLink
;
2180 Entry
->BackLink
->ForwardLink
= Entry
->ForwardLink
;
2181 return Entry
->ForwardLink
;