VirtualBox

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

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

OVF: add export support for remaining description entry items (actual image export is next)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 4.3 KB
Line 
1/* $Id: string.cpp 17634 2009-03-10 15:01:07Z 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.virtualbox.org. 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
40size_t Utf8Str::find(const char *pcszFind,
41 size_t pos /*= 0*/)
42 const
43{
44 const char *pszThis, *p;
45
46 if ( ((pszThis = c_str()))
47 && (pos < length())
48 && ((p = strstr(pszThis + pos, pcszFind)))
49 )
50 return p - pszThis;
51
52 return npos;
53}
54
55Utf8Str Utf8Str::substr(size_t pos /*= 0*/, size_t n /*= npos*/)
56 const
57{
58 Utf8Str ret;
59
60 if (n)
61 {
62 const char *psz;
63
64 if ((psz = c_str()))
65 {
66 RTUNICP cp;
67
68 // walk the UTF-8 characters until where the caller wants to start
69 size_t i = pos;
70 while (*psz && i--)
71 if (RT_FAILURE(RTStrGetCpEx(&psz, &cp)))
72 return ret; // return empty string on bad encoding
73
74 const char *pFirst = psz;
75
76 if (n == npos)
77 // all the rest:
78 ret = pFirst;
79 else
80 {
81 i = n;
82 while (*psz && i--)
83 if (RT_FAILURE(RTStrGetCpEx(&psz, &cp)))
84 return ret; // return empty string on bad encoding
85
86 size_t cbCopy = psz - pFirst;
87 ret.alloc(cbCopy + 1);
88 memcpy(ret.str, pFirst, cbCopy);
89 ret.str[cbCopy] = '\0';
90 }
91 }
92 }
93
94 return ret;
95}
96
97int Utf8Str::toInt(uint64_t &i) const
98{
99 if (!str)
100 return VERR_NO_DIGITS;
101 return RTStrToUInt64Ex(str, NULL, 0, &i);
102}
103
104int Utf8Str::toInt(uint32_t &i) const
105{
106 if (!str)
107 return VERR_NO_DIGITS;
108 return RTStrToUInt32Ex(str, NULL, 0, &i);
109}
110
111struct FormatData
112{
113 static const size_t CacheIncrement = 256;
114 size_t size;
115 size_t pos;
116 char *cache;
117};
118
119void Utf8StrFmt::init (const char *format, va_list args)
120{
121 if (!format)
122 return;
123
124 // assume an extra byte for a terminating zero
125 size_t fmtlen = strlen (format) + 1;
126
127 FormatData data;
128 data.size = FormatData::CacheIncrement;
129 if (fmtlen >= FormatData::CacheIncrement)
130 data.size += fmtlen;
131 data.pos = 0;
132 data.cache = (char *) ::RTMemTmpAllocZ (data.size);
133
134 size_t n = ::RTStrFormatV (strOutput, &data, NULL, NULL, format, args);
135
136 AssertMsg (n == data.pos,
137 ("The number of bytes formatted doesn't match: %d and %d!",
138 n, data.pos));
139 NOREF (n);
140
141 // finalize formatting
142 data.cache [data.pos] = 0;
143 (*static_cast <Utf8Str *> (this)) = data.cache;
144 ::RTMemTmpFree (data.cache);
145}
146
147// static
148DECLCALLBACK(size_t) Utf8StrFmt::strOutput (void *pvArg, const char *pachChars,
149 size_t cbChars)
150{
151 Assert (pvArg);
152 FormatData &data = *(FormatData *) pvArg;
153
154 if (!(pachChars == NULL && cbChars == 0))
155 {
156 Assert (pachChars);
157
158 // append to cache (always assume an extra byte for a terminating zero)
159 size_t needed = cbChars + 1;
160 if (data.pos + needed > data.size)
161 {
162 data.size += FormatData::CacheIncrement;
163 if (needed >= FormatData::CacheIncrement)
164 data.size += needed;
165 data.cache = (char *) ::RTMemRealloc (data.cache, data.size);
166 }
167 strncpy (data.cache + data.pos, pachChars, cbChars);
168 data.pos += cbChars;
169 }
170
171 return cbChars;
172}
173
174
175} /* namespace com */
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