VirtualBox

source: vbox/trunk/src/VBox/Runtime/common/string/strformatnum.cpp@ 78398

Last change on this file since 78398 was 76553, checked in by vboxsync, 6 years ago

scm --update-copyright-year

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 12.5 KB
Line 
1/* $Id: strformatnum.cpp 76553 2019-01-01 01:45:53Z vboxsync $ */
2/** @file
3 * IPRT - String Formatter, Single Numbers.
4 */
5
6/*
7 * Copyright (C) 2010-2019 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * The contents of this file may alternatively be used under the terms
18 * of the Common Development and Distribution License Version 1.0
19 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20 * VirtualBox OSE distribution, in which case the provisions of the
21 * CDDL are applicable instead of those of the GPL.
22 *
23 * You may elect to license modified versions of this file under the
24 * terms and conditions of either the GPL or the CDDL or both.
25 */
26
27
28/*********************************************************************************************************************************
29* Header Files *
30*********************************************************************************************************************************/
31#define LOG_GROUP RTLOGGROUP_STRING
32#include <iprt/string.h>
33#include "internal/iprt.h"
34
35#include <iprt/assert.h>
36#include <iprt/errcore.h>
37#include "internal/string.h"
38
39
40RTDECL(ssize_t) RTStrFormatU8(char *pszBuf, size_t cbBuf, uint8_t u8Value, unsigned int uiBase,
41 signed int cchWidth, signed int cchPrecision, uint32_t fFlags)
42{
43 fFlags &= ~RTSTR_F_BIT_MASK;
44 fFlags |= RTSTR_F_8BIT;
45
46 ssize_t cchRet;
47 if (cbBuf >= 64)
48 cchRet = RTStrFormatNumber(pszBuf, u8Value, uiBase, cchWidth, cchPrecision, fFlags);
49 else
50 {
51 char szTmp[64];
52 cchRet = RTStrFormatNumber(szTmp, u8Value, uiBase, cchWidth, cchPrecision, fFlags);
53 if ((size_t)cchRet < cbBuf)
54 memcpy(pszBuf, szTmp, cchRet + 1);
55 else
56 {
57 if (cbBuf)
58 {
59 memcpy(pszBuf, szTmp, cbBuf - 1);
60 pszBuf[cbBuf - 1] = '\0';
61 }
62 cchRet = VERR_BUFFER_OVERFLOW;
63 }
64 }
65 return cchRet;
66}
67
68
69RTDECL(ssize_t) RTStrFormatU16(char *pszBuf, size_t cbBuf, uint16_t u16Value, unsigned int uiBase,
70 signed int cchWidth, signed int cchPrecision, uint32_t fFlags)
71{
72 fFlags &= ~RTSTR_F_BIT_MASK;
73 fFlags |= RTSTR_F_16BIT;
74
75 ssize_t cchRet;
76 if (cbBuf >= 64)
77 cchRet = RTStrFormatNumber(pszBuf, u16Value, uiBase, cchWidth, cchPrecision, fFlags);
78 else
79 {
80 char szTmp[64];
81 cchRet = RTStrFormatNumber(szTmp, u16Value, uiBase, cchWidth, cchPrecision, fFlags);
82 if ((size_t)cchRet <= cbBuf)
83 memcpy(pszBuf, szTmp, cchRet + 1);
84 else
85 {
86 if (cbBuf)
87 {
88 memcpy(pszBuf, szTmp, cbBuf - 1);
89 pszBuf[cbBuf - 1] = '\0';
90 }
91 cchRet = VERR_BUFFER_OVERFLOW;
92 }
93 }
94 return cchRet;
95}
96
97
98RTDECL(ssize_t) RTStrFormatU32(char *pszBuf, size_t cbBuf, uint32_t u32Value, unsigned int uiBase,
99 signed int cchWidth, signed int cchPrecision, uint32_t fFlags)
100{
101 fFlags &= ~RTSTR_F_BIT_MASK;
102 fFlags |= RTSTR_F_32BIT;
103
104 ssize_t cchRet;
105 if (cbBuf >= 64)
106 cchRet = RTStrFormatNumber(pszBuf, u32Value, uiBase, cchWidth, cchPrecision, fFlags);
107 else
108 {
109 char szTmp[64];
110 cchRet = RTStrFormatNumber(szTmp, u32Value, uiBase, cchWidth, cchPrecision, fFlags);
111 if ((size_t)cchRet <= cbBuf)
112 memcpy(pszBuf, szTmp, cchRet + 1);
113 else
114 {
115 if (cbBuf)
116 {
117 memcpy(pszBuf, szTmp, cbBuf - 1);
118 pszBuf[cbBuf - 1] = '\0';
119 }
120 cchRet = VERR_BUFFER_OVERFLOW;
121 }
122 }
123 return cchRet;
124}
125
126
127RTDECL(ssize_t) RTStrFormatU64(char *pszBuf, size_t cbBuf, uint64_t u64Value, unsigned int uiBase,
128 signed int cchWidth, signed int cchPrecision, uint32_t fFlags)
129{
130 fFlags &= ~RTSTR_F_BIT_MASK;
131 fFlags |= RTSTR_F_64BIT;
132
133 ssize_t cchRet;
134 if (cbBuf >= 64)
135 cchRet = RTStrFormatNumber(pszBuf, u64Value, uiBase, cchWidth, cchPrecision, fFlags);
136 else
137 {
138 char szTmp[64];
139 cchRet = RTStrFormatNumber(szTmp, u64Value, uiBase, cchWidth, cchPrecision, fFlags);
140 if ((size_t)cchRet <= cbBuf)
141 memcpy(pszBuf, szTmp, cchRet + 1);
142 else
143 {
144 if (cbBuf)
145 {
146 memcpy(pszBuf, szTmp, cbBuf - 1);
147 pszBuf[cbBuf - 1] = '\0';
148 }
149 cchRet = VERR_BUFFER_OVERFLOW;
150 }
151 }
152 return cchRet;
153}
154
155
156RTDECL(ssize_t) RTStrFormatU128(char *pszBuf, size_t cbBuf, PCRTUINT128U pu128, unsigned int uiBase,
157 signed int cchWidth, signed int cchPrecision, uint32_t fFlags)
158{
159 NOREF(cchWidth); NOREF(cchPrecision);
160 if (uiBase != 16)
161 fFlags |= RTSTR_F_SPECIAL;
162 fFlags &= ~RTSTR_F_BIT_MASK;
163
164 char szTmp[64+32+32+32];
165 char *pszTmp = cbBuf >= sizeof(szTmp) ? pszBuf : szTmp;
166 size_t cchResult = RTStrFormatNumber(pszTmp, pu128->QWords.qw1, 16, 0, 0, fFlags | RTSTR_F_64BIT);
167 cchResult += RTStrFormatNumber(&pszTmp[cchResult], pu128->QWords.qw0, 16, 8, 0,
168 (fFlags | RTSTR_F_64BIT | RTSTR_F_ZEROPAD) & ~RTSTR_F_SPECIAL);
169 if (pszTmp == pszBuf)
170 return cchResult;
171 int rc = RTStrCopy(pszBuf, cbBuf, pszTmp);
172 if (RT_SUCCESS(rc))
173 return cchResult;
174 return rc;
175}
176
177
178RTDECL(ssize_t) RTStrFormatU256(char *pszBuf, size_t cbBuf, PCRTUINT256U pu256, unsigned int uiBase,
179 signed int cchWidth, signed int cchPrecision, uint32_t fFlags)
180{
181 NOREF(cchWidth); NOREF(cchPrecision);
182 if (uiBase != 16)
183 fFlags |= RTSTR_F_SPECIAL;
184 fFlags &= ~RTSTR_F_BIT_MASK;
185
186 char szTmp[64+32+32+32];
187 char *pszTmp = cbBuf >= sizeof(szTmp) ? pszBuf : szTmp;
188 size_t cchResult = RTStrFormatNumber(pszTmp, pu256->QWords.qw3, 16, 0, 0, fFlags | RTSTR_F_64BIT);
189 cchResult += RTStrFormatNumber(&pszTmp[cchResult], pu256->QWords.qw2, 16, 8, 0,
190 (fFlags | RTSTR_F_64BIT | RTSTR_F_ZEROPAD) & ~RTSTR_F_SPECIAL);
191 cchResult += RTStrFormatNumber(&pszTmp[cchResult], pu256->QWords.qw1, 16, 8, 0,
192 (fFlags | RTSTR_F_64BIT | RTSTR_F_ZEROPAD) & ~RTSTR_F_SPECIAL);
193 cchResult += RTStrFormatNumber(&pszTmp[cchResult], pu256->QWords.qw0, 16, 8, 0,
194 (fFlags | RTSTR_F_64BIT | RTSTR_F_ZEROPAD) & ~RTSTR_F_SPECIAL);
195 if (pszTmp == pszBuf)
196 return cchResult;
197 int rc = RTStrCopy(pszBuf, cbBuf, pszTmp);
198 if (RT_SUCCESS(rc))
199 return cchResult;
200 return rc;
201}
202
203
204RTDECL(ssize_t) RTStrFormatU512(char *pszBuf, size_t cbBuf, PCRTUINT512U pu512, unsigned int uiBase,
205 signed int cchWidth, signed int cchPrecision, uint32_t fFlags)
206{
207 NOREF(cchWidth); NOREF(cchPrecision);
208 if (uiBase != 16)
209 fFlags |= RTSTR_F_SPECIAL;
210 fFlags &= ~RTSTR_F_BIT_MASK;
211
212 char szTmp[64+32+32+32 + 32+32+32+32];
213 char *pszTmp = cbBuf >= sizeof(szTmp) ? pszBuf : szTmp;
214 size_t cchResult = RTStrFormatNumber(pszTmp, pu512->QWords.qw7, 16, 0, 0, fFlags | RTSTR_F_64BIT);
215 cchResult += RTStrFormatNumber(&pszTmp[cchResult], pu512->QWords.qw6, 16, 8, 0,
216 (fFlags | RTSTR_F_64BIT | RTSTR_F_ZEROPAD) & ~RTSTR_F_SPECIAL);
217 cchResult += RTStrFormatNumber(&pszTmp[cchResult], pu512->QWords.qw5, 16, 8, 0,
218 (fFlags | RTSTR_F_64BIT | RTSTR_F_ZEROPAD) & ~RTSTR_F_SPECIAL);
219 cchResult += RTStrFormatNumber(&pszTmp[cchResult], pu512->QWords.qw4, 16, 8, 0,
220 (fFlags | RTSTR_F_64BIT | RTSTR_F_ZEROPAD) & ~RTSTR_F_SPECIAL);
221 cchResult += RTStrFormatNumber(&pszTmp[cchResult], pu512->QWords.qw3, 16, 8, 0,
222 (fFlags | RTSTR_F_64BIT | RTSTR_F_ZEROPAD) & ~RTSTR_F_SPECIAL);
223 cchResult += RTStrFormatNumber(&pszTmp[cchResult], pu512->QWords.qw2, 16, 8, 0,
224 (fFlags | RTSTR_F_64BIT | RTSTR_F_ZEROPAD) & ~RTSTR_F_SPECIAL);
225 cchResult += RTStrFormatNumber(&pszTmp[cchResult], pu512->QWords.qw1, 16, 8, 0,
226 (fFlags | RTSTR_F_64BIT | RTSTR_F_ZEROPAD) & ~RTSTR_F_SPECIAL);
227 cchResult += RTStrFormatNumber(&pszTmp[cchResult], pu512->QWords.qw0, 16, 8, 0,
228 (fFlags | RTSTR_F_64BIT | RTSTR_F_ZEROPAD) & ~RTSTR_F_SPECIAL);
229 if (pszTmp == pszBuf)
230 return cchResult;
231 int rc = RTStrCopy(pszBuf, cbBuf, pszTmp);
232 if (RT_SUCCESS(rc))
233 return cchResult;
234 return rc;
235}
236
237
238RTDECL(ssize_t) RTStrFormatR80u2(char *pszBuf, size_t cbBuf, PCRTFLOAT80U2 pr80Value, signed int cchWidth,
239 signed int cchPrecision, uint32_t fFlags)
240{
241 NOREF(cchWidth); NOREF(cchPrecision); NOREF(fFlags);
242 char szTmp[160];
243
244 char *pszTmp = szTmp;
245 if (pr80Value->s.fSign)
246 *pszTmp++ = '-';
247 else
248 *pszTmp++ = '+';
249
250 if (pr80Value->s.uExponent == 0)
251 {
252#ifdef RT_COMPILER_GROKS_64BIT_BITFIELDS
253 if ( !pr80Value->sj64.u63Fraction
254 && pr80Value->sj64.fInteger)
255#else
256 if ( !pr80Value->sj.u32FractionLow
257 && !pr80Value->sj.u31FractionHigh
258 && pr80Value->sj.fInteger)
259#endif
260 *pszTmp++ = '0';
261 /* else: Denormal, handled way below. */
262 }
263#ifdef RT_COMPILER_GROKS_64BIT_BITFIELDS
264 else if (pr80Value->sj64.uExponent == UINT16_C(0x7fff))
265#else
266 else if (pr80Value->sj.uExponent == UINT16_C(0x7fff))
267#endif
268 {
269 /** @todo Figure out Pseudo inf/nan... */
270#ifdef RT_COMPILER_GROKS_64BIT_BITFIELDS
271 if (pr80Value->sj64.fInteger)
272#else
273 if (pr80Value->sj.fInteger)
274#endif
275 *pszTmp++ = 'P';
276#ifdef RT_COMPILER_GROKS_64BIT_BITFIELDS
277 if (pr80Value->sj64.u63Fraction == 0)
278#else
279 if ( pr80Value->sj.u32FractionLow == 0
280 && pr80Value->sj.u31FractionHigh == 0)
281#endif
282 {
283 *pszTmp++ = 'I';
284 *pszTmp++ = 'n';
285 *pszTmp++ = 'f';
286 }
287 else
288 {
289 *pszTmp++ = 'N';
290 *pszTmp++ = 'a';
291 *pszTmp++ = 'N';
292 }
293 }
294 if (pszTmp != &szTmp[1])
295 *pszTmp = '\0';
296 else
297 {
298#ifdef RT_COMPILER_GROKS_64BIT_BITFIELDS
299 *pszTmp++ = pr80Value->sj64.fInteger ? '1' : '0';
300#else
301 *pszTmp++ = pr80Value->sj.fInteger ? '1' : '0';
302#endif
303 *pszTmp++ = 'm';
304#ifdef RT_COMPILER_GROKS_64BIT_BITFIELDS
305 pszTmp += RTStrFormatNumber(pszTmp, pr80Value->sj64.u63Fraction, 16, 2+16, 0,
306 RTSTR_F_SPECIAL | RTSTR_F_ZEROPAD | RTSTR_F_64BIT);
307#else
308 pszTmp += RTStrFormatNumber(pszTmp, RT_MAKE_U64(pr80Value->sj.u32FractionLow, pr80Value->sj.u31FractionHigh), 16, 2+16, 0,
309 RTSTR_F_SPECIAL | RTSTR_F_ZEROPAD | RTSTR_F_64BIT);
310#endif
311
312 *pszTmp++ = 'e';
313#ifdef RT_COMPILER_GROKS_64BIT_BITFIELDS
314 pszTmp += RTStrFormatNumber(pszTmp, (int32_t)pr80Value->sj64.uExponent - 16383, 10, 0, 0,
315 RTSTR_F_ZEROPAD | RTSTR_F_32BIT | RTSTR_F_VALSIGNED);
316#else
317 pszTmp += RTStrFormatNumber(pszTmp, (int32_t)pr80Value->sj.uExponent - 16383, 10, 0, 0,
318 RTSTR_F_ZEROPAD | RTSTR_F_32BIT | RTSTR_F_VALSIGNED);
319#endif
320 }
321
322 /*
323 * Copy out the result.
324 */
325 ssize_t cchRet = pszTmp - &szTmp[0];
326 if ((size_t)cchRet <= cbBuf)
327 memcpy(pszBuf, szTmp, cchRet + 1);
328 else
329 {
330 if (cbBuf)
331 {
332 memcpy(pszBuf, szTmp, cbBuf - 1);
333 pszBuf[cbBuf - 1] = '\0';
334 }
335 cchRet = VERR_BUFFER_OVERFLOW;
336 }
337 return cchRet;
338}
339
340
341RTDECL(ssize_t) RTStrFormatR80(char *pszBuf, size_t cbBuf, PCRTFLOAT80U pr80Value, signed int cchWidth,
342 signed int cchPrecision, uint32_t fFlags)
343{
344 RTFLOAT80U2 r80ValueU2;
345 RT_ZERO(r80ValueU2);
346 r80ValueU2.s.fSign = pr80Value->s.fSign;
347 r80ValueU2.s.uExponent = pr80Value->s.uExponent;
348 r80ValueU2.s.u64Mantissa = pr80Value->s.u64Mantissa;
349 return RTStrFormatR80u2(pszBuf, cbBuf, &r80ValueU2, cchWidth, cchPrecision, fFlags);
350}
351
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette