1edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project/* 2edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Copyright (C) 2005 The Android Open Source Project 3edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * 4edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 5edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * you may not use this file except in compliance with the License. 6edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * You may obtain a copy of the License at 7edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * 8edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * 10edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 12edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * See the License for the specific language governing permissions and 14edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * limitations under the License. 15edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */ 16edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 17edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/String8.h> 18edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 19edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/Log.h> 20c412dcb3eb259458905aae9a2f5109c59c9548c0Kenny Root#include <utils/Unicode.h> 21c412dcb3eb259458905aae9a2f5109c59c9548c0Kenny Root#include <utils/SharedBuffer.h> 22edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/String16.h> 23edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/TextOutput.h> 24edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/threads.h> 25edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 26edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <private/utils/Static.h> 27edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 28edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <ctype.h> 29edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 309f220247f64d7db8a36532851cff087f5a6e4070Daisuke Miyakawa/* 319f220247f64d7db8a36532851cff087f5a6e4070Daisuke Miyakawa * Functions outside android is below the namespace android, since they use 329f220247f64d7db8a36532851cff087f5a6e4070Daisuke Miyakawa * functions and constants in android namespace. 339f220247f64d7db8a36532851cff087f5a6e4070Daisuke Miyakawa */ 34edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 35edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// --------------------------------------------------------------------------- 36edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 379f220247f64d7db8a36532851cff087f5a6e4070Daisuke Miyakawanamespace android { 389f220247f64d7db8a36532851cff087f5a6e4070Daisuke Miyakawa 39edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// Separator used by resource paths. This is not platform dependent contrary 40edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// to OS_PATH_SEPARATOR. 41edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define RES_PATH_SEPARATOR '/' 42edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 43edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic SharedBuffer* gEmptyStringBuf = NULL; 44edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic char* gEmptyString = NULL; 45edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 46edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectextern int gDarwinCantLoadAllObjects; 47edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectint gDarwinIsReallyAnnoying; 48edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 49edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic inline char* getEmptyString() 50edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 51edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project gEmptyStringBuf->acquire(); 52edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return gEmptyString; 53edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 54edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 55edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid initialize_string8() 56edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 57386a332b4f70718cccb08d5511d66e9f4f5bd409Dan Egnor // HACK: This dummy dependency forces linking libutils Static.cpp, 58386a332b4f70718cccb08d5511d66e9f4f5bd409Dan Egnor // which is needed to initialize String8/String16 classes. 59386a332b4f70718cccb08d5511d66e9f4f5bd409Dan Egnor // These variables are named for Darwin, but are needed elsewhere too, 60386a332b4f70718cccb08d5511d66e9f4f5bd409Dan Egnor // including static linking on any platform. 61386a332b4f70718cccb08d5511d66e9f4f5bd409Dan Egnor gDarwinIsReallyAnnoying = gDarwinCantLoadAllObjects; 629f220247f64d7db8a36532851cff087f5a6e4070Daisuke Miyakawa 63edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project SharedBuffer* buf = SharedBuffer::alloc(1); 64edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project char* str = (char*)buf->data(); 65edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *str = 0; 66edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project gEmptyStringBuf = buf; 67edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project gEmptyString = str; 68edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 69edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 70edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid terminate_string8() 71edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 72edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project SharedBuffer::bufferFromData(gEmptyString)->release(); 73edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project gEmptyStringBuf = NULL; 74edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project gEmptyString = NULL; 75edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 76edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 77edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// --------------------------------------------------------------------------- 78edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 79edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic char* allocFromUTF8(const char* in, size_t len) 80edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 81edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (len > 0) { 82edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project SharedBuffer* buf = SharedBuffer::alloc(len+1); 836726347e8950d34ae162fb8d6a3680a871d359e2Steve Block ALOG_ASSERT(buf, "Unable to allocate shared buffer"); 84edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (buf) { 85edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project char* str = (char*)buf->data(); 86edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project memcpy(str, in, len); 87edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project str[len] = 0; 88edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return str; 89edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 90edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NULL; 91edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 92edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 93edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return getEmptyString(); 94edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 95edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 96c412dcb3eb259458905aae9a2f5109c59c9548c0Kenny Rootstatic char* allocFromUTF16(const char16_t* in, size_t len) 97edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 98edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (len == 0) return getEmptyString(); 999f220247f64d7db8a36532851cff087f5a6e4070Daisuke Miyakawa 100c412dcb3eb259458905aae9a2f5109c59c9548c0Kenny Root const ssize_t bytes = utf16_to_utf8_length(in, len); 101c412dcb3eb259458905aae9a2f5109c59c9548c0Kenny Root if (bytes < 0) { 102c412dcb3eb259458905aae9a2f5109c59c9548c0Kenny Root return getEmptyString(); 103edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1049f220247f64d7db8a36532851cff087f5a6e4070Daisuke Miyakawa 105edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project SharedBuffer* buf = SharedBuffer::alloc(bytes+1); 1066726347e8950d34ae162fb8d6a3680a871d359e2Steve Block ALOG_ASSERT(buf, "Unable to allocate shared buffer"); 107c412dcb3eb259458905aae9a2f5109c59c9548c0Kenny Root if (!buf) { 108c412dcb3eb259458905aae9a2f5109c59c9548c0Kenny Root return getEmptyString(); 109edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 1109f220247f64d7db8a36532851cff087f5a6e4070Daisuke Miyakawa 111c412dcb3eb259458905aae9a2f5109c59c9548c0Kenny Root char* str = (char*)buf->data(); 112c412dcb3eb259458905aae9a2f5109c59c9548c0Kenny Root utf16_to_utf8(in, len, str); 113c412dcb3eb259458905aae9a2f5109c59c9548c0Kenny Root return str; 114edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 115edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 116c412dcb3eb259458905aae9a2f5109c59c9548c0Kenny Rootstatic char* allocFromUTF32(const char32_t* in, size_t len) 1179f220247f64d7db8a36532851cff087f5a6e4070Daisuke Miyakawa{ 118c412dcb3eb259458905aae9a2f5109c59c9548c0Kenny Root if (len == 0) { 119c412dcb3eb259458905aae9a2f5109c59c9548c0Kenny Root return getEmptyString(); 120c412dcb3eb259458905aae9a2f5109c59c9548c0Kenny Root } 12192f5984d2c2cd73b6b9f68c02c147877d1e2fc46Kenny Root 122c412dcb3eb259458905aae9a2f5109c59c9548c0Kenny Root const ssize_t bytes = utf32_to_utf8_length(in, len); 123c412dcb3eb259458905aae9a2f5109c59c9548c0Kenny Root if (bytes < 0) { 124c412dcb3eb259458905aae9a2f5109c59c9548c0Kenny Root return getEmptyString(); 125c412dcb3eb259458905aae9a2f5109c59c9548c0Kenny Root } 12692f5984d2c2cd73b6b9f68c02c147877d1e2fc46Kenny Root 12792f5984d2c2cd73b6b9f68c02c147877d1e2fc46Kenny Root SharedBuffer* buf = SharedBuffer::alloc(bytes+1); 1286726347e8950d34ae162fb8d6a3680a871d359e2Steve Block ALOG_ASSERT(buf, "Unable to allocate shared buffer"); 129c412dcb3eb259458905aae9a2f5109c59c9548c0Kenny Root if (!buf) { 130c412dcb3eb259458905aae9a2f5109c59c9548c0Kenny Root return getEmptyString(); 13192f5984d2c2cd73b6b9f68c02c147877d1e2fc46Kenny Root } 13292f5984d2c2cd73b6b9f68c02c147877d1e2fc46Kenny Root 133c412dcb3eb259458905aae9a2f5109c59c9548c0Kenny Root char* str = (char*) buf->data(); 134c412dcb3eb259458905aae9a2f5109c59c9548c0Kenny Root utf32_to_utf8(in, len, str); 1359f220247f64d7db8a36532851cff087f5a6e4070Daisuke Miyakawa 136c412dcb3eb259458905aae9a2f5109c59c9548c0Kenny Root return str; 1379f220247f64d7db8a36532851cff087f5a6e4070Daisuke Miyakawa} 1389f220247f64d7db8a36532851cff087f5a6e4070Daisuke Miyakawa 139edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// --------------------------------------------------------------------------- 140edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 141edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectString8::String8() 142edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project : mString(getEmptyString()) 143edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 144edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 145edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 146edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectString8::String8(const String8& o) 147edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project : mString(o.mString) 148edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 149edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project SharedBuffer::bufferFromData(mString)->acquire(); 150edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 151edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 152edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectString8::String8(const char* o) 153edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project : mString(allocFromUTF8(o, strlen(o))) 154edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 155edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (mString == NULL) { 156edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mString = getEmptyString(); 157edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 158edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 159edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 160edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectString8::String8(const char* o, size_t len) 161edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project : mString(allocFromUTF8(o, len)) 162edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 163edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (mString == NULL) { 164edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mString = getEmptyString(); 165edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 166edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 167edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 168edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectString8::String8(const String16& o) 169edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project : mString(allocFromUTF16(o.string(), o.size())) 170edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 171edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 172edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 173edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectString8::String8(const char16_t* o) 174edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project : mString(allocFromUTF16(o, strlen16(o))) 175edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 176edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 177edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 178edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectString8::String8(const char16_t* o, size_t len) 179edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project : mString(allocFromUTF16(o, len)) 180edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 181edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 182edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 1839f220247f64d7db8a36532851cff087f5a6e4070Daisuke MiyakawaString8::String8(const char32_t* o) 1849f220247f64d7db8a36532851cff087f5a6e4070Daisuke Miyakawa : mString(allocFromUTF32(o, strlen32(o))) 1859f220247f64d7db8a36532851cff087f5a6e4070Daisuke Miyakawa{ 1869f220247f64d7db8a36532851cff087f5a6e4070Daisuke Miyakawa} 1879f220247f64d7db8a36532851cff087f5a6e4070Daisuke Miyakawa 1889f220247f64d7db8a36532851cff087f5a6e4070Daisuke MiyakawaString8::String8(const char32_t* o, size_t len) 1899f220247f64d7db8a36532851cff087f5a6e4070Daisuke Miyakawa : mString(allocFromUTF32(o, len)) 1909f220247f64d7db8a36532851cff087f5a6e4070Daisuke Miyakawa{ 1919f220247f64d7db8a36532851cff087f5a6e4070Daisuke Miyakawa} 1929f220247f64d7db8a36532851cff087f5a6e4070Daisuke Miyakawa 193edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectString8::~String8() 194edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 195edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project SharedBuffer::bufferFromData(mString)->release(); 196edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 197edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 198db360642ed7a48eb3b3607a791bbe449cc6529bbJeff BrownString8 String8::format(const char* fmt, ...) 199db360642ed7a48eb3b3607a791bbe449cc6529bbJeff Brown{ 200db360642ed7a48eb3b3607a791bbe449cc6529bbJeff Brown va_list args; 201db360642ed7a48eb3b3607a791bbe449cc6529bbJeff Brown va_start(args, fmt); 202db360642ed7a48eb3b3607a791bbe449cc6529bbJeff Brown 203db360642ed7a48eb3b3607a791bbe449cc6529bbJeff Brown String8 result(formatV(fmt, args)); 204db360642ed7a48eb3b3607a791bbe449cc6529bbJeff Brown 205db360642ed7a48eb3b3607a791bbe449cc6529bbJeff Brown va_end(args); 206db360642ed7a48eb3b3607a791bbe449cc6529bbJeff Brown return result; 207db360642ed7a48eb3b3607a791bbe449cc6529bbJeff Brown} 208db360642ed7a48eb3b3607a791bbe449cc6529bbJeff Brown 209db360642ed7a48eb3b3607a791bbe449cc6529bbJeff BrownString8 String8::formatV(const char* fmt, va_list args) 210db360642ed7a48eb3b3607a791bbe449cc6529bbJeff Brown{ 211db360642ed7a48eb3b3607a791bbe449cc6529bbJeff Brown String8 result; 212db360642ed7a48eb3b3607a791bbe449cc6529bbJeff Brown result.appendFormatV(fmt, args); 213db360642ed7a48eb3b3607a791bbe449cc6529bbJeff Brown return result; 214db360642ed7a48eb3b3607a791bbe449cc6529bbJeff Brown} 215db360642ed7a48eb3b3607a791bbe449cc6529bbJeff Brown 2166a817e22e4b09a982ba17c1aff57f9fcb735c950Jeff Brownvoid String8::clear() { 2176a817e22e4b09a982ba17c1aff57f9fcb735c950Jeff Brown SharedBuffer::bufferFromData(mString)->release(); 2186a817e22e4b09a982ba17c1aff57f9fcb735c950Jeff Brown mString = getEmptyString(); 2196a817e22e4b09a982ba17c1aff57f9fcb735c950Jeff Brown} 2206a817e22e4b09a982ba17c1aff57f9fcb735c950Jeff Brown 221edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid String8::setTo(const String8& other) 222edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 223edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project SharedBuffer::bufferFromData(other.mString)->acquire(); 224edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project SharedBuffer::bufferFromData(mString)->release(); 225edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mString = other.mString; 226edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 227edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 228edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t String8::setTo(const char* other) 229edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 230a637eb48690eb253903dd07e037e63f60a2fd6f9Andreas Huber const char *newString = allocFromUTF8(other, strlen(other)); 231edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project SharedBuffer::bufferFromData(mString)->release(); 232a637eb48690eb253903dd07e037e63f60a2fd6f9Andreas Huber mString = newString; 233edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (mString) return NO_ERROR; 234edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 235edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mString = getEmptyString(); 236edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_MEMORY; 237edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 238edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 239edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t String8::setTo(const char* other, size_t len) 240edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 241a637eb48690eb253903dd07e037e63f60a2fd6f9Andreas Huber const char *newString = allocFromUTF8(other, len); 242edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project SharedBuffer::bufferFromData(mString)->release(); 243a637eb48690eb253903dd07e037e63f60a2fd6f9Andreas Huber mString = newString; 244edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (mString) return NO_ERROR; 245edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 246edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mString = getEmptyString(); 247edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_MEMORY; 248edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 249edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 250edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t String8::setTo(const char16_t* other, size_t len) 251edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 252a637eb48690eb253903dd07e037e63f60a2fd6f9Andreas Huber const char *newString = allocFromUTF16(other, len); 253edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project SharedBuffer::bufferFromData(mString)->release(); 254a637eb48690eb253903dd07e037e63f60a2fd6f9Andreas Huber mString = newString; 255edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (mString) return NO_ERROR; 256edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 257edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mString = getEmptyString(); 258edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_MEMORY; 259edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 260edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2619f220247f64d7db8a36532851cff087f5a6e4070Daisuke Miyakawastatus_t String8::setTo(const char32_t* other, size_t len) 2629f220247f64d7db8a36532851cff087f5a6e4070Daisuke Miyakawa{ 263a637eb48690eb253903dd07e037e63f60a2fd6f9Andreas Huber const char *newString = allocFromUTF32(other, len); 2649f220247f64d7db8a36532851cff087f5a6e4070Daisuke Miyakawa SharedBuffer::bufferFromData(mString)->release(); 265a637eb48690eb253903dd07e037e63f60a2fd6f9Andreas Huber mString = newString; 2669f220247f64d7db8a36532851cff087f5a6e4070Daisuke Miyakawa if (mString) return NO_ERROR; 2679f220247f64d7db8a36532851cff087f5a6e4070Daisuke Miyakawa 2689f220247f64d7db8a36532851cff087f5a6e4070Daisuke Miyakawa mString = getEmptyString(); 2699f220247f64d7db8a36532851cff087f5a6e4070Daisuke Miyakawa return NO_MEMORY; 2709f220247f64d7db8a36532851cff087f5a6e4070Daisuke Miyakawa} 2719f220247f64d7db8a36532851cff087f5a6e4070Daisuke Miyakawa 272edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t String8::append(const String8& other) 273edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 274edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const size_t otherLen = other.bytes(); 275edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (bytes() == 0) { 276edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project setTo(other); 277edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 278edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else if (otherLen == 0) { 279edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 280edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 281edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 282edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return real_append(other.string(), otherLen); 283edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 284edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 285edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t String8::append(const char* other) 286edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 287edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return append(other, strlen(other)); 288edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 289edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 290edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t String8::append(const char* other, size_t otherLen) 291edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 292edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (bytes() == 0) { 293edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return setTo(other, otherLen); 294edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else if (otherLen == 0) { 295edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 296edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 297edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 298edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return real_append(other, otherLen); 299edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 300edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 3010a128e3cbef25e17aa7280928e682801041fa55fJeff Brownstatus_t String8::appendFormat(const char* fmt, ...) 3020a128e3cbef25e17aa7280928e682801041fa55fJeff Brown{ 303a3477c862a5debcac7dfb076749059406ec59512Jeff Brown va_list args; 304a3477c862a5debcac7dfb076749059406ec59512Jeff Brown va_start(args, fmt); 3050a128e3cbef25e17aa7280928e682801041fa55fJeff Brown 306a3477c862a5debcac7dfb076749059406ec59512Jeff Brown status_t result = appendFormatV(fmt, args); 307a3477c862a5debcac7dfb076749059406ec59512Jeff Brown 308a3477c862a5debcac7dfb076749059406ec59512Jeff Brown va_end(args); 309a3477c862a5debcac7dfb076749059406ec59512Jeff Brown return result; 310a3477c862a5debcac7dfb076749059406ec59512Jeff Brown} 311a3477c862a5debcac7dfb076749059406ec59512Jeff Brown 312a3477c862a5debcac7dfb076749059406ec59512Jeff Brownstatus_t String8::appendFormatV(const char* fmt, va_list args) 313a3477c862a5debcac7dfb076749059406ec59512Jeff Brown{ 3140a128e3cbef25e17aa7280928e682801041fa55fJeff Brown int result = NO_ERROR; 315a3477c862a5debcac7dfb076749059406ec59512Jeff Brown int n = vsnprintf(NULL, 0, fmt, args); 3160a128e3cbef25e17aa7280928e682801041fa55fJeff Brown if (n != 0) { 3170a128e3cbef25e17aa7280928e682801041fa55fJeff Brown size_t oldLength = length(); 3180a128e3cbef25e17aa7280928e682801041fa55fJeff Brown char* buf = lockBuffer(oldLength + n); 3190a128e3cbef25e17aa7280928e682801041fa55fJeff Brown if (buf) { 320a3477c862a5debcac7dfb076749059406ec59512Jeff Brown vsnprintf(buf + oldLength, n + 1, fmt, args); 3210a128e3cbef25e17aa7280928e682801041fa55fJeff Brown } else { 3220a128e3cbef25e17aa7280928e682801041fa55fJeff Brown result = NO_MEMORY; 3230a128e3cbef25e17aa7280928e682801041fa55fJeff Brown } 3240a128e3cbef25e17aa7280928e682801041fa55fJeff Brown } 3250a128e3cbef25e17aa7280928e682801041fa55fJeff Brown return result; 3260a128e3cbef25e17aa7280928e682801041fa55fJeff Brown} 3270a128e3cbef25e17aa7280928e682801041fa55fJeff Brown 328edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t String8::real_append(const char* other, size_t otherLen) 329edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 330edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const size_t myLen = bytes(); 331edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 332edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project SharedBuffer* buf = SharedBuffer::bufferFromData(mString) 333edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project ->editResize(myLen+otherLen+1); 334edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (buf) { 335edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project char* str = (char*)buf->data(); 336edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mString = str; 337edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project str += myLen; 338edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project memcpy(str, other, otherLen); 339edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project str[otherLen] = '\0'; 340edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 341edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 342edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_MEMORY; 343edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 344edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 345edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectchar* String8::lockBuffer(size_t size) 346edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 347edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project SharedBuffer* buf = SharedBuffer::bufferFromData(mString) 348edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project ->editResize(size+1); 349edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (buf) { 350edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project char* str = (char*)buf->data(); 351edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mString = str; 352edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return str; 353edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 354edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NULL; 355edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 356edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 357edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid String8::unlockBuffer() 358edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 359edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project unlockBuffer(strlen(mString)); 360edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 361edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 362edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t String8::unlockBuffer(size_t size) 363edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 364edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (size != this->size()) { 365edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project SharedBuffer* buf = SharedBuffer::bufferFromData(mString) 366edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project ->editResize(size+1); 3670a128e3cbef25e17aa7280928e682801041fa55fJeff Brown if (! buf) { 3680a128e3cbef25e17aa7280928e682801041fa55fJeff Brown return NO_MEMORY; 369edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 3700a128e3cbef25e17aa7280928e682801041fa55fJeff Brown 3710a128e3cbef25e17aa7280928e682801041fa55fJeff Brown char* str = (char*)buf->data(); 3720a128e3cbef25e17aa7280928e682801041fa55fJeff Brown str[size] = 0; 3730a128e3cbef25e17aa7280928e682801041fa55fJeff Brown mString = str; 374edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 3750a128e3cbef25e17aa7280928e682801041fa55fJeff Brown 3760a128e3cbef25e17aa7280928e682801041fa55fJeff Brown return NO_ERROR; 377edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 378edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 379edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectssize_t String8::find(const char* other, size_t start) const 380edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 381edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project size_t len = size(); 382edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (start >= len) { 383edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return -1; 384edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 385edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const char* s = mString+start; 386edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const char* p = strstr(s, other); 387edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return p ? p-mString : -1; 388edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 389edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 390edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid String8::toLower() 391edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 392edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project toLower(0, size()); 393edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 394edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 395edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid String8::toLower(size_t start, size_t length) 396edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 397edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const size_t len = size(); 398edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (start >= len) { 399edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return; 400edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 401edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (start+length > len) { 402edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project length = len-start; 403edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 404edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project char* buf = lockBuffer(len); 405edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project buf += start; 406edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project while (length > 0) { 407edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *buf = tolower(*buf); 408edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project buf++; 409edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project length--; 410edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 411edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project unlockBuffer(len); 412edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 413edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 414edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid String8::toUpper() 415edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 416edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project toUpper(0, size()); 417edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 418edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 419edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid String8::toUpper(size_t start, size_t length) 420edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 421edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const size_t len = size(); 422edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (start >= len) { 423edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return; 424edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 425edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (start+length > len) { 426edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project length = len-start; 427edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 428edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project char* buf = lockBuffer(len); 429edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project buf += start; 430edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project while (length > 0) { 431edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *buf = toupper(*buf); 432edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project buf++; 433edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project length--; 434edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 435edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project unlockBuffer(len); 436edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 437edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 4389f220247f64d7db8a36532851cff087f5a6e4070Daisuke Miyakawasize_t String8::getUtf32Length() const 4399f220247f64d7db8a36532851cff087f5a6e4070Daisuke Miyakawa{ 440c412dcb3eb259458905aae9a2f5109c59c9548c0Kenny Root return utf8_to_utf32_length(mString, length()); 4419f220247f64d7db8a36532851cff087f5a6e4070Daisuke Miyakawa} 4429f220247f64d7db8a36532851cff087f5a6e4070Daisuke Miyakawa 4439f220247f64d7db8a36532851cff087f5a6e4070Daisuke Miyakawaint32_t String8::getUtf32At(size_t index, size_t *next_index) const 4449f220247f64d7db8a36532851cff087f5a6e4070Daisuke Miyakawa{ 445c412dcb3eb259458905aae9a2f5109c59c9548c0Kenny Root return utf32_from_utf8_at(mString, length(), index, next_index); 4469f220247f64d7db8a36532851cff087f5a6e4070Daisuke Miyakawa} 4479f220247f64d7db8a36532851cff087f5a6e4070Daisuke Miyakawa 448c412dcb3eb259458905aae9a2f5109c59c9548c0Kenny Rootvoid String8::getUtf32(char32_t* dst) const 4499f220247f64d7db8a36532851cff087f5a6e4070Daisuke Miyakawa{ 450c412dcb3eb259458905aae9a2f5109c59c9548c0Kenny Root utf8_to_utf32(mString, length(), dst); 4519f220247f64d7db8a36532851cff087f5a6e4070Daisuke Miyakawa} 4529f220247f64d7db8a36532851cff087f5a6e4070Daisuke Miyakawa 453edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectTextOutput& operator<<(TextOutput& to, const String8& val) 454edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 455edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project to << val.string(); 456edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return to; 457edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 458edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 459edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// --------------------------------------------------------------------------- 460edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// Path functions 461edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 462edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid String8::setPathName(const char* name) 463edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 464edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project setPathName(name, strlen(name)); 465edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 466edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 467edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid String8::setPathName(const char* name, size_t len) 468edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 469edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project char* buf = lockBuffer(len); 470edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 471edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project memcpy(buf, name, len); 472edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 473edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // remove trailing path separator, if present 474edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (len > 0 && buf[len-1] == OS_PATH_SEPARATOR) 475edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project len--; 476edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 477edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project buf[len] = '\0'; 478edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 479edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project unlockBuffer(len); 480edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 481edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 482edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectString8 String8::getPathLeaf(void) const 483edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 484edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const char* cp; 485edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const char*const buf = mString; 486edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 487edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project cp = strrchr(buf, OS_PATH_SEPARATOR); 488edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (cp == NULL) 489edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return String8(*this); 490edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project else 491edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return String8(cp+1); 492edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 493edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 494edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectString8 String8::getPathDir(void) const 495edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 496edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const char* cp; 497edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const char*const str = mString; 498edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 499edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project cp = strrchr(str, OS_PATH_SEPARATOR); 500edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (cp == NULL) 501edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return String8(""); 502edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project else 503edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return String8(str, cp - str); 504edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 505edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 506edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectString8 String8::walkPath(String8* outRemains) const 507edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 508edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const char* cp; 509edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const char*const str = mString; 510edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const char* buf = str; 511edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 512edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project cp = strchr(buf, OS_PATH_SEPARATOR); 513edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (cp == buf) { 514edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // don't include a leading '/'. 515edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project buf = buf+1; 516edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project cp = strchr(buf, OS_PATH_SEPARATOR); 517edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 518edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 519edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (cp == NULL) { 520edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project String8 res = buf != str ? String8(buf) : *this; 521edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (outRemains) *outRemains = String8(""); 522edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return res; 523edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 524edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 525edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project String8 res(buf, cp-buf); 526edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (outRemains) *outRemains = String8(cp+1); 527edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return res; 528edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 529edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 530edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project/* 531edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Helper function for finding the start of an extension in a pathname. 532edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * 533edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Returns a pointer inside mString, or NULL if no extension was found. 534edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */ 535edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectchar* String8::find_extension(void) const 536edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 537edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const char* lastSlash; 538edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const char* lastDot; 539edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int extLen; 540edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const char* const str = mString; 541edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 542edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // only look at the filename 543edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project lastSlash = strrchr(str, OS_PATH_SEPARATOR); 544edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (lastSlash == NULL) 545edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project lastSlash = str; 546edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project else 547edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project lastSlash++; 548edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 549edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // find the last dot 550edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project lastDot = strrchr(lastSlash, '.'); 551edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (lastDot == NULL) 552edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NULL; 553edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 554edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // looks good, ship it 555edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return const_cast<char*>(lastDot); 556edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 557edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 558edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectString8 String8::getPathExtension(void) const 559edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 560edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project char* ext; 561edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 562edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project ext = find_extension(); 563edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (ext != NULL) 564edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return String8(ext); 565edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project else 566edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return String8(""); 567edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 568edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 569edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectString8 String8::getBasePath(void) const 570edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 571edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project char* ext; 572edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const char* const str = mString; 573edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 574edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project ext = find_extension(); 575edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (ext == NULL) 576edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return String8(*this); 577edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project else 578edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return String8(str, ext - str); 579edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 580edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 581edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectString8& String8::appendPath(const char* name) 582edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 583edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // TODO: The test below will fail for Win32 paths. Fix later or ignore. 584edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (name[0] != OS_PATH_SEPARATOR) { 585edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (*name == '\0') { 586edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // nothing to do 587edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return *this; 588edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 589edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 590edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project size_t len = length(); 591edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (len == 0) { 592edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // no existing filename, just use the new one 593edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project setPathName(name); 594edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return *this; 595edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 596edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 597edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // make room for oldPath + '/' + newPath 598edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int newlen = strlen(name); 599edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 600edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project char* buf = lockBuffer(len+1+newlen); 601edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 602edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // insert a '/' if needed 603edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (buf[len-1] != OS_PATH_SEPARATOR) 604edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project buf[len++] = OS_PATH_SEPARATOR; 605edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 606edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project memcpy(buf+len, name, newlen+1); 607edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project len += newlen; 608edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 609edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project unlockBuffer(len); 610edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 611edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return *this; 612edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 613edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project setPathName(name); 614edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return *this; 615edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 616edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 617edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 618edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectString8& String8::convertToResPath() 619edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 620edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#if OS_PATH_SEPARATOR != RES_PATH_SEPARATOR 621edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project size_t len = length(); 622edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (len > 0) { 623edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project char * buf = lockBuffer(len); 624edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project for (char * end = buf + len; buf < end; ++buf) { 625edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (*buf == OS_PATH_SEPARATOR) 626edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *buf = RES_PATH_SEPARATOR; 627edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 628edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project unlockBuffer(len); 629edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 630edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#endif 631edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return *this; 632edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 633edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 634edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android 635