1cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project/* 2cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project * Copyright (C) 2005 The Android Open Source Project 3cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project * 4cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 5cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project * you may not use this file except in compliance with the License. 6cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project * You may obtain a copy of the License at 7cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project * 8cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project * 10cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 12cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project * See the License for the specific language governing permissions and 14cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project * limitations under the License. 15cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project */ 16cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 17cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#include <utils/String8.h> 18cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 19cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#include <utils/Log.h> 20ba0165bef09729a33ab8e0ca329342be05e0d859Kenny Root#include <utils/Unicode.h> 21ba0165bef09729a33ab8e0ca329342be05e0d859Kenny Root#include <utils/SharedBuffer.h> 22cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#include <utils/String16.h> 23cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#include <utils/threads.h> 24cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 25cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#include <ctype.h> 26cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 2744dad3e006e0a966d93473dde3d74b2b43555519Daisuke Miyakawa/* 2844dad3e006e0a966d93473dde3d74b2b43555519Daisuke Miyakawa * Functions outside android is below the namespace android, since they use 2944dad3e006e0a966d93473dde3d74b2b43555519Daisuke Miyakawa * functions and constants in android namespace. 3044dad3e006e0a966d93473dde3d74b2b43555519Daisuke Miyakawa */ 31cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 32cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project// --------------------------------------------------------------------------- 33cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 3444dad3e006e0a966d93473dde3d74b2b43555519Daisuke Miyakawanamespace android { 3544dad3e006e0a966d93473dde3d74b2b43555519Daisuke Miyakawa 36cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project// Separator used by resource paths. This is not platform dependent contrary 37cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project// to OS_PATH_SEPARATOR. 38cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#define RES_PATH_SEPARATOR '/' 39cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 40cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectstatic SharedBuffer* gEmptyStringBuf = NULL; 41cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectstatic char* gEmptyString = NULL; 42cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 43cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectextern int gDarwinCantLoadAllObjects; 44cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectint gDarwinIsReallyAnnoying; 45cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 469eb2a3b1c0cc1ff3082a9283e24c8babc112f56bMathias Agopianvoid initialize_string8(); 479eb2a3b1c0cc1ff3082a9283e24c8babc112f56bMathias Agopian 48cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectstatic inline char* getEmptyString() 49cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{ 50cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project gEmptyStringBuf->acquire(); 51cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project return gEmptyString; 52cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 53cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 54cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectvoid initialize_string8() 55cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{ 5688753ae9d8f5432590df5e5338e0906834124c1dDan Egnor // HACK: This dummy dependency forces linking libutils Static.cpp, 5788753ae9d8f5432590df5e5338e0906834124c1dDan Egnor // which is needed to initialize String8/String16 classes. 5888753ae9d8f5432590df5e5338e0906834124c1dDan Egnor // These variables are named for Darwin, but are needed elsewhere too, 5988753ae9d8f5432590df5e5338e0906834124c1dDan Egnor // including static linking on any platform. 6088753ae9d8f5432590df5e5338e0906834124c1dDan Egnor gDarwinIsReallyAnnoying = gDarwinCantLoadAllObjects; 6144dad3e006e0a966d93473dde3d74b2b43555519Daisuke Miyakawa 62cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project SharedBuffer* buf = SharedBuffer::alloc(1); 63cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project char* str = (char*)buf->data(); 64cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project *str = 0; 65cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project gEmptyStringBuf = buf; 66cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project gEmptyString = str; 67cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 68cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 69cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectvoid terminate_string8() 70cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{ 71cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project SharedBuffer::bufferFromData(gEmptyString)->release(); 72cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project gEmptyStringBuf = NULL; 73cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project gEmptyString = NULL; 74cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 75cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 76cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project// --------------------------------------------------------------------------- 77cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 78cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectstatic char* allocFromUTF8(const char* in, size_t len) 79cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{ 80cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project if (len > 0) { 81cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project SharedBuffer* buf = SharedBuffer::alloc(len+1); 82ae07445e9793724324b93bb593fe20be2a386707Steve Block ALOG_ASSERT(buf, "Unable to allocate shared buffer"); 83cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project if (buf) { 84cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project char* str = (char*)buf->data(); 85cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project memcpy(str, in, len); 86cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project str[len] = 0; 87cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project return str; 88cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project } 89cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project return NULL; 90cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project } 91cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 92cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project return getEmptyString(); 93cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 94cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 95ba0165bef09729a33ab8e0ca329342be05e0d859Kenny Rootstatic char* allocFromUTF16(const char16_t* in, size_t len) 96cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{ 97cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project if (len == 0) return getEmptyString(); 9844dad3e006e0a966d93473dde3d74b2b43555519Daisuke Miyakawa 99ba0165bef09729a33ab8e0ca329342be05e0d859Kenny Root const ssize_t bytes = utf16_to_utf8_length(in, len); 100ba0165bef09729a33ab8e0ca329342be05e0d859Kenny Root if (bytes < 0) { 101ba0165bef09729a33ab8e0ca329342be05e0d859Kenny Root return getEmptyString(); 102cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project } 10344dad3e006e0a966d93473dde3d74b2b43555519Daisuke Miyakawa 104cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project SharedBuffer* buf = SharedBuffer::alloc(bytes+1); 105ae07445e9793724324b93bb593fe20be2a386707Steve Block ALOG_ASSERT(buf, "Unable to allocate shared buffer"); 106ba0165bef09729a33ab8e0ca329342be05e0d859Kenny Root if (!buf) { 107ba0165bef09729a33ab8e0ca329342be05e0d859Kenny Root return getEmptyString(); 108cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project } 10944dad3e006e0a966d93473dde3d74b2b43555519Daisuke Miyakawa 110ba0165bef09729a33ab8e0ca329342be05e0d859Kenny Root char* str = (char*)buf->data(); 111ba0165bef09729a33ab8e0ca329342be05e0d859Kenny Root utf16_to_utf8(in, len, str); 112ba0165bef09729a33ab8e0ca329342be05e0d859Kenny Root return str; 113cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 114cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 115ba0165bef09729a33ab8e0ca329342be05e0d859Kenny Rootstatic char* allocFromUTF32(const char32_t* in, size_t len) 11644dad3e006e0a966d93473dde3d74b2b43555519Daisuke Miyakawa{ 117ba0165bef09729a33ab8e0ca329342be05e0d859Kenny Root if (len == 0) { 118ba0165bef09729a33ab8e0ca329342be05e0d859Kenny Root return getEmptyString(); 119ba0165bef09729a33ab8e0ca329342be05e0d859Kenny Root } 1209a2d83e698b16ec86ad2751b6e7cf103ad645cceKenny Root 121ba0165bef09729a33ab8e0ca329342be05e0d859Kenny Root const ssize_t bytes = utf32_to_utf8_length(in, len); 122ba0165bef09729a33ab8e0ca329342be05e0d859Kenny Root if (bytes < 0) { 123ba0165bef09729a33ab8e0ca329342be05e0d859Kenny Root return getEmptyString(); 124ba0165bef09729a33ab8e0ca329342be05e0d859Kenny Root } 1259a2d83e698b16ec86ad2751b6e7cf103ad645cceKenny Root 1269a2d83e698b16ec86ad2751b6e7cf103ad645cceKenny Root SharedBuffer* buf = SharedBuffer::alloc(bytes+1); 127ae07445e9793724324b93bb593fe20be2a386707Steve Block ALOG_ASSERT(buf, "Unable to allocate shared buffer"); 128ba0165bef09729a33ab8e0ca329342be05e0d859Kenny Root if (!buf) { 129ba0165bef09729a33ab8e0ca329342be05e0d859Kenny Root return getEmptyString(); 1309a2d83e698b16ec86ad2751b6e7cf103ad645cceKenny Root } 1319a2d83e698b16ec86ad2751b6e7cf103ad645cceKenny Root 132ba0165bef09729a33ab8e0ca329342be05e0d859Kenny Root char* str = (char*) buf->data(); 133ba0165bef09729a33ab8e0ca329342be05e0d859Kenny Root utf32_to_utf8(in, len, str); 13444dad3e006e0a966d93473dde3d74b2b43555519Daisuke Miyakawa 135ba0165bef09729a33ab8e0ca329342be05e0d859Kenny Root return str; 13644dad3e006e0a966d93473dde3d74b2b43555519Daisuke Miyakawa} 13744dad3e006e0a966d93473dde3d74b2b43555519Daisuke Miyakawa 138cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project// --------------------------------------------------------------------------- 139cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 140cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source ProjectString8::String8() 141cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project : mString(getEmptyString()) 142cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{ 143cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 144cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 1454485d0d966d062d1b45b635e2447a2d2f96c3f38Mathias AgopianString8::String8(StaticLinkage) 1464485d0d966d062d1b45b635e2447a2d2f96c3f38Mathias Agopian : mString(0) 1474485d0d966d062d1b45b635e2447a2d2f96c3f38Mathias Agopian{ 1484485d0d966d062d1b45b635e2447a2d2f96c3f38Mathias Agopian // this constructor is used when we can't rely on the static-initializers 1494485d0d966d062d1b45b635e2447a2d2f96c3f38Mathias Agopian // having run. In this case we always allocate an empty string. It's less 1504485d0d966d062d1b45b635e2447a2d2f96c3f38Mathias Agopian // efficient than using getEmptyString(), but we assume it's uncommon. 1514485d0d966d062d1b45b635e2447a2d2f96c3f38Mathias Agopian 1524485d0d966d062d1b45b635e2447a2d2f96c3f38Mathias Agopian char* data = static_cast<char*>( 1534485d0d966d062d1b45b635e2447a2d2f96c3f38Mathias Agopian SharedBuffer::alloc(sizeof(char))->data()); 1544485d0d966d062d1b45b635e2447a2d2f96c3f38Mathias Agopian data[0] = 0; 1554485d0d966d062d1b45b635e2447a2d2f96c3f38Mathias Agopian mString = data; 1564485d0d966d062d1b45b635e2447a2d2f96c3f38Mathias Agopian} 1574485d0d966d062d1b45b635e2447a2d2f96c3f38Mathias Agopian 158cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source ProjectString8::String8(const String8& o) 159cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project : mString(o.mString) 160cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{ 161cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project SharedBuffer::bufferFromData(mString)->acquire(); 162cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 163cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 164cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source ProjectString8::String8(const char* o) 165cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project : mString(allocFromUTF8(o, strlen(o))) 166cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{ 167cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project if (mString == NULL) { 168cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project mString = getEmptyString(); 169cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project } 170cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 171cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 172cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source ProjectString8::String8(const char* o, size_t len) 173cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project : mString(allocFromUTF8(o, len)) 174cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{ 175cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project if (mString == NULL) { 176cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project mString = getEmptyString(); 177cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project } 178cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 179cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 180cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source ProjectString8::String8(const String16& o) 181cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project : mString(allocFromUTF16(o.string(), o.size())) 182cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{ 183cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 184cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 185cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source ProjectString8::String8(const char16_t* o) 186cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project : mString(allocFromUTF16(o, strlen16(o))) 187cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{ 188cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 189cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 190cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source ProjectString8::String8(const char16_t* o, size_t len) 191cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project : mString(allocFromUTF16(o, len)) 192cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{ 193cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 194cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 19544dad3e006e0a966d93473dde3d74b2b43555519Daisuke MiyakawaString8::String8(const char32_t* o) 19644dad3e006e0a966d93473dde3d74b2b43555519Daisuke Miyakawa : mString(allocFromUTF32(o, strlen32(o))) 19744dad3e006e0a966d93473dde3d74b2b43555519Daisuke Miyakawa{ 19844dad3e006e0a966d93473dde3d74b2b43555519Daisuke Miyakawa} 19944dad3e006e0a966d93473dde3d74b2b43555519Daisuke Miyakawa 20044dad3e006e0a966d93473dde3d74b2b43555519Daisuke MiyakawaString8::String8(const char32_t* o, size_t len) 20144dad3e006e0a966d93473dde3d74b2b43555519Daisuke Miyakawa : mString(allocFromUTF32(o, len)) 20244dad3e006e0a966d93473dde3d74b2b43555519Daisuke Miyakawa{ 20344dad3e006e0a966d93473dde3d74b2b43555519Daisuke Miyakawa} 20444dad3e006e0a966d93473dde3d74b2b43555519Daisuke Miyakawa 205cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source ProjectString8::~String8() 206cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{ 207cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project SharedBuffer::bufferFromData(mString)->release(); 208cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 209cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 2101d618d63c1bb99728b5b0afe320f5a6afa95436cJeff BrownString8 String8::format(const char* fmt, ...) 2111d618d63c1bb99728b5b0afe320f5a6afa95436cJeff Brown{ 2121d618d63c1bb99728b5b0afe320f5a6afa95436cJeff Brown va_list args; 2131d618d63c1bb99728b5b0afe320f5a6afa95436cJeff Brown va_start(args, fmt); 2141d618d63c1bb99728b5b0afe320f5a6afa95436cJeff Brown 2151d618d63c1bb99728b5b0afe320f5a6afa95436cJeff Brown String8 result(formatV(fmt, args)); 2161d618d63c1bb99728b5b0afe320f5a6afa95436cJeff Brown 2171d618d63c1bb99728b5b0afe320f5a6afa95436cJeff Brown va_end(args); 2181d618d63c1bb99728b5b0afe320f5a6afa95436cJeff Brown return result; 2191d618d63c1bb99728b5b0afe320f5a6afa95436cJeff Brown} 2201d618d63c1bb99728b5b0afe320f5a6afa95436cJeff Brown 2211d618d63c1bb99728b5b0afe320f5a6afa95436cJeff BrownString8 String8::formatV(const char* fmt, va_list args) 2221d618d63c1bb99728b5b0afe320f5a6afa95436cJeff Brown{ 2231d618d63c1bb99728b5b0afe320f5a6afa95436cJeff Brown String8 result; 2241d618d63c1bb99728b5b0afe320f5a6afa95436cJeff Brown result.appendFormatV(fmt, args); 2251d618d63c1bb99728b5b0afe320f5a6afa95436cJeff Brown return result; 2261d618d63c1bb99728b5b0afe320f5a6afa95436cJeff Brown} 2271d618d63c1bb99728b5b0afe320f5a6afa95436cJeff Brown 22848da31b735ebbc6a00c4e9fe9631f4af79e2c9dfJeff Brownvoid String8::clear() { 22948da31b735ebbc6a00c4e9fe9631f4af79e2c9dfJeff Brown SharedBuffer::bufferFromData(mString)->release(); 23048da31b735ebbc6a00c4e9fe9631f4af79e2c9dfJeff Brown mString = getEmptyString(); 23148da31b735ebbc6a00c4e9fe9631f4af79e2c9dfJeff Brown} 23248da31b735ebbc6a00c4e9fe9631f4af79e2c9dfJeff Brown 233cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectvoid String8::setTo(const String8& other) 234cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{ 235cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project SharedBuffer::bufferFromData(other.mString)->acquire(); 236cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project SharedBuffer::bufferFromData(mString)->release(); 237cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project mString = other.mString; 238cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 239cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 240cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectstatus_t String8::setTo(const char* other) 241cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{ 24210e5da58e4c22f2262f7ec7f82745d9673bed14bAndreas Huber const char *newString = allocFromUTF8(other, strlen(other)); 243cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project SharedBuffer::bufferFromData(mString)->release(); 24410e5da58e4c22f2262f7ec7f82745d9673bed14bAndreas Huber mString = newString; 245cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project if (mString) return NO_ERROR; 246cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 247cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project mString = getEmptyString(); 248cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project return NO_MEMORY; 249cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 250cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 251cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectstatus_t String8::setTo(const char* other, size_t len) 252cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{ 25310e5da58e4c22f2262f7ec7f82745d9673bed14bAndreas Huber const char *newString = allocFromUTF8(other, len); 254cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project SharedBuffer::bufferFromData(mString)->release(); 25510e5da58e4c22f2262f7ec7f82745d9673bed14bAndreas Huber mString = newString; 256cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project if (mString) return NO_ERROR; 257cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 258cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project mString = getEmptyString(); 259cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project return NO_MEMORY; 260cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 261cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 262cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectstatus_t String8::setTo(const char16_t* other, size_t len) 263cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{ 26410e5da58e4c22f2262f7ec7f82745d9673bed14bAndreas Huber const char *newString = allocFromUTF16(other, len); 265cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project SharedBuffer::bufferFromData(mString)->release(); 26610e5da58e4c22f2262f7ec7f82745d9673bed14bAndreas Huber mString = newString; 267cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project if (mString) return NO_ERROR; 268cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 269cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project mString = getEmptyString(); 270cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project return NO_MEMORY; 271cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 272cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 27344dad3e006e0a966d93473dde3d74b2b43555519Daisuke Miyakawastatus_t String8::setTo(const char32_t* other, size_t len) 27444dad3e006e0a966d93473dde3d74b2b43555519Daisuke Miyakawa{ 27510e5da58e4c22f2262f7ec7f82745d9673bed14bAndreas Huber const char *newString = allocFromUTF32(other, len); 27644dad3e006e0a966d93473dde3d74b2b43555519Daisuke Miyakawa SharedBuffer::bufferFromData(mString)->release(); 27710e5da58e4c22f2262f7ec7f82745d9673bed14bAndreas Huber mString = newString; 27844dad3e006e0a966d93473dde3d74b2b43555519Daisuke Miyakawa if (mString) return NO_ERROR; 27944dad3e006e0a966d93473dde3d74b2b43555519Daisuke Miyakawa 28044dad3e006e0a966d93473dde3d74b2b43555519Daisuke Miyakawa mString = getEmptyString(); 28144dad3e006e0a966d93473dde3d74b2b43555519Daisuke Miyakawa return NO_MEMORY; 28244dad3e006e0a966d93473dde3d74b2b43555519Daisuke Miyakawa} 28344dad3e006e0a966d93473dde3d74b2b43555519Daisuke Miyakawa 284cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectstatus_t String8::append(const String8& other) 285cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{ 286cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project const size_t otherLen = other.bytes(); 287cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project if (bytes() == 0) { 288cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project setTo(other); 289cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project return NO_ERROR; 290cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project } else if (otherLen == 0) { 291cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project return NO_ERROR; 292cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project } 293cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 294cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project return real_append(other.string(), otherLen); 295cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 296cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 297cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectstatus_t String8::append(const char* other) 298cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{ 299cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project return append(other, strlen(other)); 300cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 301cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 302cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectstatus_t String8::append(const char* other, size_t otherLen) 303cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{ 304cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project if (bytes() == 0) { 305cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project return setTo(other, otherLen); 306cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project } else if (otherLen == 0) { 307cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project return NO_ERROR; 308cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project } 309cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 310cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project return real_append(other, otherLen); 311cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 312cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 31335a154e57f2f59722de580395ccd5172e44842cbJeff Brownstatus_t String8::appendFormat(const char* fmt, ...) 31435a154e57f2f59722de580395ccd5172e44842cbJeff Brown{ 315647925ddf053989b641b4c5c8a51efd55c931f22Jeff Brown va_list args; 316647925ddf053989b641b4c5c8a51efd55c931f22Jeff Brown va_start(args, fmt); 31735a154e57f2f59722de580395ccd5172e44842cbJeff Brown 318647925ddf053989b641b4c5c8a51efd55c931f22Jeff Brown status_t result = appendFormatV(fmt, args); 319647925ddf053989b641b4c5c8a51efd55c931f22Jeff Brown 320647925ddf053989b641b4c5c8a51efd55c931f22Jeff Brown va_end(args); 321647925ddf053989b641b4c5c8a51efd55c931f22Jeff Brown return result; 322647925ddf053989b641b4c5c8a51efd55c931f22Jeff Brown} 323647925ddf053989b641b4c5c8a51efd55c931f22Jeff Brown 324647925ddf053989b641b4c5c8a51efd55c931f22Jeff Brownstatus_t String8::appendFormatV(const char* fmt, va_list args) 325647925ddf053989b641b4c5c8a51efd55c931f22Jeff Brown{ 326fff9d11be528ad8f581cc7223b879c55009d7396Fengwei Yin int n, result = NO_ERROR; 327fff9d11be528ad8f581cc7223b879c55009d7396Fengwei Yin va_list tmp_args; 328fff9d11be528ad8f581cc7223b879c55009d7396Fengwei Yin 329fff9d11be528ad8f581cc7223b879c55009d7396Fengwei Yin /* args is undefined after vsnprintf. 330fff9d11be528ad8f581cc7223b879c55009d7396Fengwei Yin * So we need a copy here to avoid the 331fff9d11be528ad8f581cc7223b879c55009d7396Fengwei Yin * second vsnprintf access undefined args. 332fff9d11be528ad8f581cc7223b879c55009d7396Fengwei Yin */ 333fff9d11be528ad8f581cc7223b879c55009d7396Fengwei Yin va_copy(tmp_args, args); 334fff9d11be528ad8f581cc7223b879c55009d7396Fengwei Yin n = vsnprintf(NULL, 0, fmt, tmp_args); 335fff9d11be528ad8f581cc7223b879c55009d7396Fengwei Yin va_end(tmp_args); 336fff9d11be528ad8f581cc7223b879c55009d7396Fengwei Yin 33735a154e57f2f59722de580395ccd5172e44842cbJeff Brown if (n != 0) { 33835a154e57f2f59722de580395ccd5172e44842cbJeff Brown size_t oldLength = length(); 33935a154e57f2f59722de580395ccd5172e44842cbJeff Brown char* buf = lockBuffer(oldLength + n); 34035a154e57f2f59722de580395ccd5172e44842cbJeff Brown if (buf) { 341647925ddf053989b641b4c5c8a51efd55c931f22Jeff Brown vsnprintf(buf + oldLength, n + 1, fmt, args); 34235a154e57f2f59722de580395ccd5172e44842cbJeff Brown } else { 34335a154e57f2f59722de580395ccd5172e44842cbJeff Brown result = NO_MEMORY; 34435a154e57f2f59722de580395ccd5172e44842cbJeff Brown } 34535a154e57f2f59722de580395ccd5172e44842cbJeff Brown } 34635a154e57f2f59722de580395ccd5172e44842cbJeff Brown return result; 34735a154e57f2f59722de580395ccd5172e44842cbJeff Brown} 34835a154e57f2f59722de580395ccd5172e44842cbJeff Brown 349cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectstatus_t String8::real_append(const char* other, size_t otherLen) 350cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{ 351cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project const size_t myLen = bytes(); 352cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 353cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project SharedBuffer* buf = SharedBuffer::bufferFromData(mString) 354cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project ->editResize(myLen+otherLen+1); 355cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project if (buf) { 356cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project char* str = (char*)buf->data(); 357cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project mString = str; 358cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project str += myLen; 359cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project memcpy(str, other, otherLen); 360cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project str[otherLen] = '\0'; 361cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project return NO_ERROR; 362cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project } 363cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project return NO_MEMORY; 364cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 365cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 366cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectchar* String8::lockBuffer(size_t size) 367cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{ 368cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project SharedBuffer* buf = SharedBuffer::bufferFromData(mString) 369cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project ->editResize(size+1); 370cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project if (buf) { 371cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project char* str = (char*)buf->data(); 372cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project mString = str; 373cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project return str; 374cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project } 375cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project return NULL; 376cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 377cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 378cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectvoid String8::unlockBuffer() 379cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{ 380cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project unlockBuffer(strlen(mString)); 381cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 382cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 383cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectstatus_t String8::unlockBuffer(size_t size) 384cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{ 385cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project if (size != this->size()) { 386cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project SharedBuffer* buf = SharedBuffer::bufferFromData(mString) 387cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project ->editResize(size+1); 38835a154e57f2f59722de580395ccd5172e44842cbJeff Brown if (! buf) { 38935a154e57f2f59722de580395ccd5172e44842cbJeff Brown return NO_MEMORY; 390cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project } 39135a154e57f2f59722de580395ccd5172e44842cbJeff Brown 39235a154e57f2f59722de580395ccd5172e44842cbJeff Brown char* str = (char*)buf->data(); 39335a154e57f2f59722de580395ccd5172e44842cbJeff Brown str[size] = 0; 39435a154e57f2f59722de580395ccd5172e44842cbJeff Brown mString = str; 395cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project } 39635a154e57f2f59722de580395ccd5172e44842cbJeff Brown 39735a154e57f2f59722de580395ccd5172e44842cbJeff Brown return NO_ERROR; 398cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 399cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 400cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectssize_t String8::find(const char* other, size_t start) const 401cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{ 402cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project size_t len = size(); 403cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project if (start >= len) { 404cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project return -1; 405cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project } 406cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project const char* s = mString+start; 407cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project const char* p = strstr(s, other); 408cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project return p ? p-mString : -1; 409cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 410cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 4115ee915afe17b7190f992addc48cb53ed6371a68dJeff Brownbool String8::removeAll(const char* other) { 4125ee915afe17b7190f992addc48cb53ed6371a68dJeff Brown ssize_t index = find(other); 4135ee915afe17b7190f992addc48cb53ed6371a68dJeff Brown if (index < 0) return false; 4145ee915afe17b7190f992addc48cb53ed6371a68dJeff Brown 4155ee915afe17b7190f992addc48cb53ed6371a68dJeff Brown char* buf = lockBuffer(size()); 4165ee915afe17b7190f992addc48cb53ed6371a68dJeff Brown if (!buf) return false; // out of memory 4175ee915afe17b7190f992addc48cb53ed6371a68dJeff Brown 4185ee915afe17b7190f992addc48cb53ed6371a68dJeff Brown size_t skip = strlen(other); 4195ee915afe17b7190f992addc48cb53ed6371a68dJeff Brown size_t len = size(); 4205ee915afe17b7190f992addc48cb53ed6371a68dJeff Brown size_t tail = index; 4215ee915afe17b7190f992addc48cb53ed6371a68dJeff Brown while (size_t(index) < len) { 4225ee915afe17b7190f992addc48cb53ed6371a68dJeff Brown ssize_t next = find(other, index + skip); 4235ee915afe17b7190f992addc48cb53ed6371a68dJeff Brown if (next < 0) { 4245ee915afe17b7190f992addc48cb53ed6371a68dJeff Brown next = len; 4255ee915afe17b7190f992addc48cb53ed6371a68dJeff Brown } 4265ee915afe17b7190f992addc48cb53ed6371a68dJeff Brown 4275ee915afe17b7190f992addc48cb53ed6371a68dJeff Brown memcpy(buf + tail, buf + index + skip, next - index - skip); 4285ee915afe17b7190f992addc48cb53ed6371a68dJeff Brown tail += next - index - skip; 4295ee915afe17b7190f992addc48cb53ed6371a68dJeff Brown index = next; 4305ee915afe17b7190f992addc48cb53ed6371a68dJeff Brown } 4315ee915afe17b7190f992addc48cb53ed6371a68dJeff Brown unlockBuffer(tail); 4325ee915afe17b7190f992addc48cb53ed6371a68dJeff Brown return true; 4335ee915afe17b7190f992addc48cb53ed6371a68dJeff Brown} 4345ee915afe17b7190f992addc48cb53ed6371a68dJeff Brown 435cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectvoid String8::toLower() 436cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{ 437cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project toLower(0, size()); 438cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 439cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 440cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectvoid String8::toLower(size_t start, size_t length) 441cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{ 442cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project const size_t len = size(); 443cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project if (start >= len) { 444cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project return; 445cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project } 446cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project if (start+length > len) { 447cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project length = len-start; 448cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project } 449cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project char* buf = lockBuffer(len); 450cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project buf += start; 451cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project while (length > 0) { 452cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project *buf = tolower(*buf); 453cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project buf++; 454cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project length--; 455cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project } 456cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project unlockBuffer(len); 457cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 458cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 459cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectvoid String8::toUpper() 460cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{ 461cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project toUpper(0, size()); 462cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 463cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 464cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectvoid String8::toUpper(size_t start, size_t length) 465cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{ 466cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project const size_t len = size(); 467cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project if (start >= len) { 468cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project return; 469cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project } 470cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project if (start+length > len) { 471cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project length = len-start; 472cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project } 473cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project char* buf = lockBuffer(len); 474cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project buf += start; 475cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project while (length > 0) { 476cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project *buf = toupper(*buf); 477cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project buf++; 478cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project length--; 479cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project } 480cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project unlockBuffer(len); 481cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 482cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 48344dad3e006e0a966d93473dde3d74b2b43555519Daisuke Miyakawasize_t String8::getUtf32Length() const 48444dad3e006e0a966d93473dde3d74b2b43555519Daisuke Miyakawa{ 485ba0165bef09729a33ab8e0ca329342be05e0d859Kenny Root return utf8_to_utf32_length(mString, length()); 48644dad3e006e0a966d93473dde3d74b2b43555519Daisuke Miyakawa} 48744dad3e006e0a966d93473dde3d74b2b43555519Daisuke Miyakawa 48844dad3e006e0a966d93473dde3d74b2b43555519Daisuke Miyakawaint32_t String8::getUtf32At(size_t index, size_t *next_index) const 48944dad3e006e0a966d93473dde3d74b2b43555519Daisuke Miyakawa{ 490ba0165bef09729a33ab8e0ca329342be05e0d859Kenny Root return utf32_from_utf8_at(mString, length(), index, next_index); 49144dad3e006e0a966d93473dde3d74b2b43555519Daisuke Miyakawa} 49244dad3e006e0a966d93473dde3d74b2b43555519Daisuke Miyakawa 493ba0165bef09729a33ab8e0ca329342be05e0d859Kenny Rootvoid String8::getUtf32(char32_t* dst) const 49444dad3e006e0a966d93473dde3d74b2b43555519Daisuke Miyakawa{ 495ba0165bef09729a33ab8e0ca329342be05e0d859Kenny Root utf8_to_utf32(mString, length(), dst); 49644dad3e006e0a966d93473dde3d74b2b43555519Daisuke Miyakawa} 49744dad3e006e0a966d93473dde3d74b2b43555519Daisuke Miyakawa 498cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project// --------------------------------------------------------------------------- 499cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project// Path functions 500cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 501cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectvoid String8::setPathName(const char* name) 502cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{ 503cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project setPathName(name, strlen(name)); 504cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 505cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 506cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectvoid String8::setPathName(const char* name, size_t len) 507cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{ 508cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project char* buf = lockBuffer(len); 509cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 510cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project memcpy(buf, name, len); 511cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 512cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project // remove trailing path separator, if present 513cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project if (len > 0 && buf[len-1] == OS_PATH_SEPARATOR) 514cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project len--; 515cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 516cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project buf[len] = '\0'; 517cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 518cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project unlockBuffer(len); 519cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 520cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 521cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source ProjectString8 String8::getPathLeaf(void) const 522cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{ 523cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project const char* cp; 524cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project const char*const buf = mString; 525cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 526cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project cp = strrchr(buf, OS_PATH_SEPARATOR); 527cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project if (cp == NULL) 528cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project return String8(*this); 529cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project else 530cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project return String8(cp+1); 531cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 532cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 533cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source ProjectString8 String8::getPathDir(void) const 534cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{ 535cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project const char* cp; 536cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project const char*const str = mString; 537cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 538cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project cp = strrchr(str, OS_PATH_SEPARATOR); 539cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project if (cp == NULL) 540cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project return String8(""); 541cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project else 542cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project return String8(str, cp - str); 543cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 544cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 545cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source ProjectString8 String8::walkPath(String8* outRemains) const 546cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{ 547cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project const char* cp; 548cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project const char*const str = mString; 549cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project const char* buf = str; 550cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 551cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project cp = strchr(buf, OS_PATH_SEPARATOR); 552cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project if (cp == buf) { 553cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project // don't include a leading '/'. 554cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project buf = buf+1; 555cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project cp = strchr(buf, OS_PATH_SEPARATOR); 556cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project } 557cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 558cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project if (cp == NULL) { 559cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project String8 res = buf != str ? String8(buf) : *this; 560cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project if (outRemains) *outRemains = String8(""); 561cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project return res; 562cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project } 563cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 564cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project String8 res(buf, cp-buf); 565cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project if (outRemains) *outRemains = String8(cp+1); 566cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project return res; 567cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 568cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 569cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project/* 570cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project * Helper function for finding the start of an extension in a pathname. 571cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project * 572cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project * Returns a pointer inside mString, or NULL if no extension was found. 573cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project */ 574cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectchar* String8::find_extension(void) const 575cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{ 576cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project const char* lastSlash; 577cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project const char* lastDot; 578cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project const char* const str = mString; 579cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 580cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project // only look at the filename 581cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project lastSlash = strrchr(str, OS_PATH_SEPARATOR); 582cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project if (lastSlash == NULL) 583cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project lastSlash = str; 584cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project else 585cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project lastSlash++; 586cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 587cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project // find the last dot 588cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project lastDot = strrchr(lastSlash, '.'); 589cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project if (lastDot == NULL) 590cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project return NULL; 591cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 592cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project // looks good, ship it 593cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project return const_cast<char*>(lastDot); 594cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 595cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 596cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source ProjectString8 String8::getPathExtension(void) const 597cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{ 598cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project char* ext; 599cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 600cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project ext = find_extension(); 601cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project if (ext != NULL) 602cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project return String8(ext); 603cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project else 604cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project return String8(""); 605cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 606cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 607cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source ProjectString8 String8::getBasePath(void) const 608cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{ 609cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project char* ext; 610cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project const char* const str = mString; 611cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 612cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project ext = find_extension(); 613cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project if (ext == NULL) 614cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project return String8(*this); 615cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project else 616cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project return String8(str, ext - str); 617cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 618cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 619cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source ProjectString8& String8::appendPath(const char* name) 620cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{ 621cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project // TODO: The test below will fail for Win32 paths. Fix later or ignore. 622cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project if (name[0] != OS_PATH_SEPARATOR) { 623cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project if (*name == '\0') { 624cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project // nothing to do 625cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project return *this; 626cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project } 627cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 628cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project size_t len = length(); 629cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project if (len == 0) { 630cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project // no existing filename, just use the new one 631cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project setPathName(name); 632cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project return *this; 633cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project } 634cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 635cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project // make room for oldPath + '/' + newPath 636cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project int newlen = strlen(name); 637cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 638cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project char* buf = lockBuffer(len+1+newlen); 639cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 640cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project // insert a '/' if needed 641cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project if (buf[len-1] != OS_PATH_SEPARATOR) 642cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project buf[len++] = OS_PATH_SEPARATOR; 643cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 644cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project memcpy(buf+len, name, newlen+1); 645cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project len += newlen; 646cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 647cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project unlockBuffer(len); 648cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 649cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project return *this; 650cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project } else { 651cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project setPathName(name); 652cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project return *this; 653cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project } 654cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 655cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 656cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source ProjectString8& String8::convertToResPath() 657cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{ 658cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#if OS_PATH_SEPARATOR != RES_PATH_SEPARATOR 659cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project size_t len = length(); 660cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project if (len > 0) { 661cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project char * buf = lockBuffer(len); 662cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project for (char * end = buf + len; buf < end; ++buf) { 663cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project if (*buf == OS_PATH_SEPARATOR) 664cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project *buf = RES_PATH_SEPARATOR; 665cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project } 666cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project unlockBuffer(len); 667cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project } 668cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#endif 669cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project return *this; 670cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 671cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 672cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project}; // namespace android 673