1 /* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include <ctype.h> 18 #include <stdarg.h> 19 #include <stdio.h> 20 #include <stdlib.h> 21 #include <string.h> 22 23 #include <binder/Parcel.h> 24 #include <utils/String8.h> 25 #include "ADebug.h" 26 #include "AString.h" 27 28 namespace android { 29 30 // static 31 const char *AString::kEmptyString = ""; 32 33 AString::AString() 34 : mData((char *)kEmptyString), 35 mSize(0), 36 mAllocSize(1) { 37 } 38 39 AString::AString(const char *s) 40 : mData(NULL), 41 mSize(0), 42 mAllocSize(1) { 43 setTo(s); 44 } 45 46 AString::AString(const char *s, size_t size) 47 : mData(NULL), 48 mSize(0), 49 mAllocSize(1) { 50 setTo(s, size); 51 } 52 53 AString::AString(const String8 &from) 54 : mData(NULL), 55 mSize(0), 56 mAllocSize(1) { 57 setTo(from.string(), from.length()); 58 } 59 60 AString::AString(const AString &from) 61 : mData(NULL), 62 mSize(0), 63 mAllocSize(1) { 64 setTo(from, 0, from.size()); 65 } 66 67 AString::AString(const AString &from, size_t offset, size_t n) 68 : mData(NULL), 69 mSize(0), 70 mAllocSize(1) { 71 setTo(from, offset, n); 72 } 73 74 AString::~AString() { 75 clear(); 76 } 77 78 AString &AString::operator=(const AString &from) { 79 if (&from != this) { 80 setTo(from, 0, from.size()); 81 } 82 83 return *this; 84 } 85 86 size_t AString::size() const { 87 return mSize; 88 } 89 90 const char *AString::c_str() const { 91 return mData; 92 } 93 94 bool AString::empty() const { 95 return mSize == 0; 96 } 97 98 void AString::setTo(const char *s) { 99 setTo(s, strlen(s)); 100 } 101 102 void AString::setTo(const char *s, size_t size) { 103 clear(); 104 append(s, size); 105 } 106 107 void AString::setTo(const AString &from, size_t offset, size_t n) { 108 CHECK(&from != this); 109 110 clear(); 111 setTo(from.mData + offset, n); 112 } 113 114 void AString::clear() { 115 if (mData && mData != kEmptyString) { 116 free(mData); 117 mData = NULL; 118 } 119 120 mData = (char *)kEmptyString; 121 mSize = 0; 122 mAllocSize = 1; 123 } 124 125 size_t AString::hash() const { 126 size_t x = 0; 127 for (size_t i = 0; i < mSize; ++i) { 128 x = (x * 31) + mData[i]; 129 } 130 131 return x; 132 } 133 134 bool AString::operator==(const AString &other) const { 135 return mSize == other.mSize && !memcmp(mData, other.mData, mSize); 136 } 137 138 void AString::trim() { 139 makeMutable(); 140 141 size_t i = 0; 142 while (i < mSize && isspace(mData[i])) { 143 ++i; 144 } 145 146 size_t j = mSize; 147 while (j > i && isspace(mData[j - 1])) { 148 --j; 149 } 150 151 memmove(mData, &mData[i], j - i); 152 mSize = j - i; 153 mData[mSize] = '\0'; 154 } 155 156 void AString::erase(size_t start, size_t n) { 157 CHECK_LT(start, mSize); 158 CHECK_LE(start + n, mSize); 159 160 makeMutable(); 161 162 memmove(&mData[start], &mData[start + n], mSize - start - n); 163 mSize -= n; 164 mData[mSize] = '\0'; 165 } 166 167 void AString::makeMutable() { 168 if (mData == kEmptyString) { 169 mData = strdup(kEmptyString); 170 } 171 } 172 173 void AString::append(const char *s) { 174 append(s, strlen(s)); 175 } 176 177 void AString::append(const char *s, size_t size) { 178 makeMutable(); 179 180 if (mSize + size + 1 > mAllocSize) { 181 mAllocSize = (mAllocSize + size + 31) & -32; 182 mData = (char *)realloc(mData, mAllocSize); 183 CHECK(mData != NULL); 184 } 185 186 memcpy(&mData[mSize], s, size); 187 mSize += size; 188 mData[mSize] = '\0'; 189 } 190 191 void AString::append(const AString &from) { 192 append(from.c_str(), from.size()); 193 } 194 195 void AString::append(const AString &from, size_t offset, size_t n) { 196 append(from.c_str() + offset, n); 197 } 198 199 void AString::append(int x) { 200 char s[16]; 201 int result = snprintf(s, sizeof(s), "%d", x); 202 CHECK((result > 0) && ((size_t) result) < sizeof(s)); 203 append(s); 204 } 205 206 void AString::append(unsigned x) { 207 char s[16]; 208 int result = snprintf(s, sizeof(s), "%u", x); 209 CHECK((result > 0) && ((size_t) result) < sizeof(s)); 210 append(s); 211 } 212 213 void AString::append(long x) { 214 char s[32]; 215 int result = snprintf(s, sizeof(s), "%ld", x); 216 CHECK((result > 0) && ((size_t) result) < sizeof(s)); 217 append(s); 218 } 219 220 void AString::append(unsigned long x) { 221 char s[32]; 222 int result = snprintf(s, sizeof(s), "%lu", x); 223 CHECK((result > 0) && ((size_t) result) < sizeof(s)); 224 append(s); 225 } 226 227 void AString::append(long long x) { 228 char s[32]; 229 int result = snprintf(s, sizeof(s), "%lld", x); 230 CHECK((result > 0) && ((size_t) result) < sizeof(s)); 231 append(s); 232 } 233 234 void AString::append(unsigned long long x) { 235 char s[32]; 236 int result = snprintf(s, sizeof(s), "%llu", x); 237 CHECK((result > 0) && ((size_t) result) < sizeof(s)); 238 append(s); 239 } 240 241 void AString::append(float x) { 242 char s[16]; 243 int result = snprintf(s, sizeof(s), "%f", x); 244 CHECK((result > 0) && ((size_t) result) < sizeof(s)); 245 append(s); 246 } 247 248 void AString::append(double x) { 249 char s[16]; 250 int result = snprintf(s, sizeof(s), "%f", x); 251 CHECK((result > 0) && ((size_t) result) < sizeof(s)); 252 append(s); 253 } 254 255 void AString::append(void *x) { 256 char s[32]; 257 int result = snprintf(s, sizeof(s), "%p", x); 258 CHECK((result > 0) && ((size_t) result) < sizeof(s)); 259 append(s); 260 } 261 262 ssize_t AString::find(const char *substring, size_t start) const { 263 CHECK_LE(start, size()); 264 265 const char *match = strstr(mData + start, substring); 266 267 if (match == NULL) { 268 return -1; 269 } 270 271 return match - mData; 272 } 273 274 void AString::insert(const AString &from, size_t insertionPos) { 275 insert(from.c_str(), from.size(), insertionPos); 276 } 277 278 void AString::insert(const char *from, size_t size, size_t insertionPos) { 279 CHECK_GE(insertionPos, 0u); 280 CHECK_LE(insertionPos, mSize); 281 282 makeMutable(); 283 284 if (mSize + size + 1 > mAllocSize) { 285 mAllocSize = (mAllocSize + size + 31) & -32; 286 mData = (char *)realloc(mData, mAllocSize); 287 CHECK(mData != NULL); 288 } 289 290 memmove(&mData[insertionPos + size], 291 &mData[insertionPos], mSize - insertionPos + 1); 292 293 memcpy(&mData[insertionPos], from, size); 294 295 mSize += size; 296 } 297 298 bool AString::operator<(const AString &other) const { 299 return compare(other) < 0; 300 } 301 302 bool AString::operator>(const AString &other) const { 303 return compare(other) > 0; 304 } 305 306 int AString::compare(const AString &other) const { 307 return strcmp(mData, other.mData); 308 } 309 310 int AString::compareIgnoreCase(const AString &other) const { 311 return strcasecmp(mData, other.mData); 312 } 313 314 bool AString::equalsIgnoreCase(const AString &other) const { 315 return compareIgnoreCase(other) == 0; 316 } 317 318 void AString::tolower() { 319 makeMutable(); 320 321 for (size_t i = 0; i < mSize; ++i) { 322 mData[i] = ::tolower(mData[i]); 323 } 324 } 325 326 bool AString::startsWith(const char *prefix) const { 327 return !strncmp(mData, prefix, strlen(prefix)); 328 } 329 330 bool AString::endsWith(const char *suffix) const { 331 size_t suffixLen = strlen(suffix); 332 333 if (mSize < suffixLen) { 334 return false; 335 } 336 337 return !strcmp(mData + mSize - suffixLen, suffix); 338 } 339 340 bool AString::startsWithIgnoreCase(const char *prefix) const { 341 return !strncasecmp(mData, prefix, strlen(prefix)); 342 } 343 344 bool AString::endsWithIgnoreCase(const char *suffix) const { 345 size_t suffixLen = strlen(suffix); 346 347 if (mSize < suffixLen) { 348 return false; 349 } 350 351 return !strcasecmp(mData + mSize - suffixLen, suffix); 352 } 353 354 // static 355 AString AString::FromParcel(const Parcel &parcel) { 356 size_t size = static_cast<size_t>(parcel.readInt32()); 357 return AString(static_cast<const char *>(parcel.readInplace(size)), size); 358 } 359 360 status_t AString::writeToParcel(Parcel *parcel) const { 361 CHECK_LE(mSize, static_cast<size_t>(INT32_MAX)); 362 status_t err = parcel->writeInt32(mSize); 363 if (err == OK) { 364 err = parcel->write(mData, mSize); 365 } 366 return err; 367 } 368 369 AString AStringPrintf(const char *format, ...) { 370 va_list ap; 371 va_start(ap, format); 372 373 char *buffer; 374 vasprintf(&buffer, format, ap); 375 376 va_end(ap); 377 378 AString result(buffer); 379 380 free(buffer); 381 buffer = NULL; 382 383 return result; 384 } 385 386 } // namespace android 387 388