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