1a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch/*
2a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch * Copyright (C) 2009, 2010 Apple Inc. All rights reserved.
3a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch *
4a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch * Redistribution and use in source and binary forms, with or without
5a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch * modification, are permitted provided that the following conditions
6a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch * are met:
7a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch * 1. Redistributions of source code must retain the above copyright
8a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch *    notice, this list of conditions and the following disclaimer.
9a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch * 2. Redistributions in binary form must reproduce the above copyright
10a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch *    notice, this list of conditions and the following disclaimer in the
11a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch *    documentation and/or other materials provided with the distribution.
12a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch *
13a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch */
25a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
26a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#ifndef StringBuilder_h
27a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#define StringBuilder_h
28a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
29a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#include <wtf/Vector.h>
30a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#include <wtf/text/WTFString.h>
31a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
32a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochnamespace WTF {
33a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
34a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochclass StringBuilder {
35a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochpublic:
36a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    StringBuilder()
37a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        : m_length(0)
38a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    {
39a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    }
40a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
41a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    void append(const UChar*, unsigned);
42a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    void append(const char*, unsigned);
43a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
44a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    void append(const String& string)
45a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    {
46a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        // If we're appending to an empty string, and there is not buffer
47a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        // (in case reserveCapacity has been called) then just retain the
48a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        // string.
49a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (!m_length && !m_buffer) {
50a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            m_string = string;
51a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            m_length = string.length();
52a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            return;
53a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        }
54a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        append(string.characters(), string.length());
55a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    }
56a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
57a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    void append(const char* characters)
58a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    {
59a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (characters)
60a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            append(characters, strlen(characters));
61a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    }
62a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
63a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    void append(UChar c)
64a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    {
65a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (m_buffer && m_length < m_buffer->length() && m_string.isNull())
66a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            m_bufferCharacters[m_length++] = c;
67a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        else
68a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            append(&c, 1);
69a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    }
70a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
71a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    void append(char c)
72a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    {
73a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (m_buffer && m_length < m_buffer->length() && m_string.isNull())
74a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            m_bufferCharacters[m_length++] = (unsigned char)c;
75a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        else
76a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            append(&c, 1);
77a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    }
78a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
79a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    String toString()
80a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    {
81a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (m_string.isNull()) {
82a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            shrinkToFit();
83a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            reifyString();
84a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        }
85a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return m_string;
86a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    }
87a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
88a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    String toStringPreserveCapacity()
89a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    {
90a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (m_string.isNull())
91a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            reifyString();
92a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return m_string;
93a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    }
94a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
95a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    unsigned length() const
96a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    {
97a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return m_length;
98a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    }
99a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
100a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    bool isEmpty() const { return !length(); }
101a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
102a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    void reserveCapacity(unsigned newCapacity);
103a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
104a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    void resize(unsigned newSize);
105a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
106a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    void shrinkToFit();
107a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
108a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    UChar operator[](unsigned i) const
109a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    {
110a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        ASSERT(i < m_length);
111a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (!m_string.isNull())
112a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            return m_string[i];
113a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        ASSERT(m_buffer);
114a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return m_buffer->characters()[i];
115a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    }
116a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
117a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    void clear()
118a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    {
119a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        m_length = 0;
120a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        m_string = String();
121a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        m_buffer = 0;
122a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    }
123a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
124a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochprivate:
125a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    void allocateBuffer(const UChar* currentCharacters, unsigned requiredLength);
126a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    UChar* appendUninitialized(unsigned length);
127a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    void reifyString();
128a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
129a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    unsigned m_length;
130a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    String m_string;
131a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    RefPtr<StringImpl> m_buffer;
132a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    UChar* m_bufferCharacters;
133a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch};
134a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
135a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch} // namespace WTF
136a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
137a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochusing WTF::StringBuilder;
138a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
139a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#endif // StringBuilder_h
140