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