2
* Copyright (C) 2005 The Android Open Source Project
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
* you may not use this file except in compliance with the License.
6
* You may obtain a copy of the License at
8
* http://www.apache.org/licenses/LICENSE-2.0
10
* Unless required by applicable law or agreed to in writing, software
11
* distributed under the License is distributed on an "AS IS" BASIS,
12
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
* See the License for the specific language governing permissions and
14
* limitations under the License.
17
#include <utils/String16.h>
19
#include <utils/Debug.h>
20
#include <utils/Log.h>
21
#include <utils/Unicode.h>
22
#include <utils/String8.h>
23
#include <utils/TextOutput.h>
24
#include <utils/threads.h>
26
#include <private/utils/Static.h>
35
static SharedBuffer* gEmptyStringBuf = NULL;
36
static char16_t* gEmptyString = NULL;
38
static inline char16_t* getEmptyString()
40
gEmptyStringBuf->acquire();
44
void initialize_string16()
46
SharedBuffer* buf = SharedBuffer::alloc(sizeof(char16_t));
47
char16_t* str = (char16_t*)buf->data();
49
gEmptyStringBuf = buf;
53
void terminate_string16()
55
SharedBuffer::bufferFromData(gEmptyString)->release();
56
gEmptyStringBuf = NULL;
60
// ---------------------------------------------------------------------------
62
static char16_t* allocFromUTF8(const char* u8str, size_t u8len)
64
if (u8len == 0) return getEmptyString();
66
const uint8_t* u8cur = (const uint8_t*) u8str;
68
const ssize_t u16len = utf8_to_utf16_length(u8cur, u8len);
70
return getEmptyString();
73
const uint8_t* const u8end = u8cur + u8len;
75
SharedBuffer* buf = SharedBuffer::alloc(sizeof(char16_t)*(u16len+1));
77
u8cur = (const uint8_t*) u8str;
78
char16_t* u16str = (char16_t*)buf->data();
80
utf8_to_utf16(u8cur, u8len, u16str);
82
//printf("Created UTF-16 string from UTF-8 \"%s\":", in);
83
//printHexData(1, str, buf->size(), 16, 1);
89
return getEmptyString();
92
// ---------------------------------------------------------------------------
95
: mString(getEmptyString())
99
String16::String16(const String16& o)
102
SharedBuffer::bufferFromData(mString)->acquire();
105
String16::String16(const String16& o, size_t len, size_t begin)
106
: mString(getEmptyString())
108
setTo(o, len, begin);
111
String16::String16(const char16_t* o)
113
size_t len = strlen16(o);
114
SharedBuffer* buf = SharedBuffer::alloc((len+1)*sizeof(char16_t));
115
ALOG_ASSERT(buf, "Unable to allocate shared buffer");
117
char16_t* str = (char16_t*)buf->data();
123
mString = getEmptyString();
126
String16::String16(const char16_t* o, size_t len)
128
SharedBuffer* buf = SharedBuffer::alloc((len+1)*sizeof(char16_t));
129
ALOG_ASSERT(buf, "Unable to allocate shared buffer");
131
char16_t* str = (char16_t*)buf->data();
132
memcpy(str, o, len*sizeof(char16_t));
138
mString = getEmptyString();
141
String16::String16(const String8& o)
142
: mString(allocFromUTF8(o.string(), o.size()))
146
String16::String16(const char* o)
147
: mString(allocFromUTF8(o, strlen(o)))
151
String16::String16(const char* o, size_t len)
152
: mString(allocFromUTF8(o, len))
156
String16::~String16()
158
SharedBuffer::bufferFromData(mString)->release();
161
void String16::setTo(const String16& other)
163
SharedBuffer::bufferFromData(other.mString)->acquire();
164
SharedBuffer::bufferFromData(mString)->release();
165
mString = other.mString;
168
status_t String16::setTo(const String16& other, size_t len, size_t begin)
170
const size_t N = other.size();
172
SharedBuffer::bufferFromData(mString)->release();
173
mString = getEmptyString();
176
if ((begin+len) > N) len = N-begin;
177
if (begin == 0 && len == N) {
182
if (&other == this) {
183
LOG_ALWAYS_FATAL("Not implemented");
186
return setTo(other.string()+begin, len);
189
status_t String16::setTo(const char16_t* other)
191
return setTo(other, strlen16(other));
194
status_t String16::setTo(const char16_t* other, size_t len)
196
SharedBuffer* buf = SharedBuffer::bufferFromData(mString)
197
->editResize((len+1)*sizeof(char16_t));
199
char16_t* str = (char16_t*)buf->data();
200
memmove(str, other, len*sizeof(char16_t));
208
status_t String16::append(const String16& other)
210
const size_t myLen = size();
211
const size_t otherLen = other.size();
215
} else if (otherLen == 0) {
219
SharedBuffer* buf = SharedBuffer::bufferFromData(mString)
220
->editResize((myLen+otherLen+1)*sizeof(char16_t));
222
char16_t* str = (char16_t*)buf->data();
223
memcpy(str+myLen, other, (otherLen+1)*sizeof(char16_t));
230
status_t String16::append(const char16_t* chrs, size_t otherLen)
232
const size_t myLen = size();
234
setTo(chrs, otherLen);
236
} else if (otherLen == 0) {
240
SharedBuffer* buf = SharedBuffer::bufferFromData(mString)
241
->editResize((myLen+otherLen+1)*sizeof(char16_t));
243
char16_t* str = (char16_t*)buf->data();
244
memcpy(str+myLen, chrs, otherLen*sizeof(char16_t));
245
str[myLen+otherLen] = 0;
252
status_t String16::insert(size_t pos, const char16_t* chrs)
254
return insert(pos, chrs, strlen16(chrs));
257
status_t String16::insert(size_t pos, const char16_t* chrs, size_t len)
259
const size_t myLen = size();
261
return setTo(chrs, len);
263
} else if (len == 0) {
267
if (pos > myLen) pos = myLen;
270
printf("Insert in to %s: pos=%d, len=%d, myLen=%d, chrs=%s\n",
271
String8(*this).string(), pos,
272
len, myLen, String8(chrs, len).string());
275
SharedBuffer* buf = SharedBuffer::bufferFromData(mString)
276
->editResize((myLen+len+1)*sizeof(char16_t));
278
char16_t* str = (char16_t*)buf->data();
280
memmove(str+pos+len, str+pos, (myLen-pos)*sizeof(char16_t));
282
memcpy(str+pos, chrs, len*sizeof(char16_t));
286
printf("Result (%d chrs): %s\n", size(), String8(*this).string());
293
ssize_t String16::findFirst(char16_t c) const
295
const char16_t* str = string();
296
const char16_t* p = str;
297
const char16_t* e = p + size();
307
ssize_t String16::findLast(char16_t c) const
309
const char16_t* str = string();
310
const char16_t* p = str;
311
const char16_t* e = p + size();
321
bool String16::startsWith(const String16& prefix) const
323
const size_t ps = prefix.size();
324
if (ps > size()) return false;
325
return strzcmp16(mString, ps, prefix.string(), ps) == 0;
328
bool String16::startsWith(const char16_t* prefix) const
330
const size_t ps = strlen16(prefix);
331
if (ps > size()) return false;
332
return strncmp16(mString, prefix, ps) == 0;
335
status_t String16::makeLower()
337
const size_t N = size();
338
const char16_t* str = string();
339
char16_t* edit = NULL;
340
for (size_t i=0; i<N; i++) {
341
const char16_t v = str[i];
342
if (v >= 'A' && v <= 'Z') {
344
SharedBuffer* buf = SharedBuffer::bufferFromData(mString)->edit();
348
edit = (char16_t*)buf->data();
349
mString = str = edit;
351
edit[i] = tolower((char)v);
357
status_t String16::replaceAll(char16_t replaceThis, char16_t withThis)
359
const size_t N = size();
360
const char16_t* str = string();
361
char16_t* edit = NULL;
362
for (size_t i=0; i<N; i++) {
363
if (str[i] == replaceThis) {
365
SharedBuffer* buf = SharedBuffer::bufferFromData(mString)->edit();
369
edit = (char16_t*)buf->data();
370
mString = str = edit;
378
status_t String16::remove(size_t len, size_t begin)
380
const size_t N = size();
382
SharedBuffer::bufferFromData(mString)->release();
383
mString = getEmptyString();
386
if ((begin+len) > N) len = N-begin;
387
if (begin == 0 && len == N) {
392
SharedBuffer* buf = SharedBuffer::bufferFromData(mString)
393
->editResize((N+1)*sizeof(char16_t));
397
char16_t* str = (char16_t*)buf->data();
398
memmove(str, str+begin, (N-begin+1)*sizeof(char16_t));
401
SharedBuffer* buf = SharedBuffer::bufferFromData(mString)
402
->editResize((len+1)*sizeof(char16_t));
404
char16_t* str = (char16_t*)buf->data();
412
TextOutput& operator<<(TextOutput& to, const String16& val)
414
to << String8(val).string();
418
}; // namespace android