1// Copyright 2014 The Android Open Source Project
2//
3// This software is licensed under the terms of the GNU General Public
4// License version 2, as published by the Free Software Foundation, and
5// may be copied, distributed, and modified under those terms.
6//
7// This program is distributed in the hope that it will be useful,
8// but WITHOUT ANY WARRANTY; without even the implied warranty of
9// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10// GNU General Public License for more details.
11
12#ifndef ANDROID_BASE_STRING_H
13#define ANDROID_BASE_STRING_H
14
15#include <stddef.h>
16
17namespace android {
18namespace base {
19
20class StringView;
21
22// Custom string implementation:
23// - Not a template, hence much better compiler error messages.
24// - Uses short-string-optimization on all platforms.
25// - No iterators (for now).
26class String {
27public:
28    // Empty constructor.
29    String();
30
31    // Regular constructor from a C string.
32    String(const char* string);
33
34    // Copy constructor.
35    String(const String& other);
36
37    // Constructor from a StringView.
38    explicit String(const StringView& other);
39
40    // Constructor from a sized C string.
41    String(const char* str, size_t len);
42
43    // Fill-constructor.
44    String(size_t count, char fill);
45
46    // Destructor.
47    ~String();
48
49    // Return string as a zero-terminated C string.
50    const char* c_str() const { return mStr; }
51
52    void* data() { return mStr; }
53
54    const void* data() const { return mStr; }
55
56    // Return size of string in bytes, not including terminating zero.
57    size_t size() const { return mSize; }
58
59    // Return true if the string is empty, i.e. its size is 0.
60    // Note that a non-empty string can embed 0 bytes.
61    bool empty() const { return mSize == 0; }
62
63    // Return current capacity.
64    size_t capacity() const {
65        return (mStr == mStorage) ?
66                static_cast<size_t>(kMinCapacity) : mCapacity;
67    }
68
69    // Clear the content of a given instance.
70    void clear() { resize(0); }
71
72    // Array indexing operators.
73    char& operator[](size_t index) { return mStr[index]; }
74    const char& operator[](size_t index) const { return mStr[index]; }
75
76    // Assign new values to strings.
77    String& assign(const char* str);
78    String& assign(const char* str, size_t len);
79    String& assign(const String& other);
80    String& assign(const StringView& other);
81    String& assign(size_t count, char fill);
82    String& assign(char ch);
83
84    // Assignment operators.
85    String& operator=(const char* str) {
86        return this->assign(str);
87    }
88
89    String& operator=(const String& other) {
90        return this->assign(other);
91    }
92
93    String& operator=(const StringView& other) {
94        return this->assign(other);
95    }
96
97    String& operator=(char ch) {
98        return this->assign(ch);
99    }
100
101    // Append new values to current string.
102    String& append(const char* str);
103    String& append(const char* str, size_t len);
104    String& append(const String& other);
105    String& append(const StringView& other);
106    String& append(char ch);
107
108    // Addition-Assignment operators.
109    String& operator+=(const char* str) {
110        return this->append(str);
111    }
112
113    String& operator+=(const String& other) {
114        return this->append(other);
115    }
116
117    String& operator+=(const StringView& other) {
118        return this->append(other);
119    }
120
121    String& operator+=(char ch) {
122        return this->append(ch);
123    }
124
125    // Resize to a new size.
126    void resize(size_t newSize);
127
128    // Reserve enough room for |newSize| characters, followed by a
129    // terminating zero.
130    void reserve(size_t newSize);
131
132    // Compare to something, return -1, 0 or +1 based on byte values.
133    int compare(const char* str, size_t len) const;
134    int compare(const char* str) const;
135    int compare(const String& other) const;
136    int compare(const StringView& other) const;
137    int compare(char ch) const;
138
139    // Compare for equality.
140    bool equals(const char* str, size_t len) const;
141    bool equals(const char* str) const;
142    bool equals(const String& other) const;
143    bool equals(const StringView& other) const;
144    bool equals(char ch) const;
145
146    // Binary operators.
147    bool operator==(const char* str) const {
148        return equals(str);
149    }
150
151    bool operator==(const String& other) const {
152        return equals(other);
153    }
154
155    bool operator==(const StringView& other) const {
156        return equals(other);
157    }
158
159    bool operator==(char ch) const {
160        return equals(ch);
161    }
162
163    bool operator!=(const char* str) const {
164        return !operator==(str);
165    }
166
167    bool operator!=(const String& other) const {
168        return !operator==(other);
169    }
170
171    bool operator!=(const StringView& other) const {
172        return !operator==(other);
173    }
174
175    bool operator!=(char ch) const {
176        return !operator==(ch);
177    }
178
179    // Swap the content of this string with another one.
180    void swap(String* other);
181
182protected:
183    friend class StringVector;
184
185    // Internal helper routine to be used when |count| strings objects
186    // have been moved or copied from |fromStrings| to |toStrings|.
187    // This adjusts any internal |mStr| pointer to |mStorage| to the
188    // new appropriate region. Used by StringVector to implement
189    // optimized insert/copy/remove operations.
190    static void adjustMovedSlice(String* fromStrings,
191                                 String* toStrings,
192                                 size_t count);
193
194    // Move |count| strings from |strings + from| to |strings + to|
195    // in memory. Used by StringVector to implement insert/delete
196    // operations.
197    static void moveSlice(String* strings,
198                          size_t from,
199                          size_t to,
200                          size_t count);
201
202    // Finalize |count| String instances from |strings|.
203    // Used by StringVector to implement resize/reserve operations.
204    static void finalizeSlice(String* strings, size_t count);
205
206    // Minimum capacity for the in-object storage array |mStorage|,
207    // not including the terminating zero. With a value of 16,
208    // each String instance is 24 bytes on a 32-bit system, and
209    // 32-bytes on a 64-bit one.
210    enum {
211        kMinCapacity = 15
212    };
213
214    char* mStr;
215    size_t mSize;
216    union {
217        size_t mCapacity;
218        char mStorage[kMinCapacity + 1U];
219    };
220};
221
222}  // namespace base
223}  // namespace android
224
225#endif  // ANDROID_BASE_STRING_H
226