Changeset 64340 in vbox for trunk/src/VBox/Runtime/common/string
- Timestamp:
- Oct 20, 2016 6:38:21 PM (9 years ago)
- svn:sync-xref-src-repo-rev:
- 111436
- File:
-
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/common/string/strprintf2.cpp
r64329 r64340 1 1 /* $Id$ */ 2 2 /** @file 3 * IPRT - String Formatters .3 * IPRT - String Formatters, alternative. 4 4 */ 5 5 … … 38 38 * Structures and Typedefs * 39 39 *********************************************************************************************************************************/ 40 /** strbufoutput() argument structure. */41 typedef struct STR BUFARG40 /** rtStrPrintf2Output() argument structure. */ 41 typedef struct STRPRINTF2OUTPUTARGS 42 42 { 43 43 /** 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. */ 51 typedef STRPRINTF2OUTPUTARGS *PSTRPRINTF2OUTPUTARGS; 56 52 57 53 … … 59 55 * Output callback. 60 56 * 61 * @returns number of bytes written. 57 * @returns cbChars 58 * 62 59 * @param pvArg Pointer to a STRBUFARG structure. 63 60 * @param pachChars Pointer to an array of utf-8 characters. 64 61 * @param cbChars Number of bytes in the character array pointed to by pachChars. 65 62 */ 66 static DECLCALLBACK(size_t) strbufoutput(void *pvArg, const char *pachChars, size_t cbChars)63 static DECLCALLBACK(size_t) rtStrPrintf2Output(void *pvArg, const char *pachChars, size_t cbChars) 67 64 { 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. */ 69 67 70 cbChars = RT_MIN(pArg->cch, cbChars); 71 if (cbChars) 68 if (cbChars < pArgs->cbLeft) 72 69 { 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'; 76 91 } 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 } 78 104 79 105 return cbChars; … … 81 107 82 108 83 RTDECL(s ize_t) RTStrPrintfExV(PFNSTRFORMAT pfnFormat, void *pvArg, char *pszBuffer, size_t cchBuffer, const char *pszFormat, va_list args)109 RTDECL(ssize_t) RTStrPrintf2(char *pszBuffer, size_t cchBuffer, const char *pszFormat, ...) 84 110 { 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")); 86 116 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; 92 120 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; 96 126 } 97 RT_EXPORT_SYMBOL(RTStrPrintf ExV);127 RT_EXPORT_SYMBOL(RTStrPrintf2); 98 128 99 129 100 RTDECL(size_t) RTStrPrintfV(char *pszBuffer, size_t cchBuffer, const char *pszFormat, va_list args) 130 RTDECL(ssize_t) RTStrPrintf2ExV(PFNSTRFORMAT pfnFormat, void *pvArg, char *pszBuffer, size_t cchBuffer, 131 const char *pszFormat, va_list args) 101 132 { 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; 103 142 } 104 RT_EXPORT_SYMBOL(RTStrPrintf V);143 RT_EXPORT_SYMBOL(RTStrPrintf2ExV); 105 144 106 145 107 RTDECL(size_t) RTStrPrintfEx(PFNSTRFORMAT pfnFormat, void *pvArg, char *pszBuffer, size_t cchBuffer, const char *pszFormat, ...) 146 RTDECL(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 } 150 RT_EXPORT_SYMBOL(RTStrPrintf2V); 151 152 153 RTDECL(ssize_t) RTStrPrintf2Ex(PFNSTRFORMAT pfnFormat, void *pvArg, char *pszBuffer, size_t cchBuffer, const char *pszFormat, ...) 108 154 { 109 155 va_list args; 110 s ize_t cbRet;156 ssize_t cbRet; 111 157 va_start(args, pszFormat); 112 cbRet = RTStrPrintf ExV(pfnFormat, pvArg, pszBuffer, cchBuffer, pszFormat, args);158 cbRet = RTStrPrintf2ExV(pfnFormat, pvArg, pszBuffer, cchBuffer, pszFormat, args); 113 159 va_end(args); 114 160 return cbRet; 115 161 } 116 RT_EXPORT_SYMBOL(RTStrPrintf Ex);162 RT_EXPORT_SYMBOL(RTStrPrintf2Ex); 117 163 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.