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/String16.h>
18edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
19edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/Debug.h>
20edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/Log.h>
21c412dcb3eb259458905aae9a2f5109c59c9548c0Kenny Root#include <utils/Unicode.h>
22edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/String8.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 <memory.h>
29edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdio.h>
30edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <ctype.h>
31edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
32edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
3392f5984d2c2cd73b6b9f68c02c147877d1e2fc46Kenny Rootnamespace android {
3492f5984d2c2cd73b6b9f68c02c147877d1e2fc46Kenny Root
35edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic SharedBuffer* gEmptyStringBuf = NULL;
36edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic char16_t* gEmptyString = NULL;
37edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
38edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic inline char16_t* getEmptyString()
39edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
40edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    gEmptyStringBuf->acquire();
41edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project   return gEmptyString;
42edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
43edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
44edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid initialize_string16()
45edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
46edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    SharedBuffer* buf = SharedBuffer::alloc(sizeof(char16_t));
47edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    char16_t* str = (char16_t*)buf->data();
48edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    *str = 0;
49edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    gEmptyStringBuf = buf;
50edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    gEmptyString = str;
51edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
52edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
53edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid terminate_string16()
54edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
55edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    SharedBuffer::bufferFromData(gEmptyString)->release();
56edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    gEmptyStringBuf = NULL;
57edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    gEmptyString = NULL;
58edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
59edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
60edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
61edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
62c412dcb3eb259458905aae9a2f5109c59c9548c0Kenny Rootstatic char16_t* allocFromUTF8(const char* u8str, size_t u8len)
63edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
64c412dcb3eb259458905aae9a2f5109c59c9548c0Kenny Root    if (u8len == 0) return getEmptyString();
65c412dcb3eb259458905aae9a2f5109c59c9548c0Kenny Root
66c412dcb3eb259458905aae9a2f5109c59c9548c0Kenny Root    const uint8_t* u8cur = (const uint8_t*) u8str;
67c412dcb3eb259458905aae9a2f5109c59c9548c0Kenny Root
68c412dcb3eb259458905aae9a2f5109c59c9548c0Kenny Root    const ssize_t u16len = utf8_to_utf16_length(u8cur, u8len);
69c412dcb3eb259458905aae9a2f5109c59c9548c0Kenny Root    if (u16len < 0) {
70c412dcb3eb259458905aae9a2f5109c59c9548c0Kenny Root        return getEmptyString();
71edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
72c412dcb3eb259458905aae9a2f5109c59c9548c0Kenny Root
73c412dcb3eb259458905aae9a2f5109c59c9548c0Kenny Root    const uint8_t* const u8end = u8cur + u8len;
74c412dcb3eb259458905aae9a2f5109c59c9548c0Kenny Root
75c412dcb3eb259458905aae9a2f5109c59c9548c0Kenny Root    SharedBuffer* buf = SharedBuffer::alloc(sizeof(char16_t)*(u16len+1));
76edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (buf) {
77c412dcb3eb259458905aae9a2f5109c59c9548c0Kenny Root        u8cur = (const uint8_t*) u8str;
78c412dcb3eb259458905aae9a2f5109c59c9548c0Kenny Root        char16_t* u16str = (char16_t*)buf->data();
79c412dcb3eb259458905aae9a2f5109c59c9548c0Kenny Root
80c412dcb3eb259458905aae9a2f5109c59c9548c0Kenny Root        utf8_to_utf16(u8cur, u8len, u16str);
8192f5984d2c2cd73b6b9f68c02c147877d1e2fc46Kenny Root
82edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        //printf("Created UTF-16 string from UTF-8 \"%s\":", in);
83edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        //printHexData(1, str, buf->size(), 16, 1);
84edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        //printf("\n");
85edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
86c412dcb3eb259458905aae9a2f5109c59c9548c0Kenny Root        return u16str;
87edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
88c412dcb3eb259458905aae9a2f5109c59c9548c0Kenny Root
89edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return getEmptyString();
90edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
91edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
92edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
93edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
94edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectString16::String16()
95edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    : mString(getEmptyString())
96edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
97edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
98edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
99edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectString16::String16(const String16& o)
100edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    : mString(o.mString)
101edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
102edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    SharedBuffer::bufferFromData(mString)->acquire();
103edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
104edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
105edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectString16::String16(const String16& o, size_t len, size_t begin)
106edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    : mString(getEmptyString())
107edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
108edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    setTo(o, len, begin);
109edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
110edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
111edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectString16::String16(const char16_t* o)
112edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
113edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    size_t len = strlen16(o);
114edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    SharedBuffer* buf = SharedBuffer::alloc((len+1)*sizeof(char16_t));
1156726347e8950d34ae162fb8d6a3680a871d359e2Steve Block    ALOG_ASSERT(buf, "Unable to allocate shared buffer");
116edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (buf) {
117edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        char16_t* str = (char16_t*)buf->data();
118edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        strcpy16(str, o);
119edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mString = str;
120edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
121edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
122edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
123edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mString = getEmptyString();
124edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
125edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
126edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectString16::String16(const char16_t* o, size_t len)
127edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
128edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    SharedBuffer* buf = SharedBuffer::alloc((len+1)*sizeof(char16_t));
1296726347e8950d34ae162fb8d6a3680a871d359e2Steve Block    ALOG_ASSERT(buf, "Unable to allocate shared buffer");
130edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (buf) {
131edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        char16_t* str = (char16_t*)buf->data();
132edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        memcpy(str, o, len*sizeof(char16_t));
133edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        str[len] = 0;
134edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mString = str;
135edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
136edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
137edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
138edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mString = getEmptyString();
139edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
140edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
141edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectString16::String16(const String8& o)
142edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    : mString(allocFromUTF8(o.string(), o.size()))
143edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
144edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
145edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
146edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectString16::String16(const char* o)
147edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    : mString(allocFromUTF8(o, strlen(o)))
148edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
149edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
150edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
151edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectString16::String16(const char* o, size_t len)
152edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    : mString(allocFromUTF8(o, len))
153edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
154edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
155edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
156edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectString16::~String16()
157edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
158edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    SharedBuffer::bufferFromData(mString)->release();
159edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
160edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
161edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid String16::setTo(const String16& other)
162edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
163edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    SharedBuffer::bufferFromData(other.mString)->acquire();
164edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    SharedBuffer::bufferFromData(mString)->release();
165edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mString = other.mString;
166edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
167edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
168edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t String16::setTo(const String16& other, size_t len, size_t begin)
169edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
170edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const size_t N = other.size();
171edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (begin >= N) {
172edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        SharedBuffer::bufferFromData(mString)->release();
173edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mString = getEmptyString();
174edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return NO_ERROR;
175edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
176edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if ((begin+len) > N) len = N-begin;
177edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (begin == 0 && len == N) {
178edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        setTo(other);
179edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return NO_ERROR;
180edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
181edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
182edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (&other == this) {
183edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        LOG_ALWAYS_FATAL("Not implemented");
184edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
185edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
186edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return setTo(other.string()+begin, len);
187edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
188edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
189edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t String16::setTo(const char16_t* other)
190edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
191edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return setTo(other, strlen16(other));
192edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
193edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
194edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t String16::setTo(const char16_t* other, size_t len)
195edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
196edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    SharedBuffer* buf = SharedBuffer::bufferFromData(mString)
197edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ->editResize((len+1)*sizeof(char16_t));
198edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (buf) {
199edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        char16_t* str = (char16_t*)buf->data();
2009adf84a4b6735354893ff1e57c129f66d97d75eeThe Android Open Source Project        memmove(str, other, len*sizeof(char16_t));
201edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        str[len] = 0;
202edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mString = str;
203edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return NO_ERROR;
204edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
205edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_MEMORY;
206edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
207edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
208edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t String16::append(const String16& other)
209edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
210edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const size_t myLen = size();
211edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const size_t otherLen = other.size();
212edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (myLen == 0) {
213edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        setTo(other);
214edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return NO_ERROR;
215edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else if (otherLen == 0) {
216edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return NO_ERROR;
217edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
218edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
219edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    SharedBuffer* buf = SharedBuffer::bufferFromData(mString)
220edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ->editResize((myLen+otherLen+1)*sizeof(char16_t));
221edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (buf) {
222edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        char16_t* str = (char16_t*)buf->data();
223edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        memcpy(str+myLen, other, (otherLen+1)*sizeof(char16_t));
224edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mString = str;
225edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return NO_ERROR;
226edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
227edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_MEMORY;
228edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
229edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
230edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t String16::append(const char16_t* chrs, size_t otherLen)
231edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
232edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const size_t myLen = size();
233edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (myLen == 0) {
234edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        setTo(chrs, otherLen);
235edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return NO_ERROR;
236edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else if (otherLen == 0) {
237edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return NO_ERROR;
238edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
239edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
240edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    SharedBuffer* buf = SharedBuffer::bufferFromData(mString)
241edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ->editResize((myLen+otherLen+1)*sizeof(char16_t));
242edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (buf) {
243edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        char16_t* str = (char16_t*)buf->data();
244edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        memcpy(str+myLen, chrs, otherLen*sizeof(char16_t));
245edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        str[myLen+otherLen] = 0;
246edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mString = str;
247edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return NO_ERROR;
248edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
249edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_MEMORY;
250edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
251edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
252edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t String16::insert(size_t pos, const char16_t* chrs)
253edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
254edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return insert(pos, chrs, strlen16(chrs));
255edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
256edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
257edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t String16::insert(size_t pos, const char16_t* chrs, size_t len)
258edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
259edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const size_t myLen = size();
260edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (myLen == 0) {
261edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return setTo(chrs, len);
262edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return NO_ERROR;
263edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else if (len == 0) {
264edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return NO_ERROR;
265edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
266edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
267edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (pos > myLen) pos = myLen;
268edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
269edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    #if 0
270edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    printf("Insert in to %s: pos=%d, len=%d, myLen=%d, chrs=%s\n",
271edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project           String8(*this).string(), pos,
272edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project           len, myLen, String8(chrs, len).string());
273edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    #endif
274edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
275edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    SharedBuffer* buf = SharedBuffer::bufferFromData(mString)
276edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ->editResize((myLen+len+1)*sizeof(char16_t));
277edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (buf) {
278edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        char16_t* str = (char16_t*)buf->data();
279edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (pos < myLen) {
280edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            memmove(str+pos+len, str+pos, (myLen-pos)*sizeof(char16_t));
281edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
282edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        memcpy(str+pos, chrs, len*sizeof(char16_t));
283edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        str[myLen+len] = 0;
284edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mString = str;
285edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        #if 0
286edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        printf("Result (%d chrs): %s\n", size(), String8(*this).string());
287edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        #endif
288edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return NO_ERROR;
289edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
290edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_MEMORY;
291edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
292edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
293edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectssize_t String16::findFirst(char16_t c) const
294edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
295edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const char16_t* str = string();
296edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const char16_t* p = str;
297edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const char16_t* e = p + size();
298edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    while (p < e) {
299edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (*p == c) {
300edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return p-str;
301edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
302edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        p++;
303edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
304edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return -1;
305edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
306edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
307edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectssize_t String16::findLast(char16_t c) const
308edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
309edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const char16_t* str = string();
310edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const char16_t* p = str;
311edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const char16_t* e = p + size();
312edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    while (p < e) {
313edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        e--;
314edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (*e == c) {
315edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return e-str;
316edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
317edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
318edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return -1;
319edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
320edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
321edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool String16::startsWith(const String16& prefix) const
322edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
323edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const size_t ps = prefix.size();
324edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (ps > size()) return false;
325edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return strzcmp16(mString, ps, prefix.string(), ps) == 0;
326edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
327edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
328edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool String16::startsWith(const char16_t* prefix) const
329edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
330edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const size_t ps = strlen16(prefix);
331edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (ps > size()) return false;
332edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return strncmp16(mString, prefix, ps) == 0;
333edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
334edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
335edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t String16::makeLower()
336edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
337edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const size_t N = size();
338edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const char16_t* str = string();
339edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    char16_t* edit = NULL;
340edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    for (size_t i=0; i<N; i++) {
341edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const char16_t v = str[i];
342edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (v >= 'A' && v <= 'Z') {
343edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (!edit) {
344edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                SharedBuffer* buf = SharedBuffer::bufferFromData(mString)->edit();
345edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                if (!buf) {
346edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    return NO_MEMORY;
347edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                }
348edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                edit = (char16_t*)buf->data();
349edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mString = str = edit;
350edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
351edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            edit[i] = tolower((char)v);
352edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
353edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
354edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
355edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
356edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
357edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t String16::replaceAll(char16_t replaceThis, char16_t withThis)
358edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
359edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const size_t N = size();
360edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const char16_t* str = string();
361edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    char16_t* edit = NULL;
362edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    for (size_t i=0; i<N; i++) {
363edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (str[i] == replaceThis) {
364edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (!edit) {
365edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                SharedBuffer* buf = SharedBuffer::bufferFromData(mString)->edit();
366edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                if (!buf) {
367edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    return NO_MEMORY;
368edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                }
369edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                edit = (char16_t*)buf->data();
370edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mString = str = edit;
371edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
372edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            edit[i] = withThis;
373edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
374edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
375edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
376edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
377edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
378edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t String16::remove(size_t len, size_t begin)
379edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
380edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const size_t N = size();
381edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (begin >= N) {
382edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        SharedBuffer::bufferFromData(mString)->release();
383edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mString = getEmptyString();
384edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return NO_ERROR;
385edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
386edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if ((begin+len) > N) len = N-begin;
387edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (begin == 0 && len == N) {
388edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return NO_ERROR;
389edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
390edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
391edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (begin > 0) {
392edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        SharedBuffer* buf = SharedBuffer::bufferFromData(mString)
393edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            ->editResize((N+1)*sizeof(char16_t));
394edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (!buf) {
395edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return NO_MEMORY;
396edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
397edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        char16_t* str = (char16_t*)buf->data();
398edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        memmove(str, str+begin, (N-begin+1)*sizeof(char16_t));
399edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mString = str;
400edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
401edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    SharedBuffer* buf = SharedBuffer::bufferFromData(mString)
402edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ->editResize((len+1)*sizeof(char16_t));
403edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (buf) {
404edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        char16_t* str = (char16_t*)buf->data();
405edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        str[len] = 0;
406edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mString = str;
407edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return NO_ERROR;
408edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
409edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_MEMORY;
410edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
411edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
412edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectTextOutput& operator<<(TextOutput& to, const String16& val)
413edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
414edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    to << String8(val).string();
415edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return to;
416edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
417edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
418edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android
419