1b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* 2b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru****************************************************************************** 3103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius* Copyright (C) 1999-2012, International Business Machines Corporation and 4103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius* others. All Rights Reserved. 5b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru****************************************************************************** 6b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 7b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* File unistr.cpp 8b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 9b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* Modification History: 10b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 11b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* Date Name Description 12b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 09/25/98 stephen Creation. 13b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 04/20/99 stephen Overhauled per 4/16 code review. 14b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 07/09/99 stephen Renamed {hi,lo},{byte,word} to icu_X for HP/UX 15b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 11/18/99 aliu Added handleReplaceBetween() to make inherit from 16b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* Replaceable. 17b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 06/25/01 grhoten Removed the dependency on iostream 18b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru****************************************************************************** 19b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*/ 20b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 21b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/utypes.h" 22b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "unicode/appendable.h" 23b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/putil.h" 24b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "cstring.h" 25b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "cmemory.h" 26b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/ustring.h" 27b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/unistr.h" 28103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#include "unicode/utf.h" 29103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#include "unicode/utf16.h" 30103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#include "uelement.h" 31b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "ustr_imp.h" 32b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "umutex.h" 33103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#include "uassert.h" 34b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 35b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if 0 36b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 37b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include <iostream> 38b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruusing namespace std; 39b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 40b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//DEBUGGING 41b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid 42b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruprint(const UnicodeString& s, 43b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char *name) 44b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 45b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UChar c; 46b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru cout << name << ":|"; 47b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(int i = 0; i < s.length(); ++i) { 48b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru c = s[i]; 49b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(c>= 0x007E || c < 0x0020) 50b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru cout << "[0x" << hex << s[i] << "]"; 51b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else 52b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru cout << (char) s[i]; 53b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 54b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru cout << '|' << endl; 55b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 56b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 57b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid 58b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruprint(const UChar *s, 59b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t len, 60b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char *name) 61b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 62b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UChar c; 63b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru cout << name << ":|"; 64b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(int i = 0; i < len; ++i) { 65b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru c = s[i]; 66b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(c>= 0x007E || c < 0x0020) 67b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru cout << "[0x" << hex << s[i] << "]"; 68b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else 69b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru cout << (char) s[i]; 70b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 71b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru cout << '|' << endl; 72b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 73b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// END DEBUGGING 74b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 75b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 76b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Local function definitions for now 77b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 78b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// need to copy areas that may overlap 79b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic 80b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruinline void 81b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruus_arrayCopy(const UChar *src, int32_t srcStart, 82b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UChar *dst, int32_t dstStart, int32_t count) 83b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 84b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(count>0) { 85b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_memmove(dst+dstStart, src+srcStart, (size_t)(count*sizeof(*src))); 86b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 87b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 88b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 89b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// u_unescapeAt() callback to get a UChar from a UnicodeString 90b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CDECL_BEGIN 91b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic UChar U_CALLCONV 92b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString_charAt(int32_t offset, void *context) { 93103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return ((icu::UnicodeString*) context)->charAt(offset); 94b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 95b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CDECL_END 96b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 97b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_NAMESPACE_BEGIN 98b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 99b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* The Replaceable virtual destructor can't be defined in the header 100b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru due to how AIX works with multiple definitions of virtual functions. 101b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*/ 102b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruReplaceable::~Replaceable() {} 1038393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 104b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUOBJECT_DEFINE_RTTI_IMPLEMENTATION(UnicodeString) 105b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 106b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString U_EXPORT2 107b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruoperator+ (const UnicodeString &s1, const UnicodeString &s2) { 108b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 109b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UnicodeString(s1.length()+s2.length()+1, (UChar32)0, 0). 110b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru append(s1). 111b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru append(s2); 112b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 113b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 114b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//======================================== 115b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Reference Counting functions, put at top of file so that optimizing compilers 116b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// have a chance to automatically inline. 117b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//======================================== 118b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 119b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid 120b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::addRef() 121c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru{ umtx_atomic_inc((int32_t *)fUnion.fFields.fArray - 1);} 122b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 123b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t 124b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::removeRef() 125c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru{ return umtx_atomic_dec((int32_t *)fUnion.fFields.fArray - 1);} 126b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 127b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t 128b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::refCount() const 129b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 130b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru umtx_lock(NULL); 131b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Note: without the lock to force a memory barrier, we might see a very 132b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // stale value on some multi-processor systems. 133c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru int32_t count = *((int32_t *)fUnion.fFields.fArray - 1); 134b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru umtx_unlock(NULL); 135b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return count; 136b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 137b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 138b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid 139b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::releaseArray() { 140b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if((fFlags & kRefCounted) && removeRef() == 0) { 141c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru uprv_free((int32_t *)fUnion.fFields.fArray - 1); 142b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 143b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 144b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 145b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 146b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 147b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//======================================== 148b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Constructors 149b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//======================================== 1508393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 1518393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius// The default constructor is inline in unistr.h. 152b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 153b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::UnicodeString(int32_t capacity, UChar32 c, int32_t count) 154c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru : fShortLength(0), 155b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFlags(0) 156b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 157b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(count <= 0 || (uint32_t)c > 0x10ffff) { 158b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // just allocate and do not do anything else 159b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru allocate(capacity); 160b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 161b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // count > 0, allocate and fill the new string with count c's 162103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t unitCount = U16_LENGTH(c), length = count * unitCount; 163b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(capacity < length) { 164b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru capacity = length; 165b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 166b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(allocate(capacity)) { 167c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru UChar *array = getArrayStart(); 168b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t i = 0; 169b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 170b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // fill the new string with c 171b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(unitCount == 1) { 172b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // fill with length UChars 173b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(i < length) { 174c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru array[i++] = (UChar)c; 175b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 176b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 177b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // get the code units for c 178103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius UChar units[U16_MAX_LENGTH]; 179103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius U16_APPEND_UNSAFE(units, i, c); 180b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 181b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // now it must be i==unitCount 182b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru i = 0; 183b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 184b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // for Unicode, unitCount can only be 1, 2, 3, or 4 185b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // 1 is handled above 186b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(i < length) { 187b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t unitIdx = 0; 188b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(unitIdx < unitCount) { 189c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru array[i++]=units[unitIdx++]; 190b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 191b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 192b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 193b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 194c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru setLength(length); 195b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 196b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 197b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 198b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::UnicodeString(UChar ch) 199c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru : fShortLength(1), 200b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFlags(kShortString) 201b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 202c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru fUnion.fStackBuffer[0] = ch; 203b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 204b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 205b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::UnicodeString(UChar32 ch) 206c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru : fShortLength(0), 207b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFlags(kShortString) 208b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 209b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t i = 0; 210b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UBool isError = FALSE; 211c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru U16_APPEND(fUnion.fStackBuffer, i, US_STACKBUF_SIZE, ch, isError); 212103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // We test isError so that the compiler does not complain that we don't. 213103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // If isError then i==0 which is what we want anyway. 214103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if(!isError) { 215103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius fShortLength = (int8_t)i; 216103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 217b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 218b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 219b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::UnicodeString(const UChar *text) 220c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru : fShortLength(0), 221b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFlags(kShortString) 222b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 223b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru doReplace(0, 0, text, 0, -1); 224b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 225b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 226b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::UnicodeString(const UChar *text, 227b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t textLength) 228c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru : fShortLength(0), 229b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFlags(kShortString) 230b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 231b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru doReplace(0, 0, text, 0, textLength); 232b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 233b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 234b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::UnicodeString(UBool isTerminated, 235b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const UChar *text, 236b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t textLength) 237c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru : fShortLength(0), 238b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFlags(kReadonlyAlias) 239b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 240b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(text == NULL) { 241b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // treat as an empty string, do not alias 242c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru setToEmpty(); 243b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else if(textLength < -1 || 244b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (textLength == -1 && !isTerminated) || 245b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (textLength >= 0 && isTerminated && text[textLength] != 0) 246b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ) { 247b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru setToBogus(); 248c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } else { 249c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if(textLength == -1) { 250c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru // text is terminated, or else it would have failed the above test 251c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru textLength = u_strlen(text); 252c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } 253c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru setArray((UChar *)text, textLength, isTerminated ? textLength + 1 : textLength); 254b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 255b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 256b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 257b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::UnicodeString(UChar *buff, 258b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t buffLength, 259b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t buffCapacity) 260c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru : fShortLength(0), 261b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFlags(kWritableAlias) 262b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 263b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(buff == NULL) { 264b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // treat as an empty string, do not alias 265c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru setToEmpty(); 266b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else if(buffLength < -1 || buffCapacity < 0 || buffLength > buffCapacity) { 267b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru setToBogus(); 268c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } else { 269c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if(buffLength == -1) { 270c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru // fLength = u_strlen(buff); but do not look beyond buffCapacity 271c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru const UChar *p = buff, *limit = buff + buffCapacity; 272c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru while(p != limit && *p != 0) { 273c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru ++p; 274c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } 275c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru buffLength = (int32_t)(p - buff); 276b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 277c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru setArray(buff, buffLength, buffCapacity); 278b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 279b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 280b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 281b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::UnicodeString(const char *src, int32_t length, EInvariant) 282c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru : fShortLength(0), 283b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFlags(kShortString) 284b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 285b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(src==NULL) { 286b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // treat as an empty string 287b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 288b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(length<0) { 289b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru length=(int32_t)uprv_strlen(src); 290b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 291b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(cloneArrayIfNeeded(length, length, FALSE)) { 292b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru u_charsToUChars(src, getArrayStart(), length); 293c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru setLength(length); 294b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 295b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru setToBogus(); 296b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 297b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 298b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 299b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 300b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#if U_CHARSET_IS_UTF8 301b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 302b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruUnicodeString::UnicodeString(const char *codepageData) 303b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru : fShortLength(0), 304b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru fFlags(kShortString) { 305b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if(codepageData != 0) { 306b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru setToUTF8(codepageData); 307b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 308b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru} 309b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 310b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruUnicodeString::UnicodeString(const char *codepageData, int32_t dataLength) 311b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru : fShortLength(0), 312b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru fFlags(kShortString) { 313b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // if there's nothing to convert, do nothing 314b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if(codepageData == 0 || dataLength == 0 || dataLength < -1) { 315b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return; 316b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 317b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if(dataLength == -1) { 318b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru dataLength = (int32_t)uprv_strlen(codepageData); 319b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 320b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru setToUTF8(StringPiece(codepageData, dataLength)); 321b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru} 322b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 323b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru// else see unistr_cnv.cpp 324b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#endif 325b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 326b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::UnicodeString(const UnicodeString& that) 327b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru : Replaceable(), 328c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru fShortLength(0), 329b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFlags(kShortString) 330b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 331b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru copyFrom(that); 332b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 333b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 334b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::UnicodeString(const UnicodeString& that, 335b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t srcStart) 336b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru : Replaceable(), 337c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru fShortLength(0), 338b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFlags(kShortString) 339b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 340b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru setTo(that, srcStart); 341b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 342b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 343b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::UnicodeString(const UnicodeString& that, 344b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t srcStart, 345b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t srcLength) 346b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru : Replaceable(), 347c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru fShortLength(0), 348b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFlags(kShortString) 349b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 350b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru setTo(that, srcStart, srcLength); 351b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 352b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 353b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Replaceable base class clone() default implementation, does not clone 354b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruReplaceable * 355b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruReplaceable::clone() const { 356b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 357b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 358b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 359b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// UnicodeString overrides clone() with a real implementation 360b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruReplaceable * 361b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::clone() const { 362b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return new UnicodeString(*this); 363b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 364b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 365b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//======================================== 366b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// array allocation 367b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//======================================== 368b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 369b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUBool 370b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::allocate(int32_t capacity) { 371b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(capacity <= US_STACKBUF_SIZE) { 372b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFlags = kShortString; 373b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 374b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // count bytes for the refCounter and the string capacity, and 375b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // round up to a multiple of 16; then divide by 4 and allocate int32_t's 376b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // to be safely aligned for the refCount 37750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // the +1 is for the NUL terminator, to avoid reallocation in getTerminatedBuffer() 37850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t words = (int32_t)(((sizeof(int32_t) + (capacity + 1) * U_SIZEOF_UCHAR + 15) & ~15) >> 2); 379b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t *array = (int32_t*) uprv_malloc( sizeof(int32_t) * words ); 380b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(array != 0) { 381b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // set initial refCount and point behind the refCount 382b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *array++ = 1; 383b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 384b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // have fArray point to the first UChar 385c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru fUnion.fFields.fArray = (UChar *)array; 386c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru fUnion.fFields.fCapacity = (int32_t)((words - 1) * (sizeof(int32_t) / U_SIZEOF_UCHAR)); 387b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFlags = kLongString; 388b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 389c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru fShortLength = 0; 390c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru fUnion.fFields.fArray = 0; 391c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru fUnion.fFields.fCapacity = 0; 392b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFlags = kIsBogus; 393b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return FALSE; 394b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 395b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 396b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return TRUE; 397b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 398b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 399b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//======================================== 400b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Destructor 401b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//======================================== 402b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::~UnicodeString() 403b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 404b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru releaseArray(); 405b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 406b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 407b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru//======================================== 408b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru// Factory methods 409b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru//======================================== 410b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 411b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruUnicodeString UnicodeString::fromUTF8(const StringPiece &utf8) { 412b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru UnicodeString result; 413b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru result.setToUTF8(utf8); 414b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return result; 415b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru} 416b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 417b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruUnicodeString UnicodeString::fromUTF32(const UChar32 *utf32, int32_t length) { 418b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru UnicodeString result; 419b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int32_t capacity; 420b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // Most UTF-32 strings will be BMP-only and result in a same-length 421b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // UTF-16 string. We overestimate the capacity just slightly, 422b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // just in case there are a few supplementary characters. 423b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if(length <= US_STACKBUF_SIZE) { 424b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru capacity = US_STACKBUF_SIZE; 425b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } else { 426b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru capacity = length + (length >> 4) + 4; 427b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 428b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru do { 429b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru UChar *utf16 = result.getBuffer(capacity); 430b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int32_t length16; 431b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru UErrorCode errorCode = U_ZERO_ERROR; 432b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru u_strFromUTF32WithSub(utf16, result.getCapacity(), &length16, 433b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru utf32, length, 434b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 0xfffd, // Substitution character. 435b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru NULL, // Don't care about number of substitutions. 436b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru &errorCode); 437b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru result.releaseBuffer(length16); 438b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if(errorCode == U_BUFFER_OVERFLOW_ERROR) { 439b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru capacity = length16 + 1; // +1 for the terminating NUL. 440b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru continue; 441b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } else if(U_FAILURE(errorCode)) { 442b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru result.setToBogus(); 443b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 444b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru break; 445b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } while(TRUE); 446b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return result; 447b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru} 448b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 449b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//======================================== 450b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Assignment 451b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//======================================== 452b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 453b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString & 454b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::operator=(const UnicodeString &src) { 455b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return copyFrom(src); 456b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 457b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 458b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString & 459b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::fastCopyFrom(const UnicodeString &src) { 460b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return copyFrom(src, TRUE); 461b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 462b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 463b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString & 464b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::copyFrom(const UnicodeString &src, UBool fastCopy) { 465b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // if assigning to ourselves, do nothing 466b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(this == 0 || this == &src) { 467b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return *this; 468b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 469b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 470b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // is the right side bogus? 471b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(&src == 0 || src.isBogus()) { 472b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru setToBogus(); 473b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return *this; 474b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 475b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 476b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // delete the current contents 477b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru releaseArray(); 478b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 479c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if(src.isEmpty()) { 480b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // empty string - use the stack buffer 481c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru setToEmpty(); 482b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return *this; 483b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 484b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 485c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru // we always copy the length 486c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru int32_t srcLength = src.length(); 487c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru setLength(srcLength); 488c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru 489b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // fLength>0 and not an "open" src.getBuffer(minCapacity) 490b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru switch(src.fFlags) { 491b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case kShortString: 492b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // short string using the stack buffer, do the same 493b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFlags = kShortString; 49450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uprv_memcpy(fUnion.fStackBuffer, src.fUnion.fStackBuffer, srcLength * U_SIZEOF_UCHAR); 495b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 496b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case kLongString: 497b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // src uses a refCounted string buffer, use that buffer with refCount 498b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // src is const, use a cast - we don't really change it 499b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ((UnicodeString &)src).addRef(); 500b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // copy all fields, share the reference-counted buffer 501c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru fUnion.fFields.fArray = src.fUnion.fFields.fArray; 502c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru fUnion.fFields.fCapacity = src.fUnion.fFields.fCapacity; 503b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFlags = src.fFlags; 504b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 505b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case kReadonlyAlias: 506b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(fastCopy) { 507b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // src is a readonly alias, do the same 508b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // -> maintain the readonly alias as such 509c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru fUnion.fFields.fArray = src.fUnion.fFields.fArray; 510c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru fUnion.fFields.fCapacity = src.fUnion.fFields.fCapacity; 511b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFlags = src.fFlags; 512b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 513b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 514b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // else if(!fastCopy) fall through to case kWritableAlias 515b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // -> allocate a new buffer and copy the contents 516b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case kWritableAlias: 517b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // src is a writable alias; we make a copy of that instead 518c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if(allocate(srcLength)) { 519c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru uprv_memcpy(getArrayStart(), src.getArrayStart(), srcLength * U_SIZEOF_UCHAR); 520b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 521b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 522b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // if there is not enough memory, then fall through to setting to bogus 523b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru default: 524b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // if src is bogus, set ourselves to bogus 525b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // do not call setToBogus() here because fArray and fFlags are not consistent here 526c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru fShortLength = 0; 527c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru fUnion.fFields.fArray = 0; 528c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru fUnion.fFields.fCapacity = 0; 529b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFlags = kIsBogus; 530b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 531b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 532b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 533b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return *this; 534b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 535b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 536b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//======================================== 537b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Miscellaneous operations 538b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//======================================== 539b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 540b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString UnicodeString::unescape() const { 541c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru UnicodeString result(length(), (UChar32)0, (int32_t)0); // construct with capacity 542c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru const UChar *array = getBuffer(); 543c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru int32_t len = length(); 544c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru int32_t prev = 0; 545c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru for (int32_t i=0;;) { 546c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if (i == len) { 547c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru result.append(array, prev, len - prev); 548c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru break; 549c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } 550c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if (array[i++] == 0x5C /*'\\'*/) { 551c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru result.append(array, prev, (i - 1) - prev); 552c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru UChar32 c = unescapeAt(i); // advances i 553c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if (c < 0) { 554b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru result.remove(); // return empty string 555b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; // invalid escape sequence 556b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 557c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru result.append(c); 558c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru prev = i; 559b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 560b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 561b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return result; 562b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 563b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 564b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUChar32 UnicodeString::unescapeAt(int32_t &offset) const { 565b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return u_unescapeAt(UnicodeString_charAt, &offset, length(), (void*)this); 566b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 567b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 568b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//======================================== 569b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Read-only implementation 570b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//======================================== 57154dcd9b6a06071f647dac967e9e267abb9410720Craig CorneliusUBool 57254dcd9b6a06071f647dac967e9e267abb9410720Craig CorneliusUnicodeString::doEquals(const UnicodeString &text, int32_t len) const { 57354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius // Requires: this & text not bogus and have same lengths. 57454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius // Byte-wise comparison works for equality regardless of endianness. 57554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius return uprv_memcmp(getArrayStart(), text.getArrayStart(), len * U_SIZEOF_UCHAR) == 0; 57654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius} 57754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius 578b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint8_t 579b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::doCompare( int32_t start, 580b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t length, 581b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const UChar *srcChars, 582b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t srcStart, 583b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t srcLength) const 584b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 585b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // compare illegal string values 586b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(isBogus()) { 587b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 588b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 589b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 590b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // pin indices to legal values 591b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pinIndices(start, length); 592b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 593b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(srcChars == NULL) { 594103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // treat const UChar *srcChars==NULL as an empty string 595103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return length == 0 ? 0 : 1; 596b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 597b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 598b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // get the correct pointer 599b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const UChar *chars = getArrayStart(); 600b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 601b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru chars += start; 602b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru srcChars += srcStart; 603b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 604b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t minLength; 605b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int8_t lengthResult; 606b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 607b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // get the srcLength if necessary 608b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(srcLength < 0) { 609b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru srcLength = u_strlen(srcChars + srcStart); 610b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 611b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 612b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // are we comparing different lengths? 613b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(length != srcLength) { 614b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(length < srcLength) { 615b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru minLength = length; 616b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru lengthResult = -1; 617b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 618b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru minLength = srcLength; 619b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru lengthResult = 1; 620b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 621b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 622b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru minLength = length; 623b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru lengthResult = 0; 624b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 625b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 626b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 627b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * note that uprv_memcmp() returns an int but we return an int8_t; 628b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * we need to take care not to truncate the result - 629b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * one way to do this is to right-shift the value to 630b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * move the sign bit into the lower 8 bits and making sure that this 631b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * does not become 0 itself 632b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 633b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 634b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(minLength > 0 && chars != srcChars) { 635b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t result; 636b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 637b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru# if U_IS_BIG_ENDIAN 638b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // big-endian: byte comparison works 639b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru result = uprv_memcmp(chars, srcChars, minLength * sizeof(UChar)); 640b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(result != 0) { 641b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return (int8_t)(result >> 15 | 1); 642b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 643b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru# else 644b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // little-endian: compare UChar units 645b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru do { 646b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru result = ((int32_t)*(chars++) - (int32_t)*(srcChars++)); 647b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(result != 0) { 648b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return (int8_t)(result >> 15 | 1); 649b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 650b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } while(--minLength > 0); 651b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru# endif 652b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 653b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return lengthResult; 654b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 655b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 656b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* String compare in code point order - doCompare() compares in code unit order. */ 657b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint8_t 658b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::doCompareCodePointOrder(int32_t start, 659b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t length, 660b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const UChar *srcChars, 661b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t srcStart, 662b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t srcLength) const 663b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 664b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // compare illegal string values 665b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // treat const UChar *srcChars==NULL as an empty string 666b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(isBogus()) { 667b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 668b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 669b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 670b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // pin indices to legal values 671b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pinIndices(start, length); 672b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 673b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(srcChars == NULL) { 674b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru srcStart = srcLength = 0; 675b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 676b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 677103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t diff = uprv_strCompare(getArrayStart() + start, length, (srcChars!=NULL)?(srcChars + srcStart):NULL, srcLength, FALSE, TRUE); 678b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* translate the 32-bit result into an 8-bit one */ 679b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(diff!=0) { 680b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return (int8_t)(diff >> 15 | 1); 681b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 682b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 683b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 684b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 685b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 686b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t 687b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::getLength() const { 688b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return length(); 689b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 690b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 691b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUChar 692b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::getCharAt(int32_t offset) const { 693b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return charAt(offset); 694b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 695b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 696b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUChar32 697b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::getChar32At(int32_t offset) const { 698b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return char32At(offset); 699b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 700b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 701103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusUChar32 702103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusUnicodeString::char32At(int32_t offset) const 703103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius{ 704103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t len = length(); 705103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if((uint32_t)offset < (uint32_t)len) { 706103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius const UChar *array = getArrayStart(); 707103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius UChar32 c; 708103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius U16_GET(array, 0, offset, len, c); 709103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return c; 710103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } else { 711103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return kInvalidUChar; 712103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 713103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius} 714103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 715103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusint32_t 716103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusUnicodeString::getChar32Start(int32_t offset) const { 717103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if((uint32_t)offset < (uint32_t)length()) { 718103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius const UChar *array = getArrayStart(); 719103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius U16_SET_CP_START(array, 0, offset); 720103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return offset; 721103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } else { 722103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return 0; 723103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 724103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius} 725103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 726103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusint32_t 727103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusUnicodeString::getChar32Limit(int32_t offset) const { 728103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t len = length(); 729103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if((uint32_t)offset < (uint32_t)len) { 730103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius const UChar *array = getArrayStart(); 731103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius U16_SET_CP_LIMIT(array, 0, offset, len); 732103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return offset; 733103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } else { 734103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return len; 735103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 736103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius} 737103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 738b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t 739b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::countChar32(int32_t start, int32_t length) const { 740b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pinIndices(start, length); 741b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // if(isBogus()) then fArray==0 and start==0 - u_countChar32() checks for NULL 742c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru return u_countChar32(getArrayStart()+start, length); 743b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 744b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 745b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUBool 746b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::hasMoreChar32Than(int32_t start, int32_t length, int32_t number) const { 747b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pinIndices(start, length); 748b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // if(isBogus()) then fArray==0 and start==0 - u_strHasMoreChar32Than() checks for NULL 749c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru return u_strHasMoreChar32Than(getArrayStart()+start, length, number); 750b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 751b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 752b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t 753b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::moveIndex32(int32_t index, int32_t delta) const { 754b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // pin index 755c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru int32_t len = length(); 756b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(index<0) { 757b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru index=0; 758c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } else if(index>len) { 759c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru index=len; 760b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 761b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 762c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru const UChar *array = getArrayStart(); 763b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(delta>0) { 764103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius U16_FWD_N(array, index, len, delta); 765b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 766103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius U16_BACK_N(array, 0, index, -delta); 767b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 768b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 769b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return index; 770b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 771b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 772b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid 773b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::doExtract(int32_t start, 774b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t length, 775b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UChar *dst, 776b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t dstStart) const 777b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 778b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // pin indices to legal values 779b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pinIndices(start, length); 780b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 781b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // do not copy anything if we alias dst itself 782c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru const UChar *array = getArrayStart(); 783c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if(array + start != dst + dstStart) { 784c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru us_arrayCopy(array, start, dst, dstStart, length); 785b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 786b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 787b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 788b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t 789b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::extract(UChar *dest, int32_t destCapacity, 790b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode &errorCode) const { 791c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru int32_t len = length(); 792b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(U_SUCCESS(errorCode)) { 793b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(isBogus() || destCapacity<0 || (destCapacity>0 && dest==0)) { 794b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru errorCode=U_ILLEGAL_ARGUMENT_ERROR; 795b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 796c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru const UChar *array = getArrayStart(); 797c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if(len>0 && len<=destCapacity && array!=dest) { 798c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru uprv_memcpy(dest, array, len*U_SIZEOF_UCHAR); 799b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 800c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru return u_terminateUChars(dest, destCapacity, len, &errorCode); 801b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 802b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 803b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 804c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru return len; 805b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 806b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 807b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t 808b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::extract(int32_t start, 809b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t length, 810b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char *target, 811b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t targetCapacity, 812b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru enum EInvariant) const 813b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 814b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // if the arguments are illegal, then do nothing 815b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(targetCapacity < 0 || (targetCapacity > 0 && target == NULL)) { 816b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 817b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 818b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 819b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // pin the indices to legal values 820b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pinIndices(start, length); 821b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 822b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(length <= targetCapacity) { 823b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru u_UCharsToChars(getArrayStart() + start, target, length); 824b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 825b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode status = U_ZERO_ERROR; 826b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return u_terminateChars(target, targetCapacity, length, &status); 827b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 828b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 82950294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoUnicodeString 83050294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoUnicodeString::tempSubString(int32_t start, int32_t len) const { 83150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho pinIndices(start, len); 83250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const UChar *array = getBuffer(); // not getArrayStart() to check kIsBogus & kOpenGetBuffer 83350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(array==NULL) { 83450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho array=fUnion.fStackBuffer; // anything not NULL because that would make an empty string 83550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho len=-2; // bogus result string 83650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 83750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return UnicodeString(FALSE, array + start, len); 83850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 83950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 840b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queruint32_t 841b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruUnicodeString::toUTF8(int32_t start, int32_t len, 842b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru char *target, int32_t capacity) const { 843b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru pinIndices(start, len); 844b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int32_t length8; 845b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru UErrorCode errorCode = U_ZERO_ERROR; 846b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru u_strToUTF8WithSub(target, capacity, &length8, 847b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru getBuffer() + start, len, 848b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 0xFFFD, // Standard substitution character. 849b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru NULL, // Don't care about number of substitutions. 850b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru &errorCode); 851b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return length8; 852b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru} 853b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 854b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#if U_CHARSET_IS_UTF8 855b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 856b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queruint32_t 857b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruUnicodeString::extract(int32_t start, int32_t len, 858b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru char *target, uint32_t dstSize) const { 859b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // if the arguments are illegal, then do nothing 860b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if(/*dstSize < 0 || */(dstSize > 0 && target == 0)) { 861b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return 0; 862b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 863b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return toUTF8(start, len, target, dstSize <= 0x7fffffff ? (int32_t)dstSize : 0x7fffffff); 864b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru} 865b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 866b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru// else see unistr_cnv.cpp 867b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#endif 868b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 869b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid 870b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::extractBetween(int32_t start, 871b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t limit, 872b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UnicodeString& target) const { 873b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pinIndex(start); 874b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pinIndex(limit); 875b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru doExtract(start, limit - start, target); 876b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 877b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 878b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru// When converting from UTF-16 to UTF-8, the result will have at most 3 times 879b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru// as many bytes as the source has UChars. 880b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru// The "worst cases" are writing systems like Indic, Thai and CJK with 881b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru// 3:1 bytes:UChars. 882b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queruvoid 883b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruUnicodeString::toUTF8(ByteSink &sink) const { 884b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int32_t length16 = length(); 885b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if(length16 != 0) { 886b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru char stackBuffer[1024]; 887b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int32_t capacity = (int32_t)sizeof(stackBuffer); 888b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru UBool utf8IsOwned = FALSE; 889b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru char *utf8 = sink.GetAppendBuffer(length16 < capacity ? length16 : capacity, 890b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 3*length16, 891b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru stackBuffer, capacity, 892b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru &capacity); 893b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int32_t length8 = 0; 894b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru UErrorCode errorCode = U_ZERO_ERROR; 895b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru u_strToUTF8WithSub(utf8, capacity, &length8, 896b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru getBuffer(), length16, 897b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 0xFFFD, // Standard substitution character. 898b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru NULL, // Don't care about number of substitutions. 899b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru &errorCode); 900b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if(errorCode == U_BUFFER_OVERFLOW_ERROR) { 901b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru utf8 = (char *)uprv_malloc(length8); 902b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if(utf8 != NULL) { 903b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru utf8IsOwned = TRUE; 904b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru errorCode = U_ZERO_ERROR; 905b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru u_strToUTF8WithSub(utf8, length8, &length8, 906b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru getBuffer(), length16, 907b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 0xFFFD, // Standard substitution character. 908b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru NULL, // Don't care about number of substitutions. 909b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru &errorCode); 910b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } else { 911b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru errorCode = U_MEMORY_ALLOCATION_ERROR; 912b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 913b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 914b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if(U_SUCCESS(errorCode)) { 915b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru sink.Append(utf8, length8); 91627f654740f2a26ad62a5c155af9199af9e69b889claireho sink.Flush(); 917b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 918b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if(utf8IsOwned) { 919b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru uprv_free(utf8); 920b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 921b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 922b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru} 923b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 924b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queruint32_t 925b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruUnicodeString::toUTF32(UChar32 *utf32, int32_t capacity, UErrorCode &errorCode) const { 926b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int32_t length32=0; 927b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if(U_SUCCESS(errorCode)) { 928b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // getBuffer() and u_strToUTF32WithSub() check for illegal arguments. 929b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru u_strToUTF32WithSub(utf32, capacity, &length32, 930b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru getBuffer(), length(), 931b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 0xfffd, // Substitution character. 932b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru NULL, // Don't care about number of substitutions. 933b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru &errorCode); 934b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 935b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return length32; 936b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru} 937b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 938b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t 939b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::indexOf(const UChar *srcChars, 940b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t srcStart, 941b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t srcLength, 942b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t start, 943b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t length) const 944b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 945b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(isBogus() || srcChars == 0 || srcStart < 0 || srcLength == 0) { 946b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 947b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 948b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 949b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // UnicodeString does not find empty substrings 950b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(srcLength < 0 && srcChars[srcStart] == 0) { 951b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 952b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 953b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 954b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // get the indices within bounds 955b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pinIndices(start, length); 956b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 957b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // find the first occurrence of the substring 958c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru const UChar *array = getArrayStart(); 959c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru const UChar *match = u_strFindFirst(array + start, length, srcChars + srcStart, srcLength); 960b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(match == NULL) { 961b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 962b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 963c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru return (int32_t)(match - array); 964b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 965b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 966b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 967b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t 968b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::doIndexOf(UChar c, 969b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t start, 970b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t length) const 971b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 972b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // pin indices 973b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pinIndices(start, length); 974b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 975b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // find the first occurrence of c 976c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru const UChar *array = getArrayStart(); 977c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru const UChar *match = u_memchr(array + start, c, length); 978b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(match == NULL) { 979b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 980b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 981c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru return (int32_t)(match - array); 982b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 983b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 984b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 985b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t 986b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::doIndexOf(UChar32 c, 987b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t start, 988b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t length) const { 989b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // pin indices 990b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pinIndices(start, length); 991b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 992b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // find the first occurrence of c 993c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru const UChar *array = getArrayStart(); 994c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru const UChar *match = u_memchr32(array + start, c, length); 995b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(match == NULL) { 996b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 997b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 998c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru return (int32_t)(match - array); 999b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1000b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1001b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1002b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t 1003b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::lastIndexOf(const UChar *srcChars, 1004b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t srcStart, 1005b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t srcLength, 1006b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t start, 1007b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t length) const 1008b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1009b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(isBogus() || srcChars == 0 || srcStart < 0 || srcLength == 0) { 1010b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 1011b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1012b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1013b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // UnicodeString does not find empty substrings 1014b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(srcLength < 0 && srcChars[srcStart] == 0) { 1015b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 1016b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1017b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1018b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // get the indices within bounds 1019b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pinIndices(start, length); 1020b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1021b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // find the last occurrence of the substring 1022c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru const UChar *array = getArrayStart(); 1023c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru const UChar *match = u_strFindLast(array + start, length, srcChars + srcStart, srcLength); 1024b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(match == NULL) { 1025b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 1026b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1027c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru return (int32_t)(match - array); 1028b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1029b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1030b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1031b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t 1032b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::doLastIndexOf(UChar c, 1033b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t start, 1034b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t length) const 1035b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1036b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(isBogus()) { 1037b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 1038b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1039b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1040b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // pin indices 1041b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pinIndices(start, length); 1042b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1043b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // find the last occurrence of c 1044c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru const UChar *array = getArrayStart(); 1045c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru const UChar *match = u_memrchr(array + start, c, length); 1046b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(match == NULL) { 1047b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 1048b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1049c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru return (int32_t)(match - array); 1050b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1051b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1052b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1053b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t 1054b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::doLastIndexOf(UChar32 c, 1055b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t start, 1056b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t length) const { 1057b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // pin indices 1058b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pinIndices(start, length); 1059b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1060b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // find the last occurrence of c 1061c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru const UChar *array = getArrayStart(); 1062c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru const UChar *match = u_memrchr32(array + start, c, length); 1063b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(match == NULL) { 1064b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 1065b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1066c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru return (int32_t)(match - array); 1067b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1068b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1069b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1070b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//======================================== 1071b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Write implementation 1072b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//======================================== 1073b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1074b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString& 1075b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::findAndReplace(int32_t start, 1076b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t length, 1077b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const UnicodeString& oldText, 1078b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t oldStart, 1079b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t oldLength, 1080b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const UnicodeString& newText, 1081b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t newStart, 1082b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t newLength) 1083b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1084b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(isBogus() || oldText.isBogus() || newText.isBogus()) { 1085b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return *this; 1086b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1087b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1088b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pinIndices(start, length); 1089b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru oldText.pinIndices(oldStart, oldLength); 1090b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru newText.pinIndices(newStart, newLength); 1091b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1092b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(oldLength == 0) { 1093b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return *this; 1094b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1095b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1096b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(length > 0 && length >= oldLength) { 1097b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t pos = indexOf(oldText, oldStart, oldLength, start, length); 1098b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(pos < 0) { 1099b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // no more oldText's here: done 1100b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1101b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1102b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // we found oldText, replace it by newText and go beyond it 1103b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru replace(pos, oldLength, newText, newStart, newLength); 1104b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru length -= pos + oldLength - start; 1105b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru start = pos + newLength; 1106b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1107b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1108b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1109b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return *this; 1110b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1111b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1112b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1113b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid 1114b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::setToBogus() 1115b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1116b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru releaseArray(); 1117b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1118c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru fShortLength = 0; 1119c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru fUnion.fFields.fArray = 0; 1120c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru fUnion.fFields.fCapacity = 0; 1121b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFlags = kIsBogus; 1122b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1123b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1124b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// turn a bogus string into an empty one 1125b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid 1126b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::unBogus() { 1127b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(fFlags & kIsBogus) { 1128c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru setToEmpty(); 1129b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1130b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1131b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1132b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// setTo() analogous to the readonly-aliasing constructor with the same signature 1133b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString & 1134b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::setTo(UBool isTerminated, 1135b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const UChar *text, 1136b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t textLength) 1137b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1138b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(fFlags & kOpenGetBuffer) { 1139b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // do not modify a string that has an "open" getBuffer(minCapacity) 1140b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return *this; 1141b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1142b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1143b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(text == NULL) { 1144b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // treat as an empty string, do not alias 1145b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru releaseArray(); 1146c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru setToEmpty(); 1147b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return *this; 1148b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1149b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1150b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if( textLength < -1 || 1151b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (textLength == -1 && !isTerminated) || 1152b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (textLength >= 0 && isTerminated && text[textLength] != 0) 1153b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ) { 1154b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru setToBogus(); 1155b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return *this; 1156b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1157b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1158b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru releaseArray(); 1159b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1160c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if(textLength == -1) { 1161b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // text is terminated, or else it would have failed the above test 1162c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru textLength = u_strlen(text); 1163b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1164c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru setArray((UChar *)text, textLength, isTerminated ? textLength + 1 : textLength); 1165b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1166b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFlags = kReadonlyAlias; 1167b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return *this; 1168b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1169b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1170b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// setTo() analogous to the writable-aliasing constructor with the same signature 1171b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString & 1172b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::setTo(UChar *buffer, 1173b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t buffLength, 1174b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t buffCapacity) { 1175b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(fFlags & kOpenGetBuffer) { 1176b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // do not modify a string that has an "open" getBuffer(minCapacity) 1177b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return *this; 1178b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1179b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1180b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(buffer == NULL) { 1181b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // treat as an empty string, do not alias 1182b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru releaseArray(); 1183c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru setToEmpty(); 1184b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return *this; 1185b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1186b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1187b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(buffLength < -1 || buffCapacity < 0 || buffLength > buffCapacity) { 1188b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru setToBogus(); 1189b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return *this; 1190b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else if(buffLength == -1) { 1191b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // buffLength = u_strlen(buff); but do not look beyond buffCapacity 1192b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const UChar *p = buffer, *limit = buffer + buffCapacity; 1193b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(p != limit && *p != 0) { 1194b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++p; 1195b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1196b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru buffLength = (int32_t)(p - buffer); 1197b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1198b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1199b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru releaseArray(); 1200b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1201c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru setArray(buffer, buffLength, buffCapacity); 1202b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFlags = kWritableAlias; 1203b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return *this; 1204b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1205b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1206b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruUnicodeString &UnicodeString::setToUTF8(const StringPiece &utf8) { 1207b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru unBogus(); 1208b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int32_t length = utf8.length(); 1209b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int32_t capacity; 1210b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // The UTF-16 string will be at most as long as the UTF-8 string. 1211b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if(length <= US_STACKBUF_SIZE) { 1212b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru capacity = US_STACKBUF_SIZE; 1213b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } else { 1214b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru capacity = length + 1; // +1 for the terminating NUL. 1215b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 1216b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru UChar *utf16 = getBuffer(capacity); 1217b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int32_t length16; 1218b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru UErrorCode errorCode = U_ZERO_ERROR; 1219b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru u_strFromUTF8WithSub(utf16, getCapacity(), &length16, 1220b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru utf8.data(), length, 1221b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 0xfffd, // Substitution character. 1222b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru NULL, // Don't care about number of substitutions. 1223b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru &errorCode); 1224b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru releaseBuffer(length16); 1225b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if(U_FAILURE(errorCode)) { 1226b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru setToBogus(); 1227b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 1228b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return *this; 1229b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru} 1230b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 1231b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString& 1232b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::setCharAt(int32_t offset, 1233b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UChar c) 1234b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1235c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru int32_t len = length(); 1236c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if(cloneArrayIfNeeded() && len > 0) { 1237b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(offset < 0) { 1238b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru offset = 0; 1239c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } else if(offset >= len) { 1240c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru offset = len - 1; 1241b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1242b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1243c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru getArrayStart()[offset] = c; 1244b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1245b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return *this; 1246b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1247b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1248b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString& 1249103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusUnicodeString::replace(int32_t start, 1250103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t _length, 1251103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius UChar32 srcChar) { 1252103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius UChar buffer[U16_MAX_LENGTH]; 1253103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t count = 0; 1254103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius UBool isError = FALSE; 1255103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius U16_APPEND(buffer, count, U16_MAX_LENGTH, srcChar, isError); 1256103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // We test isError so that the compiler does not complain that we don't. 125754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius // If isError (srcChar is not a valid code point) then count==0 which means 125854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius // we remove the source segment rather than replacing it with srcChar. 125954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius return doReplace(start, _length, buffer, 0, isError ? 0 : count); 1260103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius} 1261103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 1262103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusUnicodeString& 1263103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusUnicodeString::append(UChar32 srcChar) { 1264103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius UChar buffer[U16_MAX_LENGTH]; 1265103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t _length = 0; 1266103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius UBool isError = FALSE; 1267103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius U16_APPEND(buffer, _length, U16_MAX_LENGTH, srcChar, isError); 1268103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // We test isError so that the compiler does not complain that we don't. 1269103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // If isError then _length==0 which turns the doReplace() into a no-op anyway. 1270103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return isError ? *this : doReplace(length(), 0, buffer, 0, _length); 1271103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius} 1272103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 1273103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusUnicodeString& 1274b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::doReplace( int32_t start, 1275b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t length, 1276b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const UnicodeString& src, 1277b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t srcStart, 1278b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t srcLength) 1279b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1280b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(!src.isBogus()) { 1281b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // pin the indices to legal values 1282b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru src.pinIndices(srcStart, srcLength); 1283b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1284b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // get the characters from src 1285b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // and replace the range in ourselves with them 1286b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return doReplace(start, length, src.getArrayStart(), srcStart, srcLength); 1287b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1288b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // remove the range 1289b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return doReplace(start, length, 0, 0, 0); 1290b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1291b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1292b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1293b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString& 1294b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::doReplace(int32_t start, 1295b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t length, 1296b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const UChar *srcChars, 1297b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t srcStart, 1298b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t srcLength) 1299b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1300c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if(!isWritable()) { 1301b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return *this; 1302b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1303b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 130450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t oldLength = this->length(); 130550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 130650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // optimize (read-only alias).remove(0, start) and .remove(start, end) 130750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if((fFlags&kBufferIsReadonly) && srcLength == 0) { 130850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(start == 0) { 130950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // remove prefix by adjusting the array pointer 131050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho pinIndex(length); 131150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho fUnion.fFields.fArray += length; 131250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho fUnion.fFields.fCapacity -= length; 131350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho setLength(oldLength - length); 131450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return *this; 131550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } else { 131650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho pinIndex(start); 131750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(length >= (oldLength - start)) { 131850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // remove suffix by reducing the length (like truncate()) 131950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho setLength(start); 132050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho fUnion.fFields.fCapacity = start; // not NUL-terminated any more 132150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return *this; 132250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 132350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 132450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 132550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 1326b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(srcChars == 0) { 1327b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru srcStart = srcLength = 0; 1328b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else if(srcLength < 0) { 1329b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // get the srcLength if necessary 1330b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru srcLength = u_strlen(srcChars + srcStart); 1331b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1332b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1333c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru // calculate the size of the string after the replace 1334b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t newLength; 1335c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru 1336c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru // optimize append() onto a large-enough, owned string 1337c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if(start >= oldLength) { 1338103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if(srcLength == 0) { 1339103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return *this; 1340103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 1341b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho newLength = oldLength + srcLength; 1342b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if(newLength <= getCapacity() && isBufferWritable()) { 1343b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UChar *oldArray = getArrayStart(); 1344b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Do not copy characters when 1345b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // UChar *buffer=str.getAppendBuffer(...); 1346b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // is followed by 1347b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // str.append(buffer, length); 1348b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // or 1349b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // str.appendString(buffer, length) 1350b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // or similar. 1351b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if(srcChars + srcStart != oldArray + start || start > oldLength) { 1352b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho us_arrayCopy(srcChars, srcStart, oldArray, oldLength, srcLength); 1353b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1354b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho setLength(newLength); 1355c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru return *this; 1356c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } else { 1357c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru // pin the indices to legal values 1358c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru start = oldLength; 1359c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru length = 0; 1360c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } 1361c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } else { 1362c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru // pin the indices to legal values 1363c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru pinIndices(start, length); 1364b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1365b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho newLength = oldLength - length + srcLength; 1366c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } 1367b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1368c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru // the following may change fArray but will not copy the current contents; 1369c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru // therefore we need to keep the current fArray 1370c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru UChar oldStackBuffer[US_STACKBUF_SIZE]; 1371c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru UChar *oldArray; 1372b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if((fFlags&kUsingStackBuffer) && (newLength > US_STACKBUF_SIZE)) { 1373c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru // copy the stack buffer contents because it will be overwritten with 1374c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru // fUnion.fFields values 1375c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru u_memcpy(oldStackBuffer, fUnion.fStackBuffer, oldLength); 1376c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru oldArray = oldStackBuffer; 1377c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } else { 1378c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru oldArray = getArrayStart(); 1379c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } 1380b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1381b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // clone our array and allocate a bigger array if needed 1382c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru int32_t *bufferToDelete = 0; 1383b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if(!cloneArrayIfNeeded(newLength, newLength + (newLength >> 2) + kGrowSize, 1384b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, &bufferToDelete) 1385b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ) { 1386b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return *this; 1387b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1388b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1389b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // now do the replace 1390b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1391c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru UChar *newArray = getArrayStart(); 1392c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if(newArray != oldArray) { 1393b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // if fArray changed, then we need to copy everything except what will change 1394c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru us_arrayCopy(oldArray, 0, newArray, 0, start); 1395b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru us_arrayCopy(oldArray, start + length, 1396c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru newArray, start + srcLength, 1397b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru oldLength - (start + length)); 1398b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else if(length != srcLength) { 1399b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // fArray did not change; copy only the portion that isn't changing, leaving a hole 1400b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru us_arrayCopy(oldArray, start + length, 1401c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru newArray, start + srcLength, 1402b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru oldLength - (start + length)); 1403b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1404b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1405b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // now fill in the hole with the new string 1406c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru us_arrayCopy(srcChars, srcStart, newArray, start, srcLength); 1407b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1408b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho setLength(newLength); 1409b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1410b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // delayed delete in case srcChars == fArray when we started, and 1411b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // to keep oldArray alive for the above operations 1412b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (bufferToDelete) { 1413b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_free(bufferToDelete); 1414b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1415b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1416b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return *this; 1417b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1418b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1419b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/** 1420b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Replaceable API 1421b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 1422b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid 1423b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::handleReplaceBetween(int32_t start, 1424b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t limit, 1425b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const UnicodeString& text) { 1426b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru replaceBetween(start, limit, text); 1427b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1428b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1429b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/** 1430b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Replaceable API 1431b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 1432b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid 1433b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::copy(int32_t start, int32_t limit, int32_t dest) { 1434b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (limit <= start) { 1435b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; // Nothing to do; avoid bogus malloc call 1436b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1437b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UChar* text = (UChar*) uprv_malloc( sizeof(UChar) * (limit - start) ); 1438c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru // Check to make sure text is not null. 1439c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if (text != NULL) { 1440c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru extractBetween(start, limit, text, 0); 1441c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru insert(dest, text, 0, limit - start); 1442c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru uprv_free(text); 1443c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } 1444b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1445b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1446b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/** 1447b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Replaceable API 1448b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 1449b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * NOTE: This is for the Replaceable class. There is no rep.cpp, 1450b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * so we implement this function here. 1451b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 1452b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUBool Replaceable::hasMetaData() const { 1453b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return TRUE; 1454b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1455b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1456b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/** 1457b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Replaceable API 1458b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 1459b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUBool UnicodeString::hasMetaData() const { 1460b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return FALSE; 1461b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1462b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1463b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString& 146427f654740f2a26ad62a5c155af9199af9e69b889clairehoUnicodeString::doReverse(int32_t start, int32_t length) { 146527f654740f2a26ad62a5c155af9199af9e69b889claireho if(length <= 1 || !cloneArrayIfNeeded()) { 1466b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return *this; 1467b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1468b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1469b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // pin the indices to legal values 1470b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pinIndices(start, length); 147127f654740f2a26ad62a5c155af9199af9e69b889claireho if(length <= 1) { // pinIndices() might have shrunk the length 147227f654740f2a26ad62a5c155af9199af9e69b889claireho return *this; 147327f654740f2a26ad62a5c155af9199af9e69b889claireho } 1474b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1475b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UChar *left = getArrayStart() + start; 147627f654740f2a26ad62a5c155af9199af9e69b889claireho UChar *right = left + length - 1; // -1 for inclusive boundary (length>=2) 1477b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UChar swap; 1478b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UBool hasSupplementary = FALSE; 1479b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 148027f654740f2a26ad62a5c155af9199af9e69b889claireho // Before the loop we know left<right because length>=2. 148127f654740f2a26ad62a5c155af9199af9e69b889claireho do { 148227f654740f2a26ad62a5c155af9199af9e69b889claireho hasSupplementary |= (UBool)U16_IS_LEAD(swap = *left); 148327f654740f2a26ad62a5c155af9199af9e69b889claireho hasSupplementary |= (UBool)U16_IS_LEAD(*left++ = *right); 148427f654740f2a26ad62a5c155af9199af9e69b889claireho *right-- = swap; 148527f654740f2a26ad62a5c155af9199af9e69b889claireho } while(left < right); 148627f654740f2a26ad62a5c155af9199af9e69b889claireho // Make sure to test the middle code unit of an odd-length string. 148727f654740f2a26ad62a5c155af9199af9e69b889claireho // Redundant if the length is even. 148827f654740f2a26ad62a5c155af9199af9e69b889claireho hasSupplementary |= (UBool)U16_IS_LEAD(*left); 1489b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1490b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* if there are supplementary code points in the reversed range, then re-swap their surrogates */ 1491b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(hasSupplementary) { 1492b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UChar swap2; 1493b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1494b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru left = getArrayStart() + start; 1495c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru right = left + length - 1; // -1 so that we can look at *(left+1) if left<right 1496b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(left < right) { 149727f654740f2a26ad62a5c155af9199af9e69b889claireho if(U16_IS_TRAIL(swap = *left) && U16_IS_LEAD(swap2 = *(left + 1))) { 1498b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *left++ = swap2; 1499b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *left++ = swap; 1500b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1501b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++left; 1502b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1503b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1504b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1505b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1506b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return *this; 1507b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1508b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1509b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUBool 1510b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::padLeading(int32_t targetLength, 1511b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UChar padChar) 1512b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1513c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru int32_t oldLength = length(); 1514c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if(oldLength >= targetLength || !cloneArrayIfNeeded(targetLength)) { 1515b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return FALSE; 1516b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1517b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // move contents up by padding width 1518c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru UChar *array = getArrayStart(); 1519c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru int32_t start = targetLength - oldLength; 1520c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru us_arrayCopy(array, 0, array, start, oldLength); 1521b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1522b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // fill in padding character 1523b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(--start >= 0) { 1524c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru array[start] = padChar; 1525b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1526c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru setLength(targetLength); 1527b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return TRUE; 1528b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1529b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1530b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1531b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUBool 1532b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::padTrailing(int32_t targetLength, 1533b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UChar padChar) 1534b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1535c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru int32_t oldLength = length(); 1536c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if(oldLength >= targetLength || !cloneArrayIfNeeded(targetLength)) { 1537b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return FALSE; 1538b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1539b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // fill in padding character 1540c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru UChar *array = getArrayStart(); 1541b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t length = targetLength; 1542c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru while(--length >= oldLength) { 1543c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru array[length] = padChar; 1544b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1545c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru setLength(targetLength); 1546b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return TRUE; 1547b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1548b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1549b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1550b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//======================================== 1551b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Hashing 1552b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//======================================== 1553b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t 1554b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::doHashCode() const 1555b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1556b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* Delegate hash computation to uhash. This makes UnicodeString 1557b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * hashing consistent with UChar* hashing. */ 1558103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t hashCode = ustr_hashUCharsN(getArrayStart(), length()); 1559b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (hashCode == kInvalidHashCode) { 1560b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru hashCode = kEmptyHashCode; 1561b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1562b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return hashCode; 1563b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1564b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1565b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//======================================== 1566b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// External Buffer 1567b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//======================================== 1568b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1569b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUChar * 1570b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::getBuffer(int32_t minCapacity) { 1571b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(minCapacity>=-1 && cloneArrayIfNeeded(minCapacity)) { 1572b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFlags|=kOpenGetBuffer; 1573c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru fShortLength=0; 1574c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru return getArrayStart(); 1575b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1576b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 1577b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1578b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1579b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1580b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid 1581b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::releaseBuffer(int32_t newLength) { 1582b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(fFlags&kOpenGetBuffer && newLength>=-1) { 1583b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // set the new fLength 1584c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru int32_t capacity=getCapacity(); 1585b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(newLength==-1) { 1586b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // the new length is the string length, capped by fCapacity 1587c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru const UChar *array=getArrayStart(), *p=array, *limit=array+capacity; 1588b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(p<limit && *p!=0) { 1589b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++p; 1590b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1591c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru newLength=(int32_t)(p-array); 1592c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } else if(newLength>capacity) { 1593c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru newLength=capacity; 1594b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1595c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru setLength(newLength); 1596b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFlags&=~kOpenGetBuffer; 1597b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1598b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1599b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1600b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//======================================== 1601b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Miscellaneous 1602b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//======================================== 1603b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUBool 1604b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::cloneArrayIfNeeded(int32_t newCapacity, 1605b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t growCapacity, 1606b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UBool doCopyArray, 1607b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t **pBufferToDelete, 1608b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UBool forceClone) { 1609b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // default parameters need to be static, therefore 1610b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // the defaults are -1 to have convenience defaults 1611b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(newCapacity == -1) { 1612c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru newCapacity = getCapacity(); 1613b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1614b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1615b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // while a getBuffer(minCapacity) is "open", 1616b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // prevent any modifications of the string by returning FALSE here 1617b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // if the string is bogus, then only an assignment or similar can revive it 1618c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if(!isWritable()) { 1619b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return FALSE; 1620b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1621b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1622b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 1623b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * We need to make a copy of the array if 1624b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * the buffer is read-only, or 1625b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * the buffer is refCounted (shared), and refCount>1, or 1626b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * the buffer is too small. 1627b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Return FALSE if memory could not be allocated. 1628b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 1629b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(forceClone || 1630b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFlags & kBufferIsReadonly || 163127f654740f2a26ad62a5c155af9199af9e69b889claireho (fFlags & kRefCounted && refCount() > 1) || 1632c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru newCapacity > getCapacity() 1633b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ) { 1634b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // check growCapacity for default value and use of the stack buffer 1635103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if(growCapacity < 0) { 1636b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru growCapacity = newCapacity; 1637b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else if(newCapacity <= US_STACKBUF_SIZE && growCapacity > US_STACKBUF_SIZE) { 1638b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru growCapacity = US_STACKBUF_SIZE; 1639b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1640b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1641c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru // save old values 1642c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru UChar oldStackBuffer[US_STACKBUF_SIZE]; 1643c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru UChar *oldArray; 1644c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru uint8_t flags = fFlags; 1645c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru 1646c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if(flags&kUsingStackBuffer) { 1647103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius U_ASSERT(!(flags&kRefCounted)); /* kRefCounted and kUsingStackBuffer are mutally exclusive */ 1648c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if(doCopyArray && growCapacity > US_STACKBUF_SIZE) { 1649c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru // copy the stack buffer contents because it will be overwritten with 1650c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru // fUnion.fFields values 1651c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru us_arrayCopy(fUnion.fStackBuffer, 0, oldStackBuffer, 0, fShortLength); 1652c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru oldArray = oldStackBuffer; 1653c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } else { 1654c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru oldArray = 0; // no need to copy from stack buffer to itself 1655c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } 1656c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } else { 1657c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru oldArray = fUnion.fFields.fArray; 1658103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius U_ASSERT(oldArray!=NULL); /* when stack buffer is not used, oldArray must have a non-NULL reference */ 1659c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } 1660c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru 1661b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // allocate a new array 1662b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(allocate(growCapacity) || 166327f654740f2a26ad62a5c155af9199af9e69b889claireho (newCapacity < growCapacity && allocate(newCapacity)) 1664b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ) { 1665c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if(doCopyArray && oldArray != 0) { 1666b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // copy the contents 1667b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // do not copy more than what fits - it may be smaller than before 1668c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru int32_t minLength = length(); 1669c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru newCapacity = getCapacity(); 1670c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if(newCapacity < minLength) { 1671c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru minLength = newCapacity; 1672c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru setLength(minLength); 1673b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1674c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru us_arrayCopy(oldArray, 0, getArrayStart(), 0, minLength); 1675b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1676c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru fShortLength = 0; 1677b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1678b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1679b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // release the old array 1680b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(flags & kRefCounted) { 1681b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // the array is refCounted; decrement and release if 0 1682c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru int32_t *pRefCount = ((int32_t *)oldArray - 1); 1683b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(umtx_atomic_dec(pRefCount) == 0) { 1684b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(pBufferToDelete == 0) { 1685b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_free(pRefCount); 1686b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1687b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // the caller requested to delete it himself 1688b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *pBufferToDelete = pRefCount; 1689b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1690b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1691b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1692b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1693b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // not enough memory for growCapacity and not even for the smaller newCapacity 1694b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // reset the old values for setToBogus() to release the array 1695c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if(!(flags&kUsingStackBuffer)) { 1696c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru fUnion.fFields.fArray = oldArray; 1697c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } 1698b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFlags = flags; 1699b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru setToBogus(); 1700b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return FALSE; 1701b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1702b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1703b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return TRUE; 1704b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1705b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1706b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// UnicodeStringAppendable ------------------------------------------------- *** 1707b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1708103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusUnicodeStringAppendable::~UnicodeStringAppendable() {} 1709103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 1710b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoUBool 1711b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoUnicodeStringAppendable::appendCodeUnit(UChar c) { 1712b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return str.doReplace(str.length(), 0, &c, 0, 1).isWritable(); 1713b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 1714b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1715b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoUBool 1716b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoUnicodeStringAppendable::appendCodePoint(UChar32 c) { 1717b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UChar buffer[U16_MAX_LENGTH]; 1718b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t cLength = 0; 1719b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UBool isError = FALSE; 1720b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho U16_APPEND(buffer, cLength, U16_MAX_LENGTH, c, isError); 1721b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return !isError && str.doReplace(str.length(), 0, buffer, 0, cLength).isWritable(); 1722b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 1723b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1724b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoUBool 1725b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoUnicodeStringAppendable::appendString(const UChar *s, int32_t length) { 1726b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return str.doReplace(str.length(), 0, s, 0, length).isWritable(); 1727b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 1728b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1729b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoUBool 1730b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoUnicodeStringAppendable::reserveAppendCapacity(int32_t appendCapacity) { 1731b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return str.cloneArrayIfNeeded(str.length() + appendCapacity); 1732b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 1733b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1734b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoUChar * 1735b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoUnicodeStringAppendable::getAppendBuffer(int32_t minCapacity, 1736b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t desiredCapacityHint, 1737b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UChar *scratch, int32_t scratchCapacity, 1738b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t *resultCapacity) { 1739b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if(minCapacity < 1 || scratchCapacity < minCapacity) { 1740b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho *resultCapacity = 0; 1741b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return NULL; 1742b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1743b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t oldLength = str.length(); 1744b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if(str.cloneArrayIfNeeded(oldLength + minCapacity, oldLength + desiredCapacityHint)) { 1745b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho *resultCapacity = str.getCapacity() - oldLength; 1746b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return str.getArrayStart() + oldLength; 1747b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1748b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho *resultCapacity = scratchCapacity; 1749b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return scratch; 1750b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 1751b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1752b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_NAMESPACE_END 1753b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1754103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusU_NAMESPACE_USE 1755103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 1756103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusU_CAPI int32_t U_EXPORT2 1757103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusuhash_hashUnicodeString(const UElement key) { 1758103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius const UnicodeString *str = (const UnicodeString*) key.pointer; 1759103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return (str == NULL) ? 0 : str->hashCode(); 1760103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius} 1761103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 1762103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius// Moved here from uhash_us.cpp so that using a UVector of UnicodeString* 1763103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius// does not depend on hashtable code. 1764103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusU_CAPI UBool U_EXPORT2 1765103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusuhash_compareUnicodeString(const UElement key1, const UElement key2) { 1766103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius const UnicodeString *str1 = (const UnicodeString*) key1.pointer; 1767103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius const UnicodeString *str2 = (const UnicodeString*) key2.pointer; 1768103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (str1 == str2) { 1769103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return TRUE; 1770103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 1771103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (str1 == NULL || str2 == NULL) { 1772103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return FALSE; 1773103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 1774103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return *str1 == *str2; 1775103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius} 1776103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 1777b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#ifdef U_STATIC_IMPLEMENTATION 1778b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* 1779b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruThis should never be called. It is defined here to make sure that the 1780b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvirtual vector deleting destructor is defined within unistr.cpp. 1781b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruThe vector deleting destructor is already a part of UObject, 1782b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querubut defining it here makes sure that it is included with this object file. 1783b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruThis makes sure that static library dependencies are kept to a minimum. 1784b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*/ 1785b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void uprv_UnicodeStringDummy(void) { 1786b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru delete [] (new UnicodeString[2]); 1787b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1788b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 1789