~ubuntu-branches/ubuntu/raring/virtualbox-ose/raring

« back to all changes in this revision

Viewing changes to src/VBox/Runtime/common/string/ministring.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Felix Geyer
  • Date: 2011-01-30 23:27:25 UTC
  • mfrom: (0.3.12 upstream)
  • Revision ID: james.westby@ubuntu.com-20110130232725-2ouajjd2ggdet0zd
Tags: 4.0.2-dfsg-1ubuntu1
* Merge from Debian unstable, remaining changes:
  - Add Apport hook.
    - debian/virtualbox-ose.files/source_virtualbox-ose.py
    - debian/virtualbox-ose.install
  - Drop *-source packages.
* Drop ubuntu-01-fix-build-gcc45.patch, fixed upstream.
* Drop ubuntu-02-as-needed.patch, added to the Debian package.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* $Id: ministring.cpp $ */
 
1
/* $Id: ministring.cpp 35567 2011-01-14 14:16:45Z vboxsync $ */
2
2
/** @file
3
3
 * IPRT - Mini C++ string class.
4
4
 *
7
7
 */
8
8
 
9
9
/*
10
 
 * Copyright (C) 2007-2009 Oracle Corporation
 
10
 * Copyright (C) 2007-2010 Oracle Corporation
11
11
 *
12
12
 * This file is part of VirtualBox Open Source Edition (OSE), as
13
13
 * available from http://www.virtualbox.org. This file is free software;
27
27
 * terms and conditions of either the GPL or the CDDL or both.
28
28
 */
29
29
 
 
30
 
 
31
/*******************************************************************************
 
32
*   Header Files                                                               *
 
33
*******************************************************************************/
30
34
#include <iprt/cpp/ministring.h>
31
 
 
32
35
using namespace iprt;
33
36
 
 
37
 
 
38
/*******************************************************************************
 
39
*   Global Variables                                                           *
 
40
*******************************************************************************/
34
41
const size_t MiniString::npos = ~(size_t)0;
35
42
 
 
43
/*******************************************************************************
 
44
*   Defined Constants And Macros                                               *
 
45
*******************************************************************************/
 
46
/** Allocation block alignment used when appending bytes to a string. */
 
47
#define IPRT_MINISTRING_APPEND_ALIGNMENT    64
 
48
 
 
49
 
 
50
MiniString &MiniString::printf(const char *pszFormat, ...)
 
51
{
 
52
    va_list va;
 
53
    va_start(va, pszFormat);
 
54
    printfV(pszFormat, va);
 
55
    va_end(va);
 
56
    return *this;
 
57
}
 
58
 
 
59
/**
 
60
 * Callback used with RTStrFormatV by MiniString::printfV.
 
61
 *
 
62
 * @returns The number of bytes added (not used).
 
63
 *
 
64
 * @param   pvArg           The string object.
 
65
 * @param   pachChars       The characters to append.
 
66
 * @param   cbChars         The number of characters.  0 on the final callback.
 
67
 */
 
68
/*static*/ DECLCALLBACK(size_t)
 
69
MiniString::printfOutputCallback(void *pvArg, const char *pachChars, size_t cbChars)
 
70
{
 
71
    MiniString *pThis = (MiniString *)pvArg;
 
72
    if (cbChars)
 
73
    {
 
74
        size_t cchBoth = pThis->m_cch + cbChars;
 
75
        if (cchBoth >= pThis->m_cbAllocated)
 
76
        {
 
77
            /* Double the buffer size, if it's less that _4M. Align sizes like
 
78
               for append. */
 
79
            size_t cbAlloc = RT_ALIGN_Z(pThis->m_cbAllocated, IPRT_MINISTRING_APPEND_ALIGNMENT);
 
80
            cbAlloc += RT_MIN(cbAlloc, _4M);
 
81
            if (cbAlloc <= cchBoth)
 
82
                cbAlloc = RT_ALIGN_Z(cchBoth + 1, IPRT_MINISTRING_APPEND_ALIGNMENT);
 
83
            pThis->reserve(cbAlloc);
 
84
#ifndef RT_EXCEPTIONS_ENABLED
 
85
            AssertReleaseReturn(pThis->capacity() > cchBoth, 0);
 
86
#endif
 
87
        }
 
88
 
 
89
        memcpy(&pThis->m_psz[pThis->m_cch], pachChars, cbChars);
 
90
        pThis->m_cch = cchBoth;
 
91
        pThis->m_psz[cchBoth] = '\0';
 
92
    }
 
93
    return cbChars;
 
94
}
 
