19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2005 The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License.
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License.
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <utils/String8.h>
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <utils/Log.h>
20300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root#include <utils/Unicode.h>
21300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root#include <utils/SharedBuffer.h>
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <utils/String16.h>
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <utils/TextOutput.h>
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <utils/threads.h>
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <private/utils/Static.h>
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <ctype.h>
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
30f05b33b3a1cff40972a735ff1fb4ed6e8bfeaf2aDaisuke Miyakawa/*
31f05b33b3a1cff40972a735ff1fb4ed6e8bfeaf2aDaisuke Miyakawa * Functions outside android is below the namespace android, since they use
32f05b33b3a1cff40972a735ff1fb4ed6e8bfeaf2aDaisuke Miyakawa * functions and constants in android namespace.
33f05b33b3a1cff40972a735ff1fb4ed6e8bfeaf2aDaisuke Miyakawa */
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ---------------------------------------------------------------------------
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
37f05b33b3a1cff40972a735ff1fb4ed6e8bfeaf2aDaisuke Miyakawanamespace android {
38f05b33b3a1cff40972a735ff1fb4ed6e8bfeaf2aDaisuke Miyakawa
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// Separator used by resource paths. This is not platform dependent contrary
409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// to OS_PATH_SEPARATOR.
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define RES_PATH_SEPARATOR '/'
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic SharedBuffer* gEmptyStringBuf = NULL;
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic char* gEmptyString = NULL;
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectextern int gDarwinCantLoadAllObjects;
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint gDarwinIsReallyAnnoying;
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic inline char* getEmptyString()
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    gEmptyStringBuf->acquire();
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return gEmptyString;
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid initialize_string8()
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
5708b3d2e5ef01a5114424a871934dd9fc153352c0Dan Egnor    // HACK: This dummy dependency forces linking libutils Static.cpp,
5808b3d2e5ef01a5114424a871934dd9fc153352c0Dan Egnor    // which is needed to initialize String8/String16 classes.
5908b3d2e5ef01a5114424a871934dd9fc153352c0Dan Egnor    // These variables are named for Darwin, but are needed elsewhere too,
6008b3d2e5ef01a5114424a871934dd9fc153352c0Dan Egnor    // including static linking on any platform.
6108b3d2e5ef01a5114424a871934dd9fc153352c0Dan Egnor    gDarwinIsReallyAnnoying = gDarwinCantLoadAllObjects;
62f05b33b3a1cff40972a735ff1fb4ed6e8bfeaf2aDaisuke Miyakawa
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    SharedBuffer* buf = SharedBuffer::alloc(1);
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    char* str = (char*)buf->data();
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    *str = 0;
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    gEmptyStringBuf = buf;
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    gEmptyString = str;
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid terminate_string8()
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    SharedBuffer::bufferFromData(gEmptyString)->release();
739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    gEmptyStringBuf = NULL;
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    gEmptyString = NULL;
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ---------------------------------------------------------------------------
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic char* allocFromUTF8(const char* in, size_t len)
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (len > 0) {
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SharedBuffer* buf = SharedBuffer::alloc(len+1);
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        LOG_ASSERT(buf, "Unable to allocate shared buffer");
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (buf) {
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            char* str = (char*)buf->data();
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            memcpy(str, in, len);
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            str[len] = 0;
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return str;
899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return NULL;
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return getEmptyString();
949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
96300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Rootstatic char* allocFromUTF16(const char16_t* in, size_t len)
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (len == 0) return getEmptyString();
99f05b33b3a1cff40972a735ff1fb4ed6e8bfeaf2aDaisuke Miyakawa
100300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root    const ssize_t bytes = utf16_to_utf8_length(in, len);
101300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root    if (bytes < 0) {
102300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root        return getEmptyString();
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
104f05b33b3a1cff40972a735ff1fb4ed6e8bfeaf2aDaisuke Miyakawa
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    SharedBuffer* buf = SharedBuffer::alloc(bytes+1);
1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LOG_ASSERT(buf, "Unable to allocate shared buffer");
107300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root    if (!buf) {
108300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root        return getEmptyString();
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
110f05b33b3a1cff40972a735ff1fb4ed6e8bfeaf2aDaisuke Miyakawa
111300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root    char* str = (char*)buf->data();
112300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root    utf16_to_utf8(in, len, str);
113300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root    return str;
1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
116300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Rootstatic char* allocFromUTF32(const char32_t* in, size_t len)
117f05b33b3a1cff40972a735ff1fb4ed6e8bfeaf2aDaisuke Miyakawa{
118300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root    if (len == 0) {
119300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root        return getEmptyString();
120300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root    }
12119138468caf7050d482dc15f35a344eab11bb756Kenny Root
122300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root    const ssize_t bytes = utf32_to_utf8_length(in, len);
123300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root    if (bytes < 0) {
124300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root        return getEmptyString();
125300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root    }
12619138468caf7050d482dc15f35a344eab11bb756Kenny Root
12719138468caf7050d482dc15f35a344eab11bb756Kenny Root    SharedBuffer* buf = SharedBuffer::alloc(bytes+1);
12819138468caf7050d482dc15f35a344eab11bb756Kenny Root    LOG_ASSERT(buf, "Unable to allocate shared buffer");
129300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root    if (!buf) {
130300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root        return getEmptyString();
13119138468caf7050d482dc15f35a344eab11bb756Kenny Root    }
13219138468caf7050d482dc15f35a344eab11bb756Kenny Root
133300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root    char* str = (char*) buf->data();
134300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root    utf32_to_utf8(in, len, str);
135f05b33b3a1cff40972a735ff1fb4ed6e8bfeaf2aDaisuke Miyakawa
136300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root    return str;
137f05b33b3a1cff40972a735ff1fb4ed6e8bfeaf2aDaisuke Miyakawa}
138f05b33b3a1cff40972a735ff1fb4ed6e8bfeaf2aDaisuke Miyakawa
1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ---------------------------------------------------------------------------
1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectString8::String8()
1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    : mString(getEmptyString())
1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectString8::String8(const String8& o)
1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    : mString(o.mString)
1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    SharedBuffer::bufferFromData(mString)->acquire();
1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectString8::String8(const char* o)
1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    : mString(allocFromUTF8(o, strlen(o)))
1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (mString == NULL) {
1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mString = getEmptyString();
1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectString8::String8(const char* o, size_t len)
1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    : mString(allocFromUTF8(o, len))
1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (mString == NULL) {
1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mString = getEmptyString();
1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectString8::String8(const String16& o)
1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    : mString(allocFromUTF16(o.string(), o.size()))
1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectString8::String8(const char16_t* o)
1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    : mString(allocFromUTF16(o, strlen16(o)))
1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectString8::String8(const char16_t* o, size_t len)
1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    : mString(allocFromUTF16(o, len))
1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
183f05b33b3a1cff40972a735ff1fb4ed6e8bfeaf2aDaisuke MiyakawaString8::String8(const char32_t* o)
184f05b33b3a1cff40972a735ff1fb4ed6e8bfeaf2aDaisuke Miyakawa    : mString(allocFromUTF32(o, strlen32(o)))
185f05b33b3a1cff40972a735ff1fb4ed6e8bfeaf2aDaisuke Miyakawa{
186f05b33b3a1cff40972a735ff1fb4ed6e8bfeaf2aDaisuke Miyakawa}
187f05b33b3a1cff40972a735ff1fb4ed6e8bfeaf2aDaisuke Miyakawa
188f05b33b3a1cff40972a735ff1fb4ed6e8bfeaf2aDaisuke MiyakawaString8::String8(const char32_t* o, size_t len)
189f05b33b3a1cff40972a735ff1fb4ed6e8bfeaf2aDaisuke Miyakawa    : mString(allocFromUTF32(o, len))
190f05b33b3a1cff40972a735ff1fb4ed6e8bfeaf2aDaisuke Miyakawa{
191f05b33b3a1cff40972a735ff1fb4ed6e8bfeaf2aDaisuke Miyakawa}
192f05b33b3a1cff40972a735ff1fb4ed6e8bfeaf2aDaisuke Miyakawa
1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectString8::~String8()
1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    SharedBuffer::bufferFromData(mString)->release();
1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1989065504a63d6bf37bf621191fda1d1fe4da76ee3Jeff BrownString8 String8::format(const char* fmt, ...)
1999065504a63d6bf37bf621191fda1d1fe4da76ee3Jeff Brown{
2009065504a63d6bf37bf621191fda1d1fe4da76ee3Jeff Brown    va_list args;
2019065504a63d6bf37bf621191fda1d1fe4da76ee3Jeff Brown    va_start(args, fmt);
2029065504a63d6bf37bf621191fda1d1fe4da76ee3Jeff Brown
2039065504a63d6bf37bf621191fda1d1fe4da76ee3Jeff Brown    String8 result(formatV(fmt, args));
2049065504a63d6bf37bf621191fda1d1fe4da76ee3Jeff Brown
2059065504a63d6bf37bf621191fda1d1fe4da76ee3Jeff Brown    va_end(args);
2069065504a63d6bf37bf621191fda1d1fe4da76ee3Jeff Brown    return result;
2079065504a63d6bf37bf621191fda1d1fe4da76ee3Jeff Brown}
2089065504a63d6bf37bf621191fda1d1fe4da76ee3Jeff Brown
2099065504a63d6bf37bf621191fda1d1fe4da76ee3Jeff BrownString8 String8::formatV(const char* fmt, va_list args)
2109065504a63d6bf37bf621191fda1d1fe4da76ee3Jeff Brown{
2119065504a63d6bf37bf621191fda1d1fe4da76ee3Jeff Brown    String8 result;
2129065504a63d6bf37bf621191fda1d1fe4da76ee3Jeff Brown    result.appendFormatV(fmt, args);
2139065504a63d6bf37bf621191fda1d1fe4da76ee3Jeff Brown    return result;
2149065504a63d6bf37bf621191fda1d1fe4da76ee3Jeff Brown}
2159065504a63d6bf37bf621191fda1d1fe4da76ee3Jeff Brown
216497a92cc5ba2176b8a8484b0a7da040eac0e887bJeff Brownvoid String8::clear() {
217497a92cc5ba2176b8a8484b0a7da040eac0e887bJeff Brown    SharedBuffer::bufferFromData(mString)->release();
218497a92cc5ba2176b8a8484b0a7da040eac0e887bJeff Brown    mString = getEmptyString();
219497a92cc5ba2176b8a8484b0a7da040eac0e887bJeff Brown}
220497a92cc5ba2176b8a8484b0a7da040eac0e887bJeff Brown
2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid String8::setTo(const String8& other)
2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    SharedBuffer::bufferFromData(other.mString)->acquire();
2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    SharedBuffer::bufferFromData(mString)->release();
2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    mString = other.mString;
2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t String8::setTo(const char* other)
2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
23062a2aa01528e70c63aef60a6f48929da5a06761aAndreas Huber    const char *newString = allocFromUTF8(other, strlen(other));
2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    SharedBuffer::bufferFromData(mString)->release();
23262a2aa01528e70c63aef60a6f48929da5a06761aAndreas Huber    mString = newString;
2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (mString) return NO_ERROR;
2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    mString = getEmptyString();
2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return NO_MEMORY;
2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t String8::setTo(const char* other, size_t len)
2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
24162a2aa01528e70c63aef60a6f48929da5a06761aAndreas Huber    const char *newString = allocFromUTF8(other, len);
2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    SharedBuffer::bufferFromData(mString)->release();
24362a2aa01528e70c63aef60a6f48929da5a06761aAndreas Huber    mString = newString;
2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (mString) return NO_ERROR;
2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    mString = getEmptyString();
2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return NO_MEMORY;
2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t String8::setTo(const char16_t* other, size_t len)
2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
25262a2aa01528e70c63aef60a6f48929da5a06761aAndreas Huber    const char *newString = allocFromUTF16(other, len);
2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    SharedBuffer::bufferFromData(mString)->release();
25462a2aa01528e70c63aef60a6f48929da5a06761aAndreas Huber    mString = newString;
2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (mString) return NO_ERROR;
2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    mString = getEmptyString();
2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return NO_MEMORY;
2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
261f05b33b3a1cff40972a735ff1fb4ed6e8bfeaf2aDaisuke Miyakawastatus_t String8::setTo(const char32_t* other, size_t len)
262f05b33b3a1cff40972a735ff1fb4ed6e8bfeaf2aDaisuke Miyakawa{
26362a2aa01528e70c63aef60a6f48929da5a06761aAndreas Huber    const char *newString = allocFromUTF32(other, len);
264f05b33b3a1cff40972a735ff1fb4ed6e8bfeaf2aDaisuke Miyakawa    SharedBuffer::bufferFromData(mString)->release();
26562a2aa01528e70c63aef60a6f48929da5a06761aAndreas Huber    mString = newString;
266f05b33b3a1cff40972a735ff1fb4ed6e8bfeaf2aDaisuke Miyakawa    if (mString) return NO_ERROR;
267f05b33b3a1cff40972a735ff1fb4ed6e8bfeaf2aDaisuke Miyakawa
268f05b33b3a1cff40972a735ff1fb4ed6e8bfeaf2aDaisuke Miyakawa    mString = getEmptyString();
269f05b33b3a1cff40972a735ff1fb4ed6e8bfeaf2aDaisuke Miyakawa    return NO_MEMORY;
270f05b33b3a1cff40972a735ff1fb4ed6e8bfeaf2aDaisuke Miyakawa}
271f05b33b3a1cff40972a735ff1fb4ed6e8bfeaf2aDaisuke Miyakawa
2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t String8::append(const String8& other)
2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const size_t otherLen = other.bytes();
2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (bytes() == 0) {
2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        setTo(other);
2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return NO_ERROR;
2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else if (otherLen == 0) {
2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return NO_ERROR;
2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return real_append(other.string(), otherLen);
2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t String8::append(const char* other)
2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return append(other, strlen(other));
2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t String8::append(const char* other, size_t otherLen)
2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (bytes() == 0) {
2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return setTo(other, otherLen);
2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else if (otherLen == 0) {
2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return NO_ERROR;
2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return real_append(other, otherLen);
2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
301e33348ba54cd68d6936cffd4507037c14d4b10c2Jeff Brownstatus_t String8::appendFormat(const char* fmt, ...)
302e33348ba54cd68d6936cffd4507037c14d4b10c2Jeff Brown{
3036b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown    va_list args;
3046b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown    va_start(args, fmt);
305e33348ba54cd68d6936cffd4507037c14d4b10c2Jeff Brown
3066b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown    status_t result = appendFormatV(fmt, args);
3076b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown
3086b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown    va_end(args);
3096b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown    return result;
3106b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown}
3116b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown
3126b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brownstatus_t String8::appendFormatV(const char* fmt, va_list args)
3136b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown{
314e33348ba54cd68d6936cffd4507037c14d4b10c2Jeff Brown    int result = NO_ERROR;
3156b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown    int n = vsnprintf(NULL, 0, fmt, args);
316e33348ba54cd68d6936cffd4507037c14d4b10c2Jeff Brown    if (n != 0) {
317e33348ba54cd68d6936cffd4507037c14d4b10c2Jeff Brown        size_t oldLength = length();
318e33348ba54cd68d6936cffd4507037c14d4b10c2Jeff Brown        char* buf = lockBuffer(oldLength + n);
319e33348ba54cd68d6936cffd4507037c14d4b10c2Jeff Brown        if (buf) {
3206b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown            vsnprintf(buf + oldLength, n + 1, fmt, args);
321e33348ba54cd68d6936cffd4507037c14d4b10c2Jeff Brown        } else {
322e33348ba54cd68d6936cffd4507037c14d4b10c2Jeff Brown            result = NO_MEMORY;
323e33348ba54cd68d6936cffd4507037c14d4b10c2Jeff Brown        }
324e33348ba54cd68d6936cffd4507037c14d4b10c2Jeff Brown    }
325e33348ba54cd68d6936cffd4507037c14d4b10c2Jeff Brown    return result;
326e33348ba54cd68d6936cffd4507037c14d4b10c2Jeff Brown}
327e33348ba54cd68d6936cffd4507037c14d4b10c2Jeff Brown
3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t String8::real_append(const char* other, size_t otherLen)
3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const size_t myLen = bytes();
3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    SharedBuffer* buf = SharedBuffer::bufferFromData(mString)
3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ->editResize(myLen+otherLen+1);
3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (buf) {
3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        char* str = (char*)buf->data();
3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mString = str;
3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        str += myLen;
3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        memcpy(str, other, otherLen);
3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        str[otherLen] = '\0';
3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return NO_ERROR;
3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return NO_MEMORY;
3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectchar* String8::lockBuffer(size_t size)
3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    SharedBuffer* buf = SharedBuffer::bufferFromData(mString)
3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ->editResize(size+1);
3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (buf) {
3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        char* str = (char*)buf->data();
3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mString = str;
3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return str;
3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return NULL;
3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid String8::unlockBuffer()
3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    unlockBuffer(strlen(mString));
3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t String8::unlockBuffer(size_t size)
3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (size != this->size()) {
3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SharedBuffer* buf = SharedBuffer::bufferFromData(mString)
3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ->editResize(size+1);
367e33348ba54cd68d6936cffd4507037c14d4b10c2Jeff Brown        if (! buf) {
368e33348ba54cd68d6936cffd4507037c14d4b10c2Jeff Brown            return NO_MEMORY;
3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
370e33348ba54cd68d6936cffd4507037c14d4b10c2Jeff Brown
371e33348ba54cd68d6936cffd4507037c14d4b10c2Jeff Brown        char* str = (char*)buf->data();
372e33348ba54cd68d6936cffd4507037c14d4b10c2Jeff Brown        str[size] = 0;
373e33348ba54cd68d6936cffd4507037c14d4b10c2Jeff Brown        mString = str;
3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
375e33348ba54cd68d6936cffd4507037c14d4b10c2Jeff Brown
376e33348ba54cd68d6936cffd4507037c14d4b10c2Jeff Brown    return NO_ERROR;
3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectssize_t String8::find(const char* other, size_t start) const
3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    size_t len = size();
3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (start >= len) {
3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return -1;
3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const char* s = mString+start;
3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const char* p = strstr(s, other);
3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return p ? p-mString : -1;
3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid String8::toLower()
3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    toLower(0, size());
3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid String8::toLower(size_t start, size_t length)
3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const size_t len = size();
3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (start >= len) {
3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return;
4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (start+length > len) {
4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        length = len-start;
4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    char* buf = lockBuffer(len);
4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    buf += start;
4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    while (length > 0) {
4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        *buf = tolower(*buf);
4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        buf++;
4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        length--;
4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    unlockBuffer(len);
4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid String8::toUpper()
4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    toUpper(0, size());
4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid String8::toUpper(size_t start, size_t length)
4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const size_t len = size();
4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (start >= len) {
4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return;
4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (start+length > len) {
4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        length = len-start;
4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    char* buf = lockBuffer(len);
4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    buf += start;
4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    while (length > 0) {
4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        *buf = toupper(*buf);
4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        buf++;
4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        length--;
4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    unlockBuffer(len);
4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
438f05b33b3a1cff40972a735ff1fb4ed6e8bfeaf2aDaisuke Miyakawasize_t String8::getUtf32Length() const
439f05b33b3a1cff40972a735ff1fb4ed6e8bfeaf2aDaisuke Miyakawa{
440300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root    return utf8_to_utf32_length(mString, length());
441f05b33b3a1cff40972a735ff1fb4ed6e8bfeaf2aDaisuke Miyakawa}
442f05b33b3a1cff40972a735ff1fb4ed6e8bfeaf2aDaisuke Miyakawa
443f05b33b3a1cff40972a735ff1fb4ed6e8bfeaf2aDaisuke Miyakawaint32_t String8::getUtf32At(size_t index, size_t *next_index) const
444f05b33b3a1cff40972a735ff1fb4ed6e8bfeaf2aDaisuke Miyakawa{
445300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root    return utf32_from_utf8_at(mString, length(), index, next_index);
446f05b33b3a1cff40972a735ff1fb4ed6e8bfeaf2aDaisuke Miyakawa}
447f05b33b3a1cff40972a735ff1fb4ed6e8bfeaf2aDaisuke Miyakawa
448300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Rootvoid String8::getUtf32(char32_t* dst) const
449f05b33b3a1cff40972a735ff1fb4ed6e8bfeaf2aDaisuke Miyakawa{
450300ba6846949f5b21c6d93d7698dbc39716cf832Kenny Root    utf8_to_utf32(mString, length(), dst);
451f05b33b3a1cff40972a735ff1fb4ed6e8bfeaf2aDaisuke Miyakawa}
452f05b33b3a1cff40972a735ff1fb4ed6e8bfeaf2aDaisuke Miyakawa
4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectTextOutput& operator<<(TextOutput& to, const String8& val)
4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    to << val.string();
4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return to;
4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ---------------------------------------------------------------------------
4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// Path functions
4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid String8::setPathName(const char* name)
4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    setPathName(name, strlen(name));
4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid String8::setPathName(const char* name, size_t len)
4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    char* buf = lockBuffer(len);
4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    memcpy(buf, name, len);
4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // remove trailing path separator, if present
4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (len > 0 && buf[len-1] == OS_PATH_SEPARATOR)
4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        len--;
4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    buf[len] = '\0';
4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    unlockBuffer(len);
4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectString8 String8::getPathLeaf(void) const
4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const char* cp;
4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const char*const buf = mString;
4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    cp = strrchr(buf, OS_PATH_SEPARATOR);
4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (cp == NULL)
4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return String8(*this);
4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    else
4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return String8(cp+1);
4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectString8 String8::getPathDir(void) const
4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const char* cp;
4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const char*const str = mString;
4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    cp = strrchr(str, OS_PATH_SEPARATOR);
5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (cp == NULL)
5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return String8("");
5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    else
5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return String8(str, cp - str);
5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectString8 String8::walkPath(String8* outRemains) const
5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const char* cp;
5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const char*const str = mString;
5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const char* buf = str;
5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    cp = strchr(buf, OS_PATH_SEPARATOR);
5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (cp == buf) {
5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // don't include a leading '/'.
5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        buf = buf+1;
5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        cp = strchr(buf, OS_PATH_SEPARATOR);
5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (cp == NULL) {
5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        String8 res = buf != str ? String8(buf) : *this;
5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (outRemains) *outRemains = String8("");
5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return res;
5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    String8 res(buf, cp-buf);
5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (outRemains) *outRemains = String8(cp+1);
5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return res;
5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Helper function for finding the start of an extension in a pathname.
5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns a pointer inside mString, or NULL if no extension was found.
5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectchar* String8::find_extension(void) const
5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const char* lastSlash;
5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const char* lastDot;
5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int extLen;
5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const char* const str = mString;
5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // only look at the filename
5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    lastSlash = strrchr(str, OS_PATH_SEPARATOR);
5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (lastSlash == NULL)
5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        lastSlash = str;
5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    else
5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        lastSlash++;
5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // find the last dot
5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    lastDot = strrchr(lastSlash, '.');
5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (lastDot == NULL)
5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return NULL;
5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // looks good, ship it
5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return const_cast<char*>(lastDot);
5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectString8 String8::getPathExtension(void) const
5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    char* ext;
5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ext = find_extension();
5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (ext != NULL)
5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return String8(ext);
5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    else
5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return String8("");
5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectString8 String8::getBasePath(void) const
5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    char* ext;
5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const char* const str = mString;
5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ext = find_extension();
5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (ext == NULL)
5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return String8(*this);
5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    else
5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return String8(str, ext - str);
5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectString8& String8::appendPath(const char* name)
5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // TODO: The test below will fail for Win32 paths. Fix later or ignore.
5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (name[0] != OS_PATH_SEPARATOR) {
5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (*name == '\0') {
5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // nothing to do
5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return *this;
5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        size_t len = length();
5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (len == 0) {
5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // no existing filename, just use the new one
5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            setPathName(name);
5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return *this;
5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // make room for oldPath + '/' + newPath
5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int newlen = strlen(name);
5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        char* buf = lockBuffer(len+1+newlen);
6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // insert a '/' if needed
6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (buf[len-1] != OS_PATH_SEPARATOR)
6049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            buf[len++] = OS_PATH_SEPARATOR;
6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        memcpy(buf+len, name, newlen+1);
6079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        len += newlen;
6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        unlockBuffer(len);
6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return *this;
6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else {
6139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        setPathName(name);
6149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return *this;
6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectString8& String8::convertToResPath()
6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if OS_PATH_SEPARATOR != RES_PATH_SEPARATOR
6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    size_t len = length();
6229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (len > 0) {
6239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        char * buf = lockBuffer(len);
6249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (char * end = buf + len; buf < end; ++buf) {
6259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (*buf == OS_PATH_SEPARATOR)
6269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                *buf = RES_PATH_SEPARATOR;
6279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        unlockBuffer(len);
6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return *this;
6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; // namespace android
635