VirtualBox

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

Last change on this file since 91788 was 91788, checked in by vboxsync, 3 years ago

IPRT/strprintf2: Prep for splitting out the ellipsis functions. bugref:10124

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 5.9 KB
Line 
1/* $Id: strprintf2.cpp 91788 2021-10-17 17:55:43Z vboxsync $ */
2/** @file
3 * IPRT - String Formatters, alternative.
4 */
5
6/*
7 * Copyright (C) 2006-2020 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]; RT_FALL_THRU();
79 case 7: pszCur[6] = pachChars[6]; RT_FALL_THRU();
80 case 6: pszCur[5] = pachChars[5]; RT_FALL_THRU();
81 case 5: pszCur[4] = pachChars[4]; RT_FALL_THRU();
82 case 4: pszCur[3] = pachChars[3]; RT_FALL_THRU();
83 case 3: pszCur[2] = pachChars[2]; RT_FALL_THRU();
84 case 2: pszCur[1] = pachChars[1]; RT_FALL_THRU();
85 case 1: pszCur[0] = pachChars[0]; RT_FALL_THRU();
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
108RTDECL(ssize_t) RTStrPrintf2V(char *pszBuffer, size_t cchBuffer, const char *pszFormat, va_list args)
109{
110 STRPRINTF2OUTPUTARGS Args;
111 size_t cchRet;
112 AssertMsg(cchBuffer > 0, ("Excellent idea! Format a string with no space for the output!\n"));
113
114 Args.pszCur = pszBuffer;
115 Args.cbLeft = cchBuffer;
116 Args.fOverflowed = false;
117
118 cchRet = RTStrFormatV(rtStrPrintf2Output, &Args, NULL, NULL, pszFormat, args);
119
120 return !Args.fOverflowed ? (ssize_t)cchRet : -(ssize_t)cchRet - 1;
121}
122RT_EXPORT_SYMBOL(RTStrPrintf2V);
123
124
125
126RTDECL(ssize_t) RTStrPrintf2(char *pszBuffer, size_t cchBuffer, const char *pszFormat, ...)
127{
128 va_list va;
129 ssize_t cbRet;
130 va_start(va, pszFormat);
131 cbRet = RTStrPrintf2V(pszBuffer, cchBuffer, pszFormat, va);
132 va_end(va);
133 return cbRet;
134}
135RT_EXPORT_SYMBOL(RTStrPrintf2);
136
137
138RTDECL(ssize_t) RTStrPrintf2ExV(PFNSTRFORMAT pfnFormat, void *pvArg, char *pszBuffer, size_t cchBuffer,
139 const char *pszFormat, va_list args)
140{
141 STRPRINTF2OUTPUTARGS Args;
142 size_t cchRet;
143 AssertMsg(cchBuffer > 0, ("Excellent idea! Format a string with no space for the output!\n"));
144
145 Args.pszCur = pszBuffer;
146 Args.cbLeft = cchBuffer;
147 Args.fOverflowed = false;
148 cchRet = RTStrFormatV(rtStrPrintf2Output, &Args, pfnFormat, pvArg, pszFormat, args);
149 return !Args.fOverflowed ? (ssize_t)cchRet : -(ssize_t)cchRet - 1;
150}
151RT_EXPORT_SYMBOL(RTStrPrintf2ExV);
152
153
154RTDECL(ssize_t) RTStrPrintf2Ex(PFNSTRFORMAT pfnFormat, void *pvArg, char *pszBuffer, size_t cchBuffer, const char *pszFormat, ...)
155{
156 va_list args;
157 ssize_t cbRet;
158 va_start(args, pszFormat);
159 cbRet = RTStrPrintf2ExV(pfnFormat, pvArg, pszBuffer, cchBuffer, pszFormat, args);
160 va_end(args);
161 return cbRet;
162}
163RT_EXPORT_SYMBOL(RTStrPrintf2Ex);
164
Note: See TracBrowser for help on using the repository browser.

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