95
 
 
96
MiniString &MiniString::printfV(const char *pszFormat, va_list va)
 
97
{
 
98
    cleanup();
 
99
    RTStrFormatV(printfOutputCallback, this, NULL, NULL, pszFormat, va);
 
100
    return *this;
 
101
}
 
102
 
36
103
MiniString &MiniString::append(const MiniString &that)
37
104
{
38
 
    size_t lenThat = that.length();
39
 
    if (lenThat)
40
 
    {
41
 
        size_t lenThis = length();
42
 
        size_t cbBoth = lenThis + lenThat + 1;
43
 
 
44
 
        reserve(cbBoth);
45
 
            // calls realloc(cbBoth) and sets m_cbAllocated; may throw bad_alloc.
46
 
#ifndef RT_EXCEPTIONS_ENABLED
47
 
        AssertRelease(capacity() >= cbBoth);
48
 
#endif
49
 
 
50
 
        memcpy(m_psz + lenThis, that.m_psz, lenThat);
51
 
        m_psz[lenThis + lenThat] = '\0';
52
 
        m_cbLength = cbBoth - 1;
53
 
    }
54
 
    return *this;
55
 
}
56
 
 
57
 
MiniString& MiniString::append(char c)
58
 
{
59
 
    if (c)
 
105
    size_t cchThat = that.length();
 
106
    if (cchThat)
 
107
    {
 
108
        size_t cchThis = length();
 
109
        size_t cchBoth = cchThis + cchThat;
 
110
 
 
111
        if (cchBoth >= m_cbAllocated)
 
112
        {
 
113
            reserve(RT_ALIGN_Z(cchBoth + 1, IPRT_MINISTRING_APPEND_ALIGNMENT));
 
114
            // calls realloc(cchBoth + 1) and sets m_cbAllocated; may throw bad_alloc.
 
115
#ifndef RT_EXCEPTIONS_ENABLED
 
116
            AssertRelease(capacity() > cchBoth);
 
117
#endif
 
118
        }
 
119
 
 
120
        memcpy(m_psz + cchThis, that.m_psz, cchThat);
 
121
        m_psz[cchBoth] = '\0';
 
122
        m_cch = cchBoth;
 
123
    }
 
124
    return *this;
 
125
}
 
126
 
 
127
MiniString &MiniString::append(const char *pszThat)
 
128
{
 
129
    size_t cchThat = strlen(pszThat);
 
130
    if (cchThat)
 
131
    {
 
132
        size_t cchThis = length();
 
133
        size_t cchBoth = cchThis + cchThat;
 
134
 
 
135
        if (cchBoth >= m_cbAllocated)
 
136
        {
 
137
            reserve(RT_ALIGN_Z(cchBoth + 1, IPRT_MINISTRING_APPEND_ALIGNMENT));
 
138
            // calls realloc(cchBoth + 1) and sets m_cbAllocated; may throw bad_alloc.
 
139
#ifndef RT_EXCEPTIONS_ENABLED
 
140
            AssertRelease(capacity() > cchBoth);
 
141
#endif
 
142
        }
 
143
 
 
144
        memcpy(&m_psz[cchThis], pszThat, cchThat);
 
145
        m_psz[cchBoth] = '\0';
 
146
        m_cch = cchBoth;
 
147
    }
 
148
    return *this;
 
149
}
 
150
 
 
151
MiniString& MiniString::append(char ch)
 
