]>
Commit | Line | Data |
---|---|---|
d958721a | 1 | /** @file |
2 | Print Library worker functions. | |
3 | ||
4 | Copyright (c) 2006 - 2007, Intel Corporation<BR> | |
5 | All rights reserved. This program and the accompanying materials | |
6 | are licensed and made available under the terms and conditions of the BSD License | |
7 | which accompanies this distribution. The full text of the license may be found at | |
8 | http://opensource.org/licenses/bsd-license.php | |
9 | ||
10 | THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, | |
11 | WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. | |
12 | ||
13 | Module Name: PrintLibInternal.c | |
14 | ||
15 | **/ | |
16 | ||
17 | #include "PrintLibInternal.h" | |
18 | ||
19 | GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 mHexStr[] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'}; | |
20 | ||
21 | ||
22 | /** | |
23 | Internal function that places the character into the Buffer. | |
24 | ||
25 | Internal function that places ASCII or Unicode character into the Buffer. | |
26 | ||
27 | @param Buffer Buffer to place the Unicode or ASCII string. | |
28 | @param EndBuffer The end of the input Buffer. No characters will be | |
29 | placed after that. | |
30 | @param Length Count of character to be placed into Buffer. | |
31 | @param Character Character to be placed into Buffer. | |
32 | @param Increment Character increment in Buffer. | |
33 | ||
34 | @return Number of characters printed. | |
35 | ||
36 | **/ | |
37 | CHAR8 * | |
38 | BasePrintLibFillBuffer ( | |
39 | CHAR8 *Buffer, | |
40 | CHAR8 *EndBuffer, | |
41 | INTN Length, | |
42 | UINTN Character, | |
43 | INTN Increment | |
44 | ) | |
45 | { | |
46 | INTN Index; | |
47 | ||
48 | for (Index = 0; Index < Length && Buffer < EndBuffer; Index++) { | |
49 | *Buffer = (CHAR8) Character; | |
50 | *(Buffer + 1) = (CHAR8) (Character >> 8); | |
51 | Buffer += Increment; | |
52 | } | |
53 | return Buffer; | |
54 | } | |
55 | ||
56 | /** | |
57 | Internal function that convert a decimal number to a string in Buffer. | |
58 | ||
59 | Print worker function that convert a decimal number to a string in Buffer. | |
60 | ||
61 | @param Buffer Location to place the Unicode or ASCII string of Value. | |
62 | @param Value Value to convert to a Decimal or Hexidecimal string in Buffer. | |
63 | @param Radix Radix of the value | |
64 | ||
65 | @return Number of characters printed. | |
66 | ||
67 | **/ | |
68 | UINTN | |
69 | EFIAPI | |
70 | BasePrintLibValueToString ( | |
71 | IN OUT CHAR8 *Buffer, | |
72 | IN INT64 Value, | |
73 | IN UINTN Radix | |
74 | ) | |
75 | { | |
76 | UINTN Digits; | |
77 | UINT32 Remainder; | |
78 | ||
79 | // | |
80 | // Loop to convert one digit at a time in reverse order | |
81 | // | |
82 | *(Buffer++) = 0; | |
83 | Digits = 0; | |
84 | do { | |
85 | Value = (INT64)DivU64x32Remainder ((UINT64)Value, (UINT32)Radix, &Remainder); | |
86 | *(Buffer++) = mHexStr[Remainder]; | |
87 | Digits++; | |
88 | } while (Value != 0); | |
89 | return Digits; | |
90 | } | |
91 | ||
92 | /** | |
93 | Internal function that converts a decimal value to a Null-terminated string. | |
94 | ||
95 | Converts the decimal number specified by Value to a Null-terminated | |
96 | string specified by Buffer containing at most Width characters. | |
97 | If Width is 0 then a width of MAXIMUM_VALUE_CHARACTERS is assumed. | |
98 | The number of characters in Buffer is returned not including the Null-terminator. | |
99 | If the conversion contains more than Width characters, then only the first | |
100 | Width characters are returned, and the total number of characters | |
101 | required to perform the conversion is returned. | |
102 | Additional conversion parameters are specified in Flags. | |
103 | The Flags bit LEFT_JUSTIFY is always ignored. | |
104 | All conversions are left justified in Buffer. | |
105 | If Width is 0, PREFIX_ZERO is ignored in Flags. | |
106 | If COMMA_TYPE is set in Flags, then PREFIX_ZERO is ignored in Flags, and commas | |
107 | are inserted every 3rd digit starting from the right. | |
108 | If HEX_RADIX is set in Flags, then the output buffer will be formatted in hexadecimal format. | |
109 | If Value is < 0 and HEX_RADIX is not set in Flags, then the fist character in Buffer is a '-'. | |
110 | If PREFIX_ZERO is set in Flags and PREFIX_ZERO is not being ignored, | |
111 | then Buffer is padded with '0' characters so the combination of the optional '-' | |
112 | sign character, '0' characters, digit characters for Value, and the Null-terminator | |
113 | add up to Width characters. | |
114 | If both COMMA_TYPE and HEX_RADIX are set in Flags, then ASSERT(). | |
115 | ||
116 | If Buffer is NULL, then ASSERT(). | |
117 | If unsupported bits are set in Flags, then ASSERT(). | |
118 | If Width >= MAXIMUM_VALUE_CHARACTERS, then ASSERT() | |
119 | ||
120 | @param Buffer Pointer to the output buffer for the produced Null-terminated | |
121 | string. | |
122 | @param Flags The bitmask of flags that specify left justification, zero pad, | |
123 | and commas. | |
124 | @param Value The 64-bit signed value to convert to a string. | |
125 | @param Width The maximum number of characters to place in Buffer, not including | |
126 | the Null-terminator. | |
127 | @param Increment Character increment in Buffer. | |
128 | ||
129 | @return The number of characters in Buffer not including the Null-terminator. | |
130 | ||
131 | **/ | |
132 | UINTN | |
133 | BasePrintLibConvertValueToString ( | |
134 | IN OUT CHAR8 *Buffer, | |
135 | IN UINTN Flags, | |
136 | IN INT64 Value, | |
137 | IN UINTN Width, | |
138 | IN UINTN Increment | |
139 | ) | |
140 | { | |
141 | CHAR8 *OriginalBuffer; | |
142 | CHAR8 *EndBuffer; | |
143 | CHAR8 ValueBuffer[MAXIMUM_VALUE_CHARACTERS]; | |
144 | UINTN Count; | |
145 | UINTN Digits; | |
146 | UINTN Index; | |
147 | UINTN Radix; | |
148 | ||
149 | ASSERT (Buffer != NULL); | |
150 | ASSERT (Width < MAXIMUM_VALUE_CHARACTERS); | |
151 | // | |
152 | // Make sure Flags can only contain supported bits. | |
153 | // | |
154 | ASSERT ((Flags & ~(LEFT_JUSTIFY | COMMA_TYPE | PREFIX_ZERO | RADIX_HEX)) == 0); | |
155 | ||
156 | // | |
157 | // If both COMMA_TYPE and HEX_RADIX are set, then ASSERT () | |
158 | // | |
159 | ASSERT (((Flags & COMMA_TYPE) != 0 && (Flags & RADIX_HEX) != 0) == FALSE); | |
160 | ||
161 | OriginalBuffer = Buffer; | |
162 | ||
163 | if (Width == 0 || (Flags & COMMA_TYPE) != 0) { | |
164 | Flags &= (~PREFIX_ZERO); | |
165 | } | |
166 | ||
167 | if (Width == 0) { | |
168 | Width = MAXIMUM_VALUE_CHARACTERS - 1; | |
169 | } | |
170 | // | |
171 | // Set the tag for the end of the input Buffer. | |
172 | // | |
173 | EndBuffer = Buffer + Width * Increment; | |
174 | ||
175 | if ((Value < 0) && ((Flags & RADIX_HEX) == 0)) { | |
176 | Value = -Value; | |
177 | Buffer = BasePrintLibFillBuffer (Buffer, EndBuffer, 1, '-', Increment); | |
178 | Width--; | |
179 | } | |
180 | ||
181 | Radix = ((Flags & RADIX_HEX) == 0)? 10 : 16; | |
182 | Count = BasePrintLibValueToString (ValueBuffer, Value, Radix); | |
183 | ||
184 | if ((Flags & PREFIX_ZERO) != 0) { | |
185 | Buffer = BasePrintLibFillBuffer (Buffer, EndBuffer, Width - Count, '0', Increment); | |
186 | } | |
187 | ||
188 | Digits = Count % 3; | |
189 | if (Digits != 0) { | |
190 | Digits = 3 - Digits; | |
191 | } | |
192 | for (Index = 0; Index < Count; Index++) { | |
193 | Buffer = BasePrintLibFillBuffer (Buffer, EndBuffer, 1, ValueBuffer[Count - Index], Increment); | |
194 | if ((Flags & COMMA_TYPE) != 0) { | |
195 | Digits++; | |
196 | if (Digits == 3) { | |
197 | Digits = 0; | |
198 | if ((Index + 1) < Count) { | |
199 | Buffer = BasePrintLibFillBuffer (Buffer, EndBuffer, 1, ',', Increment); | |
200 | } | |
201 | } | |
202 | } | |
203 | } | |
204 | ||
205 | BasePrintLibFillBuffer (Buffer, EndBuffer + Increment, 1, 0, Increment); | |
206 | ||
207 | return ((Buffer - OriginalBuffer) / Increment); | |
208 | } | |
209 |