unistr.cpp revision 50294ead5e5d23f5bbfed76e00e6b510bd41eee1
1b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* 2b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru****************************************************************************** 350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho* Copyright (C) 1999-2010, International Business Machines Corporation and * 4b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 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" 22b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/putil.h" 23b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "cstring.h" 24b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "cmemory.h" 25b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/ustring.h" 26b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/unistr.h" 27b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "uhash.h" 28b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "ustr_imp.h" 29b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "umutex.h" 30b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 31b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if 0 32b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 33b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if U_IOSTREAM_SOURCE >= 199711 34b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include <iostream> 35b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruusing namespace std; 36b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#elif U_IOSTREAM_SOURCE >= 198506 37b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include <iostream.h> 38b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 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) { 93b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return ((U_NAMESPACE_QUALIFIER 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() {} 103b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruReplaceable::Replaceable() {} 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//======================================== 150b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::UnicodeString() 151c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru : fShortLength(0), 152b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFlags(kShortString) 153b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{} 154b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 155b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::UnicodeString(int32_t capacity, UChar32 c, int32_t count) 156c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru : fShortLength(0), 157b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFlags(0) 158b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 159b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(count <= 0 || (uint32_t)c > 0x10ffff) { 160b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // just allocate and do not do anything else 161b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru allocate(capacity); 162b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 163b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // count > 0, allocate and fill the new string with count c's 164b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t unitCount = UTF_CHAR_LENGTH(c), length = count * unitCount; 165b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(capacity < length) { 166b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru capacity = length; 167b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 168b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(allocate(capacity)) { 169c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru UChar *array = getArrayStart(); 170b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t i = 0; 171b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 172b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // fill the new string with c 173b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(unitCount == 1) { 174b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // fill with length UChars 175b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(i < length) { 176c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru array[i++] = (UChar)c; 177b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 178b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 179b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // get the code units for c 180b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UChar units[UTF_MAX_CHAR_LENGTH]; 181b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UTF_APPEND_CHAR_UNSAFE(units, i, c); 182b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 183b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // now it must be i==unitCount 184b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru i = 0; 185b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 186b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // for Unicode, unitCount can only be 1, 2, 3, or 4 187b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // 1 is handled above 188b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(i < length) { 189b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t unitIdx = 0; 190b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(unitIdx < unitCount) { 191c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru array[i++]=units[unitIdx++]; 192b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 193b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 194b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 195b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 196c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru setLength(length); 197b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 198b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 199b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 200b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::UnicodeString(UChar ch) 201c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru : fShortLength(1), 202b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFlags(kShortString) 203b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 204c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru fUnion.fStackBuffer[0] = ch; 205b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 206b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 207b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::UnicodeString(UChar32 ch) 208c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru : fShortLength(0), 209b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFlags(kShortString) 210b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 211b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t i = 0; 212b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UBool isError = FALSE; 213c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru U16_APPEND(fUnion.fStackBuffer, i, US_STACKBUF_SIZE, ch, isError); 214c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru fShortLength = (int8_t)i; 215b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 216b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 217b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::UnicodeString(const UChar *text) 218c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru : fShortLength(0), 219b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFlags(kShortString) 220b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 221b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru doReplace(0, 0, text, 0, -1); 222b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 223b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 224b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::UnicodeString(const UChar *text, 225b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t textLength) 226c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru : fShortLength(0), 227b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFlags(kShortString) 228b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 229b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru doReplace(0, 0, text, 0, textLength); 230b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 231b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 232b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::UnicodeString(UBool isTerminated, 233b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const UChar *text, 234b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t textLength) 235c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru : fShortLength(0), 236b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFlags(kReadonlyAlias) 237b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 238b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(text == NULL) { 239b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // treat as an empty string, do not alias 240c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru setToEmpty(); 241b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else if(textLength < -1 || 242b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (textLength == -1 && !isTerminated) || 243b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (textLength >= 0 && isTerminated && text[textLength] != 0) 244b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ) { 245b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru setToBogus(); 246c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } else { 247c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if(textLength == -1) { 248c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru // text is terminated, or else it would have failed the above test 249c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru textLength = u_strlen(text); 250c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } 251c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru setArray((UChar *)text, textLength, isTerminated ? textLength + 1 : textLength); 252b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 253b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 254b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 255b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::UnicodeString(UChar *buff, 256b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t buffLength, 257b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t buffCapacity) 258c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru : fShortLength(0), 259b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFlags(kWritableAlias) 260b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 261b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(buff == NULL) { 262b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // treat as an empty string, do not alias 263c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru setToEmpty(); 264b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else if(buffLength < -1 || buffCapacity < 0 || buffLength > buffCapacity) { 265b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru setToBogus(); 266c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } else { 267c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if(buffLength == -1) { 268c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru // fLength = u_strlen(buff); but do not look beyond buffCapacity 269c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru const UChar *p = buff, *limit = buff + buffCapacity; 270c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru while(p != limit && *p != 0) { 271c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru ++p; 272c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } 273c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru buffLength = (int32_t)(p - buff); 274b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 275c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru setArray(buff, buffLength, buffCapacity); 276b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 277b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 278b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 279b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::UnicodeString(const char *src, int32_t length, EInvariant) 280c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru : fShortLength(0), 281b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFlags(kShortString) 282b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 283b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(src==NULL) { 284b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // treat as an empty string 285b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 286b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(length<0) { 287b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru length=(int32_t)uprv_strlen(src); 288b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 289b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(cloneArrayIfNeeded(length, length, FALSE)) { 290b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru u_charsToUChars(src, getArrayStart(), length); 291c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru setLength(length); 292b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 293b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru setToBogus(); 294b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 295b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 296b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 297b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 298b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#if U_CHARSET_IS_UTF8 299b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 300b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruUnicodeString::UnicodeString(const char *codepageData) 301b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru : fShortLength(0), 302b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru fFlags(kShortString) { 303b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if(codepageData != 0) { 304b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru setToUTF8(codepageData); 305b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 306b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru} 307b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 308b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruUnicodeString::UnicodeString(const char *codepageData, int32_t dataLength) 309b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru : fShortLength(0), 310b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru fFlags(kShortString) { 311b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // if there's nothing to convert, do nothing 312b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if(codepageData == 0 || dataLength == 0 || dataLength < -1) { 313b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return; 314b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 315b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if(dataLength == -1) { 316b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru dataLength = (int32_t)uprv_strlen(codepageData); 317b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 318b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru setToUTF8(StringPiece(codepageData, dataLength)); 319b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru} 320b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 321b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru// else see unistr_cnv.cpp 322b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#endif 323b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 324b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::UnicodeString(const UnicodeString& that) 325b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru : Replaceable(), 326c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru fShortLength(0), 327b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFlags(kShortString) 328b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 329b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru copyFrom(that); 330b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 331b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 332b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::UnicodeString(const UnicodeString& that, 333b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t srcStart) 334b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru : Replaceable(), 335c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru fShortLength(0), 336b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFlags(kShortString) 337b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 338b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru setTo(that, srcStart); 339b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 340b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 341b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::UnicodeString(const UnicodeString& that, 342b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t srcStart, 343b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t srcLength) 344b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru : Replaceable(), 345c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru fShortLength(0), 346b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFlags(kShortString) 347b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 348b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru setTo(that, srcStart, srcLength); 349b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 350b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 351b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Replaceable base class clone() default implementation, does not clone 352b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruReplaceable * 353b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruReplaceable::clone() const { 354b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 355b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 356b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 357b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// UnicodeString overrides clone() with a real implementation 358b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruReplaceable * 359b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::clone() const { 360b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return new UnicodeString(*this); 361b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 362b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 363b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//======================================== 364b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// array allocation 365b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//======================================== 366b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 367b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUBool 368b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::allocate(int32_t capacity) { 369b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(capacity <= US_STACKBUF_SIZE) { 370b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFlags = kShortString; 371b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 372b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // count bytes for the refCounter and the string capacity, and 373b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // round up to a multiple of 16; then divide by 4 and allocate int32_t's 374b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // to be safely aligned for the refCount 37550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // the +1 is for the NUL terminator, to avoid reallocation in getTerminatedBuffer() 37650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t words = (int32_t)(((sizeof(int32_t) + (capacity + 1) * U_SIZEOF_UCHAR + 15) & ~15) >> 2); 377b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t *array = (int32_t*) uprv_malloc( sizeof(int32_t) * words ); 378b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(array != 0) { 379b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // set initial refCount and point behind the refCount 380b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *array++ = 1; 381b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 382b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // have fArray point to the first UChar 383c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru fUnion.fFields.fArray = (UChar *)array; 384c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru fUnion.fFields.fCapacity = (int32_t)((words - 1) * (sizeof(int32_t) / U_SIZEOF_UCHAR)); 385b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFlags = kLongString; 386b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 387c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru fShortLength = 0; 388c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru fUnion.fFields.fArray = 0; 389c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru fUnion.fFields.fCapacity = 0; 390b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFlags = kIsBogus; 391b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return FALSE; 392b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 393b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 394b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return TRUE; 395b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 396b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 397b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//======================================== 398b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Destructor 399b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//======================================== 400b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::~UnicodeString() 401b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 402b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru releaseArray(); 403b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 404b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 405b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru//======================================== 406b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru// Factory methods 407b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru//======================================== 408b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 409b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruUnicodeString UnicodeString::fromUTF8(const StringPiece &utf8) { 410b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru UnicodeString result; 411b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru result.setToUTF8(utf8); 412b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return result; 413b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru} 414b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 415b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruUnicodeString UnicodeString::fromUTF32(const UChar32 *utf32, int32_t length) { 416b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru UnicodeString result; 417b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int32_t capacity; 418b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // Most UTF-32 strings will be BMP-only and result in a same-length 419b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // UTF-16 string. We overestimate the capacity just slightly, 420b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // just in case there are a few supplementary characters. 421b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if(length <= US_STACKBUF_SIZE) { 422b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru capacity = US_STACKBUF_SIZE; 423b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } else { 424b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru capacity = length + (length >> 4) + 4; 425b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 426b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru do { 427b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru UChar *utf16 = result.getBuffer(capacity); 428b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int32_t length16; 429b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru UErrorCode errorCode = U_ZERO_ERROR; 430b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru u_strFromUTF32WithSub(utf16, result.getCapacity(), &length16, 431b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru utf32, length, 432b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 0xfffd, // Substitution character. 433b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru NULL, // Don't care about number of substitutions. 434b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru &errorCode); 435b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru result.releaseBuffer(length16); 436b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if(errorCode == U_BUFFER_OVERFLOW_ERROR) { 437b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru capacity = length16 + 1; // +1 for the terminating NUL. 438b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru continue; 439b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } else if(U_FAILURE(errorCode)) { 440b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru result.setToBogus(); 441b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 442b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru break; 443b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } while(TRUE); 444b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return result; 445b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru} 446b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 447b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//======================================== 448b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Assignment 449b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//======================================== 450b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 451b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString & 452b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::operator=(const UnicodeString &src) { 453b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return copyFrom(src); 454b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 455b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 456b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString & 457b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::fastCopyFrom(const UnicodeString &src) { 458b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return copyFrom(src, TRUE); 459b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 460b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 461b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString & 462b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::copyFrom(const UnicodeString &src, UBool fastCopy) { 463b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // if assigning to ourselves, do nothing 464b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(this == 0 || this == &src) { 465b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return *this; 466b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 467b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 468b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // is the right side bogus? 469b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(&src == 0 || src.isBogus()) { 470b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru setToBogus(); 471b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return *this; 472b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 473b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 474b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // delete the current contents 475b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru releaseArray(); 476b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 477c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if(src.isEmpty()) { 478b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // empty string - use the stack buffer 479c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru setToEmpty(); 480b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return *this; 481b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 482b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 483c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru // we always copy the length 484c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru int32_t srcLength = src.length(); 485c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru setLength(srcLength); 486c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru 487b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // fLength>0 and not an "open" src.getBuffer(minCapacity) 488b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru switch(src.fFlags) { 489b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case kShortString: 490b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // short string using the stack buffer, do the same 491b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFlags = kShortString; 49250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uprv_memcpy(fUnion.fStackBuffer, src.fUnion.fStackBuffer, srcLength * U_SIZEOF_UCHAR); 493b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 494b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case kLongString: 495b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // src uses a refCounted string buffer, use that buffer with refCount 496b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // src is const, use a cast - we don't really change it 497b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ((UnicodeString &)src).addRef(); 498b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // copy all fields, share the reference-counted buffer 499c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru fUnion.fFields.fArray = src.fUnion.fFields.fArray; 500c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru fUnion.fFields.fCapacity = src.fUnion.fFields.fCapacity; 501b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFlags = src.fFlags; 502b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 503b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case kReadonlyAlias: 504b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(fastCopy) { 505b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // src is a readonly alias, do the same 506b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // -> maintain the readonly alias as such 507c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru fUnion.fFields.fArray = src.fUnion.fFields.fArray; 508c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru fUnion.fFields.fCapacity = src.fUnion.fFields.fCapacity; 509b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFlags = src.fFlags; 510b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 511b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 512b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // else if(!fastCopy) fall through to case kWritableAlias 513b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // -> allocate a new buffer and copy the contents 514b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case kWritableAlias: 515b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // src is a writable alias; we make a copy of that instead 516c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if(allocate(srcLength)) { 517c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru uprv_memcpy(getArrayStart(), src.getArrayStart(), srcLength * U_SIZEOF_UCHAR); 518b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 519b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 520b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // if there is not enough memory, then fall through to setting to bogus 521b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru default: 522b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // if src is bogus, set ourselves to bogus 523b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // do not call setToBogus() here because fArray and fFlags are not consistent here 524c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru fShortLength = 0; 525c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru fUnion.fFields.fArray = 0; 526c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru fUnion.fFields.fCapacity = 0; 527b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFlags = kIsBogus; 528b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 529b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 530b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 531b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return *this; 532b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 533b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 534b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//======================================== 535b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Miscellaneous operations 536b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//======================================== 537b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 538b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString UnicodeString::unescape() const { 539c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru UnicodeString result(length(), (UChar32)0, (int32_t)0); // construct with capacity 540c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru const UChar *array = getBuffer(); 541c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru int32_t len = length(); 542c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru int32_t prev = 0; 543c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru for (int32_t i=0;;) { 544c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if (i == len) { 545c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru result.append(array, prev, len - prev); 546c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru break; 547c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } 548c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if (array[i++] == 0x5C /*'\\'*/) { 549c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru result.append(array, prev, (i - 1) - prev); 550c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru UChar32 c = unescapeAt(i); // advances i 551c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if (c < 0) { 552b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru result.remove(); // return empty string 553b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; // invalid escape sequence 554b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 555c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru result.append(c); 556c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru prev = i; 557b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 558b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 559b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return result; 560b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 561b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 562b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUChar32 UnicodeString::unescapeAt(int32_t &offset) const { 563b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return u_unescapeAt(UnicodeString_charAt, &offset, length(), (void*)this); 564b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 565b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 566b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//======================================== 567b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Read-only implementation 568b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//======================================== 569b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint8_t 570b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::doCompare( int32_t start, 571b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t length, 572b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const UChar *srcChars, 573b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t srcStart, 574b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t srcLength) const 575b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 576b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // compare illegal string values 577b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // treat const UChar *srcChars==NULL as an empty string 578b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(isBogus()) { 579b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 580b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 581b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 582b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // pin indices to legal values 583b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pinIndices(start, length); 584b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 585b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(srcChars == NULL) { 586b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru srcStart = srcLength = 0; 587b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 588b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 589b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // get the correct pointer 590b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const UChar *chars = getArrayStart(); 591b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 592b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru chars += start; 593b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru srcChars += srcStart; 594b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 595b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t minLength; 596b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int8_t lengthResult; 597b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 598b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // get the srcLength if necessary 599b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(srcLength < 0) { 600b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru srcLength = u_strlen(srcChars + srcStart); 601b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 602b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 603b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // are we comparing different lengths? 604b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(length != srcLength) { 605b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(length < srcLength) { 606b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru minLength = length; 607b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru lengthResult = -1; 608b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 609b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru minLength = srcLength; 610b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru lengthResult = 1; 611b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 612b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 613b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru minLength = length; 614b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru lengthResult = 0; 615b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 616b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 617b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 618b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * note that uprv_memcmp() returns an int but we return an int8_t; 619b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * we need to take care not to truncate the result - 620b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * one way to do this is to right-shift the value to 621b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * move the sign bit into the lower 8 bits and making sure that this 622b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * does not become 0 itself 623b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 624b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 625b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(minLength > 0 && chars != srcChars) { 626b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t result; 627b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 628b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru# if U_IS_BIG_ENDIAN 629b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // big-endian: byte comparison works 630b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru result = uprv_memcmp(chars, srcChars, minLength * sizeof(UChar)); 631b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(result != 0) { 632b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return (int8_t)(result >> 15 | 1); 633b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 634b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru# else 635b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // little-endian: compare UChar units 636b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru do { 637b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru result = ((int32_t)*(chars++) - (int32_t)*(srcChars++)); 638b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(result != 0) { 639b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return (int8_t)(result >> 15 | 1); 640b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 641b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } while(--minLength > 0); 642b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru# endif 643b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 644b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return lengthResult; 645b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 646b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 647b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* String compare in code point order - doCompare() compares in code unit order. */ 648b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint8_t 649b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::doCompareCodePointOrder(int32_t start, 650b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t length, 651b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const UChar *srcChars, 652b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t srcStart, 653b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t srcLength) const 654b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 655b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // compare illegal string values 656b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // treat const UChar *srcChars==NULL as an empty string 657b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(isBogus()) { 658b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 659b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 660b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 661b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // pin indices to legal values 662b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pinIndices(start, length); 663b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 664b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(srcChars == NULL) { 665b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru srcStart = srcLength = 0; 666b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 667b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 668c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru int32_t diff = uprv_strCompare(getArrayStart() + start, length, srcChars + srcStart, srcLength, FALSE, TRUE); 669b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* translate the 32-bit result into an 8-bit one */ 670b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(diff!=0) { 671b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return (int8_t)(diff >> 15 | 1); 672b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 673b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 674b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 675b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 676b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 677b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t 678b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::getLength() const { 679b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return length(); 680b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 681b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 682b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUChar 683b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::getCharAt(int32_t offset) const { 684b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return charAt(offset); 685b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 686b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 687b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUChar32 688b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::getChar32At(int32_t offset) const { 689b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return char32At(offset); 690b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 691b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 692b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t 693b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::countChar32(int32_t start, int32_t length) const { 694b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pinIndices(start, length); 695b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // if(isBogus()) then fArray==0 and start==0 - u_countChar32() checks for NULL 696c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru return u_countChar32(getArrayStart()+start, length); 697b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 698b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 699b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUBool 700b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::hasMoreChar32Than(int32_t start, int32_t length, int32_t number) const { 701b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pinIndices(start, length); 702b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // if(isBogus()) then fArray==0 and start==0 - u_strHasMoreChar32Than() checks for NULL 703c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru return u_strHasMoreChar32Than(getArrayStart()+start, length, number); 704b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 705b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 706b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t 707b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::moveIndex32(int32_t index, int32_t delta) const { 708b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // pin index 709c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru int32_t len = length(); 710b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(index<0) { 711b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru index=0; 712c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } else if(index>len) { 713c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru index=len; 714b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 715b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 716c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru const UChar *array = getArrayStart(); 717b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(delta>0) { 718c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru UTF_FWD_N(array, index, len, delta); 719b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 720c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru UTF_BACK_N(array, 0, index, -delta); 721b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 722b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 723b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return index; 724b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 725b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 726b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid 727b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::doExtract(int32_t start, 728b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t length, 729b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UChar *dst, 730b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t dstStart) const 731b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 732b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // pin indices to legal values 733b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pinIndices(start, length); 734b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 735b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // do not copy anything if we alias dst itself 736c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru const UChar *array = getArrayStart(); 737c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if(array + start != dst + dstStart) { 738c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru us_arrayCopy(array, start, dst, dstStart, length); 739b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 740b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 741b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 742b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t 743b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::extract(UChar *dest, int32_t destCapacity, 744b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode &errorCode) const { 745c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru int32_t len = length(); 746b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(U_SUCCESS(errorCode)) { 747b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(isBogus() || destCapacity<0 || (destCapacity>0 && dest==0)) { 748b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru errorCode=U_ILLEGAL_ARGUMENT_ERROR; 749b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 750c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru const UChar *array = getArrayStart(); 751c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if(len>0 && len<=destCapacity && array!=dest) { 752c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru uprv_memcpy(dest, array, len*U_SIZEOF_UCHAR); 753b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 754c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru return u_terminateUChars(dest, destCapacity, len, &errorCode); 755b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 756b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 757b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 758c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru return len; 759b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 760b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 761b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t 762b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::extract(int32_t start, 763b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t length, 764b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char *target, 765b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t targetCapacity, 766b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru enum EInvariant) const 767b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 768b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // if the arguments are illegal, then do nothing 769b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(targetCapacity < 0 || (targetCapacity > 0 && target == NULL)) { 770b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 771b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 772b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 773b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // pin the indices to legal values 774b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pinIndices(start, length); 775b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 776b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(length <= targetCapacity) { 777b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru u_UCharsToChars(getArrayStart() + start, target, length); 778b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 779b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode status = U_ZERO_ERROR; 780b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return u_terminateChars(target, targetCapacity, length, &status); 781b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 782b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 78350294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoUnicodeString 78450294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoUnicodeString::tempSubString(int32_t start, int32_t len) const { 78550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho pinIndices(start, len); 78650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const UChar *array = getBuffer(); // not getArrayStart() to check kIsBogus & kOpenGetBuffer 78750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(array==NULL) { 78850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho array=fUnion.fStackBuffer; // anything not NULL because that would make an empty string 78950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho len=-2; // bogus result string 79050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 79150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return UnicodeString(FALSE, array + start, len); 79250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 79350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 794b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queruint32_t 795b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruUnicodeString::toUTF8(int32_t start, int32_t len, 796b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru char *target, int32_t capacity) const { 797b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru pinIndices(start, len); 798b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int32_t length8; 799b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru UErrorCode errorCode = U_ZERO_ERROR; 800b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru u_strToUTF8WithSub(target, capacity, &length8, 801b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru getBuffer() + start, len, 802b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 0xFFFD, // Standard substitution character. 803b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru NULL, // Don't care about number of substitutions. 804b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru &errorCode); 805b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return length8; 806b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru} 807b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 808b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#if U_CHARSET_IS_UTF8 809b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 810b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queruint32_t 811b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruUnicodeString::extract(int32_t start, int32_t len, 812b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru char *target, uint32_t dstSize) const { 813b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // if the arguments are illegal, then do nothing 814b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if(/*dstSize < 0 || */(dstSize > 0 && target == 0)) { 815b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return 0; 816b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 817b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return toUTF8(start, len, target, dstSize <= 0x7fffffff ? (int32_t)dstSize : 0x7fffffff); 818b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru} 819b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 820b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru// else see unistr_cnv.cpp 821b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#endif 822b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 823b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid 824b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::extractBetween(int32_t start, 825b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t limit, 826b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UnicodeString& target) const { 827b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pinIndex(start); 828b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pinIndex(limit); 829b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru doExtract(start, limit - start, target); 830b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 831b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 832b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru// When converting from UTF-16 to UTF-8, the result will have at most 3 times 833b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru// as many bytes as the source has UChars. 834b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru// The "worst cases" are writing systems like Indic, Thai and CJK with 835b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru// 3:1 bytes:UChars. 836b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queruvoid 837b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruUnicodeString::toUTF8(ByteSink &sink) const { 838b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int32_t length16 = length(); 839b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if(length16 != 0) { 840b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru char stackBuffer[1024]; 841b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int32_t capacity = (int32_t)sizeof(stackBuffer); 842b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru UBool utf8IsOwned = FALSE; 843b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru char *utf8 = sink.GetAppendBuffer(length16 < capacity ? length16 : capacity, 844b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 3*length16, 845b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru stackBuffer, capacity, 846b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru &capacity); 847b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int32_t length8 = 0; 848b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru UErrorCode errorCode = U_ZERO_ERROR; 849b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru u_strToUTF8WithSub(utf8, capacity, &length8, 850b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru getBuffer(), length16, 851b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 0xFFFD, // Standard substitution character. 852b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru NULL, // Don't care about number of substitutions. 853b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru &errorCode); 854b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if(errorCode == U_BUFFER_OVERFLOW_ERROR) { 855b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru utf8 = (char *)uprv_malloc(length8); 856b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if(utf8 != NULL) { 857b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru utf8IsOwned = TRUE; 858b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru errorCode = U_ZERO_ERROR; 859b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru u_strToUTF8WithSub(utf8, length8, &length8, 860b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru getBuffer(), length16, 861b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 0xFFFD, // Standard substitution character. 862b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru NULL, // Don't care about number of substitutions. 863b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru &errorCode); 864b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } else { 865b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru errorCode = U_MEMORY_ALLOCATION_ERROR; 866b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 867b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 868b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if(U_SUCCESS(errorCode)) { 869b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru sink.Append(utf8, length8); 870b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 871b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if(utf8IsOwned) { 872b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru uprv_free(utf8); 873b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 874b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 875b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru} 876b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 877b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queruint32_t 878b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruUnicodeString::toUTF32(UChar32 *utf32, int32_t capacity, UErrorCode &errorCode) const { 879b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int32_t length32=0; 880b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if(U_SUCCESS(errorCode)) { 881b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // getBuffer() and u_strToUTF32WithSub() check for illegal arguments. 882b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru u_strToUTF32WithSub(utf32, capacity, &length32, 883b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru getBuffer(), length(), 884b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 0xfffd, // Substitution character. 885b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru NULL, // Don't care about number of substitutions. 886b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru &errorCode); 887b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 888b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return length32; 889b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru} 890b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 891b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t 892b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::indexOf(const UChar *srcChars, 893b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t srcStart, 894b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t srcLength, 895b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t start, 896b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t length) const 897b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 898b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(isBogus() || srcChars == 0 || srcStart < 0 || srcLength == 0) { 899b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 900b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 901b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 902b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // UnicodeString does not find empty substrings 903b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(srcLength < 0 && srcChars[srcStart] == 0) { 904b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 905b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 906b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 907b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // get the indices within bounds 908b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pinIndices(start, length); 909b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 910b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // find the first occurrence of the substring 911c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru const UChar *array = getArrayStart(); 912c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru const UChar *match = u_strFindFirst(array + start, length, srcChars + srcStart, srcLength); 913b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(match == NULL) { 914b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 915b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 916c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru return (int32_t)(match - array); 917b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 918b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 919b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 920b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t 921b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::doIndexOf(UChar c, 922b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t start, 923b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t length) const 924b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 925b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // pin indices 926b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pinIndices(start, length); 927b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 928b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // find the first occurrence of c 929c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru const UChar *array = getArrayStart(); 930c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru const UChar *match = u_memchr(array + start, c, length); 931b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(match == NULL) { 932b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 933b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 934c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru return (int32_t)(match - array); 935b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 936b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 937b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 938b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t 939b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::doIndexOf(UChar32 c, 940b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t start, 941b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t length) const { 942b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // pin indices 943b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pinIndices(start, length); 944b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 945b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // find the first occurrence of c 946c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru const UChar *array = getArrayStart(); 947c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru const UChar *match = u_memchr32(array + start, c, length); 948b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(match == NULL) { 949b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 950b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 951c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru return (int32_t)(match - array); 952b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 953b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 954b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 955b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t 956b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::lastIndexOf(const UChar *srcChars, 957b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t srcStart, 958b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t srcLength, 959b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t start, 960b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t length) const 961b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 962b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(isBogus() || srcChars == 0 || srcStart < 0 || srcLength == 0) { 963b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 964b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 965b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 966b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // UnicodeString does not find empty substrings 967b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(srcLength < 0 && srcChars[srcStart] == 0) { 968b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 969b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 970b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 971b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // get the indices within bounds 972b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pinIndices(start, length); 973b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 974b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // find the last occurrence of the substring 975c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru const UChar *array = getArrayStart(); 976c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru const UChar *match = u_strFindLast(array + start, length, srcChars + srcStart, srcLength); 977b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(match == NULL) { 978b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 979b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 980c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru return (int32_t)(match - array); 981b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 982b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 983b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 984b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t 985b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::doLastIndexOf(UChar c, 986b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t start, 987b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t length) const 988b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 989b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(isBogus()) { 990b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 991b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 992b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 993b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // pin indices 994b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pinIndices(start, length); 995b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 996b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // find the last occurrence of c 997c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru const UChar *array = getArrayStart(); 998c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru const UChar *match = u_memrchr(array + start, c, length); 999b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(match == NULL) { 1000b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 1001b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1002c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru return (int32_t)(match - array); 1003b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1004b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1005b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1006b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t 1007b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::doLastIndexOf(UChar32 c, 1008b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t start, 1009b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t length) const { 1010b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // pin indices 1011b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pinIndices(start, length); 1012b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1013b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // find the last occurrence of c 1014c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru const UChar *array = getArrayStart(); 1015c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru const UChar *match = u_memrchr32(array + start, c, length); 1016b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(match == NULL) { 1017b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 1018b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1019c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru return (int32_t)(match - array); 1020b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1021b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1022b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1023b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//======================================== 1024b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Write implementation 1025b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//======================================== 1026b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1027b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString& 1028b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::findAndReplace(int32_t start, 1029b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t length, 1030b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const UnicodeString& oldText, 1031b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t oldStart, 1032b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t oldLength, 1033b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const UnicodeString& newText, 1034b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t newStart, 1035b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t newLength) 1036b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1037b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(isBogus() || oldText.isBogus() || newText.isBogus()) { 1038b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return *this; 1039b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1040b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1041b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pinIndices(start, length); 1042b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru oldText.pinIndices(oldStart, oldLength); 1043b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru newText.pinIndices(newStart, newLength); 1044b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1045b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(oldLength == 0) { 1046b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return *this; 1047b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1048b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1049b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(length > 0 && length >= oldLength) { 1050b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t pos = indexOf(oldText, oldStart, oldLength, start, length); 1051b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(pos < 0) { 1052b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // no more oldText's here: done 1053b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1054b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1055b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // we found oldText, replace it by newText and go beyond it 1056b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru replace(pos, oldLength, newText, newStart, newLength); 1057b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru length -= pos + oldLength - start; 1058b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru start = pos + newLength; 1059b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1060b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1061b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1062b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return *this; 1063b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1064b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1065b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1066b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid 1067b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::setToBogus() 1068b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1069b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru releaseArray(); 1070b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1071c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru fShortLength = 0; 1072c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru fUnion.fFields.fArray = 0; 1073c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru fUnion.fFields.fCapacity = 0; 1074b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFlags = kIsBogus; 1075b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1076b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1077b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// turn a bogus string into an empty one 1078b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid 1079b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::unBogus() { 1080b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(fFlags & kIsBogus) { 1081c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru setToEmpty(); 1082b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1083b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1084b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1085b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// setTo() analogous to the readonly-aliasing constructor with the same signature 1086b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString & 1087b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::setTo(UBool isTerminated, 1088b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const UChar *text, 1089b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t textLength) 1090b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1091b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(fFlags & kOpenGetBuffer) { 1092b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // do not modify a string that has an "open" getBuffer(minCapacity) 1093b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return *this; 1094b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1095b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1096b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(text == NULL) { 1097b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // treat as an empty string, do not alias 1098b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru releaseArray(); 1099c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru setToEmpty(); 1100b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return *this; 1101b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1102b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1103b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if( textLength < -1 || 1104b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (textLength == -1 && !isTerminated) || 1105b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (textLength >= 0 && isTerminated && text[textLength] != 0) 1106b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ) { 1107b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru setToBogus(); 1108b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return *this; 1109b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1110b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1111b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru releaseArray(); 1112b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1113c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if(textLength == -1) { 1114b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // text is terminated, or else it would have failed the above test 1115c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru textLength = u_strlen(text); 1116b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1117c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru setArray((UChar *)text, textLength, isTerminated ? textLength + 1 : textLength); 1118b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1119b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFlags = kReadonlyAlias; 1120b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return *this; 1121b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1122b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1123b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// setTo() analogous to the writable-aliasing constructor with the same signature 1124b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString & 1125b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::setTo(UChar *buffer, 1126b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t buffLength, 1127b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t buffCapacity) { 1128b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(fFlags & kOpenGetBuffer) { 1129b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // do not modify a string that has an "open" getBuffer(minCapacity) 1130b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return *this; 1131b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1132b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1133b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(buffer == NULL) { 1134b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // treat as an empty string, do not alias 1135b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru releaseArray(); 1136c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru setToEmpty(); 1137b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return *this; 1138b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1139b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1140b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(buffLength < -1 || buffCapacity < 0 || buffLength > buffCapacity) { 1141b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru setToBogus(); 1142b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return *this; 1143b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else if(buffLength == -1) { 1144b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // buffLength = u_strlen(buff); but do not look beyond buffCapacity 1145b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const UChar *p = buffer, *limit = buffer + buffCapacity; 1146b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(p != limit && *p != 0) { 1147b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++p; 1148b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1149b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru buffLength = (int32_t)(p - buffer); 1150b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1151b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1152b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru releaseArray(); 1153b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1154c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru setArray(buffer, buffLength, buffCapacity); 1155b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFlags = kWritableAlias; 1156b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return *this; 1157b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1158b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1159b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruUnicodeString &UnicodeString::setToUTF8(const StringPiece &utf8) { 1160b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru unBogus(); 1161b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int32_t length = utf8.length(); 1162b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int32_t capacity; 1163b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // The UTF-16 string will be at most as long as the UTF-8 string. 1164b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if(length <= US_STACKBUF_SIZE) { 1165b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru capacity = US_STACKBUF_SIZE; 1166b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } else { 1167b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru capacity = length + 1; // +1 for the terminating NUL. 1168b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 1169b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru UChar *utf16 = getBuffer(capacity); 1170b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int32_t length16; 1171b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru UErrorCode errorCode = U_ZERO_ERROR; 1172b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru u_strFromUTF8WithSub(utf16, getCapacity(), &length16, 1173b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru utf8.data(), length, 1174b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 0xfffd, // Substitution character. 1175b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru NULL, // Don't care about number of substitutions. 1176b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru &errorCode); 1177b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru releaseBuffer(length16); 1178b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if(U_FAILURE(errorCode)) { 1179b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru setToBogus(); 1180b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 1181b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return *this; 1182b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru} 1183b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 1184b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString& 1185b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::setCharAt(int32_t offset, 1186b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UChar c) 1187b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1188c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru int32_t len = length(); 1189c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if(cloneArrayIfNeeded() && len > 0) { 1190b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(offset < 0) { 1191b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru offset = 0; 1192c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } else if(offset >= len) { 1193c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru offset = len - 1; 1194b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1195b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1196c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru getArrayStart()[offset] = c; 1197b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1198b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return *this; 1199b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1200b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1201b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString& 1202b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::doReplace( int32_t start, 1203b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t length, 1204b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const UnicodeString& src, 1205b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t srcStart, 1206b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t srcLength) 1207b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1208b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(!src.isBogus()) { 1209b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // pin the indices to legal values 1210b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru src.pinIndices(srcStart, srcLength); 1211b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1212b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // get the characters from src 1213b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // and replace the range in ourselves with them 1214b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return doReplace(start, length, src.getArrayStart(), srcStart, srcLength); 1215b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1216b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // remove the range 1217b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return doReplace(start, length, 0, 0, 0); 1218b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1219b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1220b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1221b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString& 1222b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::doReplace(int32_t start, 1223b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t length, 1224b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const UChar *srcChars, 1225b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t srcStart, 1226b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t srcLength) 1227b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1228c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if(!isWritable()) { 1229b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return *this; 1230b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1231b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 123250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t oldLength = this->length(); 123350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 123450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // optimize (read-only alias).remove(0, start) and .remove(start, end) 123550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if((fFlags&kBufferIsReadonly) && srcLength == 0) { 123650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(start == 0) { 123750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // remove prefix by adjusting the array pointer 123850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho pinIndex(length); 123950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho fUnion.fFields.fArray += length; 124050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho fUnion.fFields.fCapacity -= length; 124150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho setLength(oldLength - length); 124250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return *this; 124350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } else { 124450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho pinIndex(start); 124550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(length >= (oldLength - start)) { 124650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // remove suffix by reducing the length (like truncate()) 124750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho setLength(start); 124850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho fUnion.fFields.fCapacity = start; // not NUL-terminated any more 124950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return *this; 125050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 125150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 125250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 125350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 1254b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(srcChars == 0) { 1255b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru srcStart = srcLength = 0; 1256b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else if(srcLength < 0) { 1257b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // get the srcLength if necessary 1258b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru srcLength = u_strlen(srcChars + srcStart); 1259b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1260b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1261c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru // calculate the size of the string after the replace 1262c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru int32_t newSize; 1263c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru 1264c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru // optimize append() onto a large-enough, owned string 1265c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if(start >= oldLength) { 1266c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru newSize = oldLength + srcLength; 1267c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if(newSize <= getCapacity() && isBufferWritable()) { 1268c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru us_arrayCopy(srcChars, srcStart, getArrayStart(), oldLength, srcLength); 1269c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru setLength(newSize); 1270c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru return *this; 1271c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } else { 1272c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru // pin the indices to legal values 1273c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru start = oldLength; 1274c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru length = 0; 1275c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } 1276c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } else { 1277c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru // pin the indices to legal values 1278c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru pinIndices(start, length); 1279b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1280c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru newSize = oldLength - length + srcLength; 1281c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } 1282b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1283c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru // the following may change fArray but will not copy the current contents; 1284c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru // therefore we need to keep the current fArray 1285c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru UChar oldStackBuffer[US_STACKBUF_SIZE]; 1286c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru UChar *oldArray; 1287c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if((fFlags&kUsingStackBuffer) && (newSize > US_STACKBUF_SIZE)) { 1288c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru // copy the stack buffer contents because it will be overwritten with 1289c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru // fUnion.fFields values 1290c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru u_memcpy(oldStackBuffer, fUnion.fStackBuffer, oldLength); 1291c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru oldArray = oldStackBuffer; 1292c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } else { 1293c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru oldArray = getArrayStart(); 1294c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } 1295b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1296b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // clone our array and allocate a bigger array if needed 1297c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru int32_t *bufferToDelete = 0; 1298b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(!cloneArrayIfNeeded(newSize, newSize + (newSize >> 2) + kGrowSize, 1299b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, &bufferToDelete) 1300b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ) { 1301b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return *this; 1302b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1303b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1304b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // now do the replace 1305b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1306c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru UChar *newArray = getArrayStart(); 1307c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if(newArray != oldArray) { 1308b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // if fArray changed, then we need to copy everything except what will change 1309c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru us_arrayCopy(oldArray, 0, newArray, 0, start); 1310b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru us_arrayCopy(oldArray, start + length, 1311c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru newArray, start + srcLength, 1312b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru oldLength - (start + length)); 1313b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else if(length != srcLength) { 1314b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // fArray did not change; copy only the portion that isn't changing, leaving a hole 1315b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru us_arrayCopy(oldArray, start + length, 1316c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru newArray, start + srcLength, 1317b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru oldLength - (start + length)); 1318b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1319b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1320b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // now fill in the hole with the new string 1321c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru us_arrayCopy(srcChars, srcStart, newArray, start, srcLength); 1322b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1323c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru setLength(newSize); 1324b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1325b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // delayed delete in case srcChars == fArray when we started, and 1326b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // to keep oldArray alive for the above operations 1327b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (bufferToDelete) { 1328b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_free(bufferToDelete); 1329b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1330b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1331b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return *this; 1332b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1333b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1334b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/** 1335b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Replaceable API 1336b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 1337b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid 1338b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::handleReplaceBetween(int32_t start, 1339b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t limit, 1340b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const UnicodeString& text) { 1341b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru replaceBetween(start, limit, text); 1342b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1343b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1344b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/** 1345b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Replaceable API 1346b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 1347b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid 1348b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::copy(int32_t start, int32_t limit, int32_t dest) { 1349b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (limit <= start) { 1350b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; // Nothing to do; avoid bogus malloc call 1351b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1352b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UChar* text = (UChar*) uprv_malloc( sizeof(UChar) * (limit - start) ); 1353c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru // Check to make sure text is not null. 1354c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if (text != NULL) { 1355c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru extractBetween(start, limit, text, 0); 1356c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru insert(dest, text, 0, limit - start); 1357c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru uprv_free(text); 1358c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } 1359b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1360b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1361b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/** 1362b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Replaceable API 1363b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 1364b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * NOTE: This is for the Replaceable class. There is no rep.cpp, 1365b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * so we implement this function here. 1366b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 1367b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUBool Replaceable::hasMetaData() const { 1368b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return TRUE; 1369b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1370b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1371b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/** 1372b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Replaceable API 1373b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 1374b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUBool UnicodeString::hasMetaData() const { 1375b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return FALSE; 1376b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1377b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1378b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString& 1379b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::doReverse(int32_t start, 1380b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t length) 1381b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1382c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if(this->length() <= 1 || !cloneArrayIfNeeded()) { 1383b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return *this; 1384b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1385b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1386b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // pin the indices to legal values 1387b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pinIndices(start, length); 1388b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1389b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UChar *left = getArrayStart() + start; 1390c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru UChar *right = left + length; 1391b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UChar swap; 1392b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UBool hasSupplementary = FALSE; 1393b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1394b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(left < --right) { 1395b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru hasSupplementary |= (UBool)UTF_IS_LEAD(swap = *left); 1396b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru hasSupplementary |= (UBool)UTF_IS_LEAD(*left++ = *right); 1397b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *right = swap; 1398b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1399b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1400b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* if there are supplementary code points in the reversed range, then re-swap their surrogates */ 1401b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(hasSupplementary) { 1402b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UChar swap2; 1403b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1404b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru left = getArrayStart() + start; 1405c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru right = left + length - 1; // -1 so that we can look at *(left+1) if left<right 1406b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(left < right) { 1407b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(UTF_IS_TRAIL(swap = *left) && UTF_IS_LEAD(swap2 = *(left + 1))) { 1408b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *left++ = swap2; 1409b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *left++ = swap; 1410b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1411b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++left; 1412b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1413b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1414b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1415b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1416b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return *this; 1417b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1418b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1419b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUBool 1420b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::padLeading(int32_t targetLength, 1421b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UChar padChar) 1422b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1423c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru int32_t oldLength = length(); 1424c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if(oldLength >= targetLength || !cloneArrayIfNeeded(targetLength)) { 1425b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return FALSE; 1426b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1427b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // move contents up by padding width 1428c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru UChar *array = getArrayStart(); 1429c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru int32_t start = targetLength - oldLength; 1430c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru us_arrayCopy(array, 0, array, start, oldLength); 1431b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1432b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // fill in padding character 1433b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(--start >= 0) { 1434c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru array[start] = padChar; 1435b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1436c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru setLength(targetLength); 1437b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return TRUE; 1438b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1439b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1440b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1441b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUBool 1442b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::padTrailing(int32_t targetLength, 1443b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UChar padChar) 1444b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1445c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru int32_t oldLength = length(); 1446c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if(oldLength >= targetLength || !cloneArrayIfNeeded(targetLength)) { 1447b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return FALSE; 1448b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1449b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // fill in padding character 1450c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru UChar *array = getArrayStart(); 1451b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t length = targetLength; 1452c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru while(--length >= oldLength) { 1453c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru array[length] = padChar; 1454b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1455c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru setLength(targetLength); 1456b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return TRUE; 1457b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1458b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1459b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1460b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//======================================== 1461b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Hashing 1462b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//======================================== 1463b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t 1464b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::doHashCode() const 1465b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1466b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* Delegate hash computation to uhash. This makes UnicodeString 1467b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * hashing consistent with UChar* hashing. */ 1468c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru int32_t hashCode = uhash_hashUCharsN(getArrayStart(), length()); 1469b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (hashCode == kInvalidHashCode) { 1470b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru hashCode = kEmptyHashCode; 1471b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1472b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return hashCode; 1473b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1474b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1475b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//======================================== 1476b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// External Buffer 1477b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//======================================== 1478b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1479b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUChar * 1480b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::getBuffer(int32_t minCapacity) { 1481b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(minCapacity>=-1 && cloneArrayIfNeeded(minCapacity)) { 1482b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFlags|=kOpenGetBuffer; 1483c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru fShortLength=0; 1484c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru return getArrayStart(); 1485b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1486b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 1487b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1488b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1489b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1490b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid 1491b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::releaseBuffer(int32_t newLength) { 1492b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(fFlags&kOpenGetBuffer && newLength>=-1) { 1493b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // set the new fLength 1494c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru int32_t capacity=getCapacity(); 1495b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(newLength==-1) { 1496b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // the new length is the string length, capped by fCapacity 1497c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru const UChar *array=getArrayStart(), *p=array, *limit=array+capacity; 1498b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(p<limit && *p!=0) { 1499b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++p; 1500b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1501c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru newLength=(int32_t)(p-array); 1502c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } else if(newLength>capacity) { 1503c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru newLength=capacity; 1504b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1505c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru setLength(newLength); 1506b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFlags&=~kOpenGetBuffer; 1507b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1508b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1509b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1510b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//======================================== 1511b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Miscellaneous 1512b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//======================================== 1513b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUBool 1514b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::cloneArrayIfNeeded(int32_t newCapacity, 1515b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t growCapacity, 1516b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UBool doCopyArray, 1517b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t **pBufferToDelete, 1518b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UBool forceClone) { 1519b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // default parameters need to be static, therefore 1520b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // the defaults are -1 to have convenience defaults 1521b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(newCapacity == -1) { 1522c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru newCapacity = getCapacity(); 1523b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1524b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1525b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // while a getBuffer(minCapacity) is "open", 1526b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // prevent any modifications of the string by returning FALSE here 1527b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // if the string is bogus, then only an assignment or similar can revive it 1528c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if(!isWritable()) { 1529b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return FALSE; 1530b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1531b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1532b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 1533b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * We need to make a copy of the array if 1534b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * the buffer is read-only, or 1535b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * the buffer is refCounted (shared), and refCount>1, or 1536b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * the buffer is too small. 1537b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Return FALSE if memory could not be allocated. 1538b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 1539b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(forceClone || 1540b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFlags & kBufferIsReadonly || 1541b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFlags & kRefCounted && refCount() > 1 || 1542c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru newCapacity > getCapacity() 1543b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ) { 1544b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // check growCapacity for default value and use of the stack buffer 1545b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(growCapacity == -1) { 1546b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru growCapacity = newCapacity; 1547b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else if(newCapacity <= US_STACKBUF_SIZE && growCapacity > US_STACKBUF_SIZE) { 1548b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru growCapacity = US_STACKBUF_SIZE; 1549b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1550b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1551c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru // save old values 1552c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru UChar oldStackBuffer[US_STACKBUF_SIZE]; 1553c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru UChar *oldArray; 1554c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru uint8_t flags = fFlags; 1555c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru 1556c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if(flags&kUsingStackBuffer) { 1557c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if(doCopyArray && growCapacity > US_STACKBUF_SIZE) { 1558c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru // copy the stack buffer contents because it will be overwritten with 1559c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru // fUnion.fFields values 1560c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru us_arrayCopy(fUnion.fStackBuffer, 0, oldStackBuffer, 0, fShortLength); 1561c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru oldArray = oldStackBuffer; 1562c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } else { 1563c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru oldArray = 0; // no need to copy from stack buffer to itself 1564c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } 1565c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } else { 1566c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru oldArray = fUnion.fFields.fArray; 1567c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } 1568c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru 1569b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // allocate a new array 1570b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(allocate(growCapacity) || 1571b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru newCapacity < growCapacity && allocate(newCapacity) 1572b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ) { 1573c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if(doCopyArray && oldArray != 0) { 1574b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // copy the contents 1575b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // do not copy more than what fits - it may be smaller than before 1576c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru int32_t minLength = length(); 1577c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru newCapacity = getCapacity(); 1578c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if(newCapacity < minLength) { 1579c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru minLength = newCapacity; 1580c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru setLength(minLength); 1581b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1582c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru us_arrayCopy(oldArray, 0, getArrayStart(), 0, minLength); 1583b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1584c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru fShortLength = 0; 1585b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1586b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1587b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // release the old array 1588b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(flags & kRefCounted) { 1589b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // the array is refCounted; decrement and release if 0 1590c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru int32_t *pRefCount = ((int32_t *)oldArray - 1); 1591b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(umtx_atomic_dec(pRefCount) == 0) { 1592b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(pBufferToDelete == 0) { 1593b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_free(pRefCount); 1594b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1595b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // the caller requested to delete it himself 1596b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *pBufferToDelete = pRefCount; 1597b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1598b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1599b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1600b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1601b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // not enough memory for growCapacity and not even for the smaller newCapacity 1602b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // reset the old values for setToBogus() to release the array 1603c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if(!(flags&kUsingStackBuffer)) { 1604c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru fUnion.fFields.fArray = oldArray; 1605c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } 1606b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFlags = flags; 1607b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru setToBogus(); 1608b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return FALSE; 1609b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1610b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1611b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return TRUE; 1612b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1613b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_NAMESPACE_END 1614b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1615b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#ifdef U_STATIC_IMPLEMENTATION 1616b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* 1617b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruThis should never be called. It is defined here to make sure that the 1618b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvirtual vector deleting destructor is defined within unistr.cpp. 1619b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruThe vector deleting destructor is already a part of UObject, 1620b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querubut defining it here makes sure that it is included with this object file. 1621b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruThis makes sure that static library dependencies are kept to a minimum. 1622b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*/ 1623b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void uprv_UnicodeStringDummy(void) { 1624b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru U_NAMESPACE_USE 1625b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru delete [] (new UnicodeString[2]); 1626b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1627b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 1628