69template <
size_t SIZE = 64>
class StrN {
72 char mInlineData[SIZE] = {0};
73 StringHolderRef mHeapData;
80 template <
size_t M>
StrN(
const StrN<M> &other) { copy(other); }
81 StrN(
const char *str) {
82 size_t len = strlen(str);
84 if (len + 1 <= SIZE) {
85 memcpy(mInlineData, str, len + 1);
88 mHeapData = StringHolderRef::New(str);
91 StrN(
const StrN &other) { copy(other); }
92 void copy(
const char *str) {
93 size_t len = strlen(str);
95 if (len + 1 <= SIZE) {
96 memcpy(mInlineData, str, len + 1);
99 if (mHeapData && !mHeapData->isShared()) {
101 mHeapData->copy(str, len);
105 mHeapData = StringHolderRef::New(str);
108 StrN &operator=(
const StrN &other) {
112 template <
size_t M>
StrN &operator=(
const StrN<M> &other) {
118 bool operator==(
const StrN &other)
const {
119 return strcmp(c_str(), other.c_str()) == 0;
122 bool operator!=(
const StrN &other)
const {
123 return strcmp(c_str(), other.c_str()) != 0;
126 template <
size_t M>
void copy(
const StrN<M> &other) {
127 size_t len = other.size();
128 if (len + 1 <= SIZE) {
129 memcpy(mInlineData, other.c_str(), len + 1);
132 if (other.mHeapData) {
133 mHeapData = other.mHeapData;
135 mHeapData = StringHolderRef::New(other.c_str());
141 size_t write(
int n) {
143 StringFormatter::append(n, &dst);
144 return write(dst.c_str(), dst.size());
147 size_t write(
const uint8_t *data,
size_t n) {
148 const char *str =
reinterpret_cast<const char *
>(data);
149 return write(str, n);
152 size_t write(
const char *str,
size_t n) {
153 size_t newLen = mLength + n;
154 if (newLen + 1 <= SIZE) {
155 memcpy(mInlineData + mLength, str, n);
157 mInlineData[mLength] =
'\0';
160 if (mHeapData && !mHeapData->isShared()) {
161 if (!mHeapData->hasCapacity(newLen)) {
162 mHeapData->grow(newLen * 3 / 2);
164 memcpy(mHeapData->data() + mLength, str, n);
166 mHeapData->data()[mLength] =
'\0';
170 StringHolderRef newData = StringHolderRef::New(newLen);
172 memcpy(newData->data(), c_str(), mLength);
173 memcpy(newData->data() + mLength, str, n);
174 newData->data()[newLen] =
'\0';
182 size_t write(
char c) {
return write(&c, 1); }
184 size_t write(uint8_t c) {
185 const char *str =
reinterpret_cast<const char *
>(&c);
186 return write(str, 1);
193 size_t size()
const {
return mLength; }
194 size_t length()
const {
return mLength; }
195 const char *c_str()
const {
196 return mHeapData ? mHeapData->data() : mInlineData;
199 char *c_str_mutable() {
200 return mHeapData ? mHeapData->data() : mInlineData;
203 char &operator[](
size_t index) {
204 if (index >= mLength) {
205 static char dummy =
'\0';
208 return c_str_mutable()[index];
211 const char &operator[](
size_t index)
const {
212 if (index >= mLength) {
213 static char dummy =
'\0';
216 return c_str()[index];
220 void append(
const char *str) { write(str, strlen(str)); }
222 bool operator<(
const StrN &other)
const {
223 return strcmp(c_str(), other.c_str()) < 0;
226 template<
size_t M>
bool operator<(
const StrN<M> &other)
const {
227 return strcmp(c_str(), other.c_str()) < 0;
231 StringHolderRef mData;