strformat.cpp revision 44bcb269c031b80dc35c64aa1a6bb25d3b83cd68
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync * innotek Portable Runtime - String Formatter.
e64031e20c39650a7bc902a3e1aba613b9415deevboxsync * Copyright (C) 2006-2007 innotek GmbH
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync * available from http://www.virtualbox.org. This file is free software;
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync * you can redistribute it and/or modify it under the terms of the GNU
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync * General Public License (GPL) as published by the Free Software
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync * The contents of this file may alternatively be used under the terms
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync * of the Common Development and Distribution License Version 1.0
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync * VirtualBox OSE distribution, in which case the provisions of the
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync * CDDL are applicable instead of those of the GPL.
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync * You may elect to license modified versions of this file under the
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync * terms and conditions of either the GPL or the CDDL or both.
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync/*******************************************************************************
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync* Defined Constants *
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync*******************************************************************************/
aa4bcf0a4b2db3ac352b56a291d49cb8d4b66d32vboxsync/*#define MAX(a, b) ((a) >= (b) ? (a) : (b))
aa4bcf0a4b2db3ac352b56a291d49cb8d4b66d32vboxsync#define MIN(a, b) ((a) < (b) ? (a) : (b)) */
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync/*******************************************************************************
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync* Header Files *
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync*******************************************************************************/
96ae2df030763cee874d3f5ac0be07cd1f793281vboxsync/* Wrappers for converting to iprt facilities. */
96ae2df030763cee874d3f5ac0be07cd1f793281vboxsynctypedef struct
96ae2df030763cee874d3f5ac0be07cd1f793281vboxsync/*******************************************************************************
96ae2df030763cee874d3f5ac0be07cd1f793281vboxsync* Internal Functions *
96ae2df030763cee874d3f5ac0be07cd1f793281vboxsync*******************************************************************************/
96ae2df030763cee874d3f5ac0be07cd1f793281vboxsyncstatic unsigned _strnlen(const char *psz, unsigned cchMax);
96ae2df030763cee874d3f5ac0be07cd1f793281vboxsyncstatic unsigned _strnlenUtf16(PCRTUTF16 pwsz, unsigned cchMax);
96ae2df030763cee874d3f5ac0be07cd1f793281vboxsyncstatic int rtStrFormatNumber(char *psz, KSIZE64 ullValue, unsigned int uiBase, signed int cchWidth, signed int cchPrecision, unsigned int fFlags);
96ae2df030763cee874d3f5ac0be07cd1f793281vboxsync * Finds the length of a string up to cchMax.
96ae2df030763cee874d3f5ac0be07cd1f793281vboxsync * @returns Length.
96ae2df030763cee874d3f5ac0be07cd1f793281vboxsync * @param psz Pointer to string.
96ae2df030763cee874d3f5ac0be07cd1f793281vboxsync * @param cchMax Max length.
96ae2df030763cee874d3f5ac0be07cd1f793281vboxsyncstatic unsigned _strnlen(const char *psz, unsigned cchMax)
96ae2df030763cee874d3f5ac0be07cd1f793281vboxsync * Finds the length of a string up to cchMax.
96ae2df030763cee874d3f5ac0be07cd1f793281vboxsync * @returns Length.
96ae2df030763cee874d3f5ac0be07cd1f793281vboxsync * @param pwsz Pointer to string.
96ae2df030763cee874d3f5ac0be07cd1f793281vboxsync * @param cchMax Max length.
96ae2df030763cee874d3f5ac0be07cd1f793281vboxsyncstatic unsigned _strnlenUtf16(PCRTUTF16 pwsz, unsigned cchMax)
96ae2df030763cee874d3f5ac0be07cd1f793281vboxsync unsigned cwc = 0;
96ae2df030763cee874d3f5ac0be07cd1f793281vboxsync while (cchMax-- > 0)
96ae2df030763cee874d3f5ac0be07cd1f793281vboxsync#else /* !IN_RING3 */
96ae2df030763cee874d3f5ac0be07cd1f793281vboxsync#endif /* !IN_RING3 */
96ae2df030763cee874d3f5ac0be07cd1f793281vboxsync * Finds the length of a string up to cchMax.
96ae2df030763cee874d3f5ac0be07cd1f793281vboxsync * @returns Length.
96ae2df030763cee874d3f5ac0be07cd1f793281vboxsync * @param pusz Pointer to string.
96ae2df030763cee874d3f5ac0be07cd1f793281vboxsync * @param cchMax Max length.
96ae2df030763cee874d3f5ac0be07cd1f793281vboxsyncstatic unsigned _strnlenUni(PCRTUNICP pusz, unsigned cchMax)
96ae2df030763cee874d3f5ac0be07cd1f793281vboxsync * Formats an integer number according to the parameters.
96ae2df030763cee874d3f5ac0be07cd1f793281vboxsync * @returns Length of the formatted number.
96ae2df030763cee874d3f5ac0be07cd1f793281vboxsync * @param psz Pointer to output string buffer of sufficient size.
96ae2df030763cee874d3f5ac0be07cd1f793281vboxsync * @param u64Value Value to format.
96ae2df030763cee874d3f5ac0be07cd1f793281vboxsync * @param uiBase Number representation base.
96ae2df030763cee874d3f5ac0be07cd1f793281vboxsync * @param cchWidth Width.
96ae2df030763cee874d3f5ac0be07cd1f793281vboxsync * @param cchPrecision Precision.
96ae2df030763cee874d3f5ac0be07cd1f793281vboxsync * @param fFlags Flags (NTFS_*).
96ae2df030763cee874d3f5ac0be07cd1f793281vboxsyncRTDECL(int) RTStrFormatNumber(char *psz, uint64_t u64Value, unsigned int uiBase, signed int cchWidth, signed int cchPrecision, unsigned int fFlags)
96ae2df030763cee874d3f5ac0be07cd1f793281vboxsync return rtStrFormatNumber(psz, *(KSIZE64 *)(void *)&u64Value, uiBase, cchWidth, cchPrecision, fFlags);
96ae2df030763cee874d3f5ac0be07cd1f793281vboxsync * Formats an integer number according to the parameters.
96ae2df030763cee874d3f5ac0be07cd1f793281vboxsync * @returns Length of the number.
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync * @param psz Pointer to output string.
e420253a89a6e07613f49cfd9a1db9e217039575vboxsync * @param ullValue Value. Using the high part is optional.
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync * @param uiBase Number representation base.
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync * @param cchWidth Width
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync * @param cchPrecision Precision.
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync * @param fFlags Flags (NTFS_*).
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsyncstatic int rtStrFormatNumber(char *psz, KSIZE64 ullValue, unsigned int uiBase, signed int cchWidth, signed int cchPrecision, unsigned int fFlags)
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync unsigned long ul;
96ae2df030763cee874d3f5ac0be07cd1f793281vboxsync unsigned long ullow;
96ae2df030763cee874d3f5ac0be07cd1f793281vboxsync/** @todo Formatting of 64 bit numbers is broken, fix it! */
96ae2df030763cee874d3f5ac0be07cd1f793281vboxsync * Validate and addjust input...
96ae2df030763cee874d3f5ac0be07cd1f793281vboxsync/** @todo r=bird: Dmitry, who is calling this code with uiBase == 0? */
96ae2df030763cee874d3f5ac0be07cd1f793281vboxsync * Determin value length
96ae2df030763cee874d3f5ac0be07cd1f793281vboxsync if ((fFlags & RTSTR_F_VALSIGNED) && (ullValue.ulHi & 0x80000000))
33b0e5fd502b10034575ffa7c8a30c6816222ce2vboxsync ul = (fFlags & RTSTR_F_VALSIGNED) && (ullValue.ulLo & 0x80000000) ? -(int32_t)ullValue.ulLo : ullValue.ulLo;
96ae2df030763cee874d3f5ac0be07cd1f793281vboxsync * Sign (+/-).
96ae2df030763cee874d3f5ac0be07cd1f793281vboxsync if ((ullValue.ulHi || (fFlags & RTSTR_F_64BIT) ? ullValue.ulHi : ullValue.ulLo) & 0x80000000)
96ae2df030763cee874d3f5ac0be07cd1f793281vboxsync psz[i++] = (char)(fFlags & RTSTR_F_PLUS ? '+' : ' ');
96ae2df030763cee874d3f5ac0be07cd1f793281vboxsync * Special (0/0x).
96ae2df030763cee874d3f5ac0be07cd1f793281vboxsync if ((fFlags & RTSTR_F_SPECIAL) && (uiBase % 8) == 0)
96ae2df030763cee874d3f5ac0be07cd1f793281vboxsync psz[i++] = (char)(fFlags & RTSTR_F_CAPITAL ? 'X' : 'x');
96ae2df030763cee874d3f5ac0be07cd1f793281vboxsync * width - only if ZEROPAD
6e59cff536e8de93f15fa1fb6b46d0ee01e06829vboxsync while (--cchWidth >= 0)
96ae2df030763cee874d3f5ac0be07cd1f793281vboxsync for (j = i-1; j >= 0; j--)
96ae2df030763cee874d3f5ac0be07cd1f793281vboxsync for (j = 0; j < cchWidth; j++)
6e59cff536e8de93f15fa1fb6b46d0ee01e06829vboxsync * precision
} while (u64);
ul = (fFlags & RTSTR_F_VALSIGNED) && (ullValue.ulLo & 0x80000000) ? -(int32_t)ullValue.ulLo : ullValue.ulLo;
} while (ul);
while (--cchWidth >= 0)
RTDECL(size_t) RTStrFormatV(PFNRTSTROUTPUT pfnOutput, void *pvArgOutput, PFNSTRFORMAT pfnFormat, void *pvArgFormat, const char *pszFormat, va_list InArgs)
pszFormat++;
unsigned int fFlags = 0;
char chArgSize;
switch (*pszFormat++)
pszFormat--;
pszFormat++;
if (cchWidth < 0)
pszFormat++;
pszFormat++;
if (cchPrecision < 0)
cchPrecision = 0;
if (chArgSize != 'l' && chArgSize != 'L' && chArgSize != 'h' && chArgSize != 'j' && chArgSize != 'z' && chArgSize != 't')
chArgSize = 0;
pszFormat++;
pszFormat++;
pszFormat++;
switch (*pszFormat++)
char ch;
while (--cchWidth > 0)
while (--cchWidth > 0)
#ifndef IN_RING3
int cchStr;
while (cchStr-- > 0)
#ifdef IN_RING3
int cchStr;
while (cchStr-- > 0)
#ifdef IN_RING3
int cchStr;
#ifdef IN_RING3
int cchStr;
if (cchStr)
char *pszUtf8;
char *pszCurCp;
while (cchStr-- > 0)
int cchStr;
if (cchStr)
char *pszCurCp;
while (cchStr-- > 0)
int cchNum;
if (cchWidth < 0)
cchNum = RTStrFormatNumber((char *)SSToDS(&achNum), u64Value, uBase, cchWidth, cchPrecision, fFlags);
pszFormat--;
cch += rtstrFormatRt(pfnOutput, pvArgOutput, &pszFormat, &args, cchPrecision, cchWidth, fFlags, chArgSize);
pszFormat--;
cch += rtstrFormatType(pfnOutput, pvArgOutput, &pszFormat, &args, cchPrecision, cchWidth, fFlags, chArgSize);
#ifdef RT_WITH_VBOX
pszFormat--;
cch += rtstrFormatVBox(pfnOutput, pvArgOutput, &pszFormat, &args, cchPrecision, cchWidth, fFlags, chArgSize);
if (pfnFormat)
pszFormat--;
cch += pfnFormat(pvArgFormat, pfnOutput, pvArgOutput, &pszFormat, &args, cchPrecision, cchWidth, fFlags, chArgSize);
pszFormat++;
return cch;
RTDECL(size_t) RTStrFormat(PFNRTSTROUTPUT pfnOutput, void *pvArgOutput, PFNSTRFORMAT pfnFormat, void *pvArgFormat, const char *pszFormat, ...)
return cch;