]> git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/C/FCE/Common.c
BaseTools/FCE: Add a tool FCE
[mirror_edk2.git] / BaseTools / Source / C / FCE / Common.c
1 /** @file
2
3 Common library.
4
5 Copyright (c) 2011-2019, Intel Corporation. All rights reserved.<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
7
8 **/
9 #include "Common.h"
10
11 #define WARNING_STATUS_NUMBER 4
12 #define ERROR_STATUS_NUMBER 24
13
14 CONST CHAR8 mHexStr[] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
15
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
46 };
47
48 /**
49 Copies one Null-terminated Unicode string to another Null-terminated Unicode
50 string and returns the new Unicode string.
51
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.
55
56 If Destination is NULL, then return NULL.
57 If Destination is not aligned on a 16-bit boundary, then return NULL.
58
59 @param Destination A pointer to a Null-terminated Unicode string.
60 @param Source A pointer to a Null-terminated Unicode string.
61
62 @return Destination.
63
64 **/
65 CHAR16 *
66 StrCpy (
67 OUT CHAR16 *Destination,
68 IN CONST CHAR16 *Source
69 )
70 {
71 CHAR16 *ReturnValue;
72
73 ReturnValue = NULL;
74
75 if ((Destination == NULL) || ((UINTN) Destination % 2 != 0)) {
76 return NULL;
77 }
78
79 ReturnValue = Destination;
80 while (*Source != 0) {
81 *(Destination++) = *(Source++);
82 }
83 *Destination = 0;
84 return ReturnValue;
85 }
86
87 /**
88 Returns the length of a Null-terminated Unicode string.
89
90 This function returns the number of Unicode characters in the Null-terminated
91 Unicode string specified by String.
92
93 If String is NULL, then return 0.
94
95 @param String A pointer to a Null-terminated Unicode string.
96
97 @return The length of String.
98
99 **/
100 UINTN
101 FceStrLen (
102 IN CONST CHAR16 *String
103 )
104 {
105 UINTN Length;
106
107 if (String == NULL) {
108 return 0;
109 }
110 for (Length = 0; *String != L'\0'; String++, Length++) {
111 ;
112 }
113 return Length;
114 }
115
116 /**
117 Returns the size of a Null-terminated Unicode string in bytes, including the
118 Null terminator.
119
120 This function returns the size, in bytes, of the Null-terminated Unicode string
121 specified by String.
122
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().
128
129 @param String A pointer to a Null-terminated Unicode string.
130
131 @return The size of String.
132
133 **/
134 UINTN
135 FceStrSize (
136 IN CONST CHAR16 *String
137 )
138 {
139 return (FceStrLen (String) + 1) * sizeof (*String);
140 }
141
142 /**
143 Compares two Null-terminated Unicode strings, and returns the difference
144 between the first mismatched Unicode characters.
145
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.
151
152 @param FirstString A pointer to a Null-terminated Unicode string.
153 @param SecondString A pointer to a Null-terminated Unicode string.
154
155 @retval 0 FirstString is identical to SecondString.
156 @return others FirstString is not identical to SecondString.
157
158 **/
159 INTN
160 FceStrCmp (
161 IN CONST CHAR16 *FirstString,
162 IN CONST CHAR16 *SecondString
163 )
164 {
165 while ((*FirstString != L'\0') && (*FirstString == *SecondString)) {
166 FirstString++;
167 SecondString++;
168 }
169 return *FirstString - *SecondString;
170 }
171
172 /**
173 Concatenates one Null-terminated Unicode string to another Null-terminated
174 Unicode string, and returns the concatenated Unicode string.
175
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.
181
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().
197
198 @param Destination A pointer to a Null-terminated Unicode string.
199 @param Source A pointer to a Null-terminated Unicode string.
200
201 @return Destination.
202
203 **/
204 CHAR16 *
205 StrCat (
206 IN OUT CHAR16 *Destination,
207 IN CONST CHAR16 *Source
208 )
209 {
210 StrCpy (Destination + FceStrLen (Destination), Source);
211
212 //
213 // Size of the resulting string should never be zero.
214 // PcdMaximumUnicodeStringLength is tested inside FceStrLen().
215 //
216 ASSERT (FceStrSize (Destination) != 0);
217 return Destination;
218 }
219
220 /**
221 Returns the first occurrence of a Null-terminated Unicode sub-string
222 in a Null-terminated Unicode string.
223
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
228 returned.
229
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().
234
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().
238
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.
241
242 @retval NULL If the SearchString does not appear in String.
243 @return others If there is a match.
244
245 **/
246 CHAR16 *
247 StrStr (
248 IN CONST CHAR16 *String,
249 IN CONST CHAR16 *SearchString
250 )
251 {
252 CONST CHAR16 *FirstMatch;
253 CONST CHAR16 *SearchStringTmp;
254
255 //
256 // ASSERT both strings are less long than PcdMaximumUnicodeStringLength.
257 // Length tests are performed inside FceStrLen().
258 //
259 ASSERT (FceStrSize (String) != 0);
260 ASSERT (FceStrSize (SearchString) != 0);
261
262 if (*SearchString == L'\0') {
263 return (CHAR16 *) String;
264 }
265
266 while (*String != L'\0') {
267 SearchStringTmp = SearchString;
268 FirstMatch = String;
269
270 while ((*String == *SearchStringTmp)
271 && (*String != L'\0')) {
272 String++;
273 SearchStringTmp++;
274 }
275
276 if (*SearchStringTmp == L'\0') {
277 return (CHAR16 *) FirstMatch;
278 }
279
280 if (*String == L'\0') {
281 return NULL;
282 }
283
284 String = FirstMatch + 1;
285 }
286
287 return NULL;
288 }
289
290 /**
291 Convert one Null-terminated ASCII string to a Null-terminated
292 Unicode string and returns the Unicode string.
293
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.
299
300 @param Source A pointer to a Null-terminated ASCII string.
301 @param Destination A pointer to a Null-terminated Unicode string.
302
303 @return Destination.
304 @return NULL If Destination or Source is NULL, return NULL.
305
306 **/
307 CHAR16 *
308 AsciiStrToUnicodeStr (
309 IN CONST CHAR8 *Source,
310 OUT CHAR16 *Destination
311 )
312 {
313 CHAR16 *ReturnValue;
314
315 ReturnValue = NULL;
316
317 if ((Destination == NULL) || (Source == NULL) || (strlen (Source) == 0)) {
318 return NULL;
319 }
320 ReturnValue = Destination;
321 while (*Source != '\0') {
322 *(Destination++) = (CHAR16) *(Source++);
323 }
324 //
325 // End the Destination with a NULL.
326 //
327 *Destination = '\0';
328
329 return ReturnValue;
330 }
331
332 /**
333 Internal function that convert a number to a string in Buffer.
334
335 Print worker function that converts a decimal or hexadecimal number to an ASCII string in Buffer.
336
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
340
341 @return A pointer to the end of buffer filled with ASCII string.
342
343 **/
344 CHAR8 *
345 BasePrintLibValueToString (
346 IN OUT CHAR8 *Buffer,
347 IN INT64 Value,
348 IN UINTN Radix
349 )
350 {
351 UINT32 Remainder;
352
353 //
354 // Loop to convert one digit at a time in reverse order
355 //
356 *Buffer = 0;
357 do {
358 Value = (INT64)DivU64x32Remainder ((UINT64)Value, (UINT32)Radix, &Remainder);
359 *(++Buffer) = mHexStr[Remainder];
360 } while (Value != 0);
361
362 //
363 // Return pointer of the end of filled buffer.
364 //
365 return Buffer;
366 }
367
368 /**
369 Reads a 16-bit value from memory that may be unaligned.
370
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.
373
374 If the Buffer is NULL, then ASSERT().
375
376 @param Buffer A pointer to a 16-bit value that may be unaligned.
377
378 @return The 16-bit value read from Buffer.
379
380 **/
381 UINT16
382 FceReadUnaligned16 (
383 IN CONST UINT16 *Buffer
384 )
385 {
386 ASSERT (Buffer != NULL);
387
388 return *Buffer;
389 }
390
391 /**
392 Reads a 32-bit value from memory that may be unaligned.
393
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.
396
397 If the Buffer is NULL, then ASSERT().
398
399 @param Buffer A pointer to a 32-bit value that may be unaligned.
400
401 @return The 32-bit value read from Buffer.
402
403 **/
404 UINT32
405 ReadUnaligned32 (
406 IN CONST UINT32 *Buffer
407 )
408 {
409 ASSERT (Buffer != NULL);
410
411 return *Buffer;
412 }
413
414 /**
415 Internal function that places the character into the Buffer.
416
417 Internal function that places ASCII or Unicode character into the Buffer.
418
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
421 placed after that.
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.
426
427 @return Buffer.
428
429 **/
430 CHAR8 *
431 BasePrintLibFillBuffer (
432 OUT CHAR8 *Buffer,
433 IN CHAR8 *EndBuffer,
434 IN INTN Length,
435 IN UINTN Character,
436 IN INTN Increment
437 )
438 {
439 INTN Index;
440
441 for (Index = 0; Index < Length && Buffer < EndBuffer; Index++) {
442 *Buffer = (CHAR8) Character;
443 if (Increment != 1) {
444 *(Buffer + 1) = (CHAR8)(Character >> 8);
445 }
446 Buffer += Increment;
447 }
448
449 return Buffer;
450 }
451
452 /**
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.
455
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.
459
460 If COUNT_ONLY_NO_PRINT is set in Flags, Buffer will not be modified at all.
461
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
465 buffer.
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
471 processing Format.
472 @param[in] BaseListMarker BASE_LIST style variable argument list consumed
473 by processing Format.
474
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.
478
479 **/
480 UINTN
481 BasePrintLibSPrintMarker (
482 OUT CHAR8 *Buffer,
483 IN UINTN BufferSize,
484 IN UINTN Flags,
485 IN CONST CHAR8 *Format,
486 IN VA_LIST VaListMarker, OPTIONAL
487 IN BASE_LIST BaseListMarker OPTIONAL
488 )
489 {
490 CHAR8 *OriginalBuffer;
491 CHAR8 *EndBuffer;
492 CHAR8 ValueBuffer[MAXIMUM_VALUE_CHARACTERS];
493 UINT32 BytesPerOutputCharacter;
494 UINTN BytesPerFormatCharacter;
495 UINTN FormatMask;
496 UINTN FormatCharacter;
497 UINTN Width;
498 UINTN Precision;
499 INT64 Value;
500 CONST CHAR8 *ArgumentString;
501 UINTN Character;
502 EFI_GUID *TmpGuid;
503 TIME *TmpTime;
504 UINTN Count;
505 UINTN ArgumentMask;
506 INTN BytesPerArgumentCharacter;
507 UINTN ArgumentCharacter;
508 BOOLEAN Done;
509 UINTN Index;
510 CHAR8 Prefix;
511 BOOLEAN ZeroPad;
512 BOOLEAN Comma;
513 UINTN Digits;
514 UINTN Radix;
515 RETURN_STATUS Status;
516 UINT32 GuidData1;
517 UINT16 GuidData2;
518 UINT16 GuidData3;
519 UINTN LengthToReturn;
520
521 //
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).
525 //
526
527 if ((Flags & COUNT_ONLY_NO_PRINT) != 0) {
528 if (BufferSize == 0) {
529 Buffer = NULL;
530 }
531 } else {
532 //
533 // We can run without a Buffer for counting only.
534 //
535 if (BufferSize == 0) {
536 return 0;
537 }
538 ASSERT (Buffer != NULL);
539 }
540
541 if ((Flags & OUTPUT_UNICODE) != 0) {
542 BytesPerOutputCharacter = 2;
543 } else {
544 BytesPerOutputCharacter = 1;
545 }
546
547 LengthToReturn = 0;
548
549 //
550 // Reserve space for the Null terminator.
551 //
552 BufferSize--;
553 OriginalBuffer = Buffer;
554
555 //
556 // Set the tag for the end of the input Buffer.
557 //
558 EndBuffer = Buffer + BufferSize * BytesPerOutputCharacter;
559
560 if ((Flags & FORMAT_UNICODE) != 0) {
561 //
562 // Make sure format string cannot contain more than PcdMaximumUnicodeStringLength
563 // Unicode characters if PcdMaximumUnicodeStringLength is not zero.
564 //
565 ASSERT (FceStrSize ((CHAR16 *) Format) != 0);
566 BytesPerFormatCharacter = 2;
567 FormatMask = 0xffff;
568 } else {
569 //
570 // Make sure format string cannot contain more than PcdMaximumAsciiStringLength
571 // Ascii characters if PcdMaximumAsciiStringLength is not zero.
572 //
573 ASSERT (strlen (Format) + 1 != 0);
574 BytesPerFormatCharacter = 1;
575 FormatMask = 0xff;
576 }
577
578 //
579 // Get the first character from the format string
580 //
581 FormatCharacter = ((*Format & 0xff) | (*(Format + 1) << 8)) & FormatMask;
582
583 //
584 // Loop until the end of the format string is reached or the output buffer is full
585 //
586 while (FormatCharacter != 0 && Buffer < EndBuffer) {
587 //
588 // Clear all the flag bits except those that may have been passed in
589 //
590 Flags &= (OUTPUT_UNICODE | FORMAT_UNICODE | COUNT_ONLY_NO_PRINT);
591
592 //
593 // Set the default width to zero, and the default precision to 1
594 //
595 Width = 0;
596 Precision = 1;
597 Prefix = 0;
598 Comma = FALSE;
599 ZeroPad = FALSE;
600 Count = 0;
601 Digits = 0;
602
603 switch (FormatCharacter) {
604 case '%':
605 //
606 // Parse Flags and Width
607 //
608 for (Done = FALSE; !Done; ) {
609 Format += BytesPerFormatCharacter;
610 FormatCharacter = ((*Format & 0xff) | (*(Format + 1) << 8)) & FormatMask;
611 switch (FormatCharacter) {
612 case '.':
613 Flags |= PRECISION;
614 break;
615 case '-':
616 Flags |= LEFT_JUSTIFY;
617 break;
618 case '+':
619 Flags |= PREFIX_SIGN;
620 break;
621 case ' ':
622 Flags |= PREFIX_BLANK;
623 break;
624 case ',':
625 Flags |= COMMA_TYPE;
626 break;
627 case 'L':
628 case 'l':
629 Flags |= LONG_TYPE;
630 break;
631 case '*':
632 if ((Flags & PRECISION) == 0) {
633 Flags |= PAD_TO_WIDTH;
634 if (BaseListMarker == NULL) {
635 Width = VA_ARG (VaListMarker, UINTN);
636 } else {
637 Width = BASE_ARG (BaseListMarker, UINTN);
638 }
639 } else {
640 if (BaseListMarker == NULL) {
641 Precision = VA_ARG (VaListMarker, UINTN);
642 } else {
643 Precision = BASE_ARG (BaseListMarker, UINTN);
644 }
645 }
646 break;
647 case '0':
648 if ((Flags & PRECISION) == 0) {
649 Flags |= PREFIX_ZERO;
650 }
651 case '1':
652 case '2':
653 case '3':
654 case '4':
655 case '5':
656 case '6':
657 case '7':
658 case '8':
659 case '9':
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;
664 }
665 Format -= BytesPerFormatCharacter;
666 if ((Flags & PRECISION) == 0) {
667 Flags |= PAD_TO_WIDTH;
668 Width = Count;
669 } else {
670 Precision = Count;
671 }
672 break;
673
674 case '\0':
675 //
676 // Make no output if Format string terminates unexpectedly when
677 // looking up for flag, width, precision and type.
678 //
679 Format -= BytesPerFormatCharacter;
680 Precision = 0;
681 //
682 // break skipped on purpose.
683 //
684 default:
685 Done = TRUE;
686 break;
687 }
688 }
689
690 //
691 // Handle each argument type
692 //
693 switch (FormatCharacter) {
694 case 'p':
695 //
696 // Flag space, +, 0, L & l are invalid for type p.
697 //
698 Flags &= ~(PREFIX_BLANK | PREFIX_SIGN | PREFIX_ZERO | LONG_TYPE);
699 if (sizeof (VOID *) > 4) {
700 Flags |= LONG_TYPE;
701 }
702 case 'X':
703 Flags |= PREFIX_ZERO;
704 //
705 // break skipped on purpose
706 //
707 case 'x':
708 Flags |= RADIX_HEX;
709 //
710 // break skipped on purpose
711 //
712 case 'd':
713 if ((Flags & LONG_TYPE) == 0) {
714 //
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.
721 //
722 if (BaseListMarker == NULL) {
723 Value = VA_ARG (VaListMarker, int);
724 } else {
725 Value = BASE_ARG (BaseListMarker, int);
726 }
727 } else {
728 if (BaseListMarker == NULL) {
729 Value = VA_ARG (VaListMarker, INT64);
730 } else {
731 Value = BASE_ARG (BaseListMarker, INT64);
732 }
733 }
734 if ((Flags & PREFIX_BLANK) != 0) {
735 Prefix = ' ';
736 }
737 if ((Flags & PREFIX_SIGN) != 0) {
738 Prefix = '+';
739 }
740 if ((Flags & COMMA_TYPE) != 0) {
741 Comma = TRUE;
742 }
743 if ((Flags & RADIX_HEX) == 0) {
744 Radix = 10;
745 if (Comma) {
746 Flags &= (~PREFIX_ZERO);
747 Precision = 1;
748 }
749 if (Value < 0) {
750 Flags |= PREFIX_SIGN;
751 Prefix = '-';
752 Value = -Value;
753 }
754 } else {
755 Radix = 16;
756 Comma = FALSE;
757 if ((Flags & LONG_TYPE) == 0 && Value < 0) {
758 //
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.
765 //
766 Value = (unsigned int)Value;
767 }
768 }
769 //
770 // Convert Value to a reversed string
771 //
772 Count = BasePrintLibValueToString (ValueBuffer, Value, Radix) - ValueBuffer;
773 if (Value == 0 && Precision == 0) {
774 Count = 0;
775 }
776 ArgumentString = (CHAR8 *)ValueBuffer + Count;
777
778 Digits = Count % 3;
779 if (Digits != 0) {
780 Digits = 3 - Digits;
781 }
782 if (Comma && Count != 0) {
783 Count += ((Count - 1) / 3);
784 }
785 if (Prefix != 0) {
786 Count++;
787 Precision++;
788 }
789 Flags |= ARGUMENT_REVERSED;
790 ZeroPad = TRUE;
791 if ((Flags & PREFIX_ZERO) != 0) {
792 if ((Flags & LEFT_JUSTIFY) == 0) {
793 if ((Flags & PAD_TO_WIDTH) != 0) {
794 if ((Flags & PRECISION) == 0) {
795 Precision = Width;
796 }
797 }
798 }
799 }
800 break;
801
802 case 's':
803 case 'S':
804 Flags |= ARGUMENT_UNICODE;
805 //
806 // break skipped on purpose
807 //
808 case 'a':
809 if (BaseListMarker == NULL) {
810 ArgumentString = VA_ARG (VaListMarker, CHAR8 *);
811 } else {
812 ArgumentString = BASE_ARG (BaseListMarker, CHAR8 *);
813 }
814 if (ArgumentString == NULL) {
815 Flags &= (~ARGUMENT_UNICODE);
816 ArgumentString = "<null string>";
817 }
818 //
819 // Set the default precision for string to be zero if not specified.
820 //
821 if ((Flags & PRECISION) == 0) {
822 Precision = 0;
823 }
824 break;
825
826 case 'c':
827 if (BaseListMarker == NULL) {
828 Character = VA_ARG (VaListMarker, UINTN) & 0xffff;
829 } else {
830 Character = BASE_ARG (BaseListMarker, UINTN) & 0xffff;
831 }
832 ArgumentString = (CHAR8 *)&Character;
833 Flags |= ARGUMENT_UNICODE;
834 break;
835
836 case 'g':
837 if (BaseListMarker == NULL) {
838 TmpGuid = VA_ARG (VaListMarker, EFI_GUID *);
839 } else {
840 TmpGuid = BASE_ARG (BaseListMarker, EFI_GUID *);
841 }
842 if (TmpGuid == NULL) {
843 ArgumentString = "<null guid>";
844 } else {
845 GuidData1 = ReadUnaligned32 (&(TmpGuid->Data1));
846 GuidData2 = FceReadUnaligned16 (&(TmpGuid->Data2));
847 GuidData3 = FceReadUnaligned16 (&(TmpGuid->Data3));
848 BasePrintLibSPrint (
849 ValueBuffer,
850 MAXIMUM_VALUE_CHARACTERS,
851 0,
852 "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
853 GuidData1,
854 GuidData2,
855 GuidData3,
856 TmpGuid->Data4[0],
857 TmpGuid->Data4[1],
858 TmpGuid->Data4[2],
859 TmpGuid->Data4[3],
860 TmpGuid->Data4[4],
861 TmpGuid->Data4[5],
862 TmpGuid->Data4[6],
863 TmpGuid->Data4[7]
864 );
865 ArgumentString = ValueBuffer;
866 }
867 break;
868
869 case 't':
870 if (BaseListMarker == NULL) {
871 TmpTime = VA_ARG (VaListMarker, TIME *);
872 } else {
873 TmpTime = BASE_ARG (BaseListMarker, TIME *);
874 }
875 if (TmpTime == NULL) {
876 ArgumentString = "<null time>";
877 } else {
878 BasePrintLibSPrint (
879 ValueBuffer,
880 MAXIMUM_VALUE_CHARACTERS,
881 0,
882 "%02d/%02d/%04d %02d:%02d",
883 TmpTime->Month,
884 TmpTime->Day,
885 TmpTime->Year,
886 TmpTime->Hour,
887 TmpTime->Minute
888 );
889 ArgumentString = ValueBuffer;
890 }
891 break;
892
893 case 'r':
894 if (BaseListMarker == NULL) {
895 Status = VA_ARG (VaListMarker, RETURN_STATUS);
896 } else {
897 Status = BASE_ARG (BaseListMarker, RETURN_STATUS);
898 }
899 ArgumentString = ValueBuffer;
900 if (RETURN_ERROR (Status)) {
901 //
902 // Clear error bit
903 //
904 Index = Status & ~MAX_BIT;
905 if (Index > 0 && Index <= ERROR_STATUS_NUMBER) {
906 ArgumentString = mStatusString [Index + WARNING_STATUS_NUMBER];
907 }
908 } else {
909 Index = Status;
910 if (Index <= WARNING_STATUS_NUMBER) {
911 ArgumentString = mStatusString [Index];
912 }
913 }
914 if (ArgumentString == ValueBuffer) {
915 BasePrintLibSPrint ((CHAR8 *) ValueBuffer, MAXIMUM_VALUE_CHARACTERS, 0, "%08X", Status);
916 }
917 break;
918
919 case '\r':
920 Format += BytesPerFormatCharacter;
921 FormatCharacter = ((*Format & 0xff) | (*(Format + 1) << 8)) & FormatMask;
922 if (FormatCharacter == '\n') {
923 //
924 // Translate '\r\n' to '\r\n'
925 //
926 ArgumentString = "\r\n";
927 } else {
928 //
929 // Translate '\r' to '\r'
930 //
931 ArgumentString = "\r";
932 Format -= BytesPerFormatCharacter;
933 }
934 break;
935
936 case '\n':
937 //
938 // Translate '\n' to '\r\n' and '\n\r' to '\r\n'
939 //
940 ArgumentString = "\r\n";
941 Format += BytesPerFormatCharacter;
942 FormatCharacter = ((*Format & 0xff) | (*(Format + 1) << 8)) & FormatMask;
943 if (FormatCharacter != '\r') {
944 Format -= BytesPerFormatCharacter;
945 }
946 break;
947
948 case '%':
949 default:
950 //
951 // if the type is '%' or unknown, then print it to the screen
952 //
953 ArgumentString = (CHAR8 *)&FormatCharacter;
954 Flags |= ARGUMENT_UNICODE;
955 break;
956 }
957 break;
958
959 case '\r':
960 Format += BytesPerFormatCharacter;
961 FormatCharacter = ((*Format & 0xff) | (*(Format + 1) << 8)) & FormatMask;
962 if (FormatCharacter == '\n') {
963 //
964 // Translate '\r\n' to '\r\n'
965 //
966 ArgumentString = "\r\n";
967 } else {
968 //
969 // Translate '\r' to '\r'
970 //
971 ArgumentString = "\r";
972 Format -= BytesPerFormatCharacter;
973 }
974 break;
975
976 case '\n':
977 //
978 // Translate '\n' to '\r\n' and '\n\r' to '\r\n'
979 //
980 ArgumentString = "\r\n";
981 Format += BytesPerFormatCharacter;
982 FormatCharacter = ((*Format & 0xff) | (*(Format + 1) << 8)) & FormatMask;
983 if (FormatCharacter != '\r') {
984 Format -= BytesPerFormatCharacter;
985 }
986 break;
987
988 default:
989 ArgumentString = (CHAR8 *)&FormatCharacter;
990 Flags |= ARGUMENT_UNICODE;
991 break;
992 }
993
994 //
995 // Retrieve the ArgumentString attriubutes
996 //
997 if ((Flags & ARGUMENT_UNICODE) != 0) {
998 ArgumentMask = 0xffff;
999 BytesPerArgumentCharacter = 2;
1000 } else {
1001 ArgumentMask = 0xff;
1002 BytesPerArgumentCharacter = 1;
1003 }
1004 if ((Flags & ARGUMENT_REVERSED) != 0) {
1005 BytesPerArgumentCharacter = -BytesPerArgumentCharacter;
1006 } else {
1007 //
1008 // Compute the number of characters in ArgumentString and store it in Count
1009 // ArgumentString is either null-terminated, or it contains Precision characters
1010 //
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) {
1014 break;
1015 }
1016 }
1017 }
1018
1019 if (Precision < Count) {
1020 Precision = Count;
1021 }
1022
1023 //
1024 // Pad before the string
1025 //
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);
1030 }
1031 }
1032
1033 if (ZeroPad) {
1034 if (Prefix != 0) {
1035 LengthToReturn += (1 * BytesPerOutputCharacter);
1036 if ((Flags & COUNT_ONLY_NO_PRINT) == 0 && Buffer != NULL) {
1037 Buffer = BasePrintLibFillBuffer (Buffer, EndBuffer, 1, Prefix, BytesPerOutputCharacter);
1038 }
1039 }
1040 LengthToReturn += ((Precision - Count) * BytesPerOutputCharacter);
1041 if ((Flags & COUNT_ONLY_NO_PRINT) == 0 && Buffer != NULL) {
1042 Buffer = BasePrintLibFillBuffer (Buffer, EndBuffer, Precision - Count, '0', BytesPerOutputCharacter);
1043 }
1044 } else {
1045 LengthToReturn += ((Precision - Count) * BytesPerOutputCharacter);
1046 if ((Flags & COUNT_ONLY_NO_PRINT) == 0 && Buffer != NULL) {
1047 Buffer = BasePrintLibFillBuffer (Buffer, EndBuffer, Precision - Count, ' ', BytesPerOutputCharacter);
1048 }
1049 if (Prefix != 0) {
1050 LengthToReturn += (1 * BytesPerOutputCharacter);
1051 if ((Flags & COUNT_ONLY_NO_PRINT) == 0 && Buffer != NULL) {
1052 Buffer = BasePrintLibFillBuffer (Buffer, EndBuffer, 1, Prefix, BytesPerOutputCharacter);
1053 }
1054 }
1055 }
1056
1057 //
1058 // Output the Prefix character if it is present
1059 //
1060 Index = 0;
1061 if (Prefix != 0) {
1062 Index++;
1063 }
1064
1065 //
1066 // Copy the string into the output buffer performing the required type conversions
1067 //
1068 while (Index < Count) {
1069 ArgumentCharacter = ((*ArgumentString & 0xff) | (*(ArgumentString + 1) << 8)) & ArgumentMask;
1070
1071 LengthToReturn += (1 * BytesPerOutputCharacter);
1072 if ((Flags & COUNT_ONLY_NO_PRINT) == 0 && Buffer != NULL) {
1073 Buffer = BasePrintLibFillBuffer (Buffer, EndBuffer, 1, ArgumentCharacter, BytesPerOutputCharacter);
1074 }
1075 ArgumentString += BytesPerArgumentCharacter;
1076 Index++;
1077 if (Comma) {
1078 Digits++;
1079 if (Digits == 3) {
1080 Digits = 0;
1081 Index++;
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);
1086 }
1087 }
1088 }
1089 }
1090 }
1091
1092 //
1093 // Pad after the string
1094 //
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);
1099 }
1100 }
1101
1102 //
1103 // Get the next character from the format string
1104 //
1105 Format += BytesPerFormatCharacter;
1106
1107 //
1108 // Get the next character from the format string
1109 //
1110 FormatCharacter = ((*Format & 0xff) | (*(Format + 1) << 8)) & FormatMask;
1111 }
1112
1113 if ((Flags & COUNT_ONLY_NO_PRINT) != 0) {
1114 return (LengthToReturn / BytesPerOutputCharacter);
1115 }
1116
1117 ASSERT (Buffer != NULL);
1118 //
1119 // Null terminate the Unicode or ASCII string
1120 //
1121 BasePrintLibFillBuffer (Buffer, EndBuffer + BytesPerOutputCharacter, 1, 0, BytesPerOutputCharacter);
1122 //
1123 // Make sure output buffer cannot contain more than PcdMaximumUnicodeStringLength
1124 // Unicode characters if PcdMaximumUnicodeStringLength is not zero.
1125 //
1126 ASSERT ((((Flags & OUTPUT_UNICODE) == 0)) || (FceStrSize ((CHAR16 *) OriginalBuffer) != 0));
1127 //
1128 // Make sure output buffer cannot contain more than PcdMaximumAsciiStringLength
1129 // ASCII characters if PcdMaximumAsciiStringLength is not zero.
1130 //
1131 ASSERT ((((Flags & OUTPUT_UNICODE) != 0)) || ((strlen (OriginalBuffer) + 1) != 0));
1132
1133 return ((Buffer - OriginalBuffer) / BytesPerOutputCharacter);
1134 }
1135
1136 /**
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.
1139
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
1143
1144 @param StartOfBuffer The character buffer to print the results of the parsing
1145 of Format into.
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.
1152
1153 @return The number of characters printed.
1154
1155 **/
1156 UINTN
1157 BasePrintLibSPrint (
1158 OUT CHAR8 *StartOfBuffer,
1159 IN UINTN BufferSize,
1160 IN UINTN Flags,
1161 IN CONST CHAR8 *FormatString,
1162 ...
1163 )
1164 {
1165 VA_LIST Marker;
1166
1167 VA_START (Marker, FormatString);
1168 return BasePrintLibSPrintMarker (StartOfBuffer, BufferSize, Flags, FormatString, Marker, NULL);
1169 }
1170
1171 /**
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
1174
1175 Produces a Null-terminated Unicode string in the output buffer specified by StartOfBuffer
1176 and BufferSize.
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.
1183
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
1190 ASSERT().
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().
1194
1195 @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated
1196 Unicode string.
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.
1200
1201 @return The number of Unicode characters in the produced output buffer not including the
1202 Null-terminator.
1203
1204 **/
1205 UINTN
1206 UnicodeVSPrint (
1207 OUT CHAR16 *StartOfBuffer,
1208 IN UINTN BufferSize,
1209 IN CONST CHAR16 *FormatString,
1210 IN VA_LIST Marker
1211 )
1212 {
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);
1216 }
1217
1218 /**
1219 Produces a Null-terminated Unicode string in an output buffer based on a Null-terminated
1220 Unicode format string and variable argument list.
1221
1222 Produces a Null-terminated Unicode string in the output buffer specified by StartOfBuffer
1223 and BufferSize.
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.
1229
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
1236 ASSERT().
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().
1240
1241 @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated
1242 Unicode string.
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.
1247
1248 @return The number of Unicode characters in the produced output buffer not including the
1249 Null-terminator.
1250
1251 **/
1252 UINTN
1253 UnicodeSPrint (
1254 OUT CHAR16 *StartOfBuffer,
1255 IN UINTN BufferSize,
1256 IN CONST CHAR16 *FormatString,
1257 ...
1258 )
1259 {
1260 VA_LIST Marker;
1261
1262 VA_START (Marker, FormatString);
1263 return UnicodeVSPrint (StartOfBuffer, BufferSize, FormatString, Marker);
1264 }
1265
1266 /**
1267 Convert a Null-terminated Unicode string to a Null-terminated
1268 ASCII string and returns the ASCII string.
1269
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.
1276
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().
1281
1282 If any Unicode characters in Source contain non-zero value in
1283 the upper 8 bits, then ASSERT().
1284
1285 @param Source Pointer to a Null-terminated Unicode string.
1286 @param Destination Pointer to a Null-terminated ASCII string.
1287
1288 @reture Destination
1289
1290 **/
1291 CHAR8 *
1292 UnicodeStrToAsciiStr (
1293 IN CONST CHAR16 *Source,
1294 OUT CHAR8 *Destination
1295 )
1296 {
1297 CHAR8 *ReturnValue;
1298
1299 ReturnValue = Destination;
1300 assert (Destination != NULL);
1301 assert (Source != NULL);
1302 assert (((UINTN) Source & 0x01) == 0);
1303
1304 while (*Source != L'\0') {
1305 //
1306 // If any Unicode characters in Source contain
1307 // non-zero value in the upper 8 bits, then ASSERT().
1308 //
1309 assert (*Source < 0x100);
1310 *(ReturnValue++) = (CHAR8) *(Source++);
1311 }
1312
1313 *ReturnValue = '\0';
1314
1315 return Destination;
1316 }
1317
1318 /**
1319 Allocate new memory and then copy the Unicode string Source to Destination.
1320
1321 @param Dest Location to copy string
1322 @param Src String to copy
1323
1324 **/
1325 VOID
1326 NewStringCpy (
1327 IN OUT CHAR16 **Dest,
1328 IN CHAR16 *Src
1329 )
1330 {
1331 if (*Dest != NULL) {
1332 FreePool (*Dest);
1333 }
1334 *Dest = FceAllocateCopyPool (FceStrSize (Src), Src);
1335 ASSERT (*Dest != NULL);
1336 }
1337
1338 /**
1339 Check if a Unicode character is a decimal character.
1340
1341 This internal function checks if a Unicode character is a
1342 decimal character. The valid decimal character is from
1343 L'0' to L'9'.
1344
1345 @param Char The character to check against.
1346
1347 @retval TRUE If the Char is a decmial character.
1348 @retval FALSE If the Char is not a decmial character.
1349
1350 **/
1351 BOOLEAN
1352 FceInternalIsDecimalDigitCharacter (
1353 IN CHAR16 Char
1354 )
1355 {
1356 return (BOOLEAN) ((Char >= L'0') && (Char <= L'9'));
1357 }
1358
1359 /**
1360 Convert a Unicode character to upper case only if
1361 it maps to a valid small-case ASCII character.
1362
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.
1367
1368 @param Char The character to convert.
1369
1370 @retval LowerCharacter If the Char is with range L'a' to L'z'.
1371 @retval Unchanged Otherwise.
1372
1373 **/
1374 CHAR16
1375 FceInternalCharToUpper (
1376 IN CHAR16 Char
1377 )
1378 {
1379 if ((Char >= L'a') && (Char <= L'z')) {
1380 return (CHAR16) (Char - (L'a' - L'A'));
1381 }
1382
1383 return Char;
1384 }
1385
1386 /**
1387 Convert a Unicode character to numerical value.
1388
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.
1393
1394 @param Char The character to convert.
1395
1396 @return The numerical value converted.
1397
1398 **/
1399 UINTN
1400 FceInternalHexCharToUintn (
1401 IN CHAR16 Char
1402 )
1403 {
1404 if (FceInternalIsDecimalDigitCharacter (Char)) {
1405 return Char - L'0';
1406 }
1407
1408 return (UINTN) (10 + FceInternalCharToUpper (Char) - L'A');
1409 }
1410
1411 /**
1412 Check if a Unicode character is a hexadecimal character.
1413
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'.
1417
1418
1419 @param Char The character to check against.
1420
1421 @retval TRUE If the Char is a hexadecmial character.
1422 @retval FALSE If the Char is not a hexadecmial character.
1423
1424 **/
1425 BOOLEAN
1426 FceInternalIsHexaDecimalDigitCharacter (
1427 IN CHAR16 Char
1428 )
1429 {
1430
1431 return (BOOLEAN) (FceInternalIsDecimalDigitCharacter (Char) ||
1432 ((Char >= L'A') && (Char <= L'F')) ||
1433 ((Char >= L'a') && (Char <= L'f')));
1434 }
1435
1436
1437 /**
1438 Convert a Null-terminated Unicode decimal string to a value of
1439 type UINT64.
1440
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:
1444
1445 [spaces] [decimal digits].
1446
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.
1453
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,
1458 then 0 is returned.
1459 If the number represented by String overflows according
1460 to the range defined by UINT64, then ASSERT().
1461
1462 If PcdMaximumUnicodeStringLength is not zero, and String contains
1463 more than PcdMaximumUnicodeStringLength Unicode characters, not including
1464 the Null-terminator, then ASSERT().
1465
1466 @param String A pointer to a Null-terminated Unicode string.
1467
1468 @retval Value translated from String.
1469
1470 **/
1471 UINT64
1472 FceStrDecimalToUint64 (
1473 IN CONST CHAR16 *String
1474 )
1475 {
1476 UINT64 Result;
1477
1478 //
1479 // ASSERT String is less long than PcdMaximumUnicodeStringLength.
1480 // Length tests are performed inside FceStrLen().
1481 //
1482 ASSERT (FceStrSize (String) != 0);
1483
1484 //
1485 // Ignore the pad spaces (space or tab)
1486 //
1487 while ((*String == L' ') || (*String == L'\t')) {
1488 String++;
1489 }
1490
1491 //
1492 // Ignore leading Zeros after the spaces
1493 //
1494 while (*String == L'0') {
1495 String++;
1496 }
1497
1498 Result = 0;
1499
1500 while (FceInternalIsDecimalDigitCharacter (*String)) {
1501 //
1502 // If the number represented by String overflows according
1503 // to the range defined by UINTN, then ASSERT().
1504 //
1505 ASSERT (Result <= DivU64x32 (((UINT64) ~0) - (*String - L'0') , 10));
1506
1507 Result = MultU64x32 (Result, 10) + (*String - L'0');
1508 String++;
1509 }
1510
1511 return Result;
1512 }
1513
1514
1515 /**
1516 Convert a Null-terminated Unicode hexadecimal string to a value of type UINT64.
1517
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
1521
1522 [spaces][zeros][x][hexadecimal digits].
1523
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.
1532
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().
1540
1541 If PcdMaximumUnicodeStringLength is not zero, and String contains more than
1542 PcdMaximumUnicodeStringLength Unicode characters, not including the Null-terminator,
1543 then ASSERT().
1544
1545 @param String A pointer to a Null-terminated Unicode string.
1546
1547 @retval Value translated from String.
1548
1549 **/
1550 UINT64
1551 FceStrHexToUint64 (
1552 IN CONST CHAR16 *String
1553 )
1554 {
1555 UINT64 Result;
1556
1557 //
1558 // ASSERT String is less long than PcdMaximumUnicodeStringLength.
1559 // Length tests are performed inside FceStrLen().
1560 //
1561 ASSERT (FceStrSize (String) != 0);
1562
1563 //
1564 // Ignore the pad spaces (space or tab)
1565 //
1566 while ((*String == L' ') || (*String == L'\t')) {
1567 String++;
1568 }
1569
1570 //
1571 // Ignore leading Zeros after the spaces
1572 //
1573 while (*String == L'0') {
1574 String++;
1575 }
1576
1577 if (FceInternalCharToUpper (*String) == L'X') {
1578 ASSERT (*(String - 1) == L'0');
1579 if (*(String - 1) != L'0') {
1580 return 0;
1581 }
1582 //
1583 // Skip the 'X'
1584 //
1585 String++;
1586 }
1587
1588 Result = 0;
1589
1590 while (FceInternalIsHexaDecimalDigitCharacter (*String)) {
1591 //
1592 // If the Hex Number represented by String overflows according
1593 // to the range defined by UINTN, then ASSERT().
1594 //
1595 ASSERT (Result <= RShiftU64 (((UINT64) ~0) - FceInternalHexCharToUintn (*String) , 4));
1596
1597 Result = LShiftU64 (Result, 4);
1598 Result = Result + FceInternalHexCharToUintn (*String);
1599 String++;
1600 }
1601
1602 return Result;
1603 }
1604
1605
1606 CHAR16
1607 ToUpper (
1608 CHAR16 a
1609 )
1610 {
1611 if (('a' <= a) && (a <= 'z')) {
1612 return (CHAR16) (a - 0x20);
1613 } else {
1614 return a;
1615 }
1616 }
1617
1618 CHAR16
1619 ToLower (
1620 CHAR16 a
1621 )
1622 {
1623 if (('A' <= a) && (a <= 'Z')) {
1624 return (CHAR16) (a + 0x20);
1625 } else {
1626 return a;
1627 }
1628 }
1629
1630 /**
1631 Performs a case-insensitive comparison between a Null-terminated
1632 Unicode pattern string and a Null-terminated Unicode string.
1633
1634 @param String - A pointer to a Null-terminated Unicode string.
1635 @param Pattern - A pointer to a Null-terminated Unicode pattern string.
1636
1637
1638 @retval TRUE - Pattern was found in String.
1639 @retval FALSE - Pattern was not found in String.
1640
1641 **/
1642 BOOLEAN
1643 MetaiMatch (
1644 IN CHAR16 *String,
1645 IN CHAR16 *Pattern
1646 )
1647 {
1648 CHAR16 c;
1649 CHAR16 p;
1650
1651 assert (String != NULL);
1652 assert (Pattern != NULL);
1653
1654 for (;;) {
1655 p = *Pattern;
1656 Pattern += 1;
1657
1658 if (p == 0) {
1659 //
1660 // End of pattern. If end of string, TRUE match
1661 //
1662 if (*String) {
1663 return FALSE;
1664 } else {
1665 return TRUE;
1666 }
1667
1668 } else {
1669
1670 c = *String;
1671 if (ToUpper (c) != ToUpper (p)) {
1672 return FALSE;
1673 }
1674
1675 String += 1;
1676
1677 }
1678
1679 }
1680
1681 }
1682 /**
1683 Multiplies a 64-bit unsigned integer by a 32-bit unsigned integer and
1684 generates a 64-bit unsigned result.
1685
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.
1689
1690 @param Multiplicand A 64-bit unsigned value.
1691 @param Multiplier A 32-bit unsigned value.
1692
1693 @return Multiplicand * Multiplier.
1694
1695 **/
1696 UINT64
1697 MultU64x32 (
1698 IN UINT64 Multiplicand,
1699 IN UINT32 Multiplier
1700 )
1701 {
1702 return Multiplicand * Multiplier;
1703 }
1704
1705 /**
1706 Divides a 64-bit unsigned integer by a 32-bit unsigned integer and generates
1707 a 64-bit unsigned result.
1708
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.
1712
1713 If Divisor is 0, then ASSERT().
1714
1715 @param Dividend A 64-bit unsigned value.
1716 @param Divisor A 32-bit unsigned value.
1717
1718 @return Dividend / Divisor
1719
1720 **/
1721 UINT64
1722 DivU64x32 (
1723 IN UINT64 Dividend,
1724 IN UINT32 Divisor
1725 )
1726 {
1727 ASSERT (Divisor != 0);
1728 return Dividend / Divisor;
1729 }
1730
1731 /**
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.
1734
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.
1737
1738 If Count is greater than 63, then ASSERT().
1739
1740 @param Operand The 64-bit operand to shift left.
1741 @param Count The number of bits to shift left.
1742
1743 @return Operand << Count.
1744
1745 **/
1746 UINT64
1747 LShiftU64 (
1748 IN UINT64 Operand,
1749 IN UINTN Count
1750 )
1751 {
1752 ASSERT (Count < 64);
1753 return Operand << Count;
1754 }
1755
1756 /**
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.
1759
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.
1762
1763 If Count is greater than 63, then ASSERT().
1764
1765 @param Operand The 64-bit operand to shift right.
1766 @param Count The number of bits to shift right.
1767
1768 @return Operand >> Count.
1769
1770 **/
1771 UINT64
1772 RShiftU64 (
1773 IN UINT64 Operand,
1774 IN UINTN Count
1775 )
1776
1777 {
1778 ASSERT (Count < 64);
1779 return Operand >> Count;
1780 }
1781
1782
1783 /**
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.
1786
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.
1791
1792 If Divisor is 0, then ASSERT().
1793
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.
1798
1799 @return Dividend / Divisor
1800
1801 **/
1802 UINT64
1803 DivU64x32Remainder (
1804 IN UINT64 Dividend,
1805 IN UINT32 Divisor,
1806 OUT UINT32 *Remainder
1807 )
1808 {
1809 ASSERT (Divisor != 0);
1810
1811 if (Remainder != NULL) {
1812 *Remainder = (UINT32)(Dividend % Divisor);
1813 }
1814 return Dividend / Divisor;
1815 }
1816
1817 /**
1818 Copies a buffer to an allocated buffer.
1819
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.
1824
1825 If Buffer is NULL, then ASSERT().
1826
1827 @param AllocationSize The number of bytes to allocate and zero.
1828 @param Buffer The buffer to copy to the allocated buffer.
1829
1830 @return A pointer to the allocated buffer or NULL if allocation fails.
1831
1832 **/
1833 VOID *
1834 FceAllocateCopyPool (
1835 IN UINTN AllocationSize,
1836 IN CONST VOID *Buffer
1837 )
1838 {
1839 VOID *Memory;
1840
1841 Memory = NULL;
1842
1843 if ((Buffer == NULL) || (AllocationSize == 0)) {
1844 return Memory;
1845 }
1846
1847 Memory = calloc (AllocationSize, sizeof (CHAR8));
1848 if (Memory != NULL) {
1849 Memory = memcpy (Memory, Buffer, AllocationSize);
1850 }
1851 return Memory;
1852 }
1853
1854 /**
1855 Initializes the head node of a doubly-linked list, and returns the pointer to
1856 the head node of the doubly-linked list.
1857
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.
1862
1863 If ListHead is NULL, then ASSERT().
1864
1865 @param ListHead A pointer to the head node of a new doubly-linked list.
1866
1867 @return ListHead
1868
1869 **/
1870 LIST_ENTRY *
1871 InitializeListHead (
1872 IN OUT LIST_ENTRY *ListHead
1873 )
1874
1875 {
1876 assert (ListHead != NULL);
1877
1878 ListHead->ForwardLink = ListHead;
1879 ListHead->BackLink = ListHead;
1880 return ListHead;
1881 }
1882
1883 /**
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.
1886
1887 Adds the node Entry at the beginning of the doubly-linked list denoted by
1888 ListHead, and returns ListHead.
1889
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().
1897
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.
1901
1902 @return ListHead
1903
1904 **/
1905 LIST_ENTRY *
1906 InsertHeadList (
1907 IN OUT LIST_ENTRY *ListHead,
1908 IN OUT LIST_ENTRY *Entry
1909 )
1910 {
1911 assert ((ListHead != NULL) && (Entry != NULL));
1912
1913 Entry->ForwardLink = ListHead->ForwardLink;
1914 Entry->BackLink = ListHead;
1915 Entry->ForwardLink->BackLink = Entry;
1916 ListHead->ForwardLink = Entry;
1917 return ListHead;
1918 }
1919
1920 /**
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.
1923
1924 Adds the node Entry to the end of the doubly-linked list denoted by ListHead,
1925 and returns ListHead.
1926
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().
1934
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
1937 doubly-linked list.
1938
1939 @return ListHead
1940
1941 **/
1942 LIST_ENTRY *
1943 InsertTailList (
1944 IN OUT LIST_ENTRY *ListHead,
1945 IN OUT LIST_ENTRY *Entry
1946 )
1947 {
1948 assert ((ListHead != NULL) && (Entry != NULL));
1949
1950 Entry->ForwardLink = ListHead;
1951 Entry->BackLink = ListHead->BackLink;
1952 Entry->BackLink->ForwardLink = Entry;
1953 ListHead->BackLink = Entry;
1954 return ListHead;
1955 }
1956
1957 /**
1958 Retrieves the first node of a doubly-linked list.
1959
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.
1963
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().
1970
1971 @param List A pointer to the head node of a doubly-linked list.
1972
1973 @return The first node of a doubly-linked list.
1974 @retval NULL The list is empty.
1975
1976 **/
1977 LIST_ENTRY *
1978 GetFirstNode (
1979 IN CONST LIST_ENTRY *List
1980 )
1981 {
1982 assert (List != NULL);
1983
1984 return List->ForwardLink;
1985 }
1986
1987 /**
1988 Retrieves the next node of a doubly-linked list.
1989
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.
1993
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().
2001
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.
2004
2005 @return A pointer to the next node if one exists. Otherwise List is returned.
2006
2007 **/
2008 LIST_ENTRY *
2009 GetNextNode (
2010 IN CONST LIST_ENTRY *List,
2011 IN CONST LIST_ENTRY *Node
2012 )
2013 {
2014 assert ((List != NULL) && (Node != NULL));
2015
2016 return Node->ForwardLink;
2017 }
2018
2019 /**
2020 Retrieves the previous node of a doubly-linked list.
2021
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.
2025
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().
2033
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.
2036
2037 @return A pointer to the previous node if one exists. Otherwise List is returned.
2038
2039 **/
2040 LIST_ENTRY *
2041 GetPreviousNode (
2042 IN CONST LIST_ENTRY *List,
2043 IN CONST LIST_ENTRY *Node
2044 )
2045 {
2046 assert ((List != NULL) && (Node != NULL));
2047
2048 return Node->BackLink;
2049 }
2050
2051 /**
2052 Checks to see if a doubly-linked list is empty or not.
2053
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.
2056
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().
2063
2064 @param ListHead A pointer to the head node of a doubly-linked list.
2065
2066 @retval TRUE The linked list is empty.
2067 @retval FALSE The linked list is not empty.
2068
2069 **/
2070 BOOLEAN
2071 IsListEmpty (
2072 IN CONST LIST_ENTRY *ListHead
2073 )
2074 {
2075 assert (ListHead != NULL);
2076
2077 return (BOOLEAN)(ListHead->ForwardLink == ListHead);
2078 }
2079
2080 /**
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.
2084
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().
2088
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(),
2092 then ASSERT().
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().
2098
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.
2101
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.
2104
2105 **/
2106 BOOLEAN
2107 IsNull (
2108 IN CONST LIST_ENTRY *List,
2109 IN CONST LIST_ENTRY *Node
2110 )
2111 {
2112 assert ((List != NULL) && (Node != NULL));
2113
2114 return (BOOLEAN)(Node == List);
2115 }
2116
2117 /**
2118 Determines if a node the last node in a doubly-linked list.
2119
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().
2123
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().
2132
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.
2135
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.
2138
2139 **/
2140 BOOLEAN
2141 IsNodeAtEnd (
2142 IN CONST LIST_ENTRY *List,
2143 IN CONST LIST_ENTRY *Node
2144 )
2145 {
2146 assert ((List != NULL) && (Node != NULL));
2147
2148 return (BOOLEAN)(!IsNull (List, Node) && (List->BackLink == Node));
2149 }
2150
2151 /**
2152 Removes a node from a doubly-linked list, and returns the node that follows
2153 the removed node.
2154
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
2159 list is returned.
2160
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().
2166
2167 @param Entry A pointer to a node in a linked list.
2168
2169 @return Entry.
2170
2171 **/
2172 LIST_ENTRY *
2173 RemoveEntryList (
2174 IN CONST LIST_ENTRY *Entry
2175 )
2176 {
2177 assert (!IsListEmpty (Entry));
2178
2179 Entry->ForwardLink->BackLink = Entry->BackLink;
2180 Entry->BackLink->ForwardLink = Entry->ForwardLink;
2181 return Entry->ForwardLink;
2182 }
2183