String8.cpp revision 647925ddf053989b641b4c5c8a51efd55c931f22
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/TextOutput.h> 24cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#include <utils/threads.h> 25cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 26cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#include <private/utils/Static.h> 27cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 28cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#include <ctype.h> 29cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 3044dad3e006e0a966d93473dde3d74b2b43555519Daisuke Miyakawa/* 3144dad3e006e0a966d93473dde3d74b2b43555519Daisuke Miyakawa * Functions outside android is below the namespace android, since they use 3244dad3e006e0a966d93473dde3d74b2b43555519Daisuke Miyakawa * functions and constants in android namespace. 3344dad3e006e0a966d93473dde3d74b2b43555519Daisuke Miyakawa */ 34cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 35cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project// --------------------------------------------------------------------------- 36cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 3744dad3e006e0a966d93473dde3d74b2b43555519Daisuke Miyakawanamespace android { 3844dad3e006e0a966d93473dde3d74b2b43555519Daisuke Miyakawa 39cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project// Separator used by resource paths. This is not platform dependent contrary 40cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project// to OS_PATH_SEPARATOR. 41cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#define RES_PATH_SEPARATOR '/' 42cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 43cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectstatic SharedBuffer* gEmptyStringBuf = NULL; 44cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectstatic char* gEmptyString = NULL; 45cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 46cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectextern int gDarwinCantLoadAllObjects; 47cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectint gDarwinIsReallyAnnoying; 48cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 49cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectstatic inline char* getEmptyString() 50cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{ 51cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project gEmptyStringBuf->acquire(); 52cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project return gEmptyString; 53cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 54cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 55cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectvoid initialize_string8() 56cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{ 5788753ae9d8f5432590df5e5338e0906834124c1dDan Egnor // HACK: This dummy dependency forces linking libutils Static.cpp, 5888753ae9d8f5432590df5e5338e0906834124c1dDan Egnor // which is needed to initialize String8/String16 classes. 5988753ae9d8f5432590df5e5338e0906834124c1dDan Egnor // These variables are named for Darwin, but are needed elsewhere too, 6088753ae9d8f5432590df5e5338e0906834124c1dDan Egnor // including static linking on any platform. 6188753ae9d8f5432590df5e5338e0906834124c1dDan Egnor gDarwinIsReallyAnnoying = gDarwinCantLoadAllObjects; 6244dad3e006e0a966d93473dde3d74b2b43555519Daisuke Miyakawa 63cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project SharedBuffer* buf = SharedBuffer::alloc(1); 64cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project char* str = (char*)buf->data(); 65cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project *str = 0; 66cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project gEmptyStringBuf = buf; 67cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project gEmptyString = str; 68cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 69cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 70cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectvoid terminate_string8() 71cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{ 72cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project SharedBuffer::bufferFromData(gEmptyString)->release(); 73cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project gEmptyStringBuf = NULL; 74cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project gEmptyString = NULL; 75cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 76cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 77cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project// --------------------------------------------------------------------------- 78cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 79cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectstatic char* allocFromUTF8(const char* in, size_t len) 80cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{ 81cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project if (len > 0) { 82cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project SharedBuffer* buf = SharedBuffer::alloc(len+1); 83cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project LOG_ASSERT(buf, "Unable to allocate shared buffer"); 84cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project if (buf) { 85cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project char* str = (char*)buf->data(); 86cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project memcpy(str, in, len); 87cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project str[len] = 0; 88cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project return str; 89cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project } 90cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project return NULL; 91cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project } 92cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 93cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project return getEmptyString(); 94cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 95cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 96ba0165bef09729a33ab8e0ca329342be05e0d859Kenny Rootstatic char* allocFromUTF16(const char16_t* in, size_t len) 97cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{ 98cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project if (len == 0) return getEmptyString(); 9944dad3e006e0a966d93473dde3d74b2b43555519Daisuke Miyakawa 100ba0165bef09729a33ab8e0ca329342be05e0d859Kenny Root const ssize_t bytes = utf16_to_utf8_length(in, len); 101ba0165bef09729a33ab8e0ca329342be05e0d859Kenny Root if (bytes < 0) { 102ba0165bef09729a33ab8e0ca329342be05e0d859Kenny Root return getEmptyString(); 103cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project } 10444dad3e006e0a966d93473dde3d74b2b43555519Daisuke Miyakawa 105cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project SharedBuffer* buf = SharedBuffer::alloc(bytes+1); 106cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project LOG_ASSERT(buf, "Unable to allocate shared buffer"); 107ba0165bef09729a33ab8e0ca329342be05e0d859Kenny Root if (!buf) { 108ba0165bef09729a33ab8e0ca329342be05e0d859Kenny Root return getEmptyString(); 109cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project } 11044dad3e006e0a966d93473dde3d74b2b43555519Daisuke Miyakawa 111ba0165bef09729a33ab8e0ca329342be05e0d859Kenny Root char* str = (char*)buf->data(); 112ba0165bef09729a33ab8e0ca329342be05e0d859Kenny Root utf16_to_utf8(in, len, str); 113ba0165bef09729a33ab8e0ca329342be05e0d859Kenny Root return str; 114cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 115cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 116ba0165bef09729a33ab8e0ca329342be05e0d859Kenny Rootstatic char* allocFromUTF32(const char32_t* in, size_t len) 11744dad3e006e0a966d93473dde3d74b2b43555519Daisuke Miyakawa{ 118ba0165bef09729a33ab8e0ca329342be05e0d859Kenny Root if (len == 0) { 119ba0165bef09729a33ab8e0ca329342be05e0d859Kenny Root return getEmptyString(); 120ba0165bef09729a33ab8e0ca329342be05e0d859Kenny Root } 1219a2d83e698b16ec86ad2751b6e7cf103ad645cceKenny Root 122ba0165bef09729a33ab8e0ca329342be05e0d859Kenny Root const ssize_t bytes = utf32_to_utf8_length(in, len); 123ba0165bef09729a33ab8e0ca329342be05e0d859Kenny Root if (bytes < 0) { 124ba0165bef09729a33ab8e0ca329342be05e0d859Kenny Root return getEmptyString(); 125ba0165bef09729a33ab8e0ca329342be05e0d859Kenny Root } 1269a2d83e698b16ec86ad2751b6e7cf103ad645cceKenny Root 1279a2d83e698b16ec86ad2751b6e7cf103ad645cceKenny Root SharedBuffer* buf = SharedBuffer::alloc(bytes+1); 1289a2d83e698b16ec86ad2751b6e7cf103ad645cceKenny Root LOG_ASSERT(buf, "Unable to allocate shared buffer"); 129ba0165bef09729a33ab8e0ca329342be05e0d859Kenny Root if (!buf) { 130ba0165bef09729a33ab8e0ca329342be05e0d859Kenny Root return getEmptyString(); 1319a2d83e698b16ec86ad2751b6e7cf103ad645cceKenny Root } 1329a2d83e698b16ec86ad2751b6e7cf103ad645cceKenny Root 133ba0165bef09729a33ab8e0ca329342be05e0d859Kenny Root char* str = (char*) buf->data(); 134ba0165bef09729a33ab8e0ca329342be05e0d859Kenny Root utf32_to_utf8(in, len, str); 13544dad3e006e0a966d93473dde3d74b2b43555519Daisuke Miyakawa 136ba0165bef09729a33ab8e0ca329342be05e0d859Kenny Root return str; 13744dad3e006e0a966d93473dde3d74b2b43555519Daisuke Miyakawa} 13844dad3e006e0a966d93473dde3d74b2b43555519Daisuke Miyakawa 139cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project// --------------------------------------------------------------------------- 140cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 141cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source ProjectString8::String8() 142cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project : mString(getEmptyString()) 143cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{ 144cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 145cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 146cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source ProjectString8::String8(const String8& o) 147cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project : mString(o.mString) 148cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{ 149cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project SharedBuffer::bufferFromData(mString)->acquire(); 150cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 151cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 152cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source ProjectString8::String8(const char* o) 153cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project : mString(allocFromUTF8(o, strlen(o))) 154cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{ 155cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project if (mString == NULL) { 156cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project mString = getEmptyString(); 157cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project } 158cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 159cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 160cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source ProjectString8::String8(const char* o, size_t len) 161cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project : mString(allocFromUTF8(o, len)) 162cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{ 163cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project if (mString == NULL) { 164cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project mString = getEmptyString(); 165cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project } 166cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 167cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 168cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source ProjectString8::String8(const String16& o) 169cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project : mString(allocFromUTF16(o.string(), o.size())) 170cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{ 171cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 172cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 173cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source ProjectString8::String8(const char16_t* o) 174cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project : mString(allocFromUTF16(o, strlen16(o))) 175cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{ 176cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 177cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 178cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source ProjectString8::String8(const char16_t* o, size_t len) 179cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project : mString(allocFromUTF16(o, len)) 180cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{ 181cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 182cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 18344dad3e006e0a966d93473dde3d74b2b43555519Daisuke MiyakawaString8::String8(const char32_t* o) 18444dad3e006e0a966d93473dde3d74b2b43555519Daisuke Miyakawa : mString(allocFromUTF32(o, strlen32(o))) 18544dad3e006e0a966d93473dde3d74b2b43555519Daisuke Miyakawa{ 18644dad3e006e0a966d93473dde3d74b2b43555519Daisuke Miyakawa} 18744dad3e006e0a966d93473dde3d74b2b43555519Daisuke Miyakawa 18844dad3e006e0a966d93473dde3d74b2b43555519Daisuke MiyakawaString8::String8(const char32_t* o, size_t len) 18944dad3e006e0a966d93473dde3d74b2b43555519Daisuke Miyakawa : mString(allocFromUTF32(o, len)) 19044dad3e006e0a966d93473dde3d74b2b43555519Daisuke Miyakawa{ 19144dad3e006e0a966d93473dde3d74b2b43555519Daisuke Miyakawa} 19244dad3e006e0a966d93473dde3d74b2b43555519Daisuke Miyakawa 193cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source ProjectString8::~String8() 194cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{ 195cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project SharedBuffer::bufferFromData(mString)->release(); 196cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 197cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 19848da31b735ebbc6a00c4e9fe9631f4af79e2c9dfJeff Brownvoid String8::clear() { 19948da31b735ebbc6a00c4e9fe9631f4af79e2c9dfJeff Brown SharedBuffer::bufferFromData(mString)->release(); 20048da31b735ebbc6a00c4e9fe9631f4af79e2c9dfJeff Brown mString = getEmptyString(); 20148da31b735ebbc6a00c4e9fe9631f4af79e2c9dfJeff Brown} 20248da31b735ebbc6a00c4e9fe9631f4af79e2c9dfJeff Brown 203cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectvoid String8::setTo(const String8& other) 204cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{ 205cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project SharedBuffer::bufferFromData(other.mString)->acquire(); 206cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project SharedBuffer::bufferFromData(mString)->release(); 207cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project mString = other.mString; 208cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 209cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 210cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectstatus_t String8::setTo(const char* other) 211cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{ 21210e5da58e4c22f2262f7ec7f82745d9673bed14bAndreas Huber const char *newString = allocFromUTF8(other, strlen(other)); 213cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project SharedBuffer::bufferFromData(mString)->release(); 21410e5da58e4c22f2262f7ec7f82745d9673bed14bAndreas Huber mString = newString; 215cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project if (mString) return NO_ERROR; 216cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 217cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project mString = getEmptyString(); 218cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project return NO_MEMORY; 219cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 220cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 221cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectstatus_t String8::setTo(const char* other, size_t len) 222cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{ 22310e5da58e4c22f2262f7ec7f82745d9673bed14bAndreas Huber const char *newString = allocFromUTF8(other, len); 224cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project SharedBuffer::bufferFromData(mString)->release(); 22510e5da58e4c22f2262f7ec7f82745d9673bed14bAndreas Huber mString = newString; 226cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project if (mString) return NO_ERROR; 227cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 228cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project mString = getEmptyString(); 229cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project return NO_MEMORY; 230cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 231cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 232cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectstatus_t String8::setTo(const char16_t* other, size_t len) 233cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{ 23410e5da58e4c22f2262f7ec7f82745d9673bed14bAndreas Huber const char *newString = allocFromUTF16(other, len); 235cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project SharedBuffer::bufferFromData(mString)->release(); 23610e5da58e4c22f2262f7ec7f82745d9673bed14bAndreas Huber mString = newString; 237cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project if (mString) return NO_ERROR; 238cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 239cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project mString = getEmptyString(); 240cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project return NO_MEMORY; 241cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 242cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 24344dad3e006e0a966d93473dde3d74b2b43555519Daisuke Miyakawastatus_t String8::setTo(const char32_t* other, size_t len) 24444dad3e006e0a966d93473dde3d74b2b43555519Daisuke Miyakawa{ 24510e5da58e4c22f2262f7ec7f82745d9673bed14bAndreas Huber const char *newString = allocFromUTF32(other, len); 24644dad3e006e0a966d93473dde3d74b2b43555519Daisuke Miyakawa SharedBuffer::bufferFromData(mString)->release(); 24710e5da58e4c22f2262f7ec7f82745d9673bed14bAndreas Huber mString = newString; 24844dad3e006e0a966d93473dde3d74b2b43555519Daisuke Miyakawa if (mString) return NO_ERROR; 24944dad3e006e0a966d93473dde3d74b2b43555519Daisuke Miyakawa 25044dad3e006e0a966d93473dde3d74b2b43555519Daisuke Miyakawa mString = getEmptyString(); 25144dad3e006e0a966d93473dde3d74b2b43555519Daisuke Miyakawa return NO_MEMORY; 25244dad3e006e0a966d93473dde3d74b2b43555519Daisuke Miyakawa} 25344dad3e006e0a966d93473dde3d74b2b43555519Daisuke Miyakawa 254cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectstatus_t String8::append(const String8& other) 255cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{ 256cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project const size_t otherLen = other.bytes(); 257cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project if (bytes() == 0) { 258cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project setTo(other); 259cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project return NO_ERROR; 260cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project } else if (otherLen == 0) { 261cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project return NO_ERROR; 262cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project } 263cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 264cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project return real_append(other.string(), otherLen); 265cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 266cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 267cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectstatus_t String8::append(const char* other) 268cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{ 269cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project return append(other, strlen(other)); 270cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 271cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 272cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectstatus_t String8::append(const char* other, size_t otherLen) 273cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{ 274cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project if (bytes() == 0) { 275cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project return setTo(other, otherLen); 276cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project } else if (otherLen == 0) { 277cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project return NO_ERROR; 278cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project } 279cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 280cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project return real_append(other, otherLen); 281cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 282cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 28335a154e57f2f59722de580395ccd5172e44842cbJeff Brownstatus_t String8::appendFormat(const char* fmt, ...) 28435a154e57f2f59722de580395ccd5172e44842cbJeff Brown{ 285647925ddf053989b641b4c5c8a51efd55c931f22Jeff Brown va_list args; 286647925ddf053989b641b4c5c8a51efd55c931f22Jeff Brown va_start(args, fmt); 28735a154e57f2f59722de580395ccd5172e44842cbJeff Brown 288647925ddf053989b641b4c5c8a51efd55c931f22Jeff Brown status_t result = appendFormatV(fmt, args); 289647925ddf053989b641b4c5c8a51efd55c931f22Jeff Brown 290647925ddf053989b641b4c5c8a51efd55c931f22Jeff Brown va_end(args); 291647925ddf053989b641b4c5c8a51efd55c931f22Jeff Brown return result; 292647925ddf053989b641b4c5c8a51efd55c931f22Jeff Brown} 293647925ddf053989b641b4c5c8a51efd55c931f22Jeff Brown 294647925ddf053989b641b4c5c8a51efd55c931f22Jeff Brownstatus_t String8::appendFormatV(const char* fmt, va_list args) 295647925ddf053989b641b4c5c8a51efd55c931f22Jeff Brown{ 29635a154e57f2f59722de580395ccd5172e44842cbJeff Brown int result = NO_ERROR; 297647925ddf053989b641b4c5c8a51efd55c931f22Jeff Brown int n = vsnprintf(NULL, 0, fmt, args); 29835a154e57f2f59722de580395ccd5172e44842cbJeff Brown if (n != 0) { 29935a154e57f2f59722de580395ccd5172e44842cbJeff Brown size_t oldLength = length(); 30035a154e57f2f59722de580395ccd5172e44842cbJeff Brown char* buf = lockBuffer(oldLength + n); 30135a154e57f2f59722de580395ccd5172e44842cbJeff Brown if (buf) { 302647925ddf053989b641b4c5c8a51efd55c931f22Jeff Brown vsnprintf(buf + oldLength, n + 1, fmt, args); 30335a154e57f2f59722de580395ccd5172e44842cbJeff Brown } else { 30435a154e57f2f59722de580395ccd5172e44842cbJeff Brown result = NO_MEMORY; 30535a154e57f2f59722de580395ccd5172e44842cbJeff Brown } 30635a154e57f2f59722de580395ccd5172e44842cbJeff Brown } 30735a154e57f2f59722de580395ccd5172e44842cbJeff Brown return result; 30835a154e57f2f59722de580395ccd5172e44842cbJeff Brown} 30935a154e57f2f59722de580395ccd5172e44842cbJeff Brown 310cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectstatus_t String8::real_append(const char* other, size_t otherLen) 311cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{ 312cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project const size_t myLen = bytes(); 313cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 314cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project SharedBuffer* buf = SharedBuffer::bufferFromData(mString) 315cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project ->editResize(myLen+otherLen+1); 316cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project if (buf) { 317cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project char* str = (char*)buf->data(); 318cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project mString = str; 319cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project str += myLen; 320cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project memcpy(str, other, otherLen); 321cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project str[otherLen] = '\0'; 322cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project return NO_ERROR; 323cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project } 324cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project return NO_MEMORY; 325cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 326cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 327cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectchar* String8::lockBuffer(size_t size) 328cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{ 329cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project SharedBuffer* buf = SharedBuffer::bufferFromData(mString) 330cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project ->editResize(size+1); 331cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project if (buf) { 332cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project char* str = (char*)buf->data(); 333cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project mString = str; 334cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project return str; 335cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project } 336cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project return NULL; 337cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 338cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 339cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectvoid String8::unlockBuffer() 340cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{ 341cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project unlockBuffer(strlen(mString)); 342cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 343cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 344cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectstatus_t String8::unlockBuffer(size_t size) 345cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{ 346cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project if (size != this->size()) { 347cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project SharedBuffer* buf = SharedBuffer::bufferFromData(mString) 348cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project ->editResize(size+1); 34935a154e57f2f59722de580395ccd5172e44842cbJeff Brown if (! buf) { 35035a154e57f2f59722de580395ccd5172e44842cbJeff Brown return NO_MEMORY; 351cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project } 35235a154e57f2f59722de580395ccd5172e44842cbJeff Brown 35335a154e57f2f59722de580395ccd5172e44842cbJeff Brown char* str = (char*)buf->data(); 35435a154e57f2f59722de580395ccd5172e44842cbJeff Brown str[size] = 0; 35535a154e57f2f59722de580395ccd5172e44842cbJeff Brown mString = str; 356cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project } 35735a154e57f2f59722de580395ccd5172e44842cbJeff Brown 35835a154e57f2f59722de580395ccd5172e44842cbJeff Brown return NO_ERROR; 359cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 360cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 361cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectssize_t String8::find(const char* other, size_t start) const 362cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{ 363cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project size_t len = size(); 364cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project if (start >= len) { 365cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project return -1; 366cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project } 367cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project const char* s = mString+start; 368cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project const char* p = strstr(s, other); 369cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project return p ? p-mString : -1; 370cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 371cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 372cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectvoid String8::toLower() 373cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{ 374cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project toLower(0, size()); 375cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 376cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 377cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectvoid String8::toLower(size_t start, size_t length) 378cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{ 379cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project const size_t len = size(); 380cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project if (start >= len) { 381cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project return; 382cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project } 383cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project if (start+length > len) { 384cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project length = len-start; 385cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project } 386cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project char* buf = lockBuffer(len); 387cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project buf += start; 388cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project while (length > 0) { 389cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project *buf = tolower(*buf); 390cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project buf++; 391cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project length--; 392cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project } 393cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project unlockBuffer(len); 394cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 395cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 396cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectvoid String8::toUpper() 397cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{ 398cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project toUpper(0, size()); 399cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 400cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 401cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectvoid String8::toUpper(size_t start, size_t length) 402cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{ 403cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project const size_t len = size(); 404cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project if (start >= len) { 405cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project return; 406cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project } 407cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project if (start+length > len) { 408cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project length = len-start; 409cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project } 410cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project char* buf = lockBuffer(len); 411cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project buf += start; 412cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project while (length > 0) { 413cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project *buf = toupper(*buf); 414cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project buf++; 415cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project length--; 416cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project } 417cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project unlockBuffer(len); 418cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 419cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 42044dad3e006e0a966d93473dde3d74b2b43555519Daisuke Miyakawasize_t String8::getUtf32Length() const 42144dad3e006e0a966d93473dde3d74b2b43555519Daisuke Miyakawa{ 422ba0165bef09729a33ab8e0ca329342be05e0d859Kenny Root return utf8_to_utf32_length(mString, length()); 42344dad3e006e0a966d93473dde3d74b2b43555519Daisuke Miyakawa} 42444dad3e006e0a966d93473dde3d74b2b43555519Daisuke Miyakawa 42544dad3e006e0a966d93473dde3d74b2b43555519Daisuke Miyakawaint32_t String8::getUtf32At(size_t index, size_t *next_index) const 42644dad3e006e0a966d93473dde3d74b2b43555519Daisuke Miyakawa{ 427ba0165bef09729a33ab8e0ca329342be05e0d859Kenny Root return utf32_from_utf8_at(mString, length(), index, next_index); 42844dad3e006e0a966d93473dde3d74b2b43555519Daisuke Miyakawa} 42944dad3e006e0a966d93473dde3d74b2b43555519Daisuke Miyakawa 430ba0165bef09729a33ab8e0ca329342be05e0d859Kenny Rootvoid String8::getUtf32(char32_t* dst) const 43144dad3e006e0a966d93473dde3d74b2b43555519Daisuke Miyakawa{ 432ba0165bef09729a33ab8e0ca329342be05e0d859Kenny Root utf8_to_utf32(mString, length(), dst); 43344dad3e006e0a966d93473dde3d74b2b43555519Daisuke Miyakawa} 43444dad3e006e0a966d93473dde3d74b2b43555519Daisuke Miyakawa 435cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source ProjectTextOutput& operator<<(TextOutput& to, const String8& val) 436cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{ 437cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project to << val.string(); 438cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project return to; 439cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 440cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 441cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project// --------------------------------------------------------------------------- 442cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project// Path functions 443cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 444cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectvoid String8::setPathName(const char* name) 445cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{ 446cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project setPathName(name, strlen(name)); 447cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 448cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 449cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectvoid String8::setPathName(const char* name, size_t len) 450cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{ 451cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project char* buf = lockBuffer(len); 452cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 453cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project memcpy(buf, name, len); 454cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 455cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project // remove trailing path separator, if present 456cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project if (len > 0 && buf[len-1] == OS_PATH_SEPARATOR) 457cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project len--; 458cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 459cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project buf[len] = '\0'; 460cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 461cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project unlockBuffer(len); 462cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 463cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 464cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source ProjectString8 String8::getPathLeaf(void) const 465cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{ 466cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project const char* cp; 467cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project const char*const buf = mString; 468cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 469cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project cp = strrchr(buf, OS_PATH_SEPARATOR); 470cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project if (cp == NULL) 471cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project return String8(*this); 472cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project else 473cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project return String8(cp+1); 474cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 475cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 476cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source ProjectString8 String8::getPathDir(void) const 477cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{ 478cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project const char* cp; 479cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project const char*const str = mString; 480cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 481cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project cp = strrchr(str, OS_PATH_SEPARATOR); 482cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project if (cp == NULL) 483cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project return String8(""); 484cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project else 485cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project return String8(str, cp - str); 486cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 487cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 488cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source ProjectString8 String8::walkPath(String8* outRemains) const 489cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{ 490cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project const char* cp; 491cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project const char*const str = mString; 492cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project const char* buf = str; 493cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 494cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project cp = strchr(buf, OS_PATH_SEPARATOR); 495cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project if (cp == buf) { 496cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project // don't include a leading '/'. 497cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project buf = buf+1; 498cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project cp = strchr(buf, OS_PATH_SEPARATOR); 499cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project } 500cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 501cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project if (cp == NULL) { 502cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project String8 res = buf != str ? String8(buf) : *this; 503cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project if (outRemains) *outRemains = String8(""); 504cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project return res; 505cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project } 506cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 507cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project String8 res(buf, cp-buf); 508cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project if (outRemains) *outRemains = String8(cp+1); 509cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project return res; 510cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 511cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 512cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project/* 513cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project * Helper function for finding the start of an extension in a pathname. 514cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project * 515cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project * Returns a pointer inside mString, or NULL if no extension was found. 516cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project */ 517cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectchar* String8::find_extension(void) const 518cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{ 519cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project const char* lastSlash; 520cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project const char* lastDot; 521cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project int extLen; 522cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project const char* const str = mString; 523cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 524cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project // only look at the filename 525cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project lastSlash = strrchr(str, OS_PATH_SEPARATOR); 526cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project if (lastSlash == NULL) 527cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project lastSlash = str; 528cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project else 529cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project lastSlash++; 530cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 531cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project // find the last dot 532cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project lastDot = strrchr(lastSlash, '.'); 533cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project if (lastDot == NULL) 534cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project return NULL; 535cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 536cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project // looks good, ship it 537cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project return const_cast<char*>(lastDot); 538cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 539cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 540cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source ProjectString8 String8::getPathExtension(void) const 541cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{ 542cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project char* ext; 543cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 544cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project ext = find_extension(); 545cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project if (ext != NULL) 546cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project return String8(ext); 547cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project else 548cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project return String8(""); 549cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 550cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 551cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source ProjectString8 String8::getBasePath(void) const 552cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{ 553cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project char* ext; 554cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project const char* const str = mString; 555cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 556cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project ext = find_extension(); 557cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project if (ext == NULL) 558cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project return String8(*this); 559cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project else 560cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project return String8(str, ext - str); 561cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 562cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 563cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source ProjectString8& String8::appendPath(const char* name) 564cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{ 565cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project // TODO: The test below will fail for Win32 paths. Fix later or ignore. 566cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project if (name[0] != OS_PATH_SEPARATOR) { 567cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project if (*name == '\0') { 568cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project // nothing to do 569cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project return *this; 570cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project } 571cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 572cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project size_t len = length(); 573cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project if (len == 0) { 574cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project // no existing filename, just use the new one 575cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project setPathName(name); 576cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project return *this; 577cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project } 578cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 579cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project // make room for oldPath + '/' + newPath 580cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project int newlen = strlen(name); 581cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 582cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project char* buf = lockBuffer(len+1+newlen); 583cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 584cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project // insert a '/' if needed 585cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project if (buf[len-1] != OS_PATH_SEPARATOR) 586cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project buf[len++] = OS_PATH_SEPARATOR; 587cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 588cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project memcpy(buf+len, name, newlen+1); 589cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project len += newlen; 590cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 591cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project unlockBuffer(len); 592cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 593cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project return *this; 594cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project } else { 595cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project setPathName(name); 596cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project return *this; 597cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project } 598cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 599cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 600cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source ProjectString8& String8::convertToResPath() 601cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{ 602cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#if OS_PATH_SEPARATOR != RES_PATH_SEPARATOR 603cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project size_t len = length(); 604cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project if (len > 0) { 605cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project char * buf = lockBuffer(len); 606cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project for (char * end = buf + len; buf < end; ++buf) { 607cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project if (*buf == OS_PATH_SEPARATOR) 608cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project *buf = RES_PATH_SEPARATOR; 609cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project } 610cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project unlockBuffer(len); 611cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project } 612cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#endif 613cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project return *this; 614cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 615cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 616cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project}; // namespace android 617