VirtualBox

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

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

scm --update-copyright-year

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 5.2 KB
Line 
1/* $Id: strprintf2.cpp 93115 2022-01-01 11:31:46Z vboxsync $ */
2/** @file
3 * IPRT - String Formatters, alternative.
4 */
5
6/*
7 * Copyright (C) 2006-2022 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
108
109RTDECL(ssize_t) RTStrPrintf2V(char *pszBuffer, size_t cchBuffer, const char *pszFormat, va_list args)
110{
111 STRPRINTF2OUTPUTARGS Args;
112 size_t cchRet;
113 AssertMsg(cchBuffer > 0, ("Excellent idea! Format a string with no space for the output!\n"));
114
115 Args.pszCur = pszBuffer;
116 Args.cbLeft = cchBuffer;
117 Args.fOverflowed = false;
118
119 cchRet = RTStrFormatV(rtStrPrintf2Output, &Args, NULL, NULL, pszFormat, args);
120
121 return !Args.fOverflowed ? (ssize_t)cchRet : -(ssize_t)cchRet - 1;
122}
123RT_EXPORT_SYMBOL(RTStrPrintf2V);
124
125
126RTDECL(ssize_t) RTStrPrintf2ExV(PFNSTRFORMAT pfnFormat, void *pvArg, char *pszBuffer, size_t cchBuffer,
127 const char *pszFormat, va_list args)
128{
129 STRPRINTF2OUTPUTARGS Args;
130 size_t cchRet;
131 AssertMsg(cchBuffer > 0, ("Excellent idea! Format a string with no space for the output!\n"));
132
133 Args.pszCur = pszBuffer;
134 Args.cbLeft = cchBuffer;
135 Args.fOverflowed = false;
136 cchRet = RTStrFormatV(rtStrPrintf2Output, &Args, pfnFormat, pvArg, pszFormat, args);
137 return !Args.fOverflowed ? (ssize_t)cchRet : -(ssize_t)cchRet - 1;
138}
139RT_EXPORT_SYMBOL(RTStrPrintf2ExV);
140
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