1b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* 2b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru****************************************************************************** 359d709d503bab6e2b61931737e662dd293b40578ccornelius* Copyright (C) 1999-2013, International Business Machines Corporation and 4103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius* others. All Rights Reserved. 5b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru****************************************************************************** 6b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 7b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* File unistr.cpp 8b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 9b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* Modification History: 10b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 11b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* Date Name Description 12b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 09/25/98 stephen Creation. 13b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 04/20/99 stephen Overhauled per 4/16 code review. 14b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 07/09/99 stephen Renamed {hi,lo},{byte,word} to icu_X for HP/UX 15b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 11/18/99 aliu Added handleReplaceBetween() to make inherit from 16b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* Replaceable. 17b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 06/25/01 grhoten Removed the dependency on iostream 18b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru****************************************************************************** 19b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*/ 20b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 21b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/utypes.h" 22b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "unicode/appendable.h" 23b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/putil.h" 24b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "cstring.h" 25b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "cmemory.h" 26b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/ustring.h" 27b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/unistr.h" 28103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#include "unicode/utf.h" 29103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#include "unicode/utf16.h" 30103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#include "uelement.h" 31b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "ustr_imp.h" 32b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "umutex.h" 33103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#include "uassert.h" 34b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 35b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if 0 36b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 37b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include <iostream> 38b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruusing namespace std; 39b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 40b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//DEBUGGING 41b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid 42b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruprint(const UnicodeString& s, 43b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char *name) 44b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 45b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UChar c; 46b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru cout << name << ":|"; 47b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(int i = 0; i < s.length(); ++i) { 48b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru c = s[i]; 49b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(c>= 0x007E || c < 0x0020) 50b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru cout << "[0x" << hex << s[i] << "]"; 51b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else 52b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru cout << (char) s[i]; 53b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 54b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru cout << '|' << endl; 55b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 56b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 57b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid 58b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruprint(const UChar *s, 59b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t len, 60b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char *name) 61b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 62b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UChar c; 63b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru cout << name << ":|"; 64b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(int i = 0; i < len; ++i) { 65b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru c = s[i]; 66b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(c>= 0x007E || c < 0x0020) 67b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru cout << "[0x" << hex << s[i] << "]"; 68b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else 69b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru cout << (char) s[i]; 70b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 71b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru cout << '|' << endl; 72b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 73b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// END DEBUGGING 74b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 75b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 76b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Local function definitions for now 77b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 78b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// need to copy areas that may overlap 79b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic 80b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruinline void 81b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruus_arrayCopy(const UChar *src, int32_t srcStart, 82b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UChar *dst, int32_t dstStart, int32_t count) 83b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 84b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(count>0) { 85b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_memmove(dst+dstStart, src+srcStart, (size_t)(count*sizeof(*src))); 86b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 87b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 88b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 89b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// u_unescapeAt() callback to get a UChar from a UnicodeString 90b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CDECL_BEGIN 91b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic UChar U_CALLCONV 92b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString_charAt(int32_t offset, void *context) { 93103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return ((icu::UnicodeString*) context)->charAt(offset); 94b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 95b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CDECL_END 96b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 97b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_NAMESPACE_BEGIN 98b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 99b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* The Replaceable virtual destructor can't be defined in the header 100b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru due to how AIX works with multiple definitions of virtual functions. 101b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*/ 102b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruReplaceable::~Replaceable() {} 1038393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 104b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUOBJECT_DEFINE_RTTI_IMPLEMENTATION(UnicodeString) 105b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 106b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString U_EXPORT2 107b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruoperator+ (const UnicodeString &s1, const UnicodeString &s2) { 108b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 109b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UnicodeString(s1.length()+s2.length()+1, (UChar32)0, 0). 110b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru append(s1). 111b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru append(s2); 112b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 113b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 114b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//======================================== 115b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Reference Counting functions, put at top of file so that optimizing compilers 116b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// have a chance to automatically inline. 117b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//======================================== 118b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 119b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid 12059d709d503bab6e2b61931737e662dd293b40578ccorneliusUnicodeString::addRef() { 12159d709d503bab6e2b61931737e662dd293b40578ccornelius umtx_atomic_inc((u_atomic_int32_t *)fUnion.fFields.fArray - 1); 12259d709d503bab6e2b61931737e662dd293b40578ccornelius} 123b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 124b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t 12559d709d503bab6e2b61931737e662dd293b40578ccorneliusUnicodeString::removeRef() { 12659d709d503bab6e2b61931737e662dd293b40578ccornelius return umtx_atomic_dec((u_atomic_int32_t *)fUnion.fFields.fArray - 1); 12759d709d503bab6e2b61931737e662dd293b40578ccornelius} 128b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 129b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t 13059d709d503bab6e2b61931737e662dd293b40578ccorneliusUnicodeString::refCount() const { 13159d709d503bab6e2b61931737e662dd293b40578ccornelius return umtx_loadAcquire(*((u_atomic_int32_t *)fUnion.fFields.fArray - 1)); 13259d709d503bab6e2b61931737e662dd293b40578ccornelius} 133b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 134b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid 135b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::releaseArray() { 136b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if((fFlags & kRefCounted) && removeRef() == 0) { 137c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru uprv_free((int32_t *)fUnion.fFields.fArray - 1); 138b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 139b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 140b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 141b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 142b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 143b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//======================================== 144b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Constructors 145b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//======================================== 1468393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 1478393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius// The default constructor is inline in unistr.h. 148b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 149b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::UnicodeString(int32_t capacity, UChar32 c, int32_t count) 150c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru : fShortLength(0), 151b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFlags(0) 152b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 153b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(count <= 0 || (uint32_t)c > 0x10ffff) { 154b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // just allocate and do not do anything else 155b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru allocate(capacity); 156b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 157b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // count > 0, allocate and fill the new string with count c's 158103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t unitCount = U16_LENGTH(c), length = count * unitCount; 159b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(capacity < length) { 160b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru capacity = length; 161b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 162b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(allocate(capacity)) { 163c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru UChar *array = getArrayStart(); 164b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t i = 0; 165b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 166b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // fill the new string with c 167b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(unitCount == 1) { 168b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // fill with length UChars 169b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(i < length) { 170c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru array[i++] = (UChar)c; 171b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 172b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 173b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // get the code units for c 174103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius UChar units[U16_MAX_LENGTH]; 175103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius U16_APPEND_UNSAFE(units, i, c); 176b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 177b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // now it must be i==unitCount 178b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru i = 0; 179b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 180b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // for Unicode, unitCount can only be 1, 2, 3, or 4 181b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // 1 is handled above 182b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(i < length) { 183b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t unitIdx = 0; 184b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(unitIdx < unitCount) { 185c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru array[i++]=units[unitIdx++]; 186b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 187b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 188b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 189b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 190c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru setLength(length); 191b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 192b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 193b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 194b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::UnicodeString(UChar ch) 195c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru : fShortLength(1), 196b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFlags(kShortString) 197b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 198c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru fUnion.fStackBuffer[0] = ch; 199b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 200b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 201b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::UnicodeString(UChar32 ch) 202c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru : fShortLength(0), 203b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFlags(kShortString) 204b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 205b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t i = 0; 206b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UBool isError = FALSE; 207c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru U16_APPEND(fUnion.fStackBuffer, i, US_STACKBUF_SIZE, ch, isError); 208103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // We test isError so that the compiler does not complain that we don't. 209103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // If isError then i==0 which is what we want anyway. 210103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if(!isError) { 211103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius fShortLength = (int8_t)i; 212103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 213b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 214b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 215b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::UnicodeString(const UChar *text) 216c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru : fShortLength(0), 217b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFlags(kShortString) 218b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 219b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru doReplace(0, 0, text, 0, -1); 220b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 221b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 222b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::UnicodeString(const UChar *text, 223b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t textLength) 224c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru : fShortLength(0), 225b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFlags(kShortString) 226b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 227b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru doReplace(0, 0, text, 0, textLength); 228b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 229b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 230b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::UnicodeString(UBool isTerminated, 231b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const UChar *text, 232b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t textLength) 233c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru : fShortLength(0), 234b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFlags(kReadonlyAlias) 235b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 236b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(text == NULL) { 237b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // treat as an empty string, do not alias 238c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru setToEmpty(); 239b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else if(textLength < -1 || 240b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (textLength == -1 && !isTerminated) || 241b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (textLength >= 0 && isTerminated && text[textLength] != 0) 242b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ) { 243b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru setToBogus(); 244c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } else { 245c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if(textLength == -1) { 246c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru // text is terminated, or else it would have failed the above test 247c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru textLength = u_strlen(text); 248c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } 249c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru setArray((UChar *)text, textLength, isTerminated ? textLength + 1 : textLength); 250b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 251b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 252b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 253b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::UnicodeString(UChar *buff, 254b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t buffLength, 255b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t buffCapacity) 256c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru : fShortLength(0), 257b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFlags(kWritableAlias) 258b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 259b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(buff == NULL) { 260b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // treat as an empty string, do not alias 261c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru setToEmpty(); 262b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else if(buffLength < -1 || buffCapacity < 0 || buffLength > buffCapacity) { 263b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru setToBogus(); 264c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } else { 265c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if(buffLength == -1) { 266c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru // fLength = u_strlen(buff); but do not look beyond buffCapacity 267c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru const UChar *p = buff, *limit = buff + buffCapacity; 268c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru while(p != limit && *p != 0) { 269c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru ++p; 270c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } 271c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru buffLength = (int32_t)(p - buff); 272b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 273c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru setArray(buff, buffLength, buffCapacity); 274b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 275b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 276b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 277b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::UnicodeString(const char *src, int32_t length, EInvariant) 278c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru : fShortLength(0), 279b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFlags(kShortString) 280b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 281b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(src==NULL) { 282b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // treat as an empty string 283b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 284b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(length<0) { 285b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru length=(int32_t)uprv_strlen(src); 286b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 287b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(cloneArrayIfNeeded(length, length, FALSE)) { 288b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru u_charsToUChars(src, getArrayStart(), length); 289c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru setLength(length); 290b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 291b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru setToBogus(); 292b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 293b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 294b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 295b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 296b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#if U_CHARSET_IS_UTF8 297b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 298b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruUnicodeString::UnicodeString(const char *codepageData) 299b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru : fShortLength(0), 300b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru fFlags(kShortString) { 301b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if(codepageData != 0) { 302b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru setToUTF8(codepageData); 303b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 304b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru} 305b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 306b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruUnicodeString::UnicodeString(const char *codepageData, int32_t dataLength) 307b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru : fShortLength(0), 308b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru fFlags(kShortString) { 309b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // if there's nothing to convert, do nothing 310b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if(codepageData == 0 || dataLength == 0 || dataLength < -1) { 311b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return; 312b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 313b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if(dataLength == -1) { 314b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru dataLength = (int32_t)uprv_strlen(codepageData); 315b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 316b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru setToUTF8(StringPiece(codepageData, dataLength)); 317b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru} 318b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 319b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru// else see unistr_cnv.cpp 320b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#endif 321b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 322b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::UnicodeString(const UnicodeString& that) 323b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru : Replaceable(), 324c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru fShortLength(0), 325b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFlags(kShortString) 326b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 327b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru copyFrom(that); 328b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 329b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 330b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::UnicodeString(const UnicodeString& that, 331b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t srcStart) 332b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru : Replaceable(), 333c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru fShortLength(0), 334b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFlags(kShortString) 335b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 336b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru setTo(that, srcStart); 337b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 338b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 339b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::UnicodeString(const UnicodeString& that, 340b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t srcStart, 341b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t srcLength) 342b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru : Replaceable(), 343c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru fShortLength(0), 344b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFlags(kShortString) 345b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 346b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru setTo(that, srcStart, srcLength); 347b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 348b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 349b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Replaceable base class clone() default implementation, does not clone 350b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruReplaceable * 351b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruReplaceable::clone() const { 352b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 353b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 354b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 355b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// UnicodeString overrides clone() with a real implementation 356b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruReplaceable * 357b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::clone() const { 358b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return new UnicodeString(*this); 359b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 360b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 361b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//======================================== 362b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// array allocation 363b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//======================================== 364b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 365b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUBool 366b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::allocate(int32_t capacity) { 367b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(capacity <= US_STACKBUF_SIZE) { 368b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFlags = kShortString; 369b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 370b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // count bytes for the refCounter and the string capacity, and 371b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // round up to a multiple of 16; then divide by 4 and allocate int32_t's 372b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // to be safely aligned for the refCount 37350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // the +1 is for the NUL terminator, to avoid reallocation in getTerminatedBuffer() 37450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t words = (int32_t)(((sizeof(int32_t) + (capacity + 1) * U_SIZEOF_UCHAR + 15) & ~15) >> 2); 375b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t *array = (int32_t*) uprv_malloc( sizeof(int32_t) * words ); 376b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(array != 0) { 377b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // set initial refCount and point behind the refCount 378b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *array++ = 1; 379b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 380b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // have fArray point to the first UChar 381c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru fUnion.fFields.fArray = (UChar *)array; 382c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru fUnion.fFields.fCapacity = (int32_t)((words - 1) * (sizeof(int32_t) / U_SIZEOF_UCHAR)); 383b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFlags = kLongString; 384b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 385c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru fShortLength = 0; 386c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru fUnion.fFields.fArray = 0; 387c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru fUnion.fFields.fCapacity = 0; 388b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFlags = kIsBogus; 389b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return FALSE; 390b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 391b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 392b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return TRUE; 393b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 394b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 395b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//======================================== 396b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Destructor 397b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//======================================== 398b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::~UnicodeString() 399b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 400b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru releaseArray(); 401b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 402b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 403b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru//======================================== 404b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru// Factory methods 405b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru//======================================== 406b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 407b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruUnicodeString UnicodeString::fromUTF8(const StringPiece &utf8) { 408b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru UnicodeString result; 409b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru result.setToUTF8(utf8); 410b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return result; 411b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru} 412b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 413b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruUnicodeString UnicodeString::fromUTF32(const UChar32 *utf32, int32_t length) { 414b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru UnicodeString result; 415b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int32_t capacity; 416b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // Most UTF-32 strings will be BMP-only and result in a same-length 417b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // UTF-16 string. We overestimate the capacity just slightly, 418b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // just in case there are a few supplementary characters. 419b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if(length <= US_STACKBUF_SIZE) { 420b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru capacity = US_STACKBUF_SIZE; 421b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } else { 422b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru capacity = length + (length >> 4) + 4; 423b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 424b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru do { 425b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru UChar *utf16 = result.getBuffer(capacity); 426b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int32_t length16; 427b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru UErrorCode errorCode = U_ZERO_ERROR; 428b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru u_strFromUTF32WithSub(utf16, result.getCapacity(), &length16, 429b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru utf32, length, 430b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 0xfffd, // Substitution character. 431b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru NULL, // Don't care about number of substitutions. 432b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru &errorCode); 433b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru result.releaseBuffer(length16); 434b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if(errorCode == U_BUFFER_OVERFLOW_ERROR) { 435b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru capacity = length16 + 1; // +1 for the terminating NUL. 436b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru continue; 437b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } else if(U_FAILURE(errorCode)) { 438b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru result.setToBogus(); 439b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 440b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru break; 441b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } while(TRUE); 442b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return result; 443b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru} 444b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 445b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//======================================== 446b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Assignment 447b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//======================================== 448b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 449b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString & 450b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::operator=(const UnicodeString &src) { 451b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return copyFrom(src); 452b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 453b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 454b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString & 455b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::fastCopyFrom(const UnicodeString &src) { 456b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return copyFrom(src, TRUE); 457b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 458b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 459b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString & 460b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::copyFrom(const UnicodeString &src, UBool fastCopy) { 461b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // if assigning to ourselves, do nothing 462b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(this == 0 || this == &src) { 463b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return *this; 464b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 465b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 466b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // is the right side bogus? 467b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(&src == 0 || src.isBogus()) { 468b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru setToBogus(); 469b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return *this; 470b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 471b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 472b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // delete the current contents 473b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru releaseArray(); 474b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 475c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if(src.isEmpty()) { 476b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // empty string - use the stack buffer 477c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru setToEmpty(); 478b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return *this; 479b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 480b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 481c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru // we always copy the length 482c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru int32_t srcLength = src.length(); 483c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru setLength(srcLength); 484c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru 485b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // fLength>0 and not an "open" src.getBuffer(minCapacity) 486b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru switch(src.fFlags) { 487b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case kShortString: 488b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // short string using the stack buffer, do the same 489b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFlags = kShortString; 49050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uprv_memcpy(fUnion.fStackBuffer, src.fUnion.fStackBuffer, srcLength * U_SIZEOF_UCHAR); 491b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 492b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case kLongString: 493b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // src uses a refCounted string buffer, use that buffer with refCount 494b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // src is const, use a cast - we don't really change it 495b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ((UnicodeString &)src).addRef(); 496b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // copy all fields, share the reference-counted buffer 497c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru fUnion.fFields.fArray = src.fUnion.fFields.fArray; 498c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru fUnion.fFields.fCapacity = src.fUnion.fFields.fCapacity; 499b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFlags = src.fFlags; 500b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 501b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case kReadonlyAlias: 502b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(fastCopy) { 503b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // src is a readonly alias, do the same 504b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // -> maintain the readonly alias as such 505c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru fUnion.fFields.fArray = src.fUnion.fFields.fArray; 506c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru fUnion.fFields.fCapacity = src.fUnion.fFields.fCapacity; 507b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFlags = src.fFlags; 508b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 509b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 510b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // else if(!fastCopy) fall through to case kWritableAlias 511b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // -> allocate a new buffer and copy the contents 512b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case kWritableAlias: 513b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // src is a writable alias; we make a copy of that instead 514c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if(allocate(srcLength)) { 515c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru uprv_memcpy(getArrayStart(), src.getArrayStart(), srcLength * U_SIZEOF_UCHAR); 516b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 517b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 518b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // if there is not enough memory, then fall through to setting to bogus 519b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru default: 520b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // if src is bogus, set ourselves to bogus 521b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // do not call setToBogus() here because fArray and fFlags are not consistent here 522c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru fShortLength = 0; 523c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru fUnion.fFields.fArray = 0; 524c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru fUnion.fFields.fCapacity = 0; 525b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFlags = kIsBogus; 526b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 527b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 528b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 529b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return *this; 530b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 531b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 532b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//======================================== 533b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Miscellaneous operations 534b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//======================================== 535b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 536b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString UnicodeString::unescape() const { 537c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru UnicodeString result(length(), (UChar32)0, (int32_t)0); // construct with capacity 538c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru const UChar *array = getBuffer(); 539c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru int32_t len = length(); 540c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru int32_t prev = 0; 541c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru for (int32_t i=0;;) { 542c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if (i == len) { 543c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru result.append(array, prev, len - prev); 544c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru break; 545c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } 546c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if (array[i++] == 0x5C /*'\\'*/) { 547c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru result.append(array, prev, (i - 1) - prev); 548c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru UChar32 c = unescapeAt(i); // advances i 549c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if (c < 0) { 550b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru result.remove(); // return empty string 551b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; // invalid escape sequence 552b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 553c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru result.append(c); 554c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru prev = i; 555b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 556b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 557b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return result; 558b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 559b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 560b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUChar32 UnicodeString::unescapeAt(int32_t &offset) const { 561b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return u_unescapeAt(UnicodeString_charAt, &offset, length(), (void*)this); 562b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 563b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 564b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//======================================== 565b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Read-only implementation 566b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//======================================== 56754dcd9b6a06071f647dac967e9e267abb9410720Craig CorneliusUBool 56854dcd9b6a06071f647dac967e9e267abb9410720Craig CorneliusUnicodeString::doEquals(const UnicodeString &text, int32_t len) const { 56954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius // Requires: this & text not bogus and have same lengths. 57054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius // Byte-wise comparison works for equality regardless of endianness. 57154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius return uprv_memcmp(getArrayStart(), text.getArrayStart(), len * U_SIZEOF_UCHAR) == 0; 57254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius} 57354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius 574b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint8_t 575b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::doCompare( int32_t start, 576b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t length, 577b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const UChar *srcChars, 578b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t srcStart, 579b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t srcLength) const 580b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 581b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // compare illegal string values 582b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(isBogus()) { 583b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 584b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 585b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 586b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // pin indices to legal values 587b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pinIndices(start, length); 588b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 589b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(srcChars == NULL) { 590103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // treat const UChar *srcChars==NULL as an empty string 591103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return length == 0 ? 0 : 1; 592b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 593b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 594b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // get the correct pointer 595b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const UChar *chars = getArrayStart(); 596b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 597b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru chars += start; 598b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru srcChars += srcStart; 599b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 600b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t minLength; 601b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int8_t lengthResult; 602b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 603b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // get the srcLength if necessary 604b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(srcLength < 0) { 605b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru srcLength = u_strlen(srcChars + srcStart); 606b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 607b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 608b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // are we comparing different lengths? 609b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(length != srcLength) { 610b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(length < srcLength) { 611b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru minLength = length; 612b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru lengthResult = -1; 613b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 614b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru minLength = srcLength; 615b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru lengthResult = 1; 616b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 617b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 618b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru minLength = length; 619b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru lengthResult = 0; 620b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 621b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 622b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 623b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * note that uprv_memcmp() returns an int but we return an int8_t; 624b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * we need to take care not to truncate the result - 625b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * one way to do this is to right-shift the value to 626b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * move the sign bit into the lower 8 bits and making sure that this 627b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * does not become 0 itself 628b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 629b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 630b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(minLength > 0 && chars != srcChars) { 631b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t result; 632b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 633b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru# if U_IS_BIG_ENDIAN 634b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // big-endian: byte comparison works 635b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru result = uprv_memcmp(chars, srcChars, minLength * sizeof(UChar)); 636b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(result != 0) { 637b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return (int8_t)(result >> 15 | 1); 638b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 639b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru# else 640b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // little-endian: compare UChar units 641b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru do { 642b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru result = ((int32_t)*(chars++) - (int32_t)*(srcChars++)); 643b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(result != 0) { 644b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return (int8_t)(result >> 15 | 1); 645b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 646b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } while(--minLength > 0); 647b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru# endif 648b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 649b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return lengthResult; 650b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 651b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 652b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* String compare in code point order - doCompare() compares in code unit order. */ 653b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint8_t 654b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::doCompareCodePointOrder(int32_t start, 655b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t length, 656b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const UChar *srcChars, 657b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t srcStart, 658b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t srcLength) const 659b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 660b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // compare illegal string values 661b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // treat const UChar *srcChars==NULL as an empty string 662b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(isBogus()) { 663b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 664b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 665b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 666b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // pin indices to legal values 667b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pinIndices(start, length); 668b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 669b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(srcChars == NULL) { 670b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru srcStart = srcLength = 0; 671b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 672b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 673103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t diff = uprv_strCompare(getArrayStart() + start, length, (srcChars!=NULL)?(srcChars + srcStart):NULL, srcLength, FALSE, TRUE); 674b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* translate the 32-bit result into an 8-bit one */ 675b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(diff!=0) { 676b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return (int8_t)(diff >> 15 | 1); 677b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 678b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 679b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 680b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 681b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 682b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t 683b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::getLength() const { 684b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return length(); 685b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 686b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 687b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUChar 688b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::getCharAt(int32_t offset) const { 689b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return charAt(offset); 690b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 691b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 692b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUChar32 693b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::getChar32At(int32_t offset) const { 694b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return char32At(offset); 695b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 696b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 697103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusUChar32 698103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusUnicodeString::char32At(int32_t offset) const 699103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius{ 700103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t len = length(); 701103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if((uint32_t)offset < (uint32_t)len) { 702103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius const UChar *array = getArrayStart(); 703103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius UChar32 c; 704103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius U16_GET(array, 0, offset, len, c); 705103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return c; 706103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } else { 707103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return kInvalidUChar; 708103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 709103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius} 710103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 711103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusint32_t 712103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusUnicodeString::getChar32Start(int32_t offset) const { 713103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if((uint32_t)offset < (uint32_t)length()) { 714103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius const UChar *array = getArrayStart(); 715103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius U16_SET_CP_START(array, 0, offset); 716103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return offset; 717103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } else { 718103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return 0; 719103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 720103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius} 721103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 722103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusint32_t 723103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusUnicodeString::getChar32Limit(int32_t offset) const { 724103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t len = length(); 725103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if((uint32_t)offset < (uint32_t)len) { 726103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius const UChar *array = getArrayStart(); 727103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius U16_SET_CP_LIMIT(array, 0, offset, len); 728103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return offset; 729103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } else { 730103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return len; 731103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 732103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius} 733103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 734b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t 735b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::countChar32(int32_t start, int32_t length) const { 736b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pinIndices(start, length); 737b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // if(isBogus()) then fArray==0 and start==0 - u_countChar32() checks for NULL 738c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru return u_countChar32(getArrayStart()+start, length); 739b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 740b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 741b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUBool 742b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::hasMoreChar32Than(int32_t start, int32_t length, int32_t number) const { 743b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pinIndices(start, length); 744b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // if(isBogus()) then fArray==0 and start==0 - u_strHasMoreChar32Than() checks for NULL 745c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru return u_strHasMoreChar32Than(getArrayStart()+start, length, number); 746b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 747b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 748b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t 749b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::moveIndex32(int32_t index, int32_t delta) const { 750b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // pin index 751c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru int32_t len = length(); 752b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(index<0) { 753b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru index=0; 754c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } else if(index>len) { 755c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru index=len; 756b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 757b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 758c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru const UChar *array = getArrayStart(); 759b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(delta>0) { 760103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius U16_FWD_N(array, index, len, delta); 761b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 762103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius U16_BACK_N(array, 0, index, -delta); 763b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 764b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 765b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return index; 766b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 767b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 768b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid 769b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::doExtract(int32_t start, 770b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t length, 771b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UChar *dst, 772b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t dstStart) const 773b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 774b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // pin indices to legal values 775b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pinIndices(start, length); 776b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 777b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // do not copy anything if we alias dst itself 778c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru const UChar *array = getArrayStart(); 779c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if(array + start != dst + dstStart) { 780c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru us_arrayCopy(array, start, dst, dstStart, length); 781b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 782b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 783b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 784b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t 785b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::extract(UChar *dest, int32_t destCapacity, 786b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode &errorCode) const { 787c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru int32_t len = length(); 788b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(U_SUCCESS(errorCode)) { 789b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(isBogus() || destCapacity<0 || (destCapacity>0 && dest==0)) { 790b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru errorCode=U_ILLEGAL_ARGUMENT_ERROR; 791b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 792c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru const UChar *array = getArrayStart(); 793c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if(len>0 && len<=destCapacity && array!=dest) { 794c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru uprv_memcpy(dest, array, len*U_SIZEOF_UCHAR); 795b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 796c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru return u_terminateUChars(dest, destCapacity, len, &errorCode); 797b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 798b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 799b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 800c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru return len; 801b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 802b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 803b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t 804b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::extract(int32_t start, 805b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t length, 806b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char *target, 807b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t targetCapacity, 808b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru enum EInvariant) const 809b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 810b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // if the arguments are illegal, then do nothing 811b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(targetCapacity < 0 || (targetCapacity > 0 && target == NULL)) { 812b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 813b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 814b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 815b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // pin the indices to legal values 816b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pinIndices(start, length); 817b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 818b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(length <= targetCapacity) { 819b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru u_UCharsToChars(getArrayStart() + start, target, length); 820b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 821b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode status = U_ZERO_ERROR; 822b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return u_terminateChars(target, targetCapacity, length, &status); 823b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 824b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 82550294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoUnicodeString 82650294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoUnicodeString::tempSubString(int32_t start, int32_t len) const { 82750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho pinIndices(start, len); 82850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const UChar *array = getBuffer(); // not getArrayStart() to check kIsBogus & kOpenGetBuffer 82950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(array==NULL) { 83050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho array=fUnion.fStackBuffer; // anything not NULL because that would make an empty string 83150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho len=-2; // bogus result string 83250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 83350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return UnicodeString(FALSE, array + start, len); 83450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 83550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 836b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queruint32_t 837b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruUnicodeString::toUTF8(int32_t start, int32_t len, 838b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru char *target, int32_t capacity) const { 839b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru pinIndices(start, len); 840b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int32_t length8; 841b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru UErrorCode errorCode = U_ZERO_ERROR; 842b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru u_strToUTF8WithSub(target, capacity, &length8, 843b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru getBuffer() + start, len, 844b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 0xFFFD, // Standard substitution character. 845b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru NULL, // Don't care about number of substitutions. 846b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru &errorCode); 847b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return length8; 848b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru} 849b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 850b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#if U_CHARSET_IS_UTF8 851b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 852b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queruint32_t 853b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruUnicodeString::extract(int32_t start, int32_t len, 854b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru char *target, uint32_t dstSize) const { 855b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // if the arguments are illegal, then do nothing 856b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if(/*dstSize < 0 || */(dstSize > 0 && target == 0)) { 857b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return 0; 858b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 859b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return toUTF8(start, len, target, dstSize <= 0x7fffffff ? (int32_t)dstSize : 0x7fffffff); 860b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru} 861b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 862b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru// else see unistr_cnv.cpp 863b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#endif 864b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 865b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid 866b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::extractBetween(int32_t start, 867b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t limit, 868b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UnicodeString& target) const { 869b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pinIndex(start); 870b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pinIndex(limit); 871b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru doExtract(start, limit - start, target); 872b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 873b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 874b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru// When converting from UTF-16 to UTF-8, the result will have at most 3 times 875b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru// as many bytes as the source has UChars. 876b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru// The "worst cases" are writing systems like Indic, Thai and CJK with 877b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru// 3:1 bytes:UChars. 878b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queruvoid 879b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruUnicodeString::toUTF8(ByteSink &sink) const { 880b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int32_t length16 = length(); 881b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if(length16 != 0) { 882b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru char stackBuffer[1024]; 883b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int32_t capacity = (int32_t)sizeof(stackBuffer); 884b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru UBool utf8IsOwned = FALSE; 885b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru char *utf8 = sink.GetAppendBuffer(length16 < capacity ? length16 : capacity, 886b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 3*length16, 887b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru stackBuffer, capacity, 888b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru &capacity); 889b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int32_t length8 = 0; 890b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru UErrorCode errorCode = U_ZERO_ERROR; 891b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru u_strToUTF8WithSub(utf8, capacity, &length8, 892b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru getBuffer(), length16, 893b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 0xFFFD, // Standard substitution character. 894b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru NULL, // Don't care about number of substitutions. 895b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru &errorCode); 896b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if(errorCode == U_BUFFER_OVERFLOW_ERROR) { 897b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru utf8 = (char *)uprv_malloc(length8); 898b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if(utf8 != NULL) { 899b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru utf8IsOwned = TRUE; 900b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru errorCode = U_ZERO_ERROR; 901b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru u_strToUTF8WithSub(utf8, length8, &length8, 902b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru getBuffer(), length16, 903b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 0xFFFD, // Standard substitution character. 904b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru NULL, // Don't care about number of substitutions. 905b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru &errorCode); 906b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } else { 907b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru errorCode = U_MEMORY_ALLOCATION_ERROR; 908b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 909b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 910b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if(U_SUCCESS(errorCode)) { 911b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru sink.Append(utf8, length8); 91227f654740f2a26ad62a5c155af9199af9e69b889claireho sink.Flush(); 913b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 914b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if(utf8IsOwned) { 915b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru uprv_free(utf8); 916b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 917b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 918b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru} 919b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 920b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queruint32_t 921b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruUnicodeString::toUTF32(UChar32 *utf32, int32_t capacity, UErrorCode &errorCode) const { 922b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int32_t length32=0; 923b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if(U_SUCCESS(errorCode)) { 924b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // getBuffer() and u_strToUTF32WithSub() check for illegal arguments. 925b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru u_strToUTF32WithSub(utf32, capacity, &length32, 926b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru getBuffer(), length(), 927b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 0xfffd, // Substitution character. 928b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru NULL, // Don't care about number of substitutions. 929b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru &errorCode); 930b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 931b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return length32; 932b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru} 933b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 934b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t 935b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::indexOf(const UChar *srcChars, 936b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t srcStart, 937b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t srcLength, 938b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t start, 939b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t length) const 940b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 941b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(isBogus() || srcChars == 0 || srcStart < 0 || srcLength == 0) { 942b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 943b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 944b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 945b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // UnicodeString does not find empty substrings 946b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(srcLength < 0 && srcChars[srcStart] == 0) { 947b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 948b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 949b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 950b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // get the indices within bounds 951b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pinIndices(start, length); 952b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 953b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // find the first occurrence of the substring 954c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru const UChar *array = getArrayStart(); 955c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru const UChar *match = u_strFindFirst(array + start, length, srcChars + srcStart, srcLength); 956b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(match == NULL) { 957b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 958b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 959c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru return (int32_t)(match - array); 960b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 961b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 962b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 963b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t 964b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::doIndexOf(UChar c, 965b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t start, 966b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t length) const 967b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 968b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // pin indices 969b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pinIndices(start, length); 970b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 971b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // find the first occurrence of c 972c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru const UChar *array = getArrayStart(); 973c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru const UChar *match = u_memchr(array + start, c, length); 974b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(match == NULL) { 975b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 976b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 977c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru return (int32_t)(match - array); 978b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 979b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 980b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 981b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t 982b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::doIndexOf(UChar32 c, 983b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t start, 984b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t length) const { 985b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // pin indices 986b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pinIndices(start, length); 987b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 988b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // find the first occurrence of c 989c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru const UChar *array = getArrayStart(); 990c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru const UChar *match = u_memchr32(array + start, c, length); 991b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(match == NULL) { 992b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 993b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 994c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru return (int32_t)(match - array); 995b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 996b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 997b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 998b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t 999b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::lastIndexOf(const UChar *srcChars, 1000b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t srcStart, 1001b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t srcLength, 1002b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t start, 1003b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t length) const 1004b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1005b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(isBogus() || srcChars == 0 || srcStart < 0 || srcLength == 0) { 1006b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 1007b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1008b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1009b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // UnicodeString does not find empty substrings 1010b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(srcLength < 0 && srcChars[srcStart] == 0) { 1011b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 1012b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1013b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1014b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // get the indices within bounds 1015b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pinIndices(start, length); 1016b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1017b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // find the last occurrence of the substring 1018c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru const UChar *array = getArrayStart(); 1019c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru const UChar *match = u_strFindLast(array + start, length, srcChars + srcStart, srcLength); 1020b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(match == NULL) { 1021b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 1022b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1023c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru return (int32_t)(match - array); 1024b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1025b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1026b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1027b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t 1028b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::doLastIndexOf(UChar c, 1029b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t start, 1030b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t length) const 1031b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1032b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(isBogus()) { 1033b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 1034b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1035b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1036b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // pin indices 1037b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pinIndices(start, length); 1038b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1039b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // find the last occurrence of c 1040c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru const UChar *array = getArrayStart(); 1041c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru const UChar *match = u_memrchr(array + start, c, length); 1042b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(match == NULL) { 1043b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 1044b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1045c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru return (int32_t)(match - array); 1046b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1047b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1048b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1049b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t 1050b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::doLastIndexOf(UChar32 c, 1051b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t start, 1052b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t length) const { 1053b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // pin indices 1054b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pinIndices(start, length); 1055b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1056b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // find the last occurrence of c 1057c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru const UChar *array = getArrayStart(); 1058c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru const UChar *match = u_memrchr32(array + start, c, length); 1059b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(match == NULL) { 1060b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 1061b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1062c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru return (int32_t)(match - array); 1063b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1064b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1065b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1066b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//======================================== 1067b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Write implementation 1068b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//======================================== 1069b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1070b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString& 1071b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::findAndReplace(int32_t start, 1072b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t length, 1073b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const UnicodeString& oldText, 1074b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t oldStart, 1075b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t oldLength, 1076b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const UnicodeString& newText, 1077b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t newStart, 1078b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t newLength) 1079b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1080b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(isBogus() || oldText.isBogus() || newText.isBogus()) { 1081b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return *this; 1082b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1083b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1084b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pinIndices(start, length); 1085b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru oldText.pinIndices(oldStart, oldLength); 1086b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru newText.pinIndices(newStart, newLength); 1087b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1088b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(oldLength == 0) { 1089b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return *this; 1090b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1091b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1092b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(length > 0 && length >= oldLength) { 1093b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t pos = indexOf(oldText, oldStart, oldLength, start, length); 1094b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(pos < 0) { 1095b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // no more oldText's here: done 1096b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1097b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1098b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // we found oldText, replace it by newText and go beyond it 1099b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru replace(pos, oldLength, newText, newStart, newLength); 1100b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru length -= pos + oldLength - start; 1101b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru start = pos + newLength; 1102b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1103b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1104b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1105b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return *this; 1106b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1107b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1108b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1109b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid 1110b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::setToBogus() 1111b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1112b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru releaseArray(); 1113b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1114c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru fShortLength = 0; 1115c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru fUnion.fFields.fArray = 0; 1116c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru fUnion.fFields.fCapacity = 0; 1117b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFlags = kIsBogus; 1118b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1119b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1120b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// turn a bogus string into an empty one 1121b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid 1122b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::unBogus() { 1123b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(fFlags & kIsBogus) { 1124c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru setToEmpty(); 1125b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1126b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1127b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 112859d709d503bab6e2b61931737e662dd293b40578ccorneliusconst UChar * 112959d709d503bab6e2b61931737e662dd293b40578ccorneliusUnicodeString::getTerminatedBuffer() { 113059d709d503bab6e2b61931737e662dd293b40578ccornelius if(!isWritable()) { 113159d709d503bab6e2b61931737e662dd293b40578ccornelius return 0; 113259d709d503bab6e2b61931737e662dd293b40578ccornelius } 113359d709d503bab6e2b61931737e662dd293b40578ccornelius UChar *array = getArrayStart(); 113459d709d503bab6e2b61931737e662dd293b40578ccornelius int32_t len = length(); 113559d709d503bab6e2b61931737e662dd293b40578ccornelius if(len < getCapacity()) { 113659d709d503bab6e2b61931737e662dd293b40578ccornelius if(fFlags & kBufferIsReadonly) { 113759d709d503bab6e2b61931737e662dd293b40578ccornelius // If len<capacity on a read-only alias, then array[len] is 113859d709d503bab6e2b61931737e662dd293b40578ccornelius // either the original NUL (if constructed with (TRUE, s, length)) 113959d709d503bab6e2b61931737e662dd293b40578ccornelius // or one of the original string contents characters (if later truncated), 114059d709d503bab6e2b61931737e662dd293b40578ccornelius // therefore we can assume that array[len] is initialized memory. 114159d709d503bab6e2b61931737e662dd293b40578ccornelius if(array[len] == 0) { 114259d709d503bab6e2b61931737e662dd293b40578ccornelius return array; 114359d709d503bab6e2b61931737e662dd293b40578ccornelius } 114459d709d503bab6e2b61931737e662dd293b40578ccornelius } else if(((fFlags & kRefCounted) == 0 || refCount() == 1)) { 114559d709d503bab6e2b61931737e662dd293b40578ccornelius // kRefCounted: Do not write the NUL if the buffer is shared. 114659d709d503bab6e2b61931737e662dd293b40578ccornelius // That is mostly safe, except when the length of one copy was modified 114759d709d503bab6e2b61931737e662dd293b40578ccornelius // without copy-on-write, e.g., via truncate(newLength) or remove(void). 114859d709d503bab6e2b61931737e662dd293b40578ccornelius // Then the NUL would be written into the middle of another copy's string. 114959d709d503bab6e2b61931737e662dd293b40578ccornelius 115059d709d503bab6e2b61931737e662dd293b40578ccornelius // Otherwise, the buffer is fully writable and it is anyway safe to write the NUL. 115159d709d503bab6e2b61931737e662dd293b40578ccornelius // Do not test if there is a NUL already because it might be uninitialized memory. 115259d709d503bab6e2b61931737e662dd293b40578ccornelius // (That would be safe, but tools like valgrind & Purify would complain.) 115359d709d503bab6e2b61931737e662dd293b40578ccornelius array[len] = 0; 115459d709d503bab6e2b61931737e662dd293b40578ccornelius return array; 115559d709d503bab6e2b61931737e662dd293b40578ccornelius } 115659d709d503bab6e2b61931737e662dd293b40578ccornelius } 115759d709d503bab6e2b61931737e662dd293b40578ccornelius if(cloneArrayIfNeeded(len+1)) { 115859d709d503bab6e2b61931737e662dd293b40578ccornelius array = getArrayStart(); 115959d709d503bab6e2b61931737e662dd293b40578ccornelius array[len] = 0; 116059d709d503bab6e2b61931737e662dd293b40578ccornelius return array; 116159d709d503bab6e2b61931737e662dd293b40578ccornelius } else { 116259d709d503bab6e2b61931737e662dd293b40578ccornelius return NULL; 116359d709d503bab6e2b61931737e662dd293b40578ccornelius } 116459d709d503bab6e2b61931737e662dd293b40578ccornelius} 116559d709d503bab6e2b61931737e662dd293b40578ccornelius 1166b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// setTo() analogous to the readonly-aliasing constructor with the same signature 1167b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString & 1168b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::setTo(UBool isTerminated, 1169b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const UChar *text, 1170b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t textLength) 1171b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1172b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(fFlags & kOpenGetBuffer) { 1173b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // do not modify a string that has an "open" getBuffer(minCapacity) 1174b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return *this; 1175b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1176b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1177b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(text == NULL) { 1178b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // treat as an empty string, do not alias 1179b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru releaseArray(); 1180c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru setToEmpty(); 1181b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return *this; 1182b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1183b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1184b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if( textLength < -1 || 1185b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (textLength == -1 && !isTerminated) || 1186b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (textLength >= 0 && isTerminated && text[textLength] != 0) 1187b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ) { 1188b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru setToBogus(); 1189b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return *this; 1190b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1191b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1192b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru releaseArray(); 1193b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1194c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if(textLength == -1) { 1195b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // text is terminated, or else it would have failed the above test 1196c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru textLength = u_strlen(text); 1197b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1198c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru setArray((UChar *)text, textLength, isTerminated ? textLength + 1 : textLength); 1199b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1200b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFlags = kReadonlyAlias; 1201b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return *this; 1202b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1203b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1204b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// setTo() analogous to the writable-aliasing constructor with the same signature 1205b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString & 1206b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::setTo(UChar *buffer, 1207b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t buffLength, 1208b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t buffCapacity) { 1209b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(fFlags & kOpenGetBuffer) { 1210b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // do not modify a string that has an "open" getBuffer(minCapacity) 1211b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return *this; 1212b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1213b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1214b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(buffer == NULL) { 1215b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // treat as an empty string, do not alias 1216b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru releaseArray(); 1217c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru setToEmpty(); 1218b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return *this; 1219b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1220b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1221b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(buffLength < -1 || buffCapacity < 0 || buffLength > buffCapacity) { 1222b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru setToBogus(); 1223b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return *this; 1224b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else if(buffLength == -1) { 1225b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // buffLength = u_strlen(buff); but do not look beyond buffCapacity 1226b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const UChar *p = buffer, *limit = buffer + buffCapacity; 1227b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(p != limit && *p != 0) { 1228b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++p; 1229b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1230b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru buffLength = (int32_t)(p - buffer); 1231b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1232b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1233b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru releaseArray(); 1234b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1235c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru setArray(buffer, buffLength, buffCapacity); 1236b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFlags = kWritableAlias; 1237b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return *this; 1238b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1239b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1240b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruUnicodeString &UnicodeString::setToUTF8(const StringPiece &utf8) { 1241b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru unBogus(); 1242b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int32_t length = utf8.length(); 1243b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int32_t capacity; 1244b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // The UTF-16 string will be at most as long as the UTF-8 string. 1245b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if(length <= US_STACKBUF_SIZE) { 1246b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru capacity = US_STACKBUF_SIZE; 1247b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } else { 1248b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru capacity = length + 1; // +1 for the terminating NUL. 1249b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 1250b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru UChar *utf16 = getBuffer(capacity); 1251b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int32_t length16; 1252b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru UErrorCode errorCode = U_ZERO_ERROR; 1253b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru u_strFromUTF8WithSub(utf16, getCapacity(), &length16, 1254b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru utf8.data(), length, 1255b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 0xfffd, // Substitution character. 1256b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru NULL, // Don't care about number of substitutions. 1257b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru &errorCode); 1258b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru releaseBuffer(length16); 1259b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if(U_FAILURE(errorCode)) { 1260b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru setToBogus(); 1261b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 1262b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return *this; 1263b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru} 1264b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 1265b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString& 1266b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::setCharAt(int32_t offset, 1267b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UChar c) 1268b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1269c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru int32_t len = length(); 1270c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if(cloneArrayIfNeeded() && len > 0) { 1271b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(offset < 0) { 1272b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru offset = 0; 1273c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } else if(offset >= len) { 1274c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru offset = len - 1; 1275b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1276b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1277c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru getArrayStart()[offset] = c; 1278b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1279b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return *this; 1280b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1281b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1282b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString& 1283103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusUnicodeString::replace(int32_t start, 1284103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t _length, 1285103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius UChar32 srcChar) { 1286103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius UChar buffer[U16_MAX_LENGTH]; 1287103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t count = 0; 1288103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius UBool isError = FALSE; 1289103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius U16_APPEND(buffer, count, U16_MAX_LENGTH, srcChar, isError); 1290103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // We test isError so that the compiler does not complain that we don't. 129154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius // If isError (srcChar is not a valid code point) then count==0 which means 129254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius // we remove the source segment rather than replacing it with srcChar. 129354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius return doReplace(start, _length, buffer, 0, isError ? 0 : count); 1294103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius} 1295103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 1296103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusUnicodeString& 1297103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusUnicodeString::append(UChar32 srcChar) { 1298103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius UChar buffer[U16_MAX_LENGTH]; 1299103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t _length = 0; 1300103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius UBool isError = FALSE; 1301103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius U16_APPEND(buffer, _length, U16_MAX_LENGTH, srcChar, isError); 1302103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // We test isError so that the compiler does not complain that we don't. 1303103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // If isError then _length==0 which turns the doReplace() into a no-op anyway. 1304103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return isError ? *this : doReplace(length(), 0, buffer, 0, _length); 1305103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius} 1306103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 1307103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusUnicodeString& 1308b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::doReplace( int32_t start, 1309b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t length, 1310b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const UnicodeString& src, 1311b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t srcStart, 1312b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t srcLength) 1313b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1314b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(!src.isBogus()) { 1315b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // pin the indices to legal values 1316b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru src.pinIndices(srcStart, srcLength); 1317b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1318b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // get the characters from src 1319b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // and replace the range in ourselves with them 1320b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return doReplace(start, length, src.getArrayStart(), srcStart, srcLength); 1321b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1322b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // remove the range 1323b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return doReplace(start, length, 0, 0, 0); 1324b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1325b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1326b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1327b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString& 1328b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::doReplace(int32_t start, 1329b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t length, 1330b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const UChar *srcChars, 1331b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t srcStart, 1332b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t srcLength) 1333b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1334c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if(!isWritable()) { 1335b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return *this; 1336b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1337b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 133850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t oldLength = this->length(); 133950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 134050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // optimize (read-only alias).remove(0, start) and .remove(start, end) 134150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if((fFlags&kBufferIsReadonly) && srcLength == 0) { 134250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(start == 0) { 134350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // remove prefix by adjusting the array pointer 134450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho pinIndex(length); 134550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho fUnion.fFields.fArray += length; 134650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho fUnion.fFields.fCapacity -= length; 134750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho setLength(oldLength - length); 134850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return *this; 134950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } else { 135050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho pinIndex(start); 135150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(length >= (oldLength - start)) { 135250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // remove suffix by reducing the length (like truncate()) 135350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho setLength(start); 135450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho fUnion.fFields.fCapacity = start; // not NUL-terminated any more 135550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return *this; 135650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 135750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 135850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 135950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 1360b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(srcChars == 0) { 1361b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru srcStart = srcLength = 0; 1362b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else if(srcLength < 0) { 1363b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // get the srcLength if necessary 1364b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru srcLength = u_strlen(srcChars + srcStart); 1365b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1366b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1367c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru // calculate the size of the string after the replace 1368b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t newLength; 1369c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru 1370c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru // optimize append() onto a large-enough, owned string 1371c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if(start >= oldLength) { 1372103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if(srcLength == 0) { 1373103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return *this; 1374103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 1375b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho newLength = oldLength + srcLength; 1376b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if(newLength <= getCapacity() && isBufferWritable()) { 1377b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UChar *oldArray = getArrayStart(); 1378b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Do not copy characters when 1379b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // UChar *buffer=str.getAppendBuffer(...); 1380b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // is followed by 1381b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // str.append(buffer, length); 1382b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // or 1383b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // str.appendString(buffer, length) 1384b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // or similar. 1385b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if(srcChars + srcStart != oldArray + start || start > oldLength) { 1386b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho us_arrayCopy(srcChars, srcStart, oldArray, oldLength, srcLength); 1387b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1388b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho setLength(newLength); 1389c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru return *this; 1390c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } else { 1391c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru // pin the indices to legal values 1392c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru start = oldLength; 1393c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru length = 0; 1394c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } 1395c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } else { 1396c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru // pin the indices to legal values 1397c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru pinIndices(start, length); 1398b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1399b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho newLength = oldLength - length + srcLength; 1400c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } 1401b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1402c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru // the following may change fArray but will not copy the current contents; 1403c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru // therefore we need to keep the current fArray 1404c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru UChar oldStackBuffer[US_STACKBUF_SIZE]; 1405c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru UChar *oldArray; 1406b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if((fFlags&kUsingStackBuffer) && (newLength > US_STACKBUF_SIZE)) { 1407c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru // copy the stack buffer contents because it will be overwritten with 1408c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru // fUnion.fFields values 1409c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru u_memcpy(oldStackBuffer, fUnion.fStackBuffer, oldLength); 1410c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru oldArray = oldStackBuffer; 1411c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } else { 1412c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru oldArray = getArrayStart(); 1413c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } 1414b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1415b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // clone our array and allocate a bigger array if needed 1416c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru int32_t *bufferToDelete = 0; 1417b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if(!cloneArrayIfNeeded(newLength, newLength + (newLength >> 2) + kGrowSize, 1418b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, &bufferToDelete) 1419b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ) { 1420b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return *this; 1421b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1422b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1423b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // now do the replace 1424b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1425c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru UChar *newArray = getArrayStart(); 1426c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if(newArray != oldArray) { 1427b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // if fArray changed, then we need to copy everything except what will change 1428c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru us_arrayCopy(oldArray, 0, newArray, 0, start); 1429b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru us_arrayCopy(oldArray, start + length, 1430c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru newArray, start + srcLength, 1431b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru oldLength - (start + length)); 1432b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else if(length != srcLength) { 1433b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // fArray did not change; copy only the portion that isn't changing, leaving a hole 1434b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru us_arrayCopy(oldArray, start + length, 1435c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru newArray, start + srcLength, 1436b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru oldLength - (start + length)); 1437b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1438b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1439b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // now fill in the hole with the new string 1440c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru us_arrayCopy(srcChars, srcStart, newArray, start, srcLength); 1441b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1442b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho setLength(newLength); 1443b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1444b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // delayed delete in case srcChars == fArray when we started, and 1445b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // to keep oldArray alive for the above operations 1446b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (bufferToDelete) { 1447b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_free(bufferToDelete); 1448b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1449b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1450b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return *this; 1451b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1452b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1453b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/** 1454b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Replaceable API 1455b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 1456b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid 1457b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::handleReplaceBetween(int32_t start, 1458b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t limit, 1459b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const UnicodeString& text) { 1460b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru replaceBetween(start, limit, text); 1461b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1462b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1463b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/** 1464b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Replaceable API 1465b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 1466b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid 1467b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::copy(int32_t start, int32_t limit, int32_t dest) { 1468b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (limit <= start) { 1469b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; // Nothing to do; avoid bogus malloc call 1470b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1471b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UChar* text = (UChar*) uprv_malloc( sizeof(UChar) * (limit - start) ); 1472c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru // Check to make sure text is not null. 1473c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if (text != NULL) { 1474c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru extractBetween(start, limit, text, 0); 1475c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru insert(dest, text, 0, limit - start); 1476c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru uprv_free(text); 1477c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } 1478b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1479b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1480b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/** 1481b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Replaceable API 1482b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 1483b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * NOTE: This is for the Replaceable class. There is no rep.cpp, 1484b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * so we implement this function here. 1485b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 1486b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUBool Replaceable::hasMetaData() const { 1487b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return TRUE; 1488b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1489b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1490b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/** 1491b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Replaceable API 1492b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 1493b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUBool UnicodeString::hasMetaData() const { 1494b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return FALSE; 1495b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1496b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1497b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString& 149827f654740f2a26ad62a5c155af9199af9e69b889clairehoUnicodeString::doReverse(int32_t start, int32_t length) { 149927f654740f2a26ad62a5c155af9199af9e69b889claireho if(length <= 1 || !cloneArrayIfNeeded()) { 1500b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return *this; 1501b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1502b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1503b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // pin the indices to legal values 1504b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pinIndices(start, length); 150527f654740f2a26ad62a5c155af9199af9e69b889claireho if(length <= 1) { // pinIndices() might have shrunk the length 150627f654740f2a26ad62a5c155af9199af9e69b889claireho return *this; 150727f654740f2a26ad62a5c155af9199af9e69b889claireho } 1508b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1509b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UChar *left = getArrayStart() + start; 151027f654740f2a26ad62a5c155af9199af9e69b889claireho UChar *right = left + length - 1; // -1 for inclusive boundary (length>=2) 1511b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UChar swap; 1512b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UBool hasSupplementary = FALSE; 1513b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 151427f654740f2a26ad62a5c155af9199af9e69b889claireho // Before the loop we know left<right because length>=2. 151527f654740f2a26ad62a5c155af9199af9e69b889claireho do { 151627f654740f2a26ad62a5c155af9199af9e69b889claireho hasSupplementary |= (UBool)U16_IS_LEAD(swap = *left); 151727f654740f2a26ad62a5c155af9199af9e69b889claireho hasSupplementary |= (UBool)U16_IS_LEAD(*left++ = *right); 151827f654740f2a26ad62a5c155af9199af9e69b889claireho *right-- = swap; 151927f654740f2a26ad62a5c155af9199af9e69b889claireho } while(left < right); 152027f654740f2a26ad62a5c155af9199af9e69b889claireho // Make sure to test the middle code unit of an odd-length string. 152127f654740f2a26ad62a5c155af9199af9e69b889claireho // Redundant if the length is even. 152227f654740f2a26ad62a5c155af9199af9e69b889claireho hasSupplementary |= (UBool)U16_IS_LEAD(*left); 1523b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1524b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* if there are supplementary code points in the reversed range, then re-swap their surrogates */ 1525b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(hasSupplementary) { 1526b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UChar swap2; 1527b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1528b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru left = getArrayStart() + start; 1529c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru right = left + length - 1; // -1 so that we can look at *(left+1) if left<right 1530b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(left < right) { 153127f654740f2a26ad62a5c155af9199af9e69b889claireho if(U16_IS_TRAIL(swap = *left) && U16_IS_LEAD(swap2 = *(left + 1))) { 1532b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *left++ = swap2; 1533b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *left++ = swap; 1534b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1535b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++left; 1536b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1537b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1538b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1539b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1540b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return *this; 1541b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1542b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1543b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUBool 1544b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::padLeading(int32_t targetLength, 1545b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UChar padChar) 1546b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1547c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru int32_t oldLength = length(); 1548c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if(oldLength >= targetLength || !cloneArrayIfNeeded(targetLength)) { 1549b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return FALSE; 1550b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1551b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // move contents up by padding width 1552c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru UChar *array = getArrayStart(); 1553c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru int32_t start = targetLength - oldLength; 1554c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru us_arrayCopy(array, 0, array, start, oldLength); 1555b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1556b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // fill in padding character 1557b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(--start >= 0) { 1558c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru array[start] = padChar; 1559b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1560c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru setLength(targetLength); 1561b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return TRUE; 1562b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1563b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1564b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1565b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUBool 1566b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::padTrailing(int32_t targetLength, 1567b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UChar padChar) 1568b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1569c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru int32_t oldLength = length(); 1570c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if(oldLength >= targetLength || !cloneArrayIfNeeded(targetLength)) { 1571b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return FALSE; 1572b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1573b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // fill in padding character 1574c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru UChar *array = getArrayStart(); 1575b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t length = targetLength; 1576c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru while(--length >= oldLength) { 1577c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru array[length] = padChar; 1578b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1579c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru setLength(targetLength); 1580b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return TRUE; 1581b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1582b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1583b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1584b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//======================================== 1585b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Hashing 1586b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//======================================== 1587b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t 1588b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::doHashCode() const 1589b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1590b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* Delegate hash computation to uhash. This makes UnicodeString 1591b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * hashing consistent with UChar* hashing. */ 1592103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t hashCode = ustr_hashUCharsN(getArrayStart(), length()); 1593b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (hashCode == kInvalidHashCode) { 1594b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru hashCode = kEmptyHashCode; 1595b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1596b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return hashCode; 1597b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1598b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1599b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//======================================== 1600b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// External Buffer 1601b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//======================================== 1602b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1603b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUChar * 1604b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::getBuffer(int32_t minCapacity) { 1605b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(minCapacity>=-1 && cloneArrayIfNeeded(minCapacity)) { 1606b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFlags|=kOpenGetBuffer; 1607c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru fShortLength=0; 1608c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru return getArrayStart(); 1609b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1610b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 1611b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1612b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1613b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1614b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid 1615b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::releaseBuffer(int32_t newLength) { 1616b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(fFlags&kOpenGetBuffer && newLength>=-1) { 1617b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // set the new fLength 1618c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru int32_t capacity=getCapacity(); 1619b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(newLength==-1) { 1620b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // the new length is the string length, capped by fCapacity 1621c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru const UChar *array=getArrayStart(), *p=array, *limit=array+capacity; 1622b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(p<limit && *p!=0) { 1623b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++p; 1624b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1625c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru newLength=(int32_t)(p-array); 1626c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } else if(newLength>capacity) { 1627c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru newLength=capacity; 1628b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1629c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru setLength(newLength); 1630b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFlags&=~kOpenGetBuffer; 1631b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1632b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1633b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1634b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//======================================== 1635b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Miscellaneous 1636b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//======================================== 1637b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUBool 1638b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString::cloneArrayIfNeeded(int32_t newCapacity, 1639b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t growCapacity, 1640b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UBool doCopyArray, 1641b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t **pBufferToDelete, 1642b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UBool forceClone) { 1643b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // default parameters need to be static, therefore 1644b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // the defaults are -1 to have convenience defaults 1645b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(newCapacity == -1) { 1646c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru newCapacity = getCapacity(); 1647b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1648b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1649b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // while a getBuffer(minCapacity) is "open", 1650b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // prevent any modifications of the string by returning FALSE here 1651b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // if the string is bogus, then only an assignment or similar can revive it 1652c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if(!isWritable()) { 1653b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return FALSE; 1654b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1655b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1656b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 1657b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * We need to make a copy of the array if 1658b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * the buffer is read-only, or 1659b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * the buffer is refCounted (shared), and refCount>1, or 1660b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * the buffer is too small. 1661b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Return FALSE if memory could not be allocated. 1662b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 1663b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(forceClone || 1664b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFlags & kBufferIsReadonly || 166527f654740f2a26ad62a5c155af9199af9e69b889claireho (fFlags & kRefCounted && refCount() > 1) || 1666c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru newCapacity > getCapacity() 1667b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ) { 1668b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // check growCapacity for default value and use of the stack buffer 1669103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if(growCapacity < 0) { 1670b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru growCapacity = newCapacity; 1671b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else if(newCapacity <= US_STACKBUF_SIZE && growCapacity > US_STACKBUF_SIZE) { 1672b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru growCapacity = US_STACKBUF_SIZE; 1673b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1674b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1675c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru // save old values 1676c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru UChar oldStackBuffer[US_STACKBUF_SIZE]; 1677c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru UChar *oldArray; 1678c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru uint8_t flags = fFlags; 1679c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru 1680c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if(flags&kUsingStackBuffer) { 1681103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius U_ASSERT(!(flags&kRefCounted)); /* kRefCounted and kUsingStackBuffer are mutally exclusive */ 1682c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if(doCopyArray && growCapacity > US_STACKBUF_SIZE) { 1683c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru // copy the stack buffer contents because it will be overwritten with 1684c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru // fUnion.fFields values 1685c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru us_arrayCopy(fUnion.fStackBuffer, 0, oldStackBuffer, 0, fShortLength); 1686c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru oldArray = oldStackBuffer; 1687c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } else { 1688c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru oldArray = 0; // no need to copy from stack buffer to itself 1689c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } 1690c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } else { 1691c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru oldArray = fUnion.fFields.fArray; 1692103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius U_ASSERT(oldArray!=NULL); /* when stack buffer is not used, oldArray must have a non-NULL reference */ 1693c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } 1694c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru 1695b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // allocate a new array 1696b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(allocate(growCapacity) || 169727f654740f2a26ad62a5c155af9199af9e69b889claireho (newCapacity < growCapacity && allocate(newCapacity)) 1698b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ) { 1699c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if(doCopyArray && oldArray != 0) { 1700b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // copy the contents 1701b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // do not copy more than what fits - it may be smaller than before 1702c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru int32_t minLength = length(); 1703c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru newCapacity = getCapacity(); 1704c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if(newCapacity < minLength) { 1705c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru minLength = newCapacity; 1706c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru setLength(minLength); 1707b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1708c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru us_arrayCopy(oldArray, 0, getArrayStart(), 0, minLength); 1709b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1710c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru fShortLength = 0; 1711b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1712b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1713b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // release the old array 1714b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(flags & kRefCounted) { 1715b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // the array is refCounted; decrement and release if 0 171659d709d503bab6e2b61931737e662dd293b40578ccornelius u_atomic_int32_t *pRefCount = ((u_atomic_int32_t *)oldArray - 1); 1717b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(umtx_atomic_dec(pRefCount) == 0) { 1718b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(pBufferToDelete == 0) { 171959d709d503bab6e2b61931737e662dd293b40578ccornelius // Note: cast to (void *) is needed with MSVC, where u_atomic_int32_t 172059d709d503bab6e2b61931737e662dd293b40578ccornelius // is defined as volatile. (Volatile has useful non-standard behavior 172159d709d503bab6e2b61931737e662dd293b40578ccornelius // with this compiler.) 172259d709d503bab6e2b61931737e662dd293b40578ccornelius uprv_free((void *)pRefCount); 1723b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1724b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // the caller requested to delete it himself 172559d709d503bab6e2b61931737e662dd293b40578ccornelius *pBufferToDelete = (int32_t *)pRefCount; 1726b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1727b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1728b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1729b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1730b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // not enough memory for growCapacity and not even for the smaller newCapacity 1731b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // reset the old values for setToBogus() to release the array 1732c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if(!(flags&kUsingStackBuffer)) { 1733c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru fUnion.fFields.fArray = oldArray; 1734c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } 1735b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFlags = flags; 1736b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru setToBogus(); 1737b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return FALSE; 1738b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1739b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1740b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return TRUE; 1741b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1742b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1743b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// UnicodeStringAppendable ------------------------------------------------- *** 1744b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1745103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusUnicodeStringAppendable::~UnicodeStringAppendable() {} 1746103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 1747b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoUBool 1748b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoUnicodeStringAppendable::appendCodeUnit(UChar c) { 1749b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return str.doReplace(str.length(), 0, &c, 0, 1).isWritable(); 1750b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 1751b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1752b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoUBool 1753b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoUnicodeStringAppendable::appendCodePoint(UChar32 c) { 1754b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UChar buffer[U16_MAX_LENGTH]; 1755b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t cLength = 0; 1756b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UBool isError = FALSE; 1757b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho U16_APPEND(buffer, cLength, U16_MAX_LENGTH, c, isError); 1758b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return !isError && str.doReplace(str.length(), 0, buffer, 0, cLength).isWritable(); 1759b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 1760b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1761b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoUBool 1762b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoUnicodeStringAppendable::appendString(const UChar *s, int32_t length) { 1763b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return str.doReplace(str.length(), 0, s, 0, length).isWritable(); 1764b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 1765b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1766b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoUBool 1767b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoUnicodeStringAppendable::reserveAppendCapacity(int32_t appendCapacity) { 1768b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return str.cloneArrayIfNeeded(str.length() + appendCapacity); 1769b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 1770b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1771b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoUChar * 1772b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoUnicodeStringAppendable::getAppendBuffer(int32_t minCapacity, 1773b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t desiredCapacityHint, 1774b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UChar *scratch, int32_t scratchCapacity, 1775b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t *resultCapacity) { 1776b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if(minCapacity < 1 || scratchCapacity < minCapacity) { 1777b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho *resultCapacity = 0; 1778b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return NULL; 1779b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1780b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t oldLength = str.length(); 1781b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if(str.cloneArrayIfNeeded(oldLength + minCapacity, oldLength + desiredCapacityHint)) { 1782b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho *resultCapacity = str.getCapacity() - oldLength; 1783b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return str.getArrayStart() + oldLength; 1784b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1785b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho *resultCapacity = scratchCapacity; 1786b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return scratch; 1787b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 1788b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1789b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_NAMESPACE_END 1790b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1791103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusU_NAMESPACE_USE 1792103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 1793103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusU_CAPI int32_t U_EXPORT2 1794103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusuhash_hashUnicodeString(const UElement key) { 1795103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius const UnicodeString *str = (const UnicodeString*) key.pointer; 1796103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return (str == NULL) ? 0 : str->hashCode(); 1797103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius} 1798103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 1799103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius// Moved here from uhash_us.cpp so that using a UVector of UnicodeString* 1800103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius// does not depend on hashtable code. 1801103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusU_CAPI UBool U_EXPORT2 1802103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusuhash_compareUnicodeString(const UElement key1, const UElement key2) { 1803103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius const UnicodeString *str1 = (const UnicodeString*) key1.pointer; 1804103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius const UnicodeString *str2 = (const UnicodeString*) key2.pointer; 1805103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (str1 == str2) { 1806103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return TRUE; 1807103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 1808103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (str1 == NULL || str2 == NULL) { 1809103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return FALSE; 1810103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 1811103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return *str1 == *str2; 1812103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius} 1813103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 1814b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#ifdef U_STATIC_IMPLEMENTATION 1815b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* 1816b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruThis should never be called. It is defined here to make sure that the 1817b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvirtual vector deleting destructor is defined within unistr.cpp. 1818b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruThe vector deleting destructor is already a part of UObject, 1819b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querubut defining it here makes sure that it is included with this object file. 1820b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruThis makes sure that static library dependencies are kept to a minimum. 1821b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*/ 1822b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void uprv_UnicodeStringDummy(void) { 1823b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru delete [] (new UnicodeString[2]); 1824b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1825b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 1826