1acf7ee61712ec6fc8db9bfbefa1fc08d82d6c3a
[efi/edk2/.git] / edk2 / MdeModulePkg / Universal / SetupBrowserDxe / Print.c
1 /** @file\r
2 Basic Ascii AvSPrintf() function named VSPrint(). VSPrint() enables very\r
3 simple implemenation of SPrint() and Print() to support debug.\r
4 \r
5 You can not Print more than EFI_DRIVER_LIB_MAX_PRINT_BUFFER characters at a\r
6 time. This makes the implementation very simple.\r
7 \r
8 VSPrint, Print, SPrint format specification has the follwoing form\r
9 \r
10 %type\r
11 \r
12 type:\r
13   'S','s' - argument is an Unicode string\r
14   'c' - argument is an ascii character\r
15   '%' - Print a %\r
16 \r
17 \r
18 Copyright (c) 2004 - 2007, Intel Corporation\r
19 All rights reserved. This program and the accompanying materials\r
20 are licensed and made available under the terms and conditions of the BSD License\r
21 which accompanies this distribution.  The full text of the license may be found at\r
22 http://opensource.org/licenses/bsd-license.php\r
23 \r
24 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
25 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
26 \r
27 **/\r
28 \r
29 #include "Setup.h"\r
30 \r
31 /**\r
32   VSPrint worker function that prints a Value as a decimal number in Buffer.\r
33 \r
34   @param  Buffer     Location to place ascii decimal number string of Value.\r
35   @param  Flags      Flags to use in printing decimal string, see file header for\r
36                      details.\r
37   @param  Value      Decimal value to convert to a string in Buffer.\r
38 \r
39   @return Number of characters printed.\r
40 \r
41 **/\r
42 UINTN\r
43 ValueToString (\r
44   IN  OUT CHAR16  *Buffer,\r
45   IN  BOOLEAN     Flags,\r
46   IN  INT64       Value\r
47   );\r
48 \r
49 /**\r
50   The internal function prints to the EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL\r
51   protocol instance.\r
52 \r
53   @param Column          The position of the output string.\r
54   @param Row             The position of the output string.\r
55   @param Out             The EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL instance.\r
56   @param Fmt             The format string.\r
57   @param Args            The additional argument for the variables in the format string.\r
58 \r
59   @return Number of Unicode character printed.\r
60 \r
61 **/\r
62 UINTN\r
63 PrintInternal (\r
64   IN UINTN                            Column,\r
65   IN UINTN                            Row,\r
66   IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *Out,\r
67   IN CHAR16                           *Fmt,\r
68   IN VA_LIST                          Args\r
69   )\r
70 {\r
71   CHAR16  *Buffer;\r
72   CHAR16  *BackupBuffer;\r
73   UINTN   Index;\r
74   UINTN   PreviousIndex;\r
75   UINTN   Count;\r
76 \r
77   //\r
78   // For now, allocate an arbitrarily long buffer\r
79   //\r
80   Buffer        = AllocateZeroPool (0x10000);\r
81   BackupBuffer  = AllocateZeroPool (0x10000);\r
82   ASSERT (Buffer);\r
83   ASSERT (BackupBuffer);\r
84 \r
85   if (Column != (UINTN) -1) {\r
86     Out->SetCursorPosition (Out, Column, Row);\r
87   }\r
88 \r
89   UnicodeVSPrint (Buffer, 0x10000, Fmt, Args);\r
90 \r
91   Out->Mode->Attribute = Out->Mode->Attribute & 0x7f;\r
92 \r
93   Out->SetAttribute (Out, Out->Mode->Attribute);\r
94 \r
95   Index         = 0;\r
96   PreviousIndex = 0;\r
97   Count         = 0;\r
98 \r
99   do {\r
100     for (; (Buffer[Index] != NARROW_CHAR) && (Buffer[Index] != WIDE_CHAR) && (Buffer[Index] != 0); Index++) {\r
101       BackupBuffer[Index] = Buffer[Index];\r
102     }\r
103 \r
104     if (Buffer[Index] == 0) {\r
105       break;\r
106     }\r
107     //\r
108     // Null-terminate the temporary string\r
109     //\r
110     BackupBuffer[Index] = 0;\r
111 \r
112     //\r
113     // Print this out, we are about to switch widths\r
114     //\r
115     Out->OutputString (Out, &BackupBuffer[PreviousIndex]);\r
116     Count += StrLen (&BackupBuffer[PreviousIndex]);\r
117 \r
118     //\r
119     // Preserve the current index + 1, since this is where we will start printing from next\r
120     //\r
121     PreviousIndex = Index + 1;\r
122 \r
123     //\r
124     // We are at a narrow or wide character directive.  Set attributes and strip it and print it\r
125     //\r
126     if (Buffer[Index] == NARROW_CHAR) {\r
127       //\r
128       // Preserve bits 0 - 6 and zero out the rest\r
129       //\r
130       Out->Mode->Attribute = Out->Mode->Attribute & 0x7f;\r
131       Out->SetAttribute (Out, Out->Mode->Attribute);\r
132     } else {\r
133       //\r
134       // Must be wide, set bit 7 ON\r
135       //\r
136       Out->Mode->Attribute = Out->Mode->Attribute | EFI_WIDE_ATTRIBUTE;\r
137       Out->SetAttribute (Out, Out->Mode->Attribute);\r
138     }\r
139 \r
140     Index++;\r
141 \r
142   } while (Buffer[Index] != 0);\r
143 \r
144   //\r
145   // We hit the end of the string - print it\r
146   //\r
147   Out->OutputString (Out, &BackupBuffer[PreviousIndex]);\r
148   Count += StrLen (&BackupBuffer[PreviousIndex]);\r
149 \r
150   FreePool (Buffer);\r
151   FreePool (BackupBuffer);\r
152   return Count;\r
153 }\r
154 \r
155 \r
156 /**\r
157   Prints a formatted unicode string to the default console.\r
158 \r
159   @param  Fmt        Format string\r
160   @param  ...        Variable argument list for format string.\r
161 \r
162   @return Length of string printed to the console.\r
163 \r
164 **/\r
165 UINTN\r
166 ConsolePrint (\r
167   IN CHAR16   *Fmt,\r
168   ...\r
169   )\r
170 {\r
171   VA_LIST Args;\r
172 \r
173   VA_START (Args, Fmt);\r
174   return PrintInternal ((UINTN) -1, (UINTN) -1, gST->ConOut, Fmt, Args);\r
175 }\r
176 \r
177 \r
178 /**\r
179   Prints a unicode string to the default console,\r
180   using L"%s" format.\r
181 \r
182   @param  String     String pointer.\r
183 \r
184   @return Length of string printed to the console\r
185 \r
186 **/\r
187 UINTN\r
188 PrintString (\r
189   IN CHAR16       *String\r
190   )\r
191 {\r
192   return ConsolePrint (L"%s", String);\r
193 }\r
194 \r
195 \r
196 /**\r
197   Prints a chracter to the default console,\r
198   using L"%c" format.\r
199 \r
200   @param  Character  Character to print.\r
201 \r
202   @return Length of string printed to the console.\r
203 \r
204 **/\r
205 UINTN\r
206 PrintChar (\r
207   CHAR16       Character\r
208   )\r
209 {\r
210   return ConsolePrint (L"%c", Character);\r
211 }\r
212 \r
213 \r
214 /**\r
215   Prints a formatted unicode string to the default console, at\r
216   the supplied cursor position.\r
217 \r
218   @param  Column     The cursor position to print the string at.\r
219   @param  Row        The cursor position to print the string at.\r
220   @param  Fmt        Format string.\r
221   @param  ...        Variable argument list for format string.\r
222 \r
223   @return Length of string printed to the console\r
224 \r
225 **/\r
226 UINTN\r
227 PrintAt (\r
228   IN UINTN     Column,\r
229   IN UINTN     Row,\r
230   IN CHAR16    *Fmt,\r
231   ...\r
232   )\r
233 {\r
234   VA_LIST Args;\r
235 \r
236   VA_START (Args, Fmt);\r
237   return PrintInternal (Column, Row, gST->ConOut, Fmt, Args);\r
238 }\r
239 \r
240 \r
241 /**\r
242   Prints a unicode string to the default console, at\r
243   the supplied cursor position, using L"%s" format.\r
244 \r
245   @param  Column     The cursor position to print the string at.\r
246   @param  Row        The cursor position to print the string at\r
247   @param  String     String pointer.\r
248 \r
249   @return Length of string printed to the console\r
250 \r
251 **/\r
252 UINTN\r
253 PrintStringAt (\r
254   IN UINTN     Column,\r
255   IN UINTN     Row,\r
256   IN CHAR16    *String\r
257   )\r
258 {\r
259   return PrintAt (Column, Row, L"%s", String);\r
260 }\r
261 \r
262 \r
263 /**\r
264   Prints a chracter to the default console, at\r
265   the supplied cursor position, using L"%c" format.\r
266 \r
267   @param  Column     The cursor position to print the string at.\r
268   @param  Row        The cursor position to print the string at.\r
269   @param  Character  Character to print.\r
270 \r
271   @return Length of string printed to the console.\r
272 \r
273 **/\r
274 UINTN\r
275 PrintCharAt (\r
276   IN UINTN     Column,\r
277   IN UINTN     Row,\r
278   CHAR16       Character\r
279   )\r
280 {\r
281   return PrintAt (Column, Row, L"%c", Character);\r
282 }\r
283 \r
284 \r
285 /**\r
286   VSPrint worker function that prints a Value as a decimal number in Buffer.\r
287 \r
288   @param  Buffer     Location to place ascii decimal number string of Value.\r
289   @param  Flags      Flags to use in printing decimal string, see file header for\r
290                      details.\r
291   @param  Value      Decimal value to convert to a string in Buffer.\r
292 \r
293   @return Number of characters printed.\r
294 \r
295 **/\r
296 UINTN\r
297 ValueToString (\r
298   IN  OUT CHAR16  *Buffer,\r
299   IN  BOOLEAN     Flags,\r
300   IN  INT64       Value\r
301   )\r
302 {\r
303   CHAR16  TempBuffer[30];\r
304   CHAR16  *TempStr;\r
305   CHAR16  *BufferPtr;\r
306   UINTN   Count;\r
307   UINTN   NumberCount;\r
308   UINT32  Remainder;\r
309   BOOLEAN Negative;\r
310 \r
311   Negative    = FALSE;\r
312   TempStr     = TempBuffer;\r
313   BufferPtr   = Buffer;\r
314   Count       = 0;\r
315   NumberCount = 0;\r
316 \r
317   if (Value < 0) {\r
318     Negative = TRUE;\r
319     Value    = -Value;\r
320   }\r
321 \r
322   do {\r
323     Value         = (INT64) DivU64x32Remainder  ((UINT64) Value, 10, &Remainder);\r
324     *(TempStr++)  = (CHAR16) (Remainder + '0');\r
325     Count++;\r
326     NumberCount++;\r
327     if ((Flags & COMMA_TYPE) == COMMA_TYPE) {\r
328       if (NumberCount % 3 == 0 && Value != 0) {\r
329         *(TempStr++) = ',';\r
330         Count++;\r
331       }\r
332     }\r
333   } while (Value != 0);\r
334 \r
335   if (Negative) {\r
336     *(BufferPtr++) = '-';\r
337     Count++;\r
338   }\r
339 \r
340   //\r
341   // Reverse temp string into Buffer.\r
342   //\r
343   while (TempStr != TempBuffer) {\r
344     *(BufferPtr++) = *(--TempStr);\r
345   }\r
346 \r
347   *BufferPtr = 0;\r
348   return Count;\r
349 }\r