152
{
 
153
    Assert((unsigned char)ch < 0x80);                  /* Don't create invalid UTF-8. */
 
154
    if (ch)
60
155
    {
61
156
        // allocate in chunks of 20 in case this gets called several times
62
 
        if (m_cbLength + 1 >= m_cbAllocated)
 
157
        if (m_cch + 1 >= m_cbAllocated)
63
158
        {
64
 
            reserve(m_cbLength + 10);
 
159
            reserve(RT_ALIGN_Z(m_cch + 2, IPRT_MINISTRING_APPEND_ALIGNMENT));
65
160
            // calls realloc(cbBoth) and sets m_cbAllocated; may throw bad_alloc.
66
161
#ifndef RT_EXCEPTIONS_ENABLED
67
 
            AssertRelease(capacity() >= m_cbLength + 1);
 
162
            AssertRelease(capacity() > m_cch + 1);
68
163
#endif
69
164
        }
70
165
 
71
 
        m_psz[m_cbLength] = c;
72
 
        m_psz[m_cbLength + 1] = '\0';
73
 
        ++m_cbLength;
74
 
    }
 
166
        m_psz[m_cch] = ch;
 
167
        m_psz[++m_cch] = '\0';
 
168
    }
 
169
    return *this;
 
170
}
 
171
 
 
172
MiniString &MiniString::appendCodePoint(RTUNICP uc)
 
173
{
 
174
    /*
 
175
     * Single byte encoding.
 
176
     */
 
177
    if (uc < 0x80)
 
178
        return MiniString::append((char)uc);
 
179
 
 
180
    /*
 
181
     * Multibyte encoding.
 
182
     * Assume max encoding length when resizing the string, that's simpler.
 
183
     */
 
184
    AssertReturn(uc <= UINT32_C(0x7fffffff), *this);
 
185
 
 
186
    if (m_cch + 6 >= m_cbAllocated)
 
187
    {
 
188
        reserve(RT_ALIGN_Z(m_cch + 6 + 1, IPRT_MINISTRING_APPEND_ALIGNMENT));
 
189
        // calls realloc(cbBoth) and sets m_cbAllocated; may throw bad_alloc.
 
190
#ifndef RT_EXCEPTIONS_ENABLED
 
191
        AssertRelease(capacity() > m_cch + 6);
 
192
#endif
 
193
    }
 
194
 
 
195
    char *pszNext = RTStrPutCp(&m_psz[m_cch], uc);
 
196
    m_cch = pszNext - m_psz;
 
197
    *pszNext = '\0';
 
198
 
75
199
    return *this;
76
200
}
77
201
 
89
213
    return npos;
90
214
}
91
215
 
92
 
MiniString MiniString::substr(size_t pos /*= 0*/, size_t n /*= npos*/)
 
216
void MiniString::findReplace(char cFind, char cReplace)
 
217
{
 
218
    for (size_t i = 0; i < length(); ++i)
 
219
    {
 
220
        char *p = &m_psz[i];
 
221
        if (*p == cFind)
 
222
            *p = cReplace;
 
223
    }
 
224
}
 
225
 
 
226
MiniString MiniString::substrCP(size_t pos /*= 0*/, size_t n /*= npos*/)
93
227
    const
94
228
{
95
229
    MiniString ret;
121
255
                        return ret;     // return empty string on bad encoding
122
256
 
123
257
                size_t cbCopy = psz - pFirst;
124
 
                ret.reserve(cbCopy + 1); // may throw bad_alloc
 
258
                if (cbCopy)
 
259
                {
 
260
                    ret.reserve(cbCopy + 1); // may throw bad_alloc
125
261
#ifndef RT_EXCEPTIONS_ENABLED
126
 
                AssertRelease(capacity() >= cbCopy + 1);
 
262
                    AssertRelease(capacity() >= cbCopy + 1);
127
263
#endif
128
 
                memcpy(ret.m_psz, pFirst, cbCopy);
129
 
                ret.m_cbLength = cbCopy;
130
 
                ret.m_psz[cbCopy] = '\0';
 
264
                    memcpy(ret.m_psz, pFirst, cbCopy);
 
265
                    ret.m_cch = cbCopy;
 
266
                    ret.m_psz[cbCopy] = '\0';
 
267
                }
131
268
            }
132
269
        }
133
270
    }