VirtualBox

source: vbox/trunk/src/VBox/Runtime/common/string/stringalloc.cpp@ 81106

Last change on this file since 81106 was 76553, checked in by vboxsync, 6 years ago

scm --update-copyright-year

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 7.5 KB
Line 
1/* $Id: stringalloc.cpp 76553 2019-01-01 01:45:53Z vboxsync $ */
2/** @file
3 * IPRT - String Manipulation.
4 */
5
6/*
7 * Copyright (C) 2006-2019 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#ifndef IN_RING0
35# include <iprt/alloca.h>
36#endif
37#include <iprt/assert.h>
38#include <iprt/mem.h>
39#include <iprt/err.h>
40#include "internal/string.h"
41
42
43
44RTDECL(char *) RTStrAllocTag(size_t cb, const char *pszTag)
45{
46 char *psz = (char *)RTMemAllocTag(RT_MAX(cb, 1), pszTag);
47 if (psz)
48 *psz = '\0';
49 return psz;
50}
51RT_EXPORT_SYMBOL(RTStrAllocTag);
52
53
54RTDECL(int) RTStrAllocExTag(char **ppsz, size_t cb, const char *pszTag)
55{
56 char *psz = *ppsz = (char *)RTMemAllocTag(RT_MAX(cb, 1), pszTag);
57 if (psz)
58 {
59 *psz = '\0';
60 return VINF_SUCCESS;
61 }
62 return VERR_NO_STR_MEMORY;
63}
64RT_EXPORT_SYMBOL(RTStrAllocExTag);
65
66
67RTDECL(int) RTStrReallocTag(char **ppsz, size_t cbNew, const char *pszTag)
68{
69 char *pszOld = *ppsz;
70 if (!cbNew)
71 {
72 RTMemFree(pszOld);
73 *ppsz = NULL;
74 }
75 else if (pszOld)
76 {
77 char *pszNew = (char *)RTMemReallocTag(pszOld, cbNew, pszTag);
78 if (!pszNew)
79 return VERR_NO_STR_MEMORY;
80 pszNew[cbNew - 1] = '\0';
81 *ppsz = pszNew;
82 }
83 else
84 {
85 char *pszNew = (char *)RTMemAllocTag(cbNew, pszTag);
86 if (!pszNew)
87 return VERR_NO_STR_MEMORY;
88 pszNew[0] = '\0';
89 pszNew[cbNew - 1] = '\0';
90 *ppsz = pszNew;
91 }
92 return VINF_SUCCESS;
93}
94RT_EXPORT_SYMBOL(RTStrReallocTag);
95
96RTDECL(void) RTStrFree(char *pszString)
97{
98 if (pszString)
99 RTMemTmpFree(pszString);
100}
101RT_EXPORT_SYMBOL(RTStrFree);
102
103
104RTDECL(char *) RTStrDupTag(const char *pszString, const char *pszTag)
105{
106#if defined(__cplusplus)
107 AssertPtr(pszString);
108#endif
109 size_t cch = strlen(pszString) + 1;
110 char *psz = (char *)RTMemAllocTag(cch, pszTag);
111 if (psz)
112 memcpy(psz, pszString, cch);
113 return psz;
114}
115RT_EXPORT_SYMBOL(RTStrDupTag);
116
117
118RTDECL(int) RTStrDupExTag(char **ppszString, const char *pszString, const char *pszTag)
119{
120#if defined(__cplusplus)
121 AssertPtr(ppszString);
122 AssertPtr(pszString);
123#endif
124
125 size_t cch = strlen(pszString) + 1;
126 char *psz = (char *)RTMemAllocTag(cch, pszTag);
127 if (psz)
128 {
129 memcpy(psz, pszString, cch);
130 *ppszString = psz;
131 return VINF_SUCCESS;
132 }
133 return VERR_NO_MEMORY;
134}
135RT_EXPORT_SYMBOL(RTStrDupExTag);
136
137
138RTDECL(char *) RTStrDupNTag(const char *pszString, size_t cchMax, const char *pszTag)
139{
140#if defined(__cplusplus)
141 AssertPtr(pszString);
142#endif
143 char const *pszEnd = RTStrEnd(pszString, cchMax);
144 size_t cch = pszEnd ? (uintptr_t)pszEnd - (uintptr_t)pszString : cchMax;
145 char *pszDst = (char *)RTMemAllocTag(cch + 1, pszTag);
146 if (pszDst)
147 {
148 memcpy(pszDst, pszString, cch);
149 pszDst[cch] = '\0';
150 }
151 return pszDst;
152}
153RT_EXPORT_SYMBOL(RTStrDupNTag);
154
155
156RTDECL(int) RTStrAAppendTag(char **ppsz, const char *pszAppend, const char *pszTag)
157{
158 if (!pszAppend)
159 return VINF_SUCCESS;
160 return RTStrAAppendNTag(ppsz, pszAppend, RTSTR_MAX, pszTag);
161}
162
163
164RTDECL(int) RTStrAAppendNTag(char **ppsz, const char *pszAppend, size_t cchAppend, const char *pszTag)
165{
166 size_t cchOrg;
167 char *pszNew;
168
169 if (!cchAppend)
170 return VINF_SUCCESS;
171 if (cchAppend == RTSTR_MAX)
172 cchAppend = strlen(pszAppend);
173 else
174 Assert(cchAppend == RTStrNLen(pszAppend, cchAppend));
175
176 cchOrg = *ppsz ? strlen(*ppsz) : 0;
177 pszNew = (char *)RTMemReallocTag(*ppsz, cchOrg + cchAppend + 1, pszTag);
178 if (!pszNew)
179 return VERR_NO_STR_MEMORY;
180
181 memcpy(&pszNew[cchOrg], pszAppend, cchAppend);
182 pszNew[cchOrg + cchAppend] = '\0';
183
184 *ppsz = pszNew;
185 return VINF_SUCCESS;
186}
187
188
189#ifndef IN_RING0
190
191/* XXX Currently not needed anywhere. alloca() induces some linker problems for ring 0 code
192 * with newer versions of VCC */
193
194RTDECL(int) RTStrAAppendExNVTag(char **ppsz, size_t cPairs, va_list va, const char *pszTag)
195{
196 AssertPtr(ppsz);
197 if (!cPairs)
198 return VINF_SUCCESS;
199
200 /*
201 * Determine the length of each string and calc the new total.
202 */
203 struct RTStrAAppendExNVStruct
204 {
205 const char *psz;
206 size_t cch;
207 } *paPairs = (struct RTStrAAppendExNVStruct *)alloca(cPairs * sizeof(*paPairs));
208 AssertReturn(paPairs, VERR_NO_STR_MEMORY);
209
210 size_t cchOrg = *ppsz ? strlen(*ppsz) : 0;
211 size_t cchNewTotal = cchOrg;
212 for (size_t i = 0; i < cPairs; i++)
213 {
214 const char *psz = va_arg(va, const char *);
215 size_t cch = va_arg(va, size_t);
216 AssertPtrNull(psz);
217 Assert(cch == RTSTR_MAX || cch == RTStrNLen(psz, cch));
218
219 if (cch == RTSTR_MAX)
220 cch = psz ? strlen(psz) : 0;
221 cchNewTotal += cch;
222
223 paPairs[i].cch = cch;
224 paPairs[i].psz = psz;
225 }
226 cchNewTotal++; /* '\0' */
227
228 /*
229 * Try reallocate the string.
230 */
231 char *pszNew = (char *)RTMemReallocTag(*ppsz, cchNewTotal, pszTag);
232 if (!pszNew)
233 return VERR_NO_STR_MEMORY;
234
235 /*
236 * Do the appending.
237 */
238 size_t off = cchOrg;
239 for (size_t i = 0; i < cPairs; i++)
240 {
241 memcpy(&pszNew[off], paPairs[i].psz, paPairs[i].cch);
242 off += paPairs[i].cch;
243 }
244 Assert(off + 1 == cchNewTotal);
245 pszNew[off] = '\0';
246
247 /* done */
248 *ppsz = pszNew;
249 return VINF_SUCCESS;
250}
251RT_EXPORT_SYMBOL(RTStrAAppendExNVTag);
252
253#endif
254
255
256RTDECL(int) RTStrATruncateTag(char **ppsz, size_t cchNew, const char *pszTag)
257{
258 char *pszNew;
259 char *pszOld = *ppsz;
260 if (!cchNew)
261 {
262 if (pszOld && *pszOld)
263 {
264 *pszOld = '\0';
265 pszNew = (char *)RTMemReallocTag(pszOld, 1, pszTag);
266 if (pszNew)
267 *ppsz = pszNew;
268 }
269 }
270 else
271 {
272 char *pszZero;
273 AssertPtrReturn(pszOld, VERR_OUT_OF_RANGE);
274 AssertReturn(cchNew < ~(size_t)64, VERR_OUT_OF_RANGE);
275 pszZero = RTStrEnd(pszOld, cchNew + 63);
276 AssertReturn(!pszZero || (size_t)(pszZero - pszOld) >= cchNew, VERR_OUT_OF_RANGE);
277 pszOld[cchNew] = '\0';
278 if (!pszZero)
279 {
280 pszNew = (char *)RTMemReallocTag(pszOld, cchNew + 1, pszTag);
281 if (pszNew)
282 *ppsz = pszNew;
283 }
284 }
285 return VINF_SUCCESS;
286}
287RT_EXPORT_SYMBOL(RTStrATruncateTag);
288
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