Index: source/common/unicode/unistr.h |
diff --git a/source/common/unicode/unistr.h b/source/common/unicode/unistr.h |
index c98aec7d3fa57b29ca8241b5cfe2221f4298a328..63f19335004793f41f3753764eee3c17becc7716 100644 |
--- a/source/common/unicode/unistr.h |
+++ b/source/common/unicode/unistr.h |
@@ -1,6 +1,6 @@ |
/* |
********************************************************************** |
-* Copyright (C) 1998-2013, International Business Machines |
+* Copyright (C) 1998-2015, International Business Machines |
* Corporation and others. All Rights Reserved. |
********************************************************************** |
* |
@@ -172,15 +172,64 @@ class UnicodeStringAppendable; // unicode/appendable.h |
# endif |
#endif |
+/* Cannot make the following #ifndef U_HIDE_INTERNAL_API, |
+ it is used to construct other non-internal constants */ |
+/** |
+ * \def UNISTR_OBJECT_SIZE |
+ * Desired sizeof(UnicodeString) in bytes. |
+ * It should be a multiple of sizeof(pointer) to avoid unusable space for padding. |
+ * The object size may want to be a multiple of 16 bytes, |
+ * which is a common granularity for heap allocation. |
+ * |
+ * Any space inside the object beyond sizeof(vtable pointer) + 2 |
+ * is available for storing short strings inside the object. |
+ * The bigger the object, the longer a string that can be stored inside the object, |
+ * without additional heap allocation. |
+ * |
+ * Depending on a platform's pointer size, pointer alignment requirements, |
+ * and struct padding, the compiler will usually round up sizeof(UnicodeString) |
+ * to 4 * sizeof(pointer) (or 3 * sizeof(pointer) for P128 data models), |
+ * to hold the fields for heap-allocated strings. |
+ * Such a minimum size also ensures that the object is easily large enough |
+ * to hold at least 2 UChars, for one supplementary code point (U16_MAX_LENGTH). |
+ * |
+ * sizeof(UnicodeString) >= 48 should work for all known platforms. |
+ * |
+ * For example, on a 64-bit machine where sizeof(vtable pointer) is 8, |
+ * sizeof(UnicodeString) = 64 would leave space for |
+ * (64 - sizeof(vtable pointer) - 2) / U_SIZEOF_UCHAR = (64 - 8 - 2) / 2 = 27 |
+ * UChars stored inside the object. |
+ * |
+ * The minimum object size on a 64-bit machine would be |
+ * 4 * sizeof(pointer) = 4 * 8 = 32 bytes, |
+ * and the internal buffer would hold up to 11 UChars in that case. |
+ * |
+ * @see U16_MAX_LENGTH |
+ * @draft ICU 56 |
+ */ |
+#ifndef UNISTR_OBJECT_SIZE |
+# define UNISTR_OBJECT_SIZE 64 |
+#endif |
+ |
/** |
* UnicodeString is a string class that stores Unicode characters directly and provides |
- * similar functionality as the Java String and StringBuffer classes. |
+ * similar functionality as the Java String and StringBuffer/StringBuilder classes. |
* It is a concrete implementation of the abstract class Replaceable (for transliteration). |
* |
+ * A UnicodeString may also "alias" an external array of characters |
+ * (that is, point to it, rather than own the array) |
+ * whose lifetime must then at least match the lifetime of the aliasing object. |
+ * This aliasing may be preserved when returning a UnicodeString by value, |
+ * depending on the compiler and the function implementation, |
+ * via Return Value Optimization (RVO) or the move assignment operator. |
+ * (However, the copy assignment operator does not preserve aliasing.) |
+ * For details see the description of storage models at the end of the class API docs |
+ * and in the User Guide chapter linked from there. |
+ * |
* The UnicodeString class is not suitable for subclassing. |
* |
* <p>For an overview of Unicode strings in C and C++ see the |
- * <a href="http://icu-project.org/userguide/strings.html">User Guide Strings chapter</a>.</p> |
+ * <a href="http://userguide.icu-project.org/strings#TOC-Strings-in-C-C-">User Guide Strings chapter</a>.</p> |
* |
* <p>In ICU, a Unicode string consists of 16-bit Unicode <em>code units</em>. |
* A Unicode character may be stored with either one code unit |
@@ -235,7 +284,7 @@ class UnicodeStringAppendable; // unicode/appendable.h |
* significant performance improvements. |
* Also, the internal buffer is accessible via special functions. |
* For details see the |
- * <a href="http://icu-project.org/userguide/strings.html">User Guide Strings chapter</a>.</p> |
+ * <a href="http://userguide.icu-project.org/strings#TOC-Maximizing-Performance-with-the-UnicodeString-Storage-Model">User Guide Strings chapter</a>.</p> |
* |
* @see utf.h |
* @see CharacterIterator |
@@ -1481,11 +1530,11 @@ public: |
/** |
* Copy the characters in the range |
- * [<tt>start</TT>, <tt>start + length</TT>) into an array of characters. |
+ * [<tt>start</TT>, <tt>start + startLength</TT>) into an array of characters. |
* All characters must be invariant (see utypes.h). |
* Use US_INV as the last, signature-distinguishing parameter. |
* |
- * This function does not write any more than <code>targetLength</code> |
+ * This function does not write any more than <code>targetCapacity</code> |
* characters but returns the length of the entire output string |
* so that one can allocate a larger buffer and call the function again |
* if necessary. |
@@ -1809,9 +1858,20 @@ public: |
/** |
* Assignment operator. Replace the characters in this UnicodeString |
* with the characters from <TT>srcText</TT>. |
+ * |
+ * Starting with ICU 2.4, the assignment operator and the copy constructor |
+ * allocate a new buffer and copy the buffer contents even for readonly aliases. |
+ * By contrast, the fastCopyFrom() function implements the old, |
+ * more efficient but less safe behavior |
+ * of making this string also a readonly alias to the same buffer. |
+ * |
+ * If the source object has an "open" buffer from getBuffer(minCapacity), |
+ * then the copy is an empty string. |
+ * |
* @param srcText The text containing the characters to replace |
* @return a reference to this |
* @stable ICU 2.0 |
+ * @see fastCopyFrom |
*/ |
UnicodeString &operator=(const UnicodeString &srcText); |
@@ -1833,12 +1893,60 @@ public: |
* including its contents, for example for strings from resource bundles |
* or aliases to string constants. |
* |
+ * If the source object has an "open" buffer from getBuffer(minCapacity), |
+ * then the copy is an empty string. |
+ * |
* @param src The text containing the characters to replace. |
* @return a reference to this |
* @stable ICU 2.4 |
*/ |
UnicodeString &fastCopyFrom(const UnicodeString &src); |
+#ifndef U_HIDE_DRAFT_API |
+#if U_HAVE_RVALUE_REFERENCES |
+ /** |
+ * Move assignment operator, might leave src in bogus state. |
+ * This string will have the same contents and state that the source string had. |
+ * The behavior is undefined if *this and src are the same object. |
+ * @param src source string |
+ * @return *this |
+ * @draft ICU 56 |
+ */ |
+ UnicodeString &operator=(UnicodeString &&src) U_NOEXCEPT { |
+ return moveFrom(src); |
+ } |
+#endif |
+ /** |
+ * Move assignment, might leave src in bogus state. |
+ * This string will have the same contents and state that the source string had. |
+ * The behavior is undefined if *this and src are the same object. |
+ * |
+ * Can be called explicitly, does not need C++11 support. |
+ * @param src source string |
+ * @return *this |
+ * @draft ICU 56 |
+ */ |
+ UnicodeString &moveFrom(UnicodeString &src) U_NOEXCEPT; |
+ |
+ /** |
+ * Swap strings. |
+ * @param other other string |
+ * @draft ICU 56 |
+ */ |
+ void swap(UnicodeString &other) U_NOEXCEPT; |
+ |
+ /** |
+ * Non-member UnicodeString swap function. |
+ * @param s1 will get s2's contents and state |
+ * @param s2 will get s1's contents and state |
+ * @draft ICU 56 |
+ */ |
+ friend U_COMMON_API inline void U_EXPORT2 |
+ swap(UnicodeString &s1, UnicodeString &s2) U_NOEXCEPT { |
+ s1.swap(s2); |
+ } |
+#endif /* U_HIDE_DRAFT_API */ |
+ |
/** |
* Assignment operator. Replace the characters in this UnicodeString |
* with the code unit <TT>ch</TT>. |
@@ -3088,11 +3196,34 @@ public: |
/** |
* Copy constructor. |
+ * |
+ * Starting with ICU 2.4, the assignment operator and the copy constructor |
+ * allocate a new buffer and copy the buffer contents even for readonly aliases. |
+ * By contrast, the fastCopyFrom() function implements the old, |
+ * more efficient but less safe behavior |
+ * of making this string also a readonly alias to the same buffer. |
+ * |
+ * If the source object has an "open" buffer from getBuffer(minCapacity), |
+ * then the copy is an empty string. |
+ * |
* @param that The UnicodeString object to copy. |
* @stable ICU 2.0 |
+ * @see fastCopyFrom |
*/ |
UnicodeString(const UnicodeString& that); |
+#ifndef U_HIDE_DRAFT_API |
+#if U_HAVE_RVALUE_REFERENCES |
+ /** |
+ * Move constructor, might leave src in bogus state. |
+ * This string will have the same contents and state that the source string had. |
+ * @param src source string |
+ * @draft ICU 56 |
+ */ |
+ UnicodeString(UnicodeString &&src) U_NOEXCEPT; |
+#endif |
+#endif /* U_HIDE_DRAFT_API */ |
+ |
/** |
* 'Substring' constructor from tail of source string. |
* @param src The UnicodeString object to copy. |
@@ -3358,6 +3489,9 @@ private: |
int32_t srcStart, |
int32_t srcLength); |
+ UnicodeString& doAppend(const UnicodeString& src, int32_t srcStart, int32_t srcLength); |
+ UnicodeString& doAppend(const UChar *srcChars, int32_t srcStart, int32_t srcLength); |
+ |
UnicodeString& doReverse(int32_t start, |
int32_t length); |
@@ -3369,6 +3503,9 @@ private: |
inline UChar* getArrayStart(void); |
inline const UChar* getArrayStart(void) const; |
+ inline UBool hasShortLength() const; |
+ inline int32_t getShortLength() const; |
+ |
// A UnicodeString object (not necessarily its current buffer) |
// is writable unless it isBogus() or it has an "open" getBuffer(minCapacity). |
inline UBool isWritable() const; |
@@ -3377,13 +3514,16 @@ private: |
inline UBool isBufferWritable() const; |
// None of the following does releaseArray(). |
- inline void setLength(int32_t len); // sets only fShortLength and fLength |
- inline void setToEmpty(); // sets fFlags=kShortString |
- inline void setArray(UChar *array, int32_t len, int32_t capacity); // does not set fFlags |
+ inline void setZeroLength(); |
+ inline void setShortLength(int32_t len); |
+ inline void setLength(int32_t len); |
+ inline void setToEmpty(); |
+ inline void setArray(UChar *array, int32_t len, int32_t capacity); // sets length but not flags |
- // allocate the array; result may be fStackBuffer |
+ // allocate the array; result may be the stack buffer |
// sets refCount to 1 if appropriate |
- // sets fArray, fCapacity, and fFlags |
+ // sets fArray, fCapacity, and flags |
+ // sets length to 0 |
// returns boolean for success or failure |
UBool allocate(int32_t capacity); |
@@ -3396,6 +3536,9 @@ private: |
// implements assigment operator, copy constructor, and fastCopyFrom() |
UnicodeString ©From(const UnicodeString &src, UBool fastCopy=FALSE); |
+ // Copies just the fields without memory management. |
+ void copyFieldsFrom(UnicodeString &src, UBool setSrcToBogus) U_NOEXCEPT; |
+ |
// Pin start and limit to acceptable values. |
inline void pinIndex(int32_t& start) const; |
inline void pinIndices(int32_t& start, |
@@ -3467,21 +3610,30 @@ private: |
// constants |
enum { |
- // Set the stack buffer size so that sizeof(UnicodeString) is, |
- // naturally (without padding), a multiple of sizeof(pointer). |
- US_STACKBUF_SIZE= sizeof(void *)==4 ? 13 : 15, // Size of stack buffer for short strings |
- kInvalidUChar=0xffff, // invalid UChar index |
+ /** |
+ * Size of stack buffer for short strings. |
+ * Must be at least U16_MAX_LENGTH for the single-code point constructor to work. |
+ * @see UNISTR_OBJECT_SIZE |
+ */ |
+ US_STACKBUF_SIZE=(int32_t)(UNISTR_OBJECT_SIZE-sizeof(void *)-2)/U_SIZEOF_UCHAR, |
+ kInvalidUChar=0xffff, // U+FFFF returned by charAt(invalid index) |
kGrowSize=128, // grow size for this buffer |
kInvalidHashCode=0, // invalid hash code |
kEmptyHashCode=1, // hash code for empty string |
- // bit flag values for fFlags |
+ // bit flag values for fLengthAndFlags |
kIsBogus=1, // this string is bogus, i.e., not valid or NULL |
- kUsingStackBuffer=2,// using fUnion.fStackBuffer instead of fUnion.fFields |
+ kUsingStackBuffer=2,// using fUnion.fStackFields instead of fUnion.fFields |
kRefCounted=4, // there is a refCount field before the characters in fArray |
kBufferIsReadonly=8,// do not write to this buffer |
kOpenGetBuffer=16, // getBuffer(minCapacity) was called (is "open"), |
// and releaseBuffer(newLength) must be called |
+ kAllStorageFlags=0x1f, |
+ |
+ kLengthShift=5, // remaining 11 bits for non-negative short length, or negative if long |
+ kLength1=1<<kLengthShift, |
+ kMaxShortLength=0x3ff, // max non-negative short length (leaves top bit 0) |
+ kLengthIsLarge=0xffe0, // short length < 0, real length is in fUnion.fFields.fLength |
// combined values for convenience |
kShortString=kUsingStackBuffer, |
@@ -3513,36 +3665,45 @@ private: |
* - sizeof(class UnicodeString) |
* - offsetof(UnicodeString, fUnion) |
* - sizeof(fUnion) |
- * - sizeof(fFields) |
+ * - sizeof(fStackFields) |
* |
- * In order to avoid padding, we make sizeof(fStackBuffer)=16 (=8 UChars) |
- * which is at least as large as sizeof(fFields) on 32-bit and 64-bit machines. |
- * (Padding at the end of fFields is ok: |
- * As long as there is no padding after fStackBuffer, it is not wasted space.) |
+ * We optimize for the longest possible internal buffer for short strings. |
+ * fUnion.fStackFields begins with 2 bytes for storage flags |
+ * and the length of relatively short strings, |
+ * followed by the buffer for short string contents. |
+ * There is no padding inside fStackFields. |
* |
- * We further assume that the compiler does not reorder the fields, |
- * so that fRestOfStackBuffer (which holds a few more UChars) immediately follows after fUnion, |
- * with at most some padding (but no other field) in between. |
- * (Padding there would be wasted space, but functionally harmless.) |
+ * Heap-allocated and aliased strings use fUnion.fFields. |
+ * Both fStackFields and fFields must begin with the same fields for flags and short length, |
+ * that is, those must have the same memory offsets inside the object, |
+ * because the flags must be inspected in order to decide which half of fUnion is being used. |
+ * We assume that the compiler does not reorder the fields. |
+ * |
+ * (Padding at the end of fFields is ok: |
+ * As long as it is no larger than fStackFields, it is not wasted space.) |
* |
- * We use a few more sizeof(pointer)'s chunks of space with |
- * fRestOfStackBuffer, fShortLength and fFlags, |
- * to get up exactly to the intended sizeof(UnicodeString). |
+ * For some of the history of the UnicodeString class fields layout, see |
+ * - ICU ticket #11551 "longer UnicodeString contents in stack buffer" |
+ * - ICU ticket #11336 "UnicodeString: recombine stack buffer arrays" |
+ * - ICU ticket #8322 "why is sizeof(UnicodeString)==48?" |
*/ |
// (implicit) *vtable; |
union StackBufferOrFields { |
- // fStackBuffer is used iff (fFlags&kUsingStackBuffer) |
- // else fFields is used |
- UChar fStackBuffer[8]; // buffer for short strings, together with fRestOfStackBuffer |
+ // fStackFields is used iff (fLengthAndFlags&kUsingStackBuffer) else fFields is used. |
+ // Each struct of the union must begin with fLengthAndFlags. |
struct { |
- UChar *fArray; // the Unicode data |
- int32_t fCapacity; // capacity of fArray (in UChars) |
+ int16_t fLengthAndFlags; // bit fields: see constants above |
+ UChar fBuffer[US_STACKBUF_SIZE]; // buffer for short strings |
+ } fStackFields; |
+ struct { |
+ int16_t fLengthAndFlags; // bit fields: see constants above |
int32_t fLength; // number of characters in fArray if >127; else undefined |
+ int32_t fCapacity; // capacity of fArray (in UChars) |
+ // array pointer last to minimize padding for machines with P128 data model |
+ // or pointer sizes that are not a power of 2 |
+ UChar *fArray; // the Unicode data |
} fFields; |
} fUnion; |
- UChar fRestOfStackBuffer[US_STACKBUF_SIZE-8]; |
- int8_t fShortLength; // 0..127: length <0: real length is in fUnion.fFields.fLength |
- uint8_t fFlags; // bit flags: see constants above |
}; |
/** |
@@ -3594,33 +3755,51 @@ UnicodeString::pinIndices(int32_t& start, |
} |
inline UChar* |
-UnicodeString::getArrayStart() |
-{ return (fFlags&kUsingStackBuffer) ? fUnion.fStackBuffer : fUnion.fFields.fArray; } |
+UnicodeString::getArrayStart() { |
+ return (fUnion.fFields.fLengthAndFlags&kUsingStackBuffer) ? |
+ fUnion.fStackFields.fBuffer : fUnion.fFields.fArray; |
+} |
inline const UChar* |
-UnicodeString::getArrayStart() const |
-{ return (fFlags&kUsingStackBuffer) ? fUnion.fStackBuffer : fUnion.fFields.fArray; } |
+UnicodeString::getArrayStart() const { |
+ return (fUnion.fFields.fLengthAndFlags&kUsingStackBuffer) ? |
+ fUnion.fStackFields.fBuffer : fUnion.fFields.fArray; |
+} |
//======================================== |
// Default constructor |
//======================================== |
inline |
-UnicodeString::UnicodeString() |
- : fShortLength(0), |
- fFlags(kShortString) |
-{} |
+UnicodeString::UnicodeString() { |
+ fUnion.fStackFields.fLengthAndFlags=kShortString; |
+} |
//======================================== |
// Read-only implementation methods |
//======================================== |
+inline UBool |
+UnicodeString::hasShortLength() const { |
+ return fUnion.fFields.fLengthAndFlags>=0; |
+} |
+ |
+inline int32_t |
+UnicodeString::getShortLength() const { |
+ // fLengthAndFlags must be non-negative -> short length >= 0 |
+ // and arithmetic or logical shift does not matter. |
+ return fUnion.fFields.fLengthAndFlags>>kLengthShift; |
+} |
+ |
inline int32_t |
-UnicodeString::length() const |
-{ return fShortLength>=0 ? fShortLength : fUnion.fFields.fLength; } |
+UnicodeString::length() const { |
+ return hasShortLength() ? getShortLength() : fUnion.fFields.fLength; |
+} |
inline int32_t |
-UnicodeString::getCapacity() const |
-{ return (fFlags&kUsingStackBuffer) ? US_STACKBUF_SIZE : fUnion.fFields.fCapacity; } |
+UnicodeString::getCapacity() const { |
+ return (fUnion.fFields.fLengthAndFlags&kUsingStackBuffer) ? |
+ US_STACKBUF_SIZE : fUnion.fFields.fCapacity; |
+} |
inline int32_t |
UnicodeString::hashCode() const |
@@ -3628,26 +3807,26 @@ UnicodeString::hashCode() const |
inline UBool |
UnicodeString::isBogus() const |
-{ return (UBool)(fFlags & kIsBogus); } |
+{ return (UBool)(fUnion.fFields.fLengthAndFlags & kIsBogus); } |
inline UBool |
UnicodeString::isWritable() const |
-{ return (UBool)!(fFlags&(kOpenGetBuffer|kIsBogus)); } |
+{ return (UBool)!(fUnion.fFields.fLengthAndFlags&(kOpenGetBuffer|kIsBogus)); } |
inline UBool |
UnicodeString::isBufferWritable() const |
{ |
return (UBool)( |
- !(fFlags&(kOpenGetBuffer|kIsBogus|kBufferIsReadonly)) && |
- (!(fFlags&kRefCounted) || refCount()==1)); |
+ !(fUnion.fFields.fLengthAndFlags&(kOpenGetBuffer|kIsBogus|kBufferIsReadonly)) && |
+ (!(fUnion.fFields.fLengthAndFlags&kRefCounted) || refCount()==1)); |
} |
inline const UChar * |
UnicodeString::getBuffer() const { |
- if(fFlags&(kIsBogus|kOpenGetBuffer)) { |
+ if(fUnion.fFields.fLengthAndFlags&(kIsBogus|kOpenGetBuffer)) { |
return 0; |
- } else if(fFlags&kUsingStackBuffer) { |
- return fUnion.fStackBuffer; |
+ } else if(fUnion.fFields.fLengthAndFlags&kUsingStackBuffer) { |
+ return fUnion.fStackFields.fBuffer; |
} else { |
return fUnion.fFields.fArray; |
} |
@@ -4248,26 +4427,38 @@ UnicodeString::operator[] (int32_t offset) const |
inline UBool |
UnicodeString::isEmpty() const { |
- return fShortLength == 0; |
+ // Arithmetic or logical right shift does not matter: only testing for 0. |
+ return (fUnion.fFields.fLengthAndFlags>>kLengthShift) == 0; |
} |
//======================================== |
// Write implementation methods |
//======================================== |
inline void |
+UnicodeString::setZeroLength() { |
+ fUnion.fFields.fLengthAndFlags &= kAllStorageFlags; |
+} |
+ |
+inline void |
+UnicodeString::setShortLength(int32_t len) { |
+ // requires 0 <= len <= kMaxShortLength |
+ fUnion.fFields.fLengthAndFlags = |
+ (int16_t)((fUnion.fFields.fLengthAndFlags & kAllStorageFlags) | (len << kLengthShift)); |
+} |
+ |
+inline void |
UnicodeString::setLength(int32_t len) { |
- if(len <= 127) { |
- fShortLength = (int8_t)len; |
+ if(len <= kMaxShortLength) { |
+ setShortLength(len); |
} else { |
- fShortLength = (int8_t)-1; |
+ fUnion.fFields.fLengthAndFlags |= kLengthIsLarge; |
fUnion.fFields.fLength = len; |
} |
} |
inline void |
UnicodeString::setToEmpty() { |
- fShortLength = 0; |
- fFlags = kShortString; |
+ fUnion.fFields.fLengthAndFlags = kShortString; |
} |
inline void |
@@ -4335,30 +4526,30 @@ inline UnicodeString& |
UnicodeString::append(const UnicodeString& srcText, |
int32_t srcStart, |
int32_t srcLength) |
-{ return doReplace(length(), 0, srcText, srcStart, srcLength); } |
+{ return doAppend(srcText, srcStart, srcLength); } |
inline UnicodeString& |
UnicodeString::append(const UnicodeString& srcText) |
-{ return doReplace(length(), 0, srcText, 0, srcText.length()); } |
+{ return doAppend(srcText, 0, srcText.length()); } |
inline UnicodeString& |
UnicodeString::append(const UChar *srcChars, |
int32_t srcStart, |
int32_t srcLength) |
-{ return doReplace(length(), 0, srcChars, srcStart, srcLength); } |
+{ return doAppend(srcChars, srcStart, srcLength); } |
inline UnicodeString& |
UnicodeString::append(const UChar *srcChars, |
int32_t srcLength) |
-{ return doReplace(length(), 0, srcChars, 0, srcLength); } |
+{ return doAppend(srcChars, 0, srcLength); } |
inline UnicodeString& |
UnicodeString::append(UChar srcChar) |
-{ return doReplace(length(), 0, &srcChar, 0, 1); } |
+{ return doAppend(&srcChar, 0, 1); } |
inline UnicodeString& |
UnicodeString::operator+= (UChar ch) |
-{ return doReplace(length(), 0, &ch, 0, 1); } |
+{ return doAppend(&ch, 0, 1); } |
inline UnicodeString& |
UnicodeString::operator+= (UChar32 ch) { |
@@ -4367,7 +4558,7 @@ UnicodeString::operator+= (UChar32 ch) { |
inline UnicodeString& |
UnicodeString::operator+= (const UnicodeString& srcText) |
-{ return doReplace(length(), 0, srcText, 0, srcText.length()); } |
+{ return doAppend(srcText, 0, srcText.length()); } |
inline UnicodeString& |
UnicodeString::insert(int32_t start, |
@@ -4412,7 +4603,7 @@ UnicodeString::remove() |
if(isBogus()) { |
setToEmpty(); |
} else { |
- fShortLength = 0; |
+ setZeroLength(); |
} |
return *this; |
} |