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