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