VirtualBox

Ignore:
Timestamp:
Oct 20, 2016 6:38:21 PM (9 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
111436
Message:

IPRT: Introducing RTStrPrintf2, RTStrPrintf2V, RTStrPrintf2Ex, and RTStrPrintf2ExV. The existing RTStrPrintf* interfaces are deprecated and unwanted in new code.

File:
1 copied

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/common/string/strprintf2.cpp

    r64329 r64340  
    11/* $Id$ */
    22/** @file
    3  * IPRT - String Formatters.
     3 * IPRT - String Formatters, alternative.
    44 */
    55
     
    3838*   Structures and Typedefs                                                                                                      *
    3939*********************************************************************************************************************************/
    40 /** strbufoutput() argument structure. */
    41 typedef struct STRBUFARG
     40/** rtStrPrintf2Output() argument structure. */
     41typedef struct STRPRINTF2OUTPUTARGS
    4242{
    4343    /** Pointer to current buffer position. */
    44     char   *psz;
    45     /** Number of bytes left in the buffer - not including the trailing zero. */
    46     size_t  cch;
    47 } STRBUFARG;
    48 /** Pointer to a strbufoutput() argument structure. */
    49 typedef STRBUFARG *PSTRBUFARG;
    50 
    51 
    52 /*********************************************************************************************************************************
    53 *   Internal Functions                                                                                                           *
    54 *********************************************************************************************************************************/
    55 static DECLCALLBACK(size_t) strbufoutput(void *pvArg, const char *pachChars, size_t cbChars);
     44    char   *pszCur;
     45    /** Number of bytes left in the buffer (including the trailing zero). */
     46    size_t  cbLeft;
     47    /** Set if we overflowed. */
     48    bool    fOverflowed;
     49} STRPRINTF2OUTPUTARGS;
     50/** Pointer to a rtStrPrintf2Output() argument structure. */
     51typedef STRPRINTF2OUTPUTARGS *PSTRPRINTF2OUTPUTARGS;
    5652
    5753
     
    5955 * Output callback.
    6056 *
    61  * @returns number of bytes written.
     57 * @returns cbChars
     58 *
    6259 * @param   pvArg       Pointer to a STRBUFARG structure.
    6360 * @param   pachChars   Pointer to an array of utf-8 characters.
    6461 * @param   cbChars     Number of bytes in the character array pointed to by pachChars.
    6562 */
    66 static DECLCALLBACK(size_t) strbufoutput(void *pvArg, const char *pachChars, size_t cbChars)
     63static DECLCALLBACK(size_t) rtStrPrintf2Output(void *pvArg, const char *pachChars, size_t cbChars)
    6764{
    68     PSTRBUFARG  pArg = (PSTRBUFARG)pvArg;
     65    PSTRPRINTF2OUTPUTARGS pArgs = (PSTRPRINTF2OUTPUTARGS)pvArg;
     66    char *pszCur = pArgs->pszCur; /* We actually have to spell this out for VS2010, or it will load it for each case. */
    6967
    70     cbChars = RT_MIN(pArg->cch, cbChars);
    71     if (cbChars)
     68    if (cbChars < pArgs->cbLeft)
    7269    {
    73         memcpy(pArg->psz, pachChars, cbChars);
    74         pArg->cch -= cbChars;
    75         pArg->psz += cbChars;
     70        pArgs->cbLeft -= cbChars;
     71
     72        /* Note! For VS2010/64 we need at least 7 case statements before it generates a jump table. */
     73        switch (cbChars)
     74        {
     75            default:
     76                memcpy(pszCur, pachChars, cbChars);
     77                break;
     78            case 8: pszCur[7] = pachChars[7];
     79            case 7: pszCur[6] = pachChars[6];
     80            case 6: pszCur[5] = pachChars[5];
     81            case 5: pszCur[4] = pachChars[4];
     82            case 4: pszCur[3] = pachChars[3];
     83            case 3: pszCur[2] = pachChars[2];
     84            case 2: pszCur[1] = pachChars[1];
     85            case 1: pszCur[0] = pachChars[0];
     86            case 0:
     87                break;
     88        }
     89        pArgs->pszCur = pszCur += cbChars;
     90        *pszCur = '\0';
    7691    }
    77     *pArg->psz = '\0';
     92    else
     93    {
     94        size_t cbLeft = pArgs->cbLeft;
     95        if (cbLeft-- > 1)
     96        {
     97            memcpy(pszCur, pachChars, cbLeft);
     98            pArgs->pszCur = pszCur += cbLeft;
     99            *pszCur = '\0';
     100            pArgs->cbLeft = 1;
     101        }
     102        pArgs->fOverflowed = true;
     103    }
    78104
    79105    return cbChars;
     
    81107
    82108
    83 RTDECL(size_t) RTStrPrintfExV(PFNSTRFORMAT pfnFormat, void *pvArg, char *pszBuffer, size_t cchBuffer, const char *pszFormat, va_list args)
     109RTDECL(ssize_t) RTStrPrintf2(char *pszBuffer, size_t cchBuffer, const char *pszFormat, ...)
    84110{
    85     STRBUFARG Arg;
     111    /* Explicitly inline RTStrPrintf2V + RTStrPrintf2ExV here because this is a frequently use API. */
     112    STRPRINTF2OUTPUTARGS Args;
     113    size_t cchRet;
     114    va_list args;
     115    AssertMsg(cchBuffer > 0, ("Excellent idea! Format a string with no space for the output!\n"));
    86116
    87     if (!cchBuffer)
    88     {
    89         AssertMsgFailed(("Excellent idea! Format a string with no space for the output!\n"));
    90         return 0;
    91     }
     117    Args.pszCur      = pszBuffer;
     118    Args.cbLeft      = cchBuffer;
     119    Args.fOverflowed = false;
    92120
    93     Arg.psz = pszBuffer;
    94     Arg.cch = cchBuffer - 1;
    95     return RTStrFormatV(strbufoutput, &Arg, pfnFormat, pvArg, pszFormat, args);
     121    va_start(args, pszFormat);
     122    cchRet = RTStrFormatV(rtStrPrintf2Output, &Args, NULL, NULL, pszFormat, args);
     123    va_end(args);
     124
     125    return !Args.fOverflowed ? (ssize_t)cchRet : -(ssize_t)cchRet - 1;
    96126}
    97 RT_EXPORT_SYMBOL(RTStrPrintfExV);
     127RT_EXPORT_SYMBOL(RTStrPrintf2);
    98128
    99129
    100 RTDECL(size_t) RTStrPrintfV(char *pszBuffer, size_t cchBuffer, const char *pszFormat, va_list args)
     130RTDECL(ssize_t) RTStrPrintf2ExV(PFNSTRFORMAT pfnFormat, void *pvArg, char *pszBuffer, size_t cchBuffer,
     131                                const char *pszFormat,  va_list args)
    101132{
    102     return RTStrPrintfExV(NULL, NULL, pszBuffer, cchBuffer, pszFormat, args);
     133    STRPRINTF2OUTPUTARGS Args;
     134    size_t cchRet;
     135    AssertMsg(cchBuffer > 0, ("Excellent idea! Format a string with no space for the output!\n"));
     136
     137    Args.pszCur      = pszBuffer;
     138    Args.cbLeft      = cchBuffer;
     139    Args.fOverflowed = false;
     140    cchRet = RTStrFormatV(rtStrPrintf2Output, &Args, pfnFormat, pvArg, pszFormat, args);
     141    return !Args.fOverflowed ? (ssize_t)cchRet : -(ssize_t)cchRet - 1;
    103142}
    104 RT_EXPORT_SYMBOL(RTStrPrintfV);
     143RT_EXPORT_SYMBOL(RTStrPrintf2ExV);
    105144
    106145
    107 RTDECL(size_t) RTStrPrintfEx(PFNSTRFORMAT pfnFormat, void *pvArg, char *pszBuffer, size_t cchBuffer, const char *pszFormat, ...)
     146RTDECL(ssize_t) RTStrPrintf2V(char *pszBuffer, size_t cchBuffer, const char *pszFormat, va_list args)
     147{
     148    return RTStrPrintf2ExV(NULL, NULL, pszBuffer, cchBuffer, pszFormat, args);
     149}
     150RT_EXPORT_SYMBOL(RTStrPrintf2V);
     151
     152
     153RTDECL(ssize_t) RTStrPrintf2Ex(PFNSTRFORMAT pfnFormat, void *pvArg, char *pszBuffer, size_t cchBuffer, const char *pszFormat, ...)
    108154{
    109155    va_list args;
    110     size_t cbRet;
     156    ssize_t cbRet;
    111157    va_start(args, pszFormat);
    112     cbRet = RTStrPrintfExV(pfnFormat, pvArg, pszBuffer, cchBuffer, pszFormat, args);
     158    cbRet = RTStrPrintf2ExV(pfnFormat, pvArg, pszBuffer, cchBuffer, pszFormat, args);
    113159    va_end(args);
    114160    return cbRet;
    115161}
    116 RT_EXPORT_SYMBOL(RTStrPrintfEx);
     162RT_EXPORT_SYMBOL(RTStrPrintf2Ex);
    117163
    118 
    119 RTDECL(size_t) RTStrPrintf(char *pszBuffer, size_t cchBuffer, const char *pszFormat, ...)
    120 {
    121     va_list args;
    122     size_t cbRet;
    123     va_start(args, pszFormat);
    124     cbRet = RTStrPrintfV(pszBuffer, cchBuffer, pszFormat, args);
    125     va_end(args);
    126     return cbRet;
    127 }
    128 RT_EXPORT_SYMBOL(RTStrPrintf);
    129 
Note: See TracChangeset for help on using the changeset viewer.

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