1 /*++
2 
3 Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>
4 This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution.  The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
8 
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11 
12 Module Name:
13 
14   ValueToString.c
15 
16 Abstract:
17 
18   Routines changing value to Hex or Dec string
19 
20 --*/
21 
22 #include "Tiano.h"
23 #include "EfiDriverLib.h"
24 
25 static CHAR16 mHexStr[] = { L'0', L'1', L'2', L'3', L'4', L'5', L'6', L'7',
26                             L'8', L'9', L'A', L'B', L'C', L'D', L'E', L'F' };
27 
28 UINTN
EfiValueToHexStr(IN OUT CHAR16 * Buffer,IN UINT64 Value,IN UINTN Flags,IN UINTN Width)29 EfiValueToHexStr (
30   IN  OUT CHAR16  *Buffer,
31   IN  UINT64      Value,
32   IN  UINTN       Flags,
33   IN  UINTN       Width
34   )
35 /*++
36 
37 Routine Description:
38 
39   VSPrint worker function that prints a Value as a hex number in Buffer
40 
41 Arguments:
42 
43   Buffer - Location to place ascii hex string of Value.
44 
45   Value  - Hex value to convert to a string in Buffer.
46 
47   Flags  - Flags to use in printing Hex string, see file header for details.
48 
49   Width  - Width of hex value.
50 
51 Returns:
52 
53   Number of characters printed.
54 
55 --*/
56 {
57   CHAR16  TempBuffer[CHARACTER_NUMBER_FOR_VALUE];
58   CHAR16  *TempStr;
59   CHAR16  Prefix;
60   CHAR16  *BufferPtr;
61   UINTN   Count;
62   UINTN   Index;
63 
64   TempStr   = TempBuffer;
65   BufferPtr = Buffer;
66 
67   //
68   // Count starts at one since we will null terminate. Each iteration of the
69   // loop picks off one nibble. Oh yea TempStr ends up backwards
70   //
71   Count = 0;
72 
73   if (Width > CHARACTER_NUMBER_FOR_VALUE - 1) {
74     Width = CHARACTER_NUMBER_FOR_VALUE - 1;
75   }
76 
77   do {
78     Index = ((UINTN)Value & 0xf);
79     *(TempStr++) = mHexStr[Index];
80     Value = RShiftU64 (Value, 4);
81     Count++;
82   } while (Value != 0);
83 
84   if (Flags & PREFIX_ZERO) {
85     Prefix = '0';
86   } else {
87     Prefix = ' ';
88   }
89 
90   Index = Count;
91   if (!(Flags & LEFT_JUSTIFY)) {
92     for (; Index < Width; Index++) {
93       *(TempStr++) = Prefix;
94     }
95   }
96 
97   //
98   // Reverse temp string into Buffer.
99   //
100   if (Width > 0 && (UINTN) (TempStr - TempBuffer) > Width) {
101     TempStr = TempBuffer + Width;
102   }
103   Index = 0;
104   while (TempStr != TempBuffer) {
105     *(BufferPtr++) = *(--TempStr);
106     Index++;
107   }
108 
109   *BufferPtr = 0;
110   return Index;
111 }
112 
113 
114 UINTN
EfiValueToString(IN OUT CHAR16 * Buffer,IN INT64 Value,IN UINTN Flags,IN UINTN Width)115 EfiValueToString (
116   IN  OUT CHAR16  *Buffer,
117   IN  INT64       Value,
118   IN  UINTN       Flags,
119   IN  UINTN       Width
120   )
121 /*++
122 
123 Routine Description:
124 
125   VSPrint worker function that prints a Value as a decimal number in Buffer
126 
127 Arguments:
128 
129   Buffer - Location to place ascii decimal number string of Value.
130 
131   Value  - Decimal value to convert to a string in Buffer.
132 
133   Flags  - Flags to use in printing decimal string, see file header for details.
134 
135   Width  - Width of hex value.
136 
137 Returns:
138 
139   Number of characters printed.
140 
141 --*/
142 {
143   CHAR16    TempBuffer[CHARACTER_NUMBER_FOR_VALUE];
144   CHAR16    *TempStr;
145   CHAR16    *BufferPtr;
146   UINTN     Count;
147   UINTN     ValueCharNum;
148   UINTN     Remainder;
149   CHAR16    Prefix;
150   UINTN     Index;
151   BOOLEAN   ValueIsNegative;
152 
153   TempStr         = TempBuffer;
154   BufferPtr       = Buffer;
155   Count           = 0;
156   ValueCharNum    = 0;
157   ValueIsNegative = FALSE;
158   Remainder       = 0;
159 
160   if (Width > CHARACTER_NUMBER_FOR_VALUE - 1) {
161     Width = CHARACTER_NUMBER_FOR_VALUE - 1;
162   }
163 
164   if (Value < 0) {
165     Value           = -Value;
166     ValueIsNegative = TRUE;
167   }
168 
169   do {
170     Value = (INT64)DivU64x32 ((UINT64)Value, 10, &Remainder);
171     *(TempStr++) = (CHAR16)(Remainder + '0');
172     ValueCharNum++;
173     Count++;
174     if ((Flags & COMMA_TYPE) == COMMA_TYPE) {
175       if (ValueCharNum % 3 == 0 && Value != 0) {
176         *(TempStr++) = ',';
177         Count++;
178       }
179     }
180   } while (Value != 0);
181 
182   if (ValueIsNegative) {
183     *(TempStr++)    = '-';
184     Count++;
185   }
186 
187   if ((Flags & PREFIX_ZERO) && !ValueIsNegative) {
188     Prefix = '0';
189   } else {
190     Prefix = ' ';
191   }
192 
193   Index = Count;
194   if (!(Flags & LEFT_JUSTIFY)) {
195     for (; Index < Width; Index++) {
196       *(TempStr++) = Prefix;
197     }
198   }
199 
200   //
201   // Reverse temp string into Buffer.
202   //
203   if (Width > 0 && (UINTN) (TempStr - TempBuffer) > Width) {
204     TempStr = TempBuffer + Width;
205   }
206   Index = 0;
207   while (TempStr != TempBuffer) {
208     *(BufferPtr++) = *(--TempStr);
209     Index++;
210   }
211 
212   *BufferPtr = 0;
213   return Index;
214 }
215