unistr.cpp revision c69afcec261fc345fda8daf46f0ea6b4351dc777
1b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* 2b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru****************************************************************************** 3c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru* Copyright (C) 1999-2008, 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 298b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::UnicodeString(const UnicodeString& that) 299b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru : Replaceable(), 300c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru fShortLength(0), 301b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFlags(kShortString) 302b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 303b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru copyFrom(that); 304b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 305b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 306b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::UnicodeString(const UnicodeString& that, 307b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t srcStart) 308b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru : Replaceable(), 309c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru fShortLength(0), 310b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFlags(kShortString) 311b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 312b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru setTo(that, srcStart); 313b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 314b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 315b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::UnicodeString(const UnicodeString& that, 316b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t srcStart, 317b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t srcLength) 318b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru : Replaceable(), 319c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru fShortLength(0), 320b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFlags(kShortString) 321b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 322b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru setTo(that, srcStart, srcLength); 323b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 324b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 325b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Replaceable base class clone() default implementation, does not clone 326b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruReplaceable * 327b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruReplaceable::clone() const { 328b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 329b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 330b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 331b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// UnicodeString overrides clone() with a real implementation 332b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruReplaceable * 333b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::clone() const { 334b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return new UnicodeString(*this); 335b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 336b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 337b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//======================================== 338b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// array allocation 339b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//======================================== 340b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 341b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUBool 342b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::allocate(int32_t capacity) { 343b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(capacity <= US_STACKBUF_SIZE) { 344b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFlags = kShortString; 345b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 346b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // count bytes for the refCounter and the string capacity, and 347b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // round up to a multiple of 16; then divide by 4 and allocate int32_t's 348b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // to be safely aligned for the refCount 349b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t words = (int32_t)(((sizeof(int32_t) + capacity * U_SIZEOF_UCHAR + 15) & ~15) >> 2); 350b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t *array = (int32_t*) uprv_malloc( sizeof(int32_t) * words ); 351b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(array != 0) { 352b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // set initial refCount and point behind the refCount 353b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *array++ = 1; 354b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 355b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // have fArray point to the first UChar 356c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru fUnion.fFields.fArray = (UChar *)array; 357c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru fUnion.fFields.fCapacity = (int32_t)((words - 1) * (sizeof(int32_t) / U_SIZEOF_UCHAR)); 358b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFlags = kLongString; 359b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 360c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru fShortLength = 0; 361c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru fUnion.fFields.fArray = 0; 362c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru fUnion.fFields.fCapacity = 0; 363b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFlags = kIsBogus; 364b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return FALSE; 365b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 366b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 367b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return TRUE; 368b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 369b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 370b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//======================================== 371b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Destructor 372b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//======================================== 373b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::~UnicodeString() 374b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 375b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru releaseArray(); 376b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 377b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 378b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 379b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//======================================== 380b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Assignment 381b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//======================================== 382b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 383b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString & 384b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::operator=(const UnicodeString &src) { 385b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return copyFrom(src); 386b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 387b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 388b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString & 389b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::fastCopyFrom(const UnicodeString &src) { 390b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return copyFrom(src, TRUE); 391b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 392b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 393b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString & 394b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::copyFrom(const UnicodeString &src, UBool fastCopy) { 395b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // if assigning to ourselves, do nothing 396b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(this == 0 || this == &src) { 397b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return *this; 398b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 399b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 400b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // is the right side bogus? 401b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(&src == 0 || src.isBogus()) { 402b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru setToBogus(); 403b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return *this; 404b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 405b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 406b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // delete the current contents 407b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru releaseArray(); 408b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 409c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if(src.isEmpty()) { 410b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // empty string - use the stack buffer 411c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru setToEmpty(); 412b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return *this; 413b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 414b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 415c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru // we always copy the length 416c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru int32_t srcLength = src.length(); 417c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru setLength(srcLength); 418c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru 419b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // fLength>0 and not an "open" src.getBuffer(minCapacity) 420b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru switch(src.fFlags) { 421b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case kShortString: 422b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // short string using the stack buffer, do the same 423b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFlags = kShortString; 424c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru uprv_memcpy(fUnion.fStackBuffer, src.fUnion.fStackBuffer, fShortLength * U_SIZEOF_UCHAR); 425b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 426b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case kLongString: 427b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // src uses a refCounted string buffer, use that buffer with refCount 428b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // src is const, use a cast - we don't really change it 429b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ((UnicodeString &)src).addRef(); 430b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // copy all fields, share the reference-counted buffer 431c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru fUnion.fFields.fArray = src.fUnion.fFields.fArray; 432c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru fUnion.fFields.fCapacity = src.fUnion.fFields.fCapacity; 433b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFlags = src.fFlags; 434b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 435b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case kReadonlyAlias: 436b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(fastCopy) { 437b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // src is a readonly alias, do the same 438b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // -> maintain the readonly alias as such 439c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru fUnion.fFields.fArray = src.fUnion.fFields.fArray; 440c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru fUnion.fFields.fCapacity = src.fUnion.fFields.fCapacity; 441b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFlags = src.fFlags; 442b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 443b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 444b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // else if(!fastCopy) fall through to case kWritableAlias 445b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // -> allocate a new buffer and copy the contents 446b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case kWritableAlias: 447b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // src is a writable alias; we make a copy of that instead 448c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if(allocate(srcLength)) { 449c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru uprv_memcpy(getArrayStart(), src.getArrayStart(), srcLength * U_SIZEOF_UCHAR); 450b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 451b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 452b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // if there is not enough memory, then fall through to setting to bogus 453b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru default: 454b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // if src is bogus, set ourselves to bogus 455b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // do not call setToBogus() here because fArray and fFlags are not consistent here 456c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru fShortLength = 0; 457c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru fUnion.fFields.fArray = 0; 458c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru fUnion.fFields.fCapacity = 0; 459b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFlags = kIsBogus; 460b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 461b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 462b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 463b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return *this; 464b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 465b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 466b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//======================================== 467b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Miscellaneous operations 468b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//======================================== 469b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 470b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString UnicodeString::unescape() const { 471c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru UnicodeString result(length(), (UChar32)0, (int32_t)0); // construct with capacity 472c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru const UChar *array = getBuffer(); 473c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru int32_t len = length(); 474c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru int32_t prev = 0; 475c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru for (int32_t i=0;;) { 476c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if (i == len) { 477c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru result.append(array, prev, len - prev); 478c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru break; 479c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } 480c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if (array[i++] == 0x5C /*'\\'*/) { 481c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru result.append(array, prev, (i - 1) - prev); 482c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru UChar32 c = unescapeAt(i); // advances i 483c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if (c < 0) { 484b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru result.remove(); // return empty string 485b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; // invalid escape sequence 486b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 487c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru result.append(c); 488c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru prev = i; 489b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 490b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 491b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return result; 492b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 493b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 494b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUChar32 UnicodeString::unescapeAt(int32_t &offset) const { 495b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return u_unescapeAt(UnicodeString_charAt, &offset, length(), (void*)this); 496b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 497b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 498b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//======================================== 499b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Read-only implementation 500b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//======================================== 501b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint8_t 502b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::doCompare( int32_t start, 503b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t length, 504b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const UChar *srcChars, 505b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t srcStart, 506b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t srcLength) const 507b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 508b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // compare illegal string values 509b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // treat const UChar *srcChars==NULL as an empty string 510b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(isBogus()) { 511b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 512b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 513b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 514b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // pin indices to legal values 515b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pinIndices(start, length); 516b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 517b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(srcChars == NULL) { 518b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru srcStart = srcLength = 0; 519b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 520b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 521b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // get the correct pointer 522b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const UChar *chars = getArrayStart(); 523b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 524b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru chars += start; 525b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru srcChars += srcStart; 526b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 527b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t minLength; 528b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int8_t lengthResult; 529b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 530b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // get the srcLength if necessary 531b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(srcLength < 0) { 532b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru srcLength = u_strlen(srcChars + srcStart); 533b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 534b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 535b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // are we comparing different lengths? 536b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(length != srcLength) { 537b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(length < srcLength) { 538b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru minLength = length; 539b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru lengthResult = -1; 540b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 541b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru minLength = srcLength; 542b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru lengthResult = 1; 543b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 544b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 545b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru minLength = length; 546b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru lengthResult = 0; 547b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 548b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 549b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 550b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * note that uprv_memcmp() returns an int but we return an int8_t; 551b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * we need to take care not to truncate the result - 552b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * one way to do this is to right-shift the value to 553b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * move the sign bit into the lower 8 bits and making sure that this 554b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * does not become 0 itself 555b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 556b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 557b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(minLength > 0 && chars != srcChars) { 558b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t result; 559b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 560b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru# if U_IS_BIG_ENDIAN 561b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // big-endian: byte comparison works 562b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru result = uprv_memcmp(chars, srcChars, minLength * sizeof(UChar)); 563b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(result != 0) { 564b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return (int8_t)(result >> 15 | 1); 565b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 566b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru# else 567b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // little-endian: compare UChar units 568b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru do { 569b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru result = ((int32_t)*(chars++) - (int32_t)*(srcChars++)); 570b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(result != 0) { 571b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return (int8_t)(result >> 15 | 1); 572b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 573b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } while(--minLength > 0); 574b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru# endif 575b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 576b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return lengthResult; 577b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 578b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 579b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* String compare in code point order - doCompare() compares in code unit order. */ 580b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint8_t 581b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::doCompareCodePointOrder(int32_t start, 582b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t length, 583b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const UChar *srcChars, 584b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t srcStart, 585b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t srcLength) const 586b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 587b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // compare illegal string values 588b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // treat const UChar *srcChars==NULL as an empty string 589b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(isBogus()) { 590b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 591b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 592b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 593b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // pin indices to legal values 594b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pinIndices(start, length); 595b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 596b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(srcChars == NULL) { 597b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru srcStart = srcLength = 0; 598b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 599b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 600c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru int32_t diff = uprv_strCompare(getArrayStart() + start, length, srcChars + srcStart, srcLength, FALSE, TRUE); 601b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* translate the 32-bit result into an 8-bit one */ 602b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(diff!=0) { 603b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return (int8_t)(diff >> 15 | 1); 604b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 605b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 606b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 607b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 608b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 609b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t 610b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::getLength() const { 611b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return length(); 612b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 613b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 614b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUChar 615b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::getCharAt(int32_t offset) const { 616b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return charAt(offset); 617b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 618b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 619b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUChar32 620b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::getChar32At(int32_t offset) const { 621b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return char32At(offset); 622b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 623b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 624b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t 625b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::countChar32(int32_t start, int32_t length) const { 626b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pinIndices(start, length); 627b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // if(isBogus()) then fArray==0 and start==0 - u_countChar32() checks for NULL 628c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru return u_countChar32(getArrayStart()+start, length); 629b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 630b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 631b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUBool 632b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::hasMoreChar32Than(int32_t start, int32_t length, int32_t number) const { 633b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pinIndices(start, length); 634b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // if(isBogus()) then fArray==0 and start==0 - u_strHasMoreChar32Than() checks for NULL 635c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru return u_strHasMoreChar32Than(getArrayStart()+start, length, number); 636b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 637b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 638b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t 639b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::moveIndex32(int32_t index, int32_t delta) const { 640b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // pin index 641c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru int32_t len = length(); 642b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(index<0) { 643b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru index=0; 644c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } else if(index>len) { 645c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru index=len; 646b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 647b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 648c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru const UChar *array = getArrayStart(); 649b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(delta>0) { 650c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru UTF_FWD_N(array, index, len, delta); 651b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 652c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru UTF_BACK_N(array, 0, index, -delta); 653b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 654b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 655b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return index; 656b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 657b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 658b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid 659b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::doExtract(int32_t start, 660b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t length, 661b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UChar *dst, 662b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t dstStart) const 663b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 664b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // pin indices to legal values 665b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pinIndices(start, length); 666b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 667b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // do not copy anything if we alias dst itself 668c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru const UChar *array = getArrayStart(); 669c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if(array + start != dst + dstStart) { 670c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru us_arrayCopy(array, start, dst, dstStart, length); 671b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 672b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 673b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 674b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t 675b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::extract(UChar *dest, int32_t destCapacity, 676b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode &errorCode) const { 677c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru int32_t len = length(); 678b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(U_SUCCESS(errorCode)) { 679b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(isBogus() || destCapacity<0 || (destCapacity>0 && dest==0)) { 680b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru errorCode=U_ILLEGAL_ARGUMENT_ERROR; 681b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 682c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru const UChar *array = getArrayStart(); 683c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if(len>0 && len<=destCapacity && array!=dest) { 684c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru uprv_memcpy(dest, array, len*U_SIZEOF_UCHAR); 685b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 686c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru return u_terminateUChars(dest, destCapacity, len, &errorCode); 687b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 688b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 689b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 690c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru return len; 691b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 692b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 693b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t 694b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::extract(int32_t start, 695b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t length, 696b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char *target, 697b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t targetCapacity, 698b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru enum EInvariant) const 699b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 700b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // if the arguments are illegal, then do nothing 701b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(targetCapacity < 0 || (targetCapacity > 0 && target == NULL)) { 702b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 703b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 704b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 705b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // pin the indices to legal values 706b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pinIndices(start, length); 707b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 708b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(length <= targetCapacity) { 709b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru u_UCharsToChars(getArrayStart() + start, target, length); 710b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 711b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode status = U_ZERO_ERROR; 712b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return u_terminateChars(target, targetCapacity, length, &status); 713b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 714b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 715b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid 716b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::extractBetween(int32_t start, 717b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t limit, 718b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UnicodeString& target) const { 719b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pinIndex(start); 720b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pinIndex(limit); 721b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru doExtract(start, limit - start, target); 722b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 723b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 724b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t 725b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::indexOf(const UChar *srcChars, 726b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t srcStart, 727b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t srcLength, 728b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t start, 729b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t length) const 730b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 731b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(isBogus() || srcChars == 0 || srcStart < 0 || srcLength == 0) { 732b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 733b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 734b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 735b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // UnicodeString does not find empty substrings 736b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(srcLength < 0 && srcChars[srcStart] == 0) { 737b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 738b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 739b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 740b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // get the indices within bounds 741b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pinIndices(start, length); 742b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 743b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // find the first occurrence of the substring 744c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru const UChar *array = getArrayStart(); 745c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru const UChar *match = u_strFindFirst(array + start, length, srcChars + srcStart, srcLength); 746b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(match == NULL) { 747b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 748b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 749c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru return (int32_t)(match - array); 750b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 751b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 752b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 753b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t 754b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::doIndexOf(UChar c, 755b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t start, 756b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t length) const 757b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 758b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // pin indices 759b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pinIndices(start, length); 760b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 761b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // find the first occurrence of c 762c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru const UChar *array = getArrayStart(); 763c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru const UChar *match = u_memchr(array + start, c, length); 764b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(match == NULL) { 765b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 766b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 767c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru return (int32_t)(match - array); 768b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 769b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 770b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 771b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t 772b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::doIndexOf(UChar32 c, 773b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t start, 774b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t length) const { 775b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // pin indices 776b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pinIndices(start, length); 777b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 778b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // find the first occurrence of c 779c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru const UChar *array = getArrayStart(); 780c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru const UChar *match = u_memchr32(array + start, c, length); 781b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(match == NULL) { 782b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 783b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 784c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru return (int32_t)(match - array); 785b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 786b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 787b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 788b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t 789b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::lastIndexOf(const UChar *srcChars, 790b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t srcStart, 791b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t srcLength, 792b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t start, 793b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t length) const 794b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 795b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(isBogus() || srcChars == 0 || srcStart < 0 || srcLength == 0) { 796b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 797b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 798b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 799b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // UnicodeString does not find empty substrings 800b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(srcLength < 0 && srcChars[srcStart] == 0) { 801b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 802b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 803b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 804b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // get the indices within bounds 805b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pinIndices(start, length); 806b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 807b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // find the last occurrence of the substring 808c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru const UChar *array = getArrayStart(); 809c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru const UChar *match = u_strFindLast(array + start, length, srcChars + srcStart, srcLength); 810b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(match == NULL) { 811b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 812b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 813c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru return (int32_t)(match - array); 814b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 815b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 816b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 817b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t 818b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::doLastIndexOf(UChar c, 819b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t start, 820b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t length) const 821b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 822b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(isBogus()) { 823b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 824b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 825b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 826b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // pin indices 827b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pinIndices(start, length); 828b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 829b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // find the last occurrence of c 830c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru const UChar *array = getArrayStart(); 831c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru const UChar *match = u_memrchr(array + start, c, length); 832b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(match == NULL) { 833b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 834b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 835c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru return (int32_t)(match - array); 836b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 837b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 838b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 839b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t 840b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::doLastIndexOf(UChar32 c, 841b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t start, 842b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t length) const { 843b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // pin indices 844b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pinIndices(start, length); 845b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 846b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // find the last occurrence of c 847c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru const UChar *array = getArrayStart(); 848c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru const UChar *match = u_memrchr32(array + start, c, length); 849b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(match == NULL) { 850b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 851b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 852c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru return (int32_t)(match - array); 853b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 854b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 855b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 856b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//======================================== 857b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Write implementation 858b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//======================================== 859b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 860b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString& 861b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::findAndReplace(int32_t start, 862b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t length, 863b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const UnicodeString& oldText, 864b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t oldStart, 865b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t oldLength, 866b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const UnicodeString& newText, 867b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t newStart, 868b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t newLength) 869b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 870b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(isBogus() || oldText.isBogus() || newText.isBogus()) { 871b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return *this; 872b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 873b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 874b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pinIndices(start, length); 875b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru oldText.pinIndices(oldStart, oldLength); 876b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru newText.pinIndices(newStart, newLength); 877b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 878b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(oldLength == 0) { 879b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return *this; 880b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 881b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 882b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(length > 0 && length >= oldLength) { 883b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t pos = indexOf(oldText, oldStart, oldLength, start, length); 884b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(pos < 0) { 885b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // no more oldText's here: done 886b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 887b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 888b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // we found oldText, replace it by newText and go beyond it 889b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru replace(pos, oldLength, newText, newStart, newLength); 890b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru length -= pos + oldLength - start; 891b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru start = pos + newLength; 892b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 893b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 894b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 895b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return *this; 896b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 897b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 898b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 899b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid 900b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::setToBogus() 901b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 902b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru releaseArray(); 903b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 904c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru fShortLength = 0; 905c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru fUnion.fFields.fArray = 0; 906c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru fUnion.fFields.fCapacity = 0; 907b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFlags = kIsBogus; 908b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 909b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 910b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// turn a bogus string into an empty one 911b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid 912b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::unBogus() { 913b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(fFlags & kIsBogus) { 914c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru setToEmpty(); 915b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 916b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 917b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 918b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// setTo() analogous to the readonly-aliasing constructor with the same signature 919b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString & 920b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::setTo(UBool isTerminated, 921b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const UChar *text, 922b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t textLength) 923b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 924b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(fFlags & kOpenGetBuffer) { 925b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // do not modify a string that has an "open" getBuffer(minCapacity) 926b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return *this; 927b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 928b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 929b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(text == NULL) { 930b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // treat as an empty string, do not alias 931b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru releaseArray(); 932c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru setToEmpty(); 933b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return *this; 934b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 935b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 936b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if( textLength < -1 || 937b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (textLength == -1 && !isTerminated) || 938b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (textLength >= 0 && isTerminated && text[textLength] != 0) 939b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ) { 940b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru setToBogus(); 941b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return *this; 942b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 943b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 944b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru releaseArray(); 945b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 946c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if(textLength == -1) { 947b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // text is terminated, or else it would have failed the above test 948c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru textLength = u_strlen(text); 949b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 950c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru setArray((UChar *)text, textLength, isTerminated ? textLength + 1 : textLength); 951b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 952b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFlags = kReadonlyAlias; 953b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return *this; 954b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 955b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 956b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// setTo() analogous to the writable-aliasing constructor with the same signature 957b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString & 958b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::setTo(UChar *buffer, 959b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t buffLength, 960b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t buffCapacity) { 961b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(fFlags & kOpenGetBuffer) { 962b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // do not modify a string that has an "open" getBuffer(minCapacity) 963b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return *this; 964b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 965b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 966b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(buffer == NULL) { 967b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // treat as an empty string, do not alias 968b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru releaseArray(); 969c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru setToEmpty(); 970b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return *this; 971b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 972b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 973b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(buffLength < -1 || buffCapacity < 0 || buffLength > buffCapacity) { 974b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru setToBogus(); 975b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return *this; 976b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else if(buffLength == -1) { 977b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // buffLength = u_strlen(buff); but do not look beyond buffCapacity 978b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const UChar *p = buffer, *limit = buffer + buffCapacity; 979b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(p != limit && *p != 0) { 980b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++p; 981b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 982b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru buffLength = (int32_t)(p - buffer); 983b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 984b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 985b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru releaseArray(); 986b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 987c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru setArray(buffer, buffLength, buffCapacity); 988b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFlags = kWritableAlias; 989b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return *this; 990b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 991b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 992b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString& 993b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::setCharAt(int32_t offset, 994b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UChar c) 995b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 996c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru int32_t len = length(); 997c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if(cloneArrayIfNeeded() && len > 0) { 998b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(offset < 0) { 999b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru offset = 0; 1000c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } else if(offset >= len) { 1001c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru offset = len - 1; 1002b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1003b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1004c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru getArrayStart()[offset] = c; 1005b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1006b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return *this; 1007b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1008b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1009b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString& 1010b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::doReplace( int32_t start, 1011b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t length, 1012b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const UnicodeString& src, 1013b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t srcStart, 1014b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t srcLength) 1015b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1016b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(!src.isBogus()) { 1017b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // pin the indices to legal values 1018b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru src.pinIndices(srcStart, srcLength); 1019b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1020b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // get the characters from src 1021b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // and replace the range in ourselves with them 1022b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return doReplace(start, length, src.getArrayStart(), srcStart, srcLength); 1023b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1024b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // remove the range 1025b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return doReplace(start, length, 0, 0, 0); 1026b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1027b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1028b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1029b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString& 1030b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::doReplace(int32_t start, 1031b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t length, 1032b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const UChar *srcChars, 1033b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t srcStart, 1034b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t srcLength) 1035b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1036c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if(!isWritable()) { 1037b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return *this; 1038b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1039b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1040b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(srcChars == 0) { 1041b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru srcStart = srcLength = 0; 1042b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else if(srcLength < 0) { 1043b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // get the srcLength if necessary 1044b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru srcLength = u_strlen(srcChars + srcStart); 1045b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1046b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1047c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru int32_t oldLength = this->length(); 1048b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1049c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru // calculate the size of the string after the replace 1050c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru int32_t newSize; 1051c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru 1052c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru // optimize append() onto a large-enough, owned string 1053c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if(start >= oldLength) { 1054c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru newSize = oldLength + srcLength; 1055c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if(newSize <= getCapacity() && isBufferWritable()) { 1056c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru us_arrayCopy(srcChars, srcStart, getArrayStart(), oldLength, srcLength); 1057c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru setLength(newSize); 1058c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru return *this; 1059c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } else { 1060c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru // pin the indices to legal values 1061c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru start = oldLength; 1062c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru length = 0; 1063c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } 1064c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } else { 1065c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru // pin the indices to legal values 1066c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru pinIndices(start, length); 1067b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1068c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru newSize = oldLength - length + srcLength; 1069c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } 1070b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1071c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru // the following may change fArray but will not copy the current contents; 1072c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru // therefore we need to keep the current fArray 1073c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru UChar oldStackBuffer[US_STACKBUF_SIZE]; 1074c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru UChar *oldArray; 1075c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if((fFlags&kUsingStackBuffer) && (newSize > US_STACKBUF_SIZE)) { 1076c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru // copy the stack buffer contents because it will be overwritten with 1077c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru // fUnion.fFields values 1078c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru u_memcpy(oldStackBuffer, fUnion.fStackBuffer, oldLength); 1079c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru oldArray = oldStackBuffer; 1080c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } else { 1081c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru oldArray = getArrayStart(); 1082c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } 1083b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1084b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // clone our array and allocate a bigger array if needed 1085c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru int32_t *bufferToDelete = 0; 1086b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(!cloneArrayIfNeeded(newSize, newSize + (newSize >> 2) + kGrowSize, 1087b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, &bufferToDelete) 1088b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ) { 1089b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return *this; 1090b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1091b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1092b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // now do the replace 1093b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1094c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru UChar *newArray = getArrayStart(); 1095c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if(newArray != oldArray) { 1096b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // if fArray changed, then we need to copy everything except what will change 1097c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru us_arrayCopy(oldArray, 0, newArray, 0, start); 1098b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru us_arrayCopy(oldArray, start + length, 1099c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru newArray, start + srcLength, 1100b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru oldLength - (start + length)); 1101b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else if(length != srcLength) { 1102b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // fArray did not change; copy only the portion that isn't changing, leaving a hole 1103b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru us_arrayCopy(oldArray, start + length, 1104c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru newArray, start + srcLength, 1105b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru oldLength - (start + length)); 1106b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1107b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1108b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // now fill in the hole with the new string 1109c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru us_arrayCopy(srcChars, srcStart, newArray, start, srcLength); 1110b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1111c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru setLength(newSize); 1112b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1113b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // delayed delete in case srcChars == fArray when we started, and 1114b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // to keep oldArray alive for the above operations 1115b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (bufferToDelete) { 1116b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_free(bufferToDelete); 1117b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1118b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1119b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return *this; 1120b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1121b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1122b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/** 1123b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Replaceable API 1124b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 1125b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid 1126b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::handleReplaceBetween(int32_t start, 1127b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t limit, 1128b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const UnicodeString& text) { 1129b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru replaceBetween(start, limit, text); 1130b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1131b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1132b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/** 1133b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Replaceable API 1134b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 1135b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid 1136b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::copy(int32_t start, int32_t limit, int32_t dest) { 1137b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (limit <= start) { 1138b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; // Nothing to do; avoid bogus malloc call 1139b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1140b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UChar* text = (UChar*) uprv_malloc( sizeof(UChar) * (limit - start) ); 1141c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru // Check to make sure text is not null. 1142c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if (text != NULL) { 1143c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru extractBetween(start, limit, text, 0); 1144c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru insert(dest, text, 0, limit - start); 1145c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru uprv_free(text); 1146c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } 1147b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1148b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1149b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/** 1150b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Replaceable API 1151b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 1152b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * NOTE: This is for the Replaceable class. There is no rep.cpp, 1153b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * so we implement this function here. 1154b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 1155b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUBool Replaceable::hasMetaData() const { 1156b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return TRUE; 1157b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1158b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1159b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/** 1160b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Replaceable API 1161b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 1162b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUBool UnicodeString::hasMetaData() const { 1163b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return FALSE; 1164b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1165b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1166b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString& 1167b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::doReverse(int32_t start, 1168b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t length) 1169b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1170c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if(this->length() <= 1 || !cloneArrayIfNeeded()) { 1171b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return *this; 1172b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1173b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1174b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // pin the indices to legal values 1175b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pinIndices(start, length); 1176b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1177b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UChar *left = getArrayStart() + start; 1178c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru UChar *right = left + length; 1179b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UChar swap; 1180b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UBool hasSupplementary = FALSE; 1181b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1182b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(left < --right) { 1183b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru hasSupplementary |= (UBool)UTF_IS_LEAD(swap = *left); 1184b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru hasSupplementary |= (UBool)UTF_IS_LEAD(*left++ = *right); 1185b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *right = swap; 1186b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1187b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1188b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* if there are supplementary code points in the reversed range, then re-swap their surrogates */ 1189b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(hasSupplementary) { 1190b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UChar swap2; 1191b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1192b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru left = getArrayStart() + start; 1193c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru right = left + length - 1; // -1 so that we can look at *(left+1) if left<right 1194b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(left < right) { 1195b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(UTF_IS_TRAIL(swap = *left) && UTF_IS_LEAD(swap2 = *(left + 1))) { 1196b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *left++ = swap2; 1197b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *left++ = swap; 1198b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1199b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++left; 1200b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1201b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1202b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1203b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1204b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return *this; 1205b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1206b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1207b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUBool 1208b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::padLeading(int32_t targetLength, 1209b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UChar padChar) 1210b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1211c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru int32_t oldLength = length(); 1212c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if(oldLength >= targetLength || !cloneArrayIfNeeded(targetLength)) { 1213b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return FALSE; 1214b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1215b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // move contents up by padding width 1216c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru UChar *array = getArrayStart(); 1217c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru int32_t start = targetLength - oldLength; 1218c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru us_arrayCopy(array, 0, array, start, oldLength); 1219b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1220b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // fill in padding character 1221b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(--start >= 0) { 1222c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru array[start] = padChar; 1223b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1224c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru setLength(targetLength); 1225b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return TRUE; 1226b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1227b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1228b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1229b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUBool 1230b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::padTrailing(int32_t targetLength, 1231b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UChar padChar) 1232b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1233c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru int32_t oldLength = length(); 1234c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if(oldLength >= targetLength || !cloneArrayIfNeeded(targetLength)) { 1235b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return FALSE; 1236b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1237b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // fill in padding character 1238c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru UChar *array = getArrayStart(); 1239b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t length = targetLength; 1240c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru while(--length >= oldLength) { 1241c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru array[length] = padChar; 1242b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1243c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru setLength(targetLength); 1244b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return TRUE; 1245b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1246b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1247b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1248b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//======================================== 1249b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Hashing 1250b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//======================================== 1251b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t 1252b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::doHashCode() const 1253b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1254b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* Delegate hash computation to uhash. This makes UnicodeString 1255b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * hashing consistent with UChar* hashing. */ 1256c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru int32_t hashCode = uhash_hashUCharsN(getArrayStart(), length()); 1257b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (hashCode == kInvalidHashCode) { 1258b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru hashCode = kEmptyHashCode; 1259b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1260b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return hashCode; 1261b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1262b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1263b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//======================================== 1264b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// External Buffer 1265b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//======================================== 1266b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1267b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUChar * 1268b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::getBuffer(int32_t minCapacity) { 1269b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(minCapacity>=-1 && cloneArrayIfNeeded(minCapacity)) { 1270b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFlags|=kOpenGetBuffer; 1271c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru fShortLength=0; 1272c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru return getArrayStart(); 1273b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1274b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 1275b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1276b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1277b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1278b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid 1279b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::releaseBuffer(int32_t newLength) { 1280b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(fFlags&kOpenGetBuffer && newLength>=-1) { 1281b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // set the new fLength 1282c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru int32_t capacity=getCapacity(); 1283b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(newLength==-1) { 1284b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // the new length is the string length, capped by fCapacity 1285c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru const UChar *array=getArrayStart(), *p=array, *limit=array+capacity; 1286b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(p<limit && *p!=0) { 1287b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++p; 1288b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1289c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru newLength=(int32_t)(p-array); 1290c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } else if(newLength>capacity) { 1291c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru newLength=capacity; 1292b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1293c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru setLength(newLength); 1294b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFlags&=~kOpenGetBuffer; 1295b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1296b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1297b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1298b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//======================================== 1299b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Miscellaneous 1300b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//======================================== 1301b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUBool 1302b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::cloneArrayIfNeeded(int32_t newCapacity, 1303b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t growCapacity, 1304b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UBool doCopyArray, 1305b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t **pBufferToDelete, 1306b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UBool forceClone) { 1307b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // default parameters need to be static, therefore 1308b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // the defaults are -1 to have convenience defaults 1309b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(newCapacity == -1) { 1310c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru newCapacity = getCapacity(); 1311b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1312b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1313b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // while a getBuffer(minCapacity) is "open", 1314b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // prevent any modifications of the string by returning FALSE here 1315b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // if the string is bogus, then only an assignment or similar can revive it 1316c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if(!isWritable()) { 1317b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return FALSE; 1318b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1319b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1320b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 1321b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * We need to make a copy of the array if 1322b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * the buffer is read-only, or 1323b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * the buffer is refCounted (shared), and refCount>1, or 1324b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * the buffer is too small. 1325b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Return FALSE if memory could not be allocated. 1326b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 1327b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(forceClone || 1328b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFlags & kBufferIsReadonly || 1329b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFlags & kRefCounted && refCount() > 1 || 1330c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru newCapacity > getCapacity() 1331b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ) { 1332b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // check growCapacity for default value and use of the stack buffer 1333b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(growCapacity == -1) { 1334b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru growCapacity = newCapacity; 1335b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else if(newCapacity <= US_STACKBUF_SIZE && growCapacity > US_STACKBUF_SIZE) { 1336b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru growCapacity = US_STACKBUF_SIZE; 1337b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1338b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1339c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru // save old values 1340c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru UChar oldStackBuffer[US_STACKBUF_SIZE]; 1341c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru UChar *oldArray; 1342c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru uint8_t flags = fFlags; 1343c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru 1344c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if(flags&kUsingStackBuffer) { 1345c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if(doCopyArray && growCapacity > US_STACKBUF_SIZE) { 1346c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru // copy the stack buffer contents because it will be overwritten with 1347c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru // fUnion.fFields values 1348c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru us_arrayCopy(fUnion.fStackBuffer, 0, oldStackBuffer, 0, fShortLength); 1349c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru oldArray = oldStackBuffer; 1350c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } else { 1351c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru oldArray = 0; // no need to copy from stack buffer to itself 1352c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } 1353c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } else { 1354c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru oldArray = fUnion.fFields.fArray; 1355c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } 1356c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru 1357b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // allocate a new array 1358b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(allocate(growCapacity) || 1359b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru newCapacity < growCapacity && allocate(newCapacity) 1360b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ) { 1361c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if(doCopyArray && oldArray != 0) { 1362b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // copy the contents 1363b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // do not copy more than what fits - it may be smaller than before 1364c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru int32_t minLength = length(); 1365c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru newCapacity = getCapacity(); 1366c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if(newCapacity < minLength) { 1367c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru minLength = newCapacity; 1368c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru setLength(minLength); 1369b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1370c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru us_arrayCopy(oldArray, 0, getArrayStart(), 0, minLength); 1371b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1372c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru fShortLength = 0; 1373b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1374b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1375b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // release the old array 1376b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(flags & kRefCounted) { 1377b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // the array is refCounted; decrement and release if 0 1378c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru int32_t *pRefCount = ((int32_t *)oldArray - 1); 1379b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(umtx_atomic_dec(pRefCount) == 0) { 1380b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(pBufferToDelete == 0) { 1381b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_free(pRefCount); 1382b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1383b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // the caller requested to delete it himself 1384b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *pBufferToDelete = pRefCount; 1385b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1386b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1387b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1388b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1389b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // not enough memory for growCapacity and not even for the smaller newCapacity 1390b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // reset the old values for setToBogus() to release the array 1391c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if(!(flags&kUsingStackBuffer)) { 1392c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru fUnion.fFields.fArray = oldArray; 1393c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } 1394b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFlags = flags; 1395b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru setToBogus(); 1396b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return FALSE; 1397b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1398b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1399b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return TRUE; 1400b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1401b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_NAMESPACE_END 1402b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1403b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#ifdef U_STATIC_IMPLEMENTATION 1404b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* 1405b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruThis should never be called. It is defined here to make sure that the 1406b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvirtual vector deleting destructor is defined within unistr.cpp. 1407b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruThe vector deleting destructor is already a part of UObject, 1408b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querubut defining it here makes sure that it is included with this object file. 1409b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruThis makes sure that static library dependencies are kept to a minimum. 1410b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*/ 1411b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void uprv_UnicodeStringDummy(void) { 1412b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru U_NAMESPACE_USE 1413b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru delete [] (new UnicodeString[2]); 1414b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1415b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 1416b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1417