VirtualBox

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

Last change on this file since 27046 was 26723, checked in by vboxsync, 15 years ago

RTStrATruncate: bugfix

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 7.0 KB
Line 
1/* $Id: stringalloc.cpp 26723 2010-02-23 19:39:36Z vboxsync $ */
2/** @file
3 * IPRT - String Manipulation.
4 */
5
6/*
7 * Copyright (C) 2006-2007 Sun Microsystems, Inc.
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 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
27 * Clara, CA 95054 USA or visit http://www.sun.com if you need
28 * additional information or have any questions.
29 */
30
31
32/*******************************************************************************
33* Header Files *
34*******************************************************************************/
35#include <iprt/string.h>
36#include "internal/iprt.h"
37
38#include <iprt/alloca.h>
39#include <iprt/assert.h>
40#include <iprt/mem.h>
41#include <iprt/err.h>
42#include "internal/string.h"
43
44
45
46RTDECL(char *) RTStrAlloc(size_t cb)
47{
48 char *psz = (char *)RTMemAlloc(RT_MAX(cb, 1));
49 if (psz)
50 *psz = '\0';
51 return psz;
52}
53RT_EXPORT_SYMBOL(RTStrAlloc);
54
55
56RTDECL(int) RTStrAllocEx(char **ppsz, size_t cb)
57{
58 char *psz = *ppsz = (char *)RTMemAlloc(RT_MAX(cb, 1));
59 if (psz)
60 {
61 *psz = '\0';
62 return VINF_SUCCESS;
63 }
64 return VERR_NO_STR_MEMORY;
65}
66RT_EXPORT_SYMBOL(RTStrAlloc);
67
68
69RTDECL(int) RTStrRealloc(char **ppsz, size_t cbNew)
70{
71 char *pszOld = *ppsz;
72 if (!cbNew)
73 {
74 RTMemFree(pszOld);
75 *ppsz = NULL;
76 }
77 else if (pszOld)
78 {
79 char *pszNew = (char *)RTMemRealloc(pszOld, cbNew);
80 if (!pszNew)
81 return VERR_NO_STR_MEMORY;
82 pszNew[cbNew - 1] = '\0';
83 *ppsz = pszNew;
84 }
85 else
86 {
87 char *pszNew = (char *)RTMemAlloc(cbNew);
88 if (!pszNew)
89 return VERR_NO_STR_MEMORY;
90 pszNew[0] = '\0';
91 pszNew[cbNew - 1] = '\0';
92 *ppsz = pszNew;
93 }
94 return VINF_SUCCESS;
95}
96
97RTDECL(void) RTStrFree(char *pszString)
98{
99 if (pszString)
100 RTMemTmpFree(pszString);
101}
102RT_EXPORT_SYMBOL(RTStrFree);
103
104
105RTDECL(char *) RTStrDup(const char *pszString)
106{
107 AssertPtr(pszString);
108 size_t cch = strlen(pszString) + 1;
109 char *psz = (char *)RTMemAlloc(cch);
110 if (psz)
111 memcpy(psz, pszString, cch);
112 return psz;
113}
114RT_EXPORT_SYMBOL(RTStrDup);
115
116
117RTDECL(int) RTStrDupEx(char **ppszString, const char *pszString)
118{
119 AssertPtr(ppszString);
120 AssertPtr(pszString);
121
122 size_t cch = strlen(pszString) + 1;
123 char *psz = (char *)RTMemAlloc(cch);
124 if (psz)
125 {
126 memcpy(psz, pszString, cch);
127 *ppszString = psz;
128 return VINF_SUCCESS;
129 }
130 return VERR_NO_MEMORY;
131}
132RT_EXPORT_SYMBOL(RTStrDupEx);
133
134
135RTDECL(char *) RTStrDupN(const char *pszString, size_t cchMax)
136{
137 AssertPtr(pszString);
138 char *pszEnd = (char *)memchr(pszString, '\0', cchMax);
139 size_t cch = pszEnd ? (uintptr_t)pszEnd - (uintptr_t)pszString : cchMax;
140 char *pszDst = (char *)RTMemAlloc(cch + 1);
141 if (pszDst)
142 {
143 memcpy(pszDst, pszString, cch);
144 pszDst[cch] = '\0';
145 }
146 return pszDst;
147}
148RT_EXPORT_SYMBOL(RTStrDupN);
149
150
151RTDECL(int) RTStrAAppend(char **ppsz, const char *pszAppend)
152{
153 if (!pszAppend)
154 return VINF_SUCCESS;
155 return RTStrAAppendN(ppsz, pszAppend, RTSTR_MAX);
156}
157
158
159RTDECL(int) RTStrAAppendN(char **ppsz, const char *pszAppend, size_t cchAppend)
160{
161 if (!cchAppend)
162 return VINF_SUCCESS;
163 if (cchAppend == RTSTR_MAX)
164 cchAppend = strlen(pszAppend);
165 else
166 Assert(cchAppend == RTStrNLen(pszAppend, cchAppend));
167
168 size_t const cchOrg = *ppsz ? strlen(*ppsz) : 0;
169 char *pszNew = (char *)RTMemRealloc(*ppsz, cchOrg + cchAppend + 1);
170 if (!pszNew)
171 return VERR_NO_STR_MEMORY;
172
173 memcpy(&pszNew[cchOrg], pszAppend, cchAppend);
174 pszNew[cchOrg + cchAppend] = '\0';
175
176 *ppsz = pszNew;
177 return VINF_SUCCESS;
178}
179
180
181RTDECL(int) RTStrAAppendExNV(char **ppsz, size_t cPairs, va_list va)
182{
183 AssertPtr(ppsz);
184 if (!cPairs)
185 return VINF_SUCCESS;
186
187 /*
188 * Determin the length of each string and calc the new total.
189 */
190 struct RTStrAAppendExNVStruct
191 {
192 const char *psz;
193 size_t cch;
194 } *paPairs = (struct RTStrAAppendExNVStruct *)alloca(cPairs * sizeof(*paPairs));
195 AssertReturn(paPairs, VERR_NO_STR_MEMORY);
196
197 size_t cchOrg = *ppsz ? strlen(*ppsz) : 0;
198 size_t cchNewTotal = cchOrg;
199 for (size_t i = 0; i < cPairs; i++)
200 {
201 const char *psz = va_arg(va, const char *);
202 size_t cch = va_arg(va, size_t);
203 AssertPtrNull(psz);
204 Assert(cch == RTSTR_MAX || cch == RTStrNLen(psz, cch));
205
206 if (cch == RTSTR_MAX)
207 cch = psz ? strlen(psz) : 0;
208 cchNewTotal += cch;
209
210 paPairs[i].cch = cch;
211 paPairs[i].psz = psz;
212 }
213 cchNewTotal++; /* '\0' */
214
215 /*
216 * Try reallocate the string.
217 */
218 char *pszNew = (char *)RTMemRealloc(*ppsz, cchNewTotal);
219 if (!pszNew)
220 return VERR_NO_STR_MEMORY;
221
222 /*
223 * Do the appending.
224 */
225 size_t off = cchOrg;
226 for (size_t i = 0; i < cPairs; i++)
227 {
228 memcpy(&pszNew[off], paPairs[i].psz, paPairs[i].cch);
229 off += paPairs[i].cch;
230 }
231 Assert(off + 1 == cchNewTotal);
232 pszNew[off] = '\0';
233
234 /* done */
235 *ppsz = pszNew;
236 return VINF_SUCCESS;
237}
238RT_EXPORT_SYMBOL(RTStrAAppendExNV);
239
240
241RTDECL(int) RTStrAAppendExN(char **ppsz, size_t cPairs, ...)
242{
243 va_list va;
244 va_start(va, cPairs);
245 int rc = RTStrAAppendExNV(ppsz, cPairs, va);
246 va_end(va);
247 return rc;
248}
249RT_EXPORT_SYMBOL(RTStrAAppendExN);
250
251
252RTDECL(int) RTStrATruncate(char **ppsz, size_t cchNew)
253{
254 char *pszOld = *ppsz;
255 if (!cchNew)
256 {
257 if (pszOld && *pszOld)
258 {
259 *pszOld = '\0';
260 char *pszNew = (char *)RTMemRealloc(pszOld, 1);
261 if (pszNew)
262 *ppsz = pszNew;
263 }
264 }
265 else
266 {
267 AssertPtrReturn(pszOld, VERR_OUT_OF_RANGE);
268 char *pszZero = (char *)memchr(pszOld, '\0', cchNew + 63);
269 AssertReturn(!pszZero || (size_t)(pszZero - pszOld) >= cchNew, VERR_OUT_OF_RANGE);
270 pszOld[cchNew] = '\0';
271 if (!pszZero)
272 {
273 char *pszNew = (char *)RTMemRealloc(pszOld, cchNew + 1);
274 if (pszNew)
275 *ppsz = pszNew;
276 }
277 }
278 return VINF_SUCCESS;
279}
280RT_EXPORT_SYMBOL(RTStrATruncate);
281
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