String16.cpp revision edbf3b6af777b721cd2a1ef461947e51e88241e1
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>
21edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/String8.h>
22edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/TextOutput.h>
23edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/threads.h>
24edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
25edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <private/utils/Static.h>
26edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
27edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#ifdef HAVE_WINSOCK
28edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project# undef  nhtol
29edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project# undef  htonl
30edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project# undef  nhtos
31edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project# undef  htons
32edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
33edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project# ifdef HAVE_LITTLE_ENDIAN
34edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#  define ntohl(x)    ( ((x) << 24) | (((x) >> 24) & 255) | (((x) << 8) & 0xff0000) | (((x) >> 8) & 0xff00) )
35edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#  define htonl(x)    ntohl(x)
36edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#  define ntohs(x)    ( (((x) << 8) & 0xff00) | (((x) >> 8) & 255) )
37edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#  define htons(x)    ntohs(x)
38edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project# else
39edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#  define ntohl(x)    (x)
40edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#  define htonl(x)    (x)
41edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#  define ntohs(x)    (x)
42edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#  define htons(x)    (x)
43edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project# endif
44edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#else
45edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project# include <netinet/in.h>
46edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#endif
47edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
48edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <memory.h>
49edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdio.h>
50edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <ctype.h>
51edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
52edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
53edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
54edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectint strcmp16(const char16_t *s1, const char16_t *s2)
55edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
56edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project  char16_t ch;
57edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project  int d = 0;
58edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
59edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project  while ( 1 ) {
60edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    d = (int)(ch = *s1++) - (int)*s2++;
61edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if ( d || !ch )
62edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project      break;
63edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project  }
64edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
65edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project  return d;
66edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
67edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
68edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectint strncmp16(const char16_t *s1, const char16_t *s2, size_t n)
69edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
70edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project  char16_t ch;
71edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project  int d = 0;
72edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
73edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project  while ( n-- ) {
74edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    d = (int)(ch = *s1++) - (int)*s2++;
75edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if ( d || !ch )
76edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project      break;
77edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project  }
78edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
79edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project  return d;
80edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
81edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
82edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectchar16_t *strcpy16(char16_t *dst, const char16_t *src)
83edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
84edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project  char16_t *q = dst;
85edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project  const char16_t *p = src;
86edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project  char16_t ch;
87edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
88edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project  do {
89edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    *q++ = ch = *p++;
90edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project  } while ( ch );
91edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
92edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project  return dst;
93edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
94edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
95edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectsize_t strlen16(const char16_t *s)
96edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
97edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project  const char16_t *ss = s;
98edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project  while ( *ss )
99edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ss++;
100edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project  return ss-s;
101edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
102edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
103edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
104edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectchar16_t *strncpy16(char16_t *dst, const char16_t *src, size_t n)
105edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
106edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project  char16_t *q = dst;
107edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project  const char16_t *p = src;
108edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project  char ch;
109edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
110edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project  while (n) {
111edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    n--;
112edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    *q++ = ch = *p++;
113edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if ( !ch )
114edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project      break;
115edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project  }
116edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
117edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project  *q = 0;
118edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
119edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project  return dst;
120edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
121edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
122edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectsize_t strnlen16(const char16_t *s, size_t maxlen)
123edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
124edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project  const char16_t *ss = s;
125edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
126edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project  /* Important: the maxlen test must precede the reference through ss;
127edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     since the byte beyond the maximum may segfault */
128edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project  while ((maxlen > 0) && *ss) {
129edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ss++;
130edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    maxlen--;
131edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project  }
132edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project  return ss-s;
133edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
134edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
135edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectint strzcmp16(const char16_t *s1, size_t n1, const char16_t *s2, size_t n2)
136edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
137edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const char16_t* e1 = s1+n1;
138edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const char16_t* e2 = s2+n2;
139edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
140edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    while (s1 < e1 && s2 < e2) {
141edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const int d = (int)*s1++ - (int)*s2++;
142edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (d) {
143edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return d;
144edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
145edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
146edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
147edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return n1 < n2
148edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ? (0 - (int)*s2)
149edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        : (n1 > n2
150edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project           ? ((int)*s1 - 0)
151edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project           : 0);
152edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
153edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
154edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectint strzcmp16_h_n(const char16_t *s1H, size_t n1, const char16_t *s2N, size_t n2)
155edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
156edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const char16_t* e1 = s1H+n1;
157edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const char16_t* e2 = s2N+n2;
158edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
159edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    while (s1H < e1 && s2N < e2) {
160edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const char16_t c2 = ntohs(*s2N);
161edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const int d = (int)*s1H++ - (int)c2;
162edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        s2N++;
163edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (d) {
164edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return d;
165edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
166edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
167edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
168edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return n1 < n2
169edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ? (0 - (int)ntohs(*s2N))
170edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        : (n1 > n2
171edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project           ? ((int)*s1H - 0)
172edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project           : 0);
173edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
174edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
175edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
176edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
177edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android {
178edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
179edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic inline size_t
180edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectutf8_char_len(uint8_t ch)
181edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
182edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return ((0xe5000000 >> ((ch >> 3) & 0x1e)) & 3) + 1;
183edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
184edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
185edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define UTF8_SHIFT_AND_MASK(unicode, byte)  (unicode)<<=6; (unicode) |= (0x3f & (byte));
186edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
187edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic inline uint32_t
188edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectutf8_to_utf32(const uint8_t *src, size_t length)
189edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
190edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t unicode;
191edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
192edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (length)
193edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    {
194edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case 1:
195edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return src[0];
196edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case 2:
197edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            unicode = src[0] & 0x1f;
198edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            UTF8_SHIFT_AND_MASK(unicode, src[1])
199edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return unicode;
200edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case 3:
201edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            unicode = src[0] & 0x0f;
202edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            UTF8_SHIFT_AND_MASK(unicode, src[1])
203edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            UTF8_SHIFT_AND_MASK(unicode, src[2])
204edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return unicode;
205edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case 4:
206edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            unicode = src[0] & 0x07;
207edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            UTF8_SHIFT_AND_MASK(unicode, src[1])
208edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            UTF8_SHIFT_AND_MASK(unicode, src[2])
209edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            UTF8_SHIFT_AND_MASK(unicode, src[3])
210edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return unicode;
211edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        default:
212edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return 0xffff;
213edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
214edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
215edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    //printf("Char at %p: len=%d, utf-16=%p\n", src, length, (void*)result);
216edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
217edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
218edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
219edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
220edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic SharedBuffer* gEmptyStringBuf = NULL;
221edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic char16_t* gEmptyString = NULL;
222edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
223edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic inline char16_t* getEmptyString()
224edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
225edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    gEmptyStringBuf->acquire();
226edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project   return gEmptyString;
227edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
228edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
229edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid initialize_string16()
230edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
231edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    SharedBuffer* buf = SharedBuffer::alloc(sizeof(char16_t));
232edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    char16_t* str = (char16_t*)buf->data();
233edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    *str = 0;
234edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    gEmptyStringBuf = buf;
235edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    gEmptyString = str;
236edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
237edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
238edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid terminate_string16()
239edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
240edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    SharedBuffer::bufferFromData(gEmptyString)->release();
241edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    gEmptyStringBuf = NULL;
242edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    gEmptyString = NULL;
243edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
244edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
245edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
246edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
247edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// Note: not dealing with generating surrogate pairs.
248edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic char16_t* allocFromUTF8(const char* in, size_t len)
249edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
250edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (len == 0) return getEmptyString();
251edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
252edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    size_t chars = 0;
253edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const char* end = in+len;
254edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const char* p = in;
255edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
256edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    while (p < end) {
257edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        chars++;
258edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        p += utf8_char_len(*p);
259edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
260edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
261edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    SharedBuffer* buf = SharedBuffer::alloc((chars+1)*sizeof(char16_t));
262edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (buf) {
263edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        p = in;
264edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        char16_t* str = (char16_t*)buf->data();
265edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        char16_t* d = str;
266edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        while (p < end) {
267edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            size_t len = utf8_char_len(*p);
268edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            *d++ = (char16_t)utf8_to_utf32((const uint8_t*)p, len);
269edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            p += len;
270edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
271edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        *d = 0;
272edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
273edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        //printf("Created UTF-16 string from UTF-8 \"%s\":", in);
274edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        //printHexData(1, str, buf->size(), 16, 1);
275edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        //printf("\n");
276edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
277edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return str;
278edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
279edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
280edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return getEmptyString();
281edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
282edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
283edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------
284edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
285edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectString16::String16()
286edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    : mString(getEmptyString())
287edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
288edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
289edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
290edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectString16::String16(const String16& o)
291edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    : mString(o.mString)
292edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
293edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    SharedBuffer::bufferFromData(mString)->acquire();
294edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
295edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
296edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectString16::String16(const String16& o, size_t len, size_t begin)
297edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    : mString(getEmptyString())
298edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
299edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    setTo(o, len, begin);
300edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
301edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
302edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectString16::String16(const char16_t* o)
303edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
304edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    size_t len = strlen16(o);
305edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    SharedBuffer* buf = SharedBuffer::alloc((len+1)*sizeof(char16_t));
306edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    LOG_ASSERT(buf, "Unable to allocate shared buffer");
307edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (buf) {
308edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        char16_t* str = (char16_t*)buf->data();
309edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        strcpy16(str, o);
310edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mString = str;
311edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
312edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
313edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
314edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mString = getEmptyString();
315edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
316edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
317edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectString16::String16(const char16_t* o, size_t len)
318edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
319edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    SharedBuffer* buf = SharedBuffer::alloc((len+1)*sizeof(char16_t));
320edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    LOG_ASSERT(buf, "Unable to allocate shared buffer");
321edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (buf) {
322edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        char16_t* str = (char16_t*)buf->data();
323edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        memcpy(str, o, len*sizeof(char16_t));
324edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        str[len] = 0;
325edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mString = str;
326edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
327edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
328edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
329edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mString = getEmptyString();
330edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
331edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
332edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectString16::String16(const String8& o)
333edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    : mString(allocFromUTF8(o.string(), o.size()))
334edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
335edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
336edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
337edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectString16::String16(const char* o)
338edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    : mString(allocFromUTF8(o, strlen(o)))
339edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
340edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
341edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
342edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectString16::String16(const char* o, size_t len)
343edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    : mString(allocFromUTF8(o, len))
344edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
345edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
346edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
347edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectString16::~String16()
348edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
349edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    SharedBuffer::bufferFromData(mString)->release();
350edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
351edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
352edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid String16::setTo(const String16& other)
353edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
354edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    SharedBuffer::bufferFromData(other.mString)->acquire();
355edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    SharedBuffer::bufferFromData(mString)->release();
356edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mString = other.mString;
357edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
358edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
359edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t String16::setTo(const String16& other, size_t len, size_t begin)
360edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
361edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const size_t N = other.size();
362edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (begin >= N) {
363edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        SharedBuffer::bufferFromData(mString)->release();
364edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mString = getEmptyString();
365edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return NO_ERROR;
366edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
367edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if ((begin+len) > N) len = N-begin;
368edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (begin == 0 && len == N) {
369edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        setTo(other);
370edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return NO_ERROR;
371edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
372edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
373edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (&other == this) {
374edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        LOG_ALWAYS_FATAL("Not implemented");
375edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
376edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
377edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return setTo(other.string()+begin, len);
378edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
379edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
380edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t String16::setTo(const char16_t* other)
381edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
382edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return setTo(other, strlen16(other));
383edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
384edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
385edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t String16::setTo(const char16_t* other, size_t len)
386edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
387edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    SharedBuffer* buf = SharedBuffer::bufferFromData(mString)
388edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ->editResize((len+1)*sizeof(char16_t));
389edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (buf) {
390edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        char16_t* str = (char16_t*)buf->data();
391edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        memcpy(str, other, len*sizeof(char16_t));
392edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        str[len] = 0;
393edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mString = str;
394edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return NO_ERROR;
395edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
396edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_MEMORY;
397edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
398edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
399edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t String16::append(const String16& other)
400edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
401edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const size_t myLen = size();
402edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const size_t otherLen = other.size();
403edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (myLen == 0) {
404edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        setTo(other);
405edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return NO_ERROR;
406edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else if (otherLen == 0) {
407edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return NO_ERROR;
408edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
409edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
410edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    SharedBuffer* buf = SharedBuffer::bufferFromData(mString)
411edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ->editResize((myLen+otherLen+1)*sizeof(char16_t));
412edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (buf) {
413edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        char16_t* str = (char16_t*)buf->data();
414edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        memcpy(str+myLen, other, (otherLen+1)*sizeof(char16_t));
415edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mString = str;
416edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return NO_ERROR;
417edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
418edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_MEMORY;
419edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
420edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
421edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t String16::append(const char16_t* chrs, size_t otherLen)
422edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
423edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const size_t myLen = size();
424edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (myLen == 0) {
425edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        setTo(chrs, otherLen);
426edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return NO_ERROR;
427edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else if (otherLen == 0) {
428edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return NO_ERROR;
429edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
430edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
431edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    SharedBuffer* buf = SharedBuffer::bufferFromData(mString)
432edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ->editResize((myLen+otherLen+1)*sizeof(char16_t));
433edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (buf) {
434edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        char16_t* str = (char16_t*)buf->data();
435edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        memcpy(str+myLen, chrs, otherLen*sizeof(char16_t));
436edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        str[myLen+otherLen] = 0;
437edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mString = str;
438edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return NO_ERROR;
439edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
440edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_MEMORY;
441edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
442edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
443edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t String16::insert(size_t pos, const char16_t* chrs)
444edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
445edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return insert(pos, chrs, strlen16(chrs));
446edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
447edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
448edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t String16::insert(size_t pos, const char16_t* chrs, size_t len)
449edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
450edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const size_t myLen = size();
451edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (myLen == 0) {
452edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return setTo(chrs, len);
453edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return NO_ERROR;
454edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else if (len == 0) {
455edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return NO_ERROR;
456edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
457edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
458edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (pos > myLen) pos = myLen;
459edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
460edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    #if 0
461edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    printf("Insert in to %s: pos=%d, len=%d, myLen=%d, chrs=%s\n",
462edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project           String8(*this).string(), pos,
463edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project           len, myLen, String8(chrs, len).string());
464edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    #endif
465edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
466edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    SharedBuffer* buf = SharedBuffer::bufferFromData(mString)
467edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ->editResize((myLen+len+1)*sizeof(char16_t));
468edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (buf) {
469edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        char16_t* str = (char16_t*)buf->data();
470edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (pos < myLen) {
471edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            memmove(str+pos+len, str+pos, (myLen-pos)*sizeof(char16_t));
472edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
473edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        memcpy(str+pos, chrs, len*sizeof(char16_t));
474edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        str[myLen+len] = 0;
475edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mString = str;
476edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        #if 0
477edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        printf("Result (%d chrs): %s\n", size(), String8(*this).string());
478edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        #endif
479edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return NO_ERROR;
480edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
481edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_MEMORY;
482edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
483edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
484edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectssize_t String16::findFirst(char16_t c) const
485edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
486edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const char16_t* str = string();
487edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const char16_t* p = str;
488edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const char16_t* e = p + size();
489edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    while (p < e) {
490edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (*p == c) {
491edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return p-str;
492edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
493edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        p++;
494edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
495edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return -1;
496edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
497edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
498edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectssize_t String16::findLast(char16_t c) const
499edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
500edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const char16_t* str = string();
501edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const char16_t* p = str;
502edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const char16_t* e = p + size();
503edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    while (p < e) {
504edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        e--;
505edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (*e == c) {
506edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return e-str;
507edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
508edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
509edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return -1;
510edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
511edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
512edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool String16::startsWith(const String16& prefix) const
513edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
514edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const size_t ps = prefix.size();
515edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (ps > size()) return false;
516edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return strzcmp16(mString, ps, prefix.string(), ps) == 0;
517edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
518edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
519edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool String16::startsWith(const char16_t* prefix) const
520edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
521edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const size_t ps = strlen16(prefix);
522edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (ps > size()) return false;
523edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return strncmp16(mString, prefix, ps) == 0;
524edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
525edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
526edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t String16::makeLower()
527edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
528edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const size_t N = size();
529edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const char16_t* str = string();
530edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    char16_t* edit = NULL;
531edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    for (size_t i=0; i<N; i++) {
532edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const char16_t v = str[i];
533edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (v >= 'A' && v <= 'Z') {
534edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (!edit) {
535edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                SharedBuffer* buf = SharedBuffer::bufferFromData(mString)->edit();
536edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                if (!buf) {
537edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    return NO_MEMORY;
538edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                }
539edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                edit = (char16_t*)buf->data();
540edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mString = str = edit;
541edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
542edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            edit[i] = tolower((char)v);
543edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
544edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
545edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
546edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
547edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
548edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t String16::replaceAll(char16_t replaceThis, char16_t withThis)
549edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
550edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const size_t N = size();
551edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const char16_t* str = string();
552edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    char16_t* edit = NULL;
553edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    for (size_t i=0; i<N; i++) {
554edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (str[i] == replaceThis) {
555edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (!edit) {
556edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                SharedBuffer* buf = SharedBuffer::bufferFromData(mString)->edit();
557edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                if (!buf) {
558edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    return NO_MEMORY;
559edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                }
560edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                edit = (char16_t*)buf->data();
561edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                mString = str = edit;
562edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
563edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            edit[i] = withThis;
564edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
565edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
566edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
567edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
568edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
569edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t String16::remove(size_t len, size_t begin)
570edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
571edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const size_t N = size();
572edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (begin >= N) {
573edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        SharedBuffer::bufferFromData(mString)->release();
574edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mString = getEmptyString();
575edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return NO_ERROR;
576edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
577edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if ((begin+len) > N) len = N-begin;
578edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (begin == 0 && len == N) {
579edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return NO_ERROR;
580edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
581edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
582edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (begin > 0) {
583edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        SharedBuffer* buf = SharedBuffer::bufferFromData(mString)
584edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            ->editResize((N+1)*sizeof(char16_t));
585edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (!buf) {
586edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return NO_MEMORY;
587edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
588edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        char16_t* str = (char16_t*)buf->data();
589edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        memmove(str, str+begin, (N-begin+1)*sizeof(char16_t));
590edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mString = str;
591edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
592edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    SharedBuffer* buf = SharedBuffer::bufferFromData(mString)
593edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ->editResize((len+1)*sizeof(char16_t));
594edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (buf) {
595edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        char16_t* str = (char16_t*)buf->data();
596edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        str[len] = 0;
597edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mString = str;
598edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return NO_ERROR;
599edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
600edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_MEMORY;
601edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
602edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
603edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectTextOutput& operator<<(TextOutput& to, const String16& val)
604edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
605edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    to << String8(val).string();
606edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return to;
607edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
608edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
609edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android
610