VirtualBox

source: vbox/trunk/src/VBox/Main/glue/string.cpp@ 16378

Last change on this file since 16378 was 16378, checked in by vboxsync, 16 years ago

string.cpp: !RT_SUCCESS -> RT_FAILURE, propsal for saving one memcpy+alloc/free.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 4.0 KB
Line 
1/* $Id: string.cpp 16378 2009-01-29 16:51:48Z vboxsync $ */
2
3/** @file
4 *
5 * MS COM / XPCOM Abstraction Layer:
6 * Smart string classes definition
7 */
8
9/*
10 * Copyright (C) 2006-2007 Sun Microsystems, Inc.
11 *
12 * This file is part of VirtualBox Open Source Edition (OSE), as
13 * available from http://www.215389.xyz. This file is free software;
14 * you can redistribute it and/or modify it under the terms of the GNU
15 * General Public License (GPL) as published by the Free Software
16 * Foundation, in version 2 as it comes in the "COPYING" file of the
17 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
18 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
19 *
20 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
21 * Clara, CA 95054 USA or visit http://www.sun.com if you need
22 * additional information or have any questions.
23 */
24
25#include "VBox/com/string.h"
26
27#include <iprt/err.h>
28
29namespace com
30{
31
32/* static */
33const Bstr Bstr::Null; /* default ctor is OK */
34
35/* static */
36const Utf8Str Utf8Str::Null; /* default ctor is OK */
37
38const size_t Utf8Str::npos = (size_t)-1;
39
40Utf8Str Utf8Str::substr(size_t pos /*= 0*/, size_t n /*= npos*/) const
41{
42 Utf8Str ret;
43
44 if (n)
45 {
46 const char *psz;
47
48 if ((psz = c_str()))
49 {
50 RTUNICP cp;
51
52 // walk the UTF-8 characters until where the caller wants to start
53 size_t i = pos;
54 while (*psz && i--)
55 if (RT_FAILURE(RTStrGetCpEx(&psz, &cp)))
56 return ret; // return empty string on bad encoding
57
58 const char *pFirst = psz;
59
60 if (n == npos)
61 // all the rest:
62 ret = pFirst;
63 else
64 {
65 i = n;
66 while (*psz && i--)
67 if (RT_FAILURE(RTStrGetCpEx(&psz, &cp)))
68 return ret; // return empty string on bad encoding
69
70 size_t len = psz - pFirst;
71#if 1
72 char *psz = (char*)RTMemAlloc(len + 1);
73 memcpy(psz, pFirst, len);
74 psz[len] = '\0';
75 ret = psz;
76 RTMemFree(psz);
77#else /* A proposal that saves a memcpy and alloc/free: */
78 ret.alloc(len + 1);
79 memcpy(ret.str, pFirst, len);
80 ret.str[len] = '\0';
81#endif
82 }
83 }
84 }
85
86 return ret;
87}
88
89struct FormatData
90{
91 static const size_t CacheIncrement = 256;
92 size_t size;
93 size_t pos;
94 char *cache;
95};
96
97void Utf8StrFmt::init (const char *format, va_list args)
98{
99 if (!format)
100 return;
101
102 // assume an extra byte for a terminating zero
103 size_t fmtlen = strlen (format) + 1;
104
105 FormatData data;
106 data.size = FormatData::CacheIncrement;
107 if (fmtlen >= FormatData::CacheIncrement)
108 data.size += fmtlen;
109 data.pos = 0;
110 data.cache = (char *) ::RTMemTmpAllocZ (data.size);
111
112 size_t n = ::RTStrFormatV (strOutput, &data, NULL, NULL, format, args);
113
114 AssertMsg (n == data.pos,
115 ("The number of bytes formatted doesn't match: %d and %d!",
116 n, data.pos));
117 NOREF (n);
118
119 // finalize formatting
120 data.cache [data.pos] = 0;
121 (*static_cast <Utf8Str *> (this)) = data.cache;
122 ::RTMemTmpFree (data.cache);
123}
124
125// static
126DECLCALLBACK(size_t) Utf8StrFmt::strOutput (void *pvArg, const char *pachChars,
127 size_t cbChars)
128{
129 Assert (pvArg);
130 FormatData &data = *(FormatData *) pvArg;
131
132 if (!(pachChars == NULL && cbChars == 0))
133 {
134 Assert (pachChars);
135
136 // append to cache (always assume an extra byte for a terminating zero)
137 size_t needed = cbChars + 1;
138 if (data.pos + needed > data.size)
139 {
140 data.size += FormatData::CacheIncrement;
141 if (needed >= FormatData::CacheIncrement)
142 data.size += needed;
143 data.cache = (char *) ::RTMemRealloc (data.cache, data.size);
144 }
145 strncpy (data.cache + data.pos, pachChars, cbChars);
146 data.pos += cbChars;
147 }
148
149 return cbChars;
150}
151
152
153} /* namespace com */
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