VirtualBox

source: vbox/trunk/src/VBox/Runtime/common/string/strprintf2.cpp@ 64340

Last change on this file since 64340 was 64340, checked in by vboxsync, 8 years ago

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

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 5.8 KB
Line 
1/* $Id: strprintf2.cpp 64340 2016-10-20 18:38:21Z vboxsync $ */
2/** @file
3 * IPRT - String Formatters, alternative.
4 */
5
6/*
7 * Copyright (C) 2006-2016 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#include <iprt/string.h>
32#include "internal/iprt.h"
33
34#include <iprt/assert.h>
35
36
37/*********************************************************************************************************************************
38* Structures and Typedefs *
39*********************************************************************************************************************************/
40/** rtStrPrintf2Output() argument structure. */
41typedef struct STRPRINTF2OUTPUTARGS
42{
43 /** Pointer to current buffer position. */
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;
52
53
54/**
55 * Output callback.
56 *
57 * @returns cbChars
58 *
59 * @param pvArg Pointer to a STRBUFARG structure.
60 * @param pachChars Pointer to an array of utf-8 characters.
61 * @param cbChars Number of bytes in the character array pointed to by pachChars.
62 */
63static DECLCALLBACK(size_t) rtStrPrintf2Output(void *pvArg, const char *pachChars, size_t cbChars)
64{
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. */
67
68 if (cbChars < pArgs->cbLeft)
69 {
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';
91 }
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 }
104
105 return cbChars;
106}
107
108
109RTDECL(ssize_t) RTStrPrintf2(char *pszBuffer, size_t cchBuffer, const char *pszFormat, ...)
110{
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"));
116
117 Args.pszCur = pszBuffer;
118 Args.cbLeft = cchBuffer;
119 Args.fOverflowed = false;
120
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;
126}
127RT_EXPORT_SYMBOL(RTStrPrintf2);
128
129
130RTDECL(ssize_t) RTStrPrintf2ExV(PFNSTRFORMAT pfnFormat, void *pvArg, char *pszBuffer, size_t cchBuffer,
131 const char *pszFormat, va_list args)
132{
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;
142}
143RT_EXPORT_SYMBOL(RTStrPrintf2ExV);
144
145
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, ...)
154{
155 va_list args;
156 ssize_t cbRet;
157 va_start(args, pszFormat);
158 cbRet = RTStrPrintf2ExV(pfnFormat, pvArg, pszBuffer, cchBuffer, pszFormat, args);
159 va_end(args);
160 return cbRet;
161}
162RT_EXPORT_SYMBOL(RTStrPrintf2Ex);
163
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