ICU 55.1 55.1

- Main Page
- Related Pages
- Modules
- Namespaces
- Data Structures
- Files

- File List
- Globals

All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
unistr.h
Go to the documentation of this file.
1 /*
2 **********************************************************************
3 * Copyright (C) 1998-2014, International Business Machines
4 * Corporation and others. All Rights Reserved.
5 **********************************************************************
6 *
7 * File unistr.h
8 *
9 * Modification History:
10 *
11 * Date Name Description
12 * 09/25/98 stephen Creation.
13 * 11/11/98 stephen Changed per 11/9 code review.
14 * 04/20/99 stephen Overhauled per 4/16 code review.
15 * 11/18/99 aliu Made to inherit from Replaceable. Added method
16 * handleReplaceBetween(); other methods unchanged.
17 * 06/25/01 grhoten Remove dependency on iostream.
18 ******************************************************************************
19 */
20
21 #ifndef UNISTR_H
22 #define UNISTR_H
23
29 #include "unicode/utypes.h"
30 #include "unicode/rep.h"
31 #include "unicode/std_string.h"
32 #include "unicode/stringpiece.h"
33 #include "unicode/bytestream.h"
34 #include "unicode/ucasemap.h"
35
36 struct UConverter; // unicode/ucnv.h
37 class StringThreadTest;
38
39 #ifndef U_COMPARE_CODE_POINT_ORDER
40 /* see also ustring.h and unorm.h */
46 #define U_COMPARE_CODE_POINT_ORDER 0x8000
47 #endif
48
49 #ifndef USTRING_H
50
53 U_STABLE int32_t U_EXPORT2
54 u_strlen(const UChar *s);
55 #endif
56
61 #ifndef U_STRING_CASE_MAPPER_DEFINED
62 #define U_STRING_CASE_MAPPER_DEFINED
63
68 typedef int32_t U_CALLCONV
69 UStringCaseMapper(const UCaseMap *csm,
70 UChar *dest, int32_t destCapacity,
71 const UChar *src, int32_t srcLength,
72 UErrorCode *pErrorCode);
73
74 #endif
75
76 U_NAMESPACE_BEGIN
77
78 class BreakIterator; // unicode/brkiter.h
79 class Locale; // unicode/locid.h
80 class StringCharacterIterator;
81 class UnicodeStringAppendable; // unicode/appendable.h
82
83 /* The <iostream> include has been moved to unicode/ustream.h */
84
95 #define US_INV icu::UnicodeString::kInvariant
96
114 #if defined(U_DECLARE_UTF16)
115 # define UNICODE_STRING(cs, _length) icu::UnicodeString(TRUE, (const UChar *)U_DECLARE_UTF16(cs), _length)
116 #elif U_SIZEOF_WCHAR_T==U_SIZEOF_UCHAR && (U_CHARSET_FAMILY==U_ASCII_FAMILY || (U_SIZEOF_UCHAR == 2 && defined(U_WCHAR_IS_UTF16)))
117 # define UNICODE_STRING(cs, _length) icu::UnicodeString(TRUE, (const UChar *)L ## cs, _length)
118 #elif U_SIZEOF_UCHAR==1 && U_CHARSET_FAMILY==U_ASCII_FAMILY
119 # define UNICODE_STRING(cs, _length) icu::UnicodeString(TRUE, (const UChar *)cs, _length)
120 #else
121 # define UNICODE_STRING(cs, _length) icu::UnicodeString(cs, _length, US_INV)
122 #endif
123
137 #define UNICODE_STRING_SIMPLE(cs) UNICODE_STRING(cs, -1)
138
146 #ifndef UNISTR_FROM_CHAR_EXPLICIT
147 # if defined(U_COMBINED_IMPLEMENTATION) || defined(U_COMMON_IMPLEMENTATION) || defined(U_I18N_IMPLEMENTATION) || defined(U_IO_IMPLEMENTATION)
148 // Auto-"explicit" in ICU library code.
149 # define UNISTR_FROM_CHAR_EXPLICIT explicit
150 # else
151 // Empty by default for source code compatibility.
152 # define UNISTR_FROM_CHAR_EXPLICIT
153 # endif
154 #endif
155
166 #ifndef UNISTR_FROM_STRING_EXPLICIT
167 # if defined(U_COMBINED_IMPLEMENTATION) || defined(U_COMMON_IMPLEMENTATION) || defined(U_I18N_IMPLEMENTATION) || defined(U_IO_IMPLEMENTATION)
168 // Auto-"explicit" in ICU library code.
169 # define UNISTR_FROM_STRING_EXPLICIT explicit
170 # else
171 // Empty by default for source code compatibility.
172 # define UNISTR_FROM_STRING_EXPLICIT
173 # endif
174 #endif
175
245 class U_COMMON_API UnicodeString : public Replaceable
246 {
247 public:
248
257 enum EInvariant {
262 kInvariant
263 };
264
265 //========================================
266 // Read-only operations
267 //========================================
268
269 /* Comparison - bitwise only - for international comparison use collation */
270
278 inline UBool operator== (const UnicodeString& text) const;
279
287 inline UBool operator!= (const UnicodeString& text) const;
288
296 inline UBool operator> (const UnicodeString& text) const;
297
305 inline UBool operator< (const UnicodeString& text) const;
306
314 inline UBool operator>= (const UnicodeString& text) const;
315
323 inline UBool operator<= (const UnicodeString& text) const;
324
336 inline int8_t compare(const UnicodeString& text) const;
337
353 inline int8_t compare(int32_t start,
354 int32_t length,
355 const UnicodeString& text) const;
356
374 inline int8_t compare(int32_t start,
375 int32_t length,
376 const UnicodeString& srcText,
377 int32_t srcStart,
378 int32_t srcLength) const;
379
392 inline int8_t compare(const UChar *srcChars,
393 int32_t srcLength) const;
394
409 inline int8_t compare(int32_t start,
410 int32_t length,
411 const UChar *srcChars) const;
412
430 inline int8_t compare(int32_t start,
431 int32_t length,
432 const UChar *srcChars,
433 int32_t srcStart,
434 int32_t srcLength) const;
435
453 inline int8_t compareBetween(int32_t start,
454 int32_t limit,
455 const UnicodeString& srcText,
456 int32_t srcStart,
457 int32_t srcLimit) const;
458
476 inline int8_t compareCodePointOrder(const UnicodeString& text) const;
477
497 inline int8_t compareCodePointOrder(int32_t start,
498 int32_t length,
499 const UnicodeString& srcText) const;
500
522 inline int8_t compareCodePointOrder(int32_t start,
523 int32_t length,
524 const UnicodeString& srcText,
525 int32_t srcStart,
526 int32_t srcLength) const;
527
546 inline int8_t compareCodePointOrder(const UChar *srcChars,
547 int32_t srcLength) const;
548
568 inline int8_t compareCodePointOrder(int32_t start,
569 int32_t length,
570 const UChar *srcChars) const;
571
593 inline int8_t compareCodePointOrder(int32_t start,
594 int32_t length,
595 const UChar *srcChars,
596 int32_t srcStart,
597 int32_t srcLength) const;
598
620 inline int8_t compareCodePointOrderBetween(int32_t start,
621 int32_t limit,
622 const UnicodeString& srcText,
623 int32_t srcStart,
624 int32_t srcLimit) const;
625
644 inline int8_t caseCompare(const UnicodeString& text, uint32_t options) const;
645
666 inline int8_t caseCompare(int32_t start,
667 int32_t length,
668 const UnicodeString& srcText,
669 uint32_t options) const;
670
693 inline int8_t caseCompare(int32_t start,
694 int32_t length,
695 const UnicodeString& srcText,
696 int32_t srcStart,
697 int32_t srcLength,
698 uint32_t options) const;
699
719 inline int8_t caseCompare(const UChar *srcChars,
720 int32_t srcLength,
721 uint32_t options) const;
722
743 inline int8_t caseCompare(int32_t start,
744 int32_t length,
745 const UChar *srcChars,
746 uint32_t options) const;
747
770 inline int8_t caseCompare(int32_t start,
771 int32_t length,
772 const UChar *srcChars,
773 int32_t srcStart,
774 int32_t srcLength,
775 uint32_t options) const;
776
799 inline int8_t caseCompareBetween(int32_t start,
800 int32_t limit,
801 const UnicodeString& srcText,
802 int32_t srcStart,
803 int32_t srcLimit,
804 uint32_t options) const;
805
813 inline UBool startsWith(const UnicodeString& text) const;
814
825 inline UBool startsWith(const UnicodeString& srcText,
826 int32_t srcStart,
827 int32_t srcLength) const;
828
837 inline UBool startsWith(const UChar *srcChars,
838 int32_t srcLength) const;
839
849 inline UBool startsWith(const UChar *srcChars,
850 int32_t srcStart,
851 int32_t srcLength) const;
852
860 inline UBool endsWith(const UnicodeString& text) const;
861
872 inline UBool endsWith(const UnicodeString& srcText,
873 int32_t srcStart,
874 int32_t srcLength) const;
875
884 inline UBool endsWith(const UChar *srcChars,
885 int32_t srcLength) const;
886
897 inline UBool endsWith(const UChar *srcChars,
898 int32_t srcStart,
899 int32_t srcLength) const;
900
901
902 /* Searching - bitwise only */
903
912 inline int32_t indexOf(const UnicodeString& text) const;
913
923 inline int32_t indexOf(const UnicodeString& text,
924 int32_t start) const;
925
937 inline int32_t indexOf(const UnicodeString& text,
938 int32_t start,
939 int32_t length) const;
940
957 inline int32_t indexOf(const UnicodeString& srcText,
958 int32_t srcStart,
959 int32_t srcLength,
960 int32_t start,
961 int32_t length) const;
962
974 inline int32_t indexOf(const UChar *srcChars,
975 int32_t srcLength,
976 int32_t start) const;
977
990 inline int32_t indexOf(const UChar *srcChars,
991 int32_t srcLength,
992 int32_t start,
993 int32_t length) const;
994
1011 int32_t indexOf(const UChar *srcChars,
1012 int32_t srcStart,
1013 int32_t srcLength,
1014 int32_t start,
1015 int32_t length) const;
1016
1024 inline int32_t indexOf(UChar c) const;
1025
1034 inline int32_t indexOf(UChar32 c) const;
1035
1044 inline int32_t indexOf(UChar c,
1045 int32_t start) const;
1046
1056 inline int32_t indexOf(UChar32 c,
1057 int32_t start) const;
1058
1069 inline int32_t indexOf(UChar c,
1070 int32_t start,
1071 int32_t length) const;
1072
1084 inline int32_t indexOf(UChar32 c,
1085 int32_t start,
1086 int32_t length) const;
1087
1096 inline int32_t lastIndexOf(const UnicodeString& text) const;
1097
1107 inline int32_t lastIndexOf(const UnicodeString& text,
1108 int32_t start) const;
1109
1121 inline int32_t lastIndexOf(const UnicodeString& text,
1122 int32_t start,
1123 int32_t length) const;
1124
1141 inline int32_t lastIndexOf(const UnicodeString& srcText,
1142 int32_t srcStart,
1143 int32_t srcLength,
1144 int32_t start,
1145 int32_t length) const;
1146
1157 inline int32_t lastIndexOf(const UChar *srcChars,
1158 int32_t srcLength,
1159 int32_t start) const;
1160
1173 inline int32_t lastIndexOf(const UChar *srcChars,
1174 int32_t srcLength,
1175 int32_t start,
1176 int32_t length) const;
1177
1194 int32_t lastIndexOf(const UChar *srcChars,
1195 int32_t srcStart,
1196 int32_t srcLength,
1197 int32_t start,
1198 int32_t length) const;
1199
1207 inline int32_t lastIndexOf(UChar c) const;
1208
1217 inline int32_t lastIndexOf(UChar32 c) const;
1218
1227 inline int32_t lastIndexOf(UChar c,
1228 int32_t start) const;
1229
1239 inline int32_t lastIndexOf(UChar32 c,
1240 int32_t start) const;
1241
1252 inline int32_t lastIndexOf(UChar c,
1253 int32_t start,
1254 int32_t length) const;
1255
1267 inline int32_t lastIndexOf(UChar32 c,
1268 int32_t start,
1269 int32_t length) const;
1270
1271
1272 /* Character access */
1273
1282 inline UChar charAt(int32_t offset) const;
1283
1291 inline UChar operator[] (int32_t offset) const;
1292
1304 UChar32 char32At(int32_t offset) const;
1305
1321 int32_t getChar32Start(int32_t offset) const;
1322
1339 int32_t getChar32Limit(int32_t offset) const;
1340
1391 int32_t moveIndex32(int32_t index, int32_t delta) const;
1392
1393 /* Substring extraction */
1394
1410 inline void extract(int32_t start,
1411 int32_t length,
1412 UChar *dst,
1413 int32_t dstStart = 0) const;
1414
1436 int32_t
1437 extract(UChar *dest, int32_t destCapacity,
1438 UErrorCode &errorCode) const;
1439
1450 inline void extract(int32_t start,
1451 int32_t length,
1452 UnicodeString& target) const;
1453
1465 inline void extractBetween(int32_t start,
1466 int32_t limit,
1467 UChar *dst,
1468 int32_t dstStart = 0) const;
1469
1479 virtual void extractBetween(int32_t start,
1480 int32_t limit,
1481 UnicodeString& target) const;
1482
1504 int32_t extract(int32_t start,
1505 int32_t startLength,
1506 char *target,
1507 int32_t targetCapacity,
1508 enum EInvariant inv) const;
1509
1510 #if U_CHARSET_IS_UTF8 || !UCONFIG_NO_CONVERSION
1511
1531 int32_t extract(int32_t start,
1532 int32_t startLength,
1533 char *target,
1534 uint32_t targetLength) const;
1535
1536 #endif
1537
1538 #if !UCONFIG_NO_CONVERSION
1539
1565 inline int32_t extract(int32_t start,
1566 int32_t startLength,
1567 char *target,
1568 const char *codepage = 0) const;
1569
1599 int32_t extract(int32_t start,
1600 int32_t startLength,
1601 char *target,
1602 uint32_t targetLength,
1603 const char *codepage) const;
1604
1622 int32_t extract(char *dest, int32_t destCapacity,
1623 UConverter *cnv,
1624 UErrorCode &errorCode) const;
1625
1626 #endif
1627
1641 UnicodeString tempSubString(int32_t start=0, int32_t length=INT32_MAX) const;
1642
1653 inline UnicodeString tempSubStringBetween(int32_t start, int32_t limit=INT32_MAX) const;
1654
1666 void toUTF8(ByteSink &sink) const;
1667
1668 #if U_HAVE_STD_STRING
1669
1682 template<typename StringClass>
1683 StringClass &toUTF8String(StringClass &result) const {
1684 StringByteSink<StringClass> sbs(&result);
1685 toUTF8(sbs);
1686 return result;
1687 }
1688
1689 #endif
1690
1706 int32_t toUTF32(UChar32 *utf32, int32_t capacity, UErrorCode &errorCode) const;
1707
1708 /* Length operations */
1709
1718 inline int32_t length(void) const;
1719
1733 int32_t
1734 countChar32(int32_t start=0, int32_t length=INT32_MAX) const;
1735
1759 UBool
1760 hasMoreChar32Than(int32_t start, int32_t length, int32_t number) const;
1761
1767 inline UBool isEmpty(void) const;
1768
1778 inline int32_t getCapacity(void) const;
1779
1780 /* Other operations */
1781
1787 inline int32_t hashCode(void) const;
1788
1801 inline UBool isBogus(void) const;
1802
1803
1804 //========================================
1805 // Write operations
1806 //========================================
1807
1808 /* Assignment operations */
1809
1817 UnicodeString &operator=(const UnicodeString &srcText);
1818
1841 UnicodeString &fastCopyFrom(const UnicodeString &src);
1842
1850 inline UnicodeString& operator= (UChar ch);
1851
1859 inline UnicodeString& operator= (UChar32 ch);
1860
1872 inline UnicodeString& setTo(const UnicodeString& srcText,
1873 int32_t srcStart);
1874
1888 inline UnicodeString& setTo(const UnicodeString& srcText,
1889 int32_t srcStart,
1890 int32_t srcLength);
1891
1900 inline UnicodeString& setTo(const UnicodeString& srcText);
1901
1910 inline UnicodeString& setTo(const UChar *srcChars,
1911 int32_t srcLength);
1912
1921 UnicodeString& setTo(UChar srcChar);
1922
1931 UnicodeString& setTo(UChar32 srcChar);
1932
1956 UnicodeString &setTo(UBool isTerminated,
1957 const UChar *text,
1958 int32_t textLength);
1959
1979 UnicodeString &setTo(UChar *buffer,
1980 int32_t buffLength,
1981 int32_t buffCapacity);
1982
2023 void setToBogus();
2024
2032 UnicodeString& setCharAt(int32_t offset,
2033 UChar ch);
2034
2035
2036 /* Append operations */
2037
2045 inline UnicodeString& operator+= (UChar ch);
2046
2054 inline UnicodeString& operator+= (UChar32 ch);
2055
2063 inline UnicodeString& operator+= (const UnicodeString& srcText);
2064
2079 inline UnicodeString& append(const UnicodeString& srcText,
2080 int32_t srcStart,
2081 int32_t srcLength);
2082
2090 inline UnicodeString& append(const UnicodeString& srcText);
2091
2105 inline UnicodeString& append(const UChar *srcChars,
2106 int32_t srcStart,
2107 int32_t srcLength);
2108
2118 inline UnicodeString& append(const UChar *srcChars,
2119 int32_t srcLength);
2120
2127 inline UnicodeString& append(UChar srcChar);
2128
2135 UnicodeString& append(UChar32 srcChar);
2136
2137
2138 /* Insert operations */
2139
2153 inline UnicodeString& insert(int32_t start,
2154 const UnicodeString& srcText,
2155 int32_t srcStart,
2156 int32_t srcLength);
2157
2166 inline UnicodeString& insert(int32_t start,
2167 const UnicodeString& srcText);
2168
2182 inline UnicodeString& insert(int32_t start,
2183 const UChar *srcChars,
2184 int32_t srcStart,
2185 int32_t srcLength);
2186
2196 inline UnicodeString& insert(int32_t start,
2197 const UChar *srcChars,
2198 int32_t srcLength);
2199
2208 inline UnicodeString& insert(int32_t start,
2209 UChar srcChar);
2210
2219 inline UnicodeString& insert(int32_t start,
2220 UChar32 srcChar);
2221
2222
2223 /* Replace operations */
2224
2242 UnicodeString& replace(int32_t start,
2243 int32_t length,
2244 const UnicodeString& srcText,
2245 int32_t srcStart,
2246 int32_t srcLength);
2247
2260 UnicodeString& replace(int32_t start,
2261 int32_t length,
2262 const UnicodeString& srcText);
2263
2281 UnicodeString& replace(int32_t start,
2282 int32_t length,
2283 const UChar *srcChars,
2284 int32_t srcStart,
2285 int32_t srcLength);
2286
2299 inline UnicodeString& replace(int32_t start,
2300 int32_t length,
2301 const UChar *srcChars,
2302 int32_t srcLength);
2303
2315 inline UnicodeString& replace(int32_t start,
2316 int32_t length,
2317 UChar srcChar);
2318
2330 UnicodeString& replace(int32_t start, int32_t length, UChar32 srcChar);
2331
2341 inline UnicodeString& replaceBetween(int32_t start,
2342 int32_t limit,
2343 const UnicodeString& srcText);
2344
2359 inline UnicodeString& replaceBetween(int32_t start,
2360 int32_t limit,
2361 const UnicodeString& srcText,
2362 int32_t srcStart,
2363 int32_t srcLimit);
2364
2375 virtual void handleReplaceBetween(int32_t start,
2376 int32_t limit,
2377 const UnicodeString& text);
2378
2384 virtual UBool hasMetaData() const;
2385
2401 virtual void copy(int32_t start, int32_t limit, int32_t dest);
2402
2403 /* Search and replace operations */
2404
2413 inline UnicodeString& findAndReplace(const UnicodeString& oldText,
2414 const UnicodeString& newText);
2415
2427 inline UnicodeString& findAndReplace(int32_t start,
2428 int32_t length,
2429 const UnicodeString& oldText,
2430 const UnicodeString& newText);
2431
2449 UnicodeString& findAndReplace(int32_t start,
2450 int32_t length,
2451 const UnicodeString& oldText,
2452 int32_t oldStart,
2453 int32_t oldLength,
2454 const UnicodeString& newText,
2455 int32_t newStart,
2456 int32_t newLength);
2457
2458
2459 /* Remove operations */
2460
2466 inline UnicodeString& remove(void);
2467
2476 inline UnicodeString& remove(int32_t start,
2477 int32_t length = (int32_t)INT32_MAX);
2478
2487 inline UnicodeString& removeBetween(int32_t start,
2488 int32_t limit = (int32_t)INT32_MAX);
2489
2499 inline UnicodeString &retainBetween(int32_t start, int32_t limit = INT32_MAX);
2500
2501 /* Length operations */
2502
2514 UBool padLeading(int32_t targetLength,
2515 UChar padChar = 0x0020);
2516
2528 UBool padTrailing(int32_t targetLength,
2529 UChar padChar = 0x0020);
2530
2537 inline UBool truncate(int32_t targetLength);
2538
2544 UnicodeString& trim(void);
2545
2546
2547 /* Miscellaneous operations */
2548
2554 inline UnicodeString& reverse(void);
2555
2564 inline UnicodeString& reverse(int32_t start,
2565 int32_t length);
2566
2573 UnicodeString& toUpper(void);
2574
2582 UnicodeString& toUpper(const Locale& locale);
2583
2590 UnicodeString& toLower(void);
2591
2599 UnicodeString& toLower(const Locale& locale);
2600
2601 #if !UCONFIG_NO_BREAK_ITERATION
2602
2629 UnicodeString &toTitle(BreakIterator *titleIter);
2630
2658 UnicodeString &toTitle(BreakIterator *titleIter, const Locale &locale);
2659
2691 UnicodeString &toTitle(BreakIterator *titleIter, const Locale &locale, uint32_t options);
2692
2693 #endif
2694
2708 UnicodeString &foldCase(uint32_t options=0 /*U_FOLD_CASE_DEFAULT*/);
2709
2710 //========================================
2711 // Access to the internal buffer
2712 //========================================
2713
2757 UChar *getBuffer(int32_t minCapacity);
2758
2779 void releaseBuffer(int32_t newLength=-1);
2780
2811 inline const UChar *getBuffer() const;
2812
2846 const UChar *getTerminatedBuffer();
2847
2848 //========================================
2849 // Constructors
2850 //========================================
2851
2855 inline UnicodeString();
2856
2868 UnicodeString(int32_t capacity, UChar32 c, int32_t count);
2869
2879 UNISTR_FROM_CHAR_EXPLICIT UnicodeString(UChar ch);
2880
2890 UNISTR_FROM_CHAR_EXPLICIT UnicodeString(UChar32 ch);
2891
2902 UNISTR_FROM_STRING_EXPLICIT UnicodeString(const UChar *text);
2903
2911 UnicodeString(const UChar *text,
2912 int32_t textLength);
2913
2936 UnicodeString(UBool isTerminated,
2937 const UChar *text,
2938 int32_t textLength);
2939
2958 UnicodeString(UChar *buffer, int32_t buffLength, int32_t buffCapacity);
2959
2960 #if U_CHARSET_IS_UTF8 || !UCONFIG_NO_CONVERSION
2961
2981 UNISTR_FROM_STRING_EXPLICIT UnicodeString(const char *codepageData);
2982
2991 UnicodeString(const char *codepageData, int32_t dataLength);
2992
2993 #endif
2994
2995 #if !UCONFIG_NO_CONVERSION
2996
3014 UnicodeString(const char *codepageData, const char *codepage);
3015
3033 UnicodeString(const char *codepageData, int32_t dataLength, const char *codepage);
3034
3056 UnicodeString(
3057 const char *src, int32_t srcLength,
3058 UConverter *cnv,
3059 UErrorCode &errorCode);
3060
3061 #endif
3062
3087 UnicodeString(const char *src, int32_t length, enum EInvariant inv);
3088
3089
3095 UnicodeString(const UnicodeString& that);
3096
3103 UnicodeString(const UnicodeString& src, int32_t srcStart);
3104
3112 UnicodeString(const UnicodeString& src, int32_t srcStart, int32_t srcLength);
3113
3130 virtual Replaceable *clone() const;
3131
3135 virtual ~UnicodeString();
3136
3150 static UnicodeString fromUTF8(const StringPiece &utf8);
3151
3163 static UnicodeString fromUTF32(const UChar32 *utf32, int32_t length);
3164
3165 /* Miscellaneous operations */
3166
3201 UnicodeString unescape() const;
3202
3222 UChar32 unescapeAt(int32_t &offset) const;
3223
3229 static UClassID U_EXPORT2 getStaticClassID();
3230
3236 virtual UClassID getDynamicClassID() const;
3237
3238 //========================================
3239 // Implementation methods
3240 //========================================
3241
3242 protected:
3247 virtual int32_t getLength() const;
3248
3254 virtual UChar getCharAt(int32_t offset) const;
3255
3261 virtual UChar32 getChar32At(int32_t offset) const;
3262
3263 private:
3264 // For char* constructors. Could be made public.
3265 UnicodeString &setToUTF8(const StringPiece &utf8);
3266 // For extract(char*).
3267 // We could make a toUTF8(target, capacity, errorCode) public but not
3268 // this version: New API will be cleaner if we make callers create substrings
3269 // rather than having start+length on every method,
3270 // and it should take a UErrorCode&.
3271 int32_t
3272 toUTF8(int32_t start, int32_t len,
3273 char *target, int32_t capacity) const;
3274
3279 UBool doEquals(const UnicodeString &text, int32_t len) const;
3280
3281 inline int8_t
3282 doCompare(int32_t start,
3283 int32_t length,
3284 const UnicodeString& srcText,
3285 int32_t srcStart,
3286 int32_t srcLength) const;
3287
3288 int8_t doCompare(int32_t start,
3289 int32_t length,
3290 const UChar *srcChars,
3291 int32_t srcStart,
3292 int32_t srcLength) const;
3293
3294 inline int8_t
3295 doCompareCodePointOrder(int32_t start,
3296 int32_t length,
3297 const UnicodeString& srcText,
3298 int32_t srcStart,
3299 int32_t srcLength) const;
3300
3301 int8_t doCompareCodePointOrder(int32_t start,
3302 int32_t length,
3303 const UChar *srcChars,
3304 int32_t srcStart,
3305 int32_t srcLength) const;
3306
3307 inline int8_t
3308 doCaseCompare(int32_t start,
3309 int32_t length,
3310 const UnicodeString &srcText,
3311 int32_t srcStart,
3312 int32_t srcLength,
3313 uint32_t options) const;
3314
3315 int8_t
3316 doCaseCompare(int32_t start,
3317 int32_t length,
3318 const UChar *srcChars,
3319 int32_t srcStart,
3320 int32_t srcLength,
3321 uint32_t options) const;
3322
3323 int32_t doIndexOf(UChar c,
3324 int32_t start,
3325 int32_t length) const;
3326
3327 int32_t doIndexOf(UChar32 c,
3328 int32_t start,
3329 int32_t length) const;
3330
3331 int32_t doLastIndexOf(UChar c,
3332 int32_t start,
3333 int32_t length) const;
3334
3335 int32_t doLastIndexOf(UChar32 c,
3336 int32_t start,
3337 int32_t length) const;
3338
3339 void doExtract(int32_t start,
3340 int32_t length,
3341 UChar *dst,
3342 int32_t dstStart) const;
3343
3344 inline void doExtract(int32_t start,
3345 int32_t length,
3346 UnicodeString& target) const;
3347
3348 inline UChar doCharAt(int32_t offset) const;
3349
3350 UnicodeString& doReplace(int32_t start,
3351 int32_t length,
3352 const UnicodeString& srcText,
3353 int32_t srcStart,
3354 int32_t srcLength);
3355
3356 UnicodeString& doReplace(int32_t start,
3357 int32_t length,
3358 const UChar *srcChars,
3359 int32_t srcStart,
3360 int32_t srcLength);
3361
3362 UnicodeString& doReverse(int32_t start,
3363 int32_t length);
3364
3365 // calculate hash code
3366 int32_t doHashCode(void) const;
3367
3368 // get pointer to start of array
3369 // these do not check for kOpenGetBuffer, unlike the public getBuffer() function
3370 inline UChar* getArrayStart(void);
3371 inline const UChar* getArrayStart(void) const;
3372
3373 inline UBool hasShortLength() const;
3374 inline int32_t getShortLength() const;
3375
3376 // A UnicodeString object (not necessarily its current buffer)
3377 // is writable unless it isBogus() or it has an "open" getBuffer(minCapacity).
3378 inline UBool isWritable() const;
3379
3380 // Is the current buffer writable?
3381 inline UBool isBufferWritable() const;
3382
3383 // None of the following does releaseArray().
3384 inline void setZeroLength();
3385 inline void setShortLength(int32_t len);
3386 inline void setLength(int32_t len);
3387 inline void setToEmpty();
3388 inline void setArray(UChar *array, int32_t len, int32_t capacity); // sets length but not flags
3389
3390 // allocate the array; result may be the stack buffer
3391 // sets refCount to 1 if appropriate
3392 // sets fArray, fCapacity, and flags
3393 // sets length to 0
3394 // returns boolean for success or failure
3395 UBool allocate(int32_t capacity);
3396
3397 // release the array if owned
3398 void releaseArray(void);
3399
3400 // turn a bogus string into an empty one
3401 void unBogus();
3402
3403 // implements assigment operator, copy constructor, and fastCopyFrom()
3404 UnicodeString &copyFrom(const UnicodeString &src, UBool fastCopy=FALSE);
3405
3406 // Pin start and limit to acceptable values.
3407 inline void pinIndex(int32_t& start) const;
3408 inline void pinIndices(int32_t& start,
3409 int32_t& length) const;
3410
3411 #if !UCONFIG_NO_CONVERSION
3412
3413 /* Internal extract() using UConverter. */
3414 int32_t doExtract(int32_t start, int32_t length,
3415 char *dest, int32_t destCapacity,
3416 UConverter *cnv,
3417 UErrorCode &errorCode) const;
3418
3419 /*
3420 * Real constructor for converting from codepage data.
3421 * It assumes that it is called with !fRefCounted.
3422 *
3423 * If <code>codepage==0</code>, then the default converter
3424 * is used for the platform encoding.
3425 * If <code>codepage</code> is an empty string (<code>""</code>),
3426 * then a simple conversion is performed on the codepage-invariant
3427 * subset ("invariant characters") of the platform encoding. See utypes.h.
3428 */
3429 void doCodepageCreate(const char *codepageData,
3430 int32_t dataLength,
3431 const char *codepage);
3432
3433 /*
3434 * Worker function for creating a UnicodeString from
3435 * a codepage string using a UConverter.
3436 */
3437 void
3438 doCodepageCreate(const char *codepageData,
3439 int32_t dataLength,
3440 UConverter *converter,
3441 UErrorCode &status);
3442
3443 #endif
3444
3445 /*
3446 * This function is called when write access to the array
3447 * is necessary.
3448 *
3449 * We need to make a copy of the array if
3450 * the buffer is read-only, or
3451 * the buffer is refCounted (shared), and refCount>1, or
3452 * the buffer is too small.
3453 *
3454 * Return FALSE if memory could not be allocated.
3455 */
3456 UBool cloneArrayIfNeeded(int32_t newCapacity = -1,
3457 int32_t growCapacity = -1,
3458 UBool doCopyArray = TRUE,
3459 int32_t **pBufferToDelete = 0,
3460 UBool forceClone = FALSE);
3461
3467 UnicodeString &
3468 caseMap(const UCaseMap *csm, UStringCaseMapper *stringCaseMapper);
3469
3470 // ref counting
3471 void addRef(void);
3472 int32_t removeRef(void);
3473 int32_t refCount(void) const;
3474
3475 // constants
3476 enum {
3477 // Set the stack buffer size so that sizeof(UnicodeString) is,
3478 // naturally (without padding), a multiple of sizeof(pointer).
3479 US_STACKBUF_SIZE= sizeof(void *)==4 ? 13 : 15, // Size of stack buffer for short strings
3480 kInvalidUChar=0xffff, // U+FFFF returned by charAt(invalid index)
3481 kGrowSize=128, // grow size for this buffer
3482 kInvalidHashCode=0, // invalid hash code
3483 kEmptyHashCode=1, // hash code for empty string
3484
3485 // bit flag values for fLengthAndFlags
3486 kIsBogus=1, // this string is bogus, i.e., not valid or NULL
3487 kUsingStackBuffer=2,// using fUnion.fStackFields instead of fUnion.fFields
3488 kRefCounted=4, // there is a refCount field before the characters in fArray
3489 kBufferIsReadonly=8,// do not write to this buffer
3490 kOpenGetBuffer=16, // getBuffer(minCapacity) was called (is "open"),
3491 // and releaseBuffer(newLength) must be called
3492 kAllStorageFlags=0x1f,
3493
3494 kLengthShift=5, // remaining 11 bits for non-negative short length, or negative if long
3495 kLength1=1<<kLengthShift,
3496 kMaxShortLength=0x3ff, // max non-negative short length (leaves top bit 0)
3497 kLengthIsLarge=0xffe0, // short length < 0, real length is in fUnion.fFields.fLength
3498
3499 // combined values for convenience
3500 kShortString=kUsingStackBuffer,
3501 kLongString=kRefCounted,
3502 kReadonlyAlias=kBufferIsReadonly,
3503 kWritableAlias=0
3504 };
3505
3506 friend class StringThreadTest;
3507 friend class UnicodeStringAppendable;
3508
3509 union StackBufferOrFields; // forward declaration necessary before friend declaration
3510 friend union StackBufferOrFields; // make US_STACKBUF_SIZE visible inside fUnion
3511
3512 /*
3513 * The following are all the class fields that are stored
3514 * in each UnicodeString object.
3515 * Note that UnicodeString has virtual functions,
3516 * therefore there is an implicit vtable pointer
3517 * as the first real field.
3518 * The fields should be aligned such that no padding is necessary.
3519 * On 32-bit machines, the size should be 32 bytes,
3520 * on 64-bit machines (8-byte pointers), it should be 40 bytes.
3521 *
3522 * We use a hack to achieve this.
3523 *
3524 * With at least some compilers, each of the following is forced to
3525 * a multiple of sizeof(pointer) [the largest field base unit here is a data pointer],
3526 * rounded up with additional padding if the fields do not already fit that requirement:
3527 * - sizeof(class UnicodeString)
3528 * - offsetof(UnicodeString, fUnion)
3529 * - sizeof(fUnion)
3530 * - sizeof(fStackFields)
3531 *
3532 * We optimize for the longest possible internal buffer for short strings.
3533 * fUnion.fStackFields begins with 2 bytes for storage flags
3534 * and the length of relatively short strings,
3535 * followed by the buffer for short string contents.
3536 * There is no padding inside fStackFields.
3537 *
3538 * Heap-allocated and aliased strings use fUnion.fFields.
3539 * Both fStackFields and fFields must begin with the same fields for flags and short length,
3540 * that is, those must have the same memory offsets inside the object,
3541 * because the flags must be inspected in order to decide which half of fUnion is being used.
3542 * We assume that the compiler does not reorder the fields.
3543 *
3544 * (Padding at the end of fFields is ok:
3545 * As long as it is no larger than fStackFields, it is not wasted space.)
3546 *
3547 * For some of the history of the UnicodeString class fields layout,
3548 * see ICU ticket #11336 "UnicodeString: recombine stack buffer arrays"
3549 * and ticket #8322 "why is sizeof(UnicodeString)==48?".
3550 */
3551 // (implicit) *vtable;
3552 union StackBufferOrFields {
3553 // fStackFields is used iff (fLengthAndFlags&kUsingStackBuffer) else fFields is used.
3554 // Each struct of the union must begin with fLengthAndFlags.
3555 struct {
3556 int16_t fLengthAndFlags; // bit fields: see constants above
3557 UChar fBuffer[US_STACKBUF_SIZE]; // buffer for short strings
3558 } fStackFields;
3559 struct {
3560 int16_t fLengthAndFlags; // bit fields: see constants above
3561 UChar *fArray; // the Unicode data
3562 int32_t fCapacity; // capacity of fArray (in UChars)
3563 int32_t fLength; // number of characters in fArray if >127; else undefined
3564 } fFields;
3565 } fUnion;
3566 };
3567
3576 U_COMMON_API UnicodeString U_EXPORT2
3577 operator+ (const UnicodeString &s1, const UnicodeString &s2);
3578
3579 //========================================
3580 // Inline members
3581 //========================================
3582
3583 //========================================
3584 // Privates
3585 //========================================
3586
3587 inline void
3588 UnicodeString::pinIndex(int32_t& start) const
3589 {
3590 // pin index
3591 if(start < 0) {
3592 start = 0;
3593 } else if(start > length()) {
3594 start = length();
3595 }
3596 }
3597
3598 inline void
3599 UnicodeString::pinIndices(int32_t& start,
3600 int32_t& _length) const
3601 {
3602 // pin indices
3603 int32_t len = length();
3604 if(start < 0) {
3605 start = 0;
3606 } else if(start > len) {
3607 start = len;
3608 }
3609 if(_length < 0) {
3610 _length = 0;
3611 } else if(_length > (len - start)) {
3612 _length = (len - start);
3613 }
3614 }
3615
3616 inline UChar*
3617 UnicodeString::getArrayStart() {
3618 return (fUnion.fFields.fLengthAndFlags&kUsingStackBuffer) ?
3619 fUnion.fStackFields.fBuffer : fUnion.fFields.fArray;
3620 }
3621
3622 inline const UChar*
3623 UnicodeString::getArrayStart() const {
3624 return (fUnion.fFields.fLengthAndFlags&kUsingStackBuffer) ?
3625 fUnion.fStackFields.fBuffer : fUnion.fFields.fArray;
3626 }
3627
3628 //========================================
3629 // Default constructor
3630 //========================================
3631
3632 inline
3633 UnicodeString::UnicodeString() {
3634 fUnion.fStackFields.fLengthAndFlags=kShortString;
3635 }
3636
3637 //========================================
3638 // Read-only implementation methods
3639 //========================================
3640 inline UBool
3641 UnicodeString::hasShortLength() const {
3642 return fUnion.fFields.fLengthAndFlags>=0;
3643 }
3644
3645 inline int32_t
3646 UnicodeString::getShortLength() const {
3647 // fLengthAndFlags must be non-negative -> short length >= 0
3648 // and arithmetic or logical shift does not matter.
3649 return fUnion.fFields.fLengthAndFlags>>kLengthShift;
3650 }
3651
3652 inline int32_t
3653 UnicodeString::length() const {
3654 return hasShortLength() ? getShortLength() : fUnion.fFields.fLength;
3655 }
3656
3657 inline int32_t
3658 UnicodeString::getCapacity() const {
3659 return (fUnion.fFields.fLengthAndFlags&kUsingStackBuffer) ?
3660 US_STACKBUF_SIZE : fUnion.fFields.fCapacity;
3661 }
3662
3663 inline int32_t
3664 UnicodeString::hashCode() const
3665 { return doHashCode(); }
3666
3667 inline UBool
3668 UnicodeString::isBogus() const
3669 { return (UBool)(fUnion.fFields.fLengthAndFlags & kIsBogus); }
3670
3671 inline UBool
3672 UnicodeString::isWritable() const
3673 { return (UBool)!(fUnion.fFields.fLengthAndFlags&(kOpenGetBuffer|kIsBogus)); }
3674
3675 inline UBool
3676 UnicodeString::isBufferWritable() const
3677 {
3678 return (UBool)(
3679 !(fUnion.fFields.fLengthAndFlags&(kOpenGetBuffer|kIsBogus|kBufferIsReadonly)) &&
3680 (!(fUnion.fFields.fLengthAndFlags&kRefCounted) || refCount()==1));
3681 }
3682
3683 inline const UChar *
3684 UnicodeString::getBuffer() const {
3685 if(fUnion.fFields.fLengthAndFlags&(kIsBogus|kOpenGetBuffer)) {
3686 return 0;
3687 } else if(fUnion.fFields.fLengthAndFlags&kUsingStackBuffer) {
3688 return fUnion.fStackFields.fBuffer;
3689 } else {
3690 return fUnion.fFields.fArray;
3691 }
3692 }
3693
3694 //========================================
3695 // Read-only alias methods
3696 //========================================
3697 inline int8_t
3698 UnicodeString::doCompare(int32_t start,
3699 int32_t thisLength,
3700 const UnicodeString& srcText,
3701 int32_t srcStart,
3702 int32_t srcLength) const
3703 {
3704 if(srcText.isBogus()) {
3705 return (int8_t)!isBogus(); // 0 if both are bogus, 1 otherwise
3706 } else {
3707 srcText.pinIndices(srcStart, srcLength);
3708 return doCompare(start, thisLength, srcText.getArrayStart(), srcStart, srcLength);
3709 }
3710 }
3711
3712 inline UBool
3713 UnicodeString::operator== (const UnicodeString& text) const
3714 {
3715 if(isBogus()) {
3716 return text.isBogus();
3717 } else {
3718 int32_t len = length(), textLength = text.length();
3719 return !text.isBogus() && len == textLength && doEquals(text, len);
3720 }
3721 }
3722
3723 inline UBool
3724 UnicodeString::operator!= (const UnicodeString& text) const
3725 { return (! operator==(text)); }
3726
3727 inline UBool
3728 UnicodeString::operator> (const UnicodeString& text) const
3729 { return doCompare(0, length(), text, 0, text.length()) == 1; }
3730
3731 inline UBool
3732 UnicodeString::operator< (const UnicodeString& text) const
3733 { return doCompare(0, length(), text, 0, text.length()) == -1; }
3734
3735 inline UBool
3736 UnicodeString::operator>= (const UnicodeString& text) const
3737 { return doCompare(0, length(), text, 0, text.length()) != -1; }
3738
3739 inline UBool
3740 UnicodeString::operator<= (const UnicodeString& text) const
3741 { return doCompare(0, length(), text, 0, text.length()) != 1; }
3742
3743 inline int8_t
3744 UnicodeString::compare(const UnicodeString& text) const
3745 { return doCompare(0, length(), text, 0, text.length()); }
3746
3747 inline int8_t
3748 UnicodeString::compare(int32_t start,
3749 int32_t _length,
3750 const UnicodeString& srcText) const
3751 { return doCompare(start, _length, srcText, 0, srcText.length()); }
3752
3753 inline int8_t
3754 UnicodeString::compare(const UChar *srcChars,
3755 int32_t srcLength) const
3756 { return doCompare(0, length(), srcChars, 0, srcLength); }
3757
3758 inline int8_t
3759 UnicodeString::compare(int32_t start,
3760 int32_t _length,
3761 const UnicodeString& srcText,
3762 int32_t srcStart,
3763 int32_t srcLength) const
3764 { return doCompare(start, _length, srcText, srcStart, srcLength); }
3765
3766 inline int8_t
3767 UnicodeString::compare(int32_t start,
3768 int32_t _length,
3769 const UChar *srcChars) const
3770 { return doCompare(start, _length, srcChars, 0, _length); }
3771
3772 inline int8_t
3773 UnicodeString::compare(int32_t start,
3774 int32_t _length,
3775 const UChar *srcChars,
3776 int32_t srcStart,
3777 int32_t srcLength) const
3778 { return doCompare(start, _length, srcChars, srcStart, srcLength); }
3779
3780 inline int8_t
3781 UnicodeString::compareBetween(int32_t start,
3782 int32_t limit,
3783 const UnicodeString& srcText,
3784 int32_t srcStart,
3785 int32_t srcLimit) const
3786 { return doCompare(start, limit - start,
3787 srcText, srcStart, srcLimit - srcStart); }
3788
3789 inline int8_t
3790 UnicodeString::doCompareCodePointOrder(int32_t start,
3791 int32_t thisLength,
3792 const UnicodeString& srcText,
3793 int32_t srcStart,
3794 int32_t srcLength) const
3795 {
3796 if(srcText.isBogus()) {
3797 return (int8_t)!isBogus(); // 0 if both are bogus, 1 otherwise
3798 } else {
3799 srcText.pinIndices(srcStart, srcLength);
3800 return doCompareCodePointOrder(start, thisLength, srcText.getArrayStart(), srcStart, srcLength);
3801 }
3802 }
3803
3804 inline int8_t
3805 UnicodeString::compareCodePointOrder(const UnicodeString& text) const
3806 { return doCompareCodePointOrder(0, length(), text, 0, text.length()); }
3807
3808 inline int8_t
3809 UnicodeString::compareCodePointOrder(int32_t start,
3810 int32_t _length,
3811 const UnicodeString& srcText) const
3812 { return doCompareCodePointOrder(start, _length, srcText, 0, srcText.length()); }
3813
3814 inline int8_t
3815 UnicodeString::compareCodePointOrder(const UChar *srcChars,
3816 int32_t srcLength) const
3817 { return doCompareCodePointOrder(0, length(), srcChars, 0, srcLength); }
3818
3819 inline int8_t
3820 UnicodeString::compareCodePointOrder(int32_t start,
3821 int32_t _length,
3822 const UnicodeString& srcText,
3823 int32_t srcStart,
3824 int32_t srcLength) const
3825 { return doCompareCodePointOrder(start, _length, srcText, srcStart, srcLength); }
3826
3827 inline int8_t
3828 UnicodeString::compareCodePointOrder(int32_t start,
3829 int32_t _length,
3830 const UChar *srcChars) const
3831 { return doCompareCodePointOrder(start, _length, srcChars, 0, _length); }
3832
3833 inline int8_t
3834 UnicodeString::compareCodePointOrder(int32_t start,
3835 int32_t _length,
3836 const UChar *srcChars,
3837 int32_t srcStart,
3838 int32_t srcLength) const
3839 { return doCompareCodePointOrder(start, _length, srcChars, srcStart, srcLength); }
3840
3841 inline int8_t
3842 UnicodeString::compareCodePointOrderBetween(int32_t start,
3843 int32_t limit,
3844 const UnicodeString& srcText,
3845 int32_t srcStart,
3846 int32_t srcLimit) const
3847 { return doCompareCodePointOrder(start, limit - start,
3848 srcText, srcStart, srcLimit - srcStart); }
3849
3850 inline int8_t
3851 UnicodeString::doCaseCompare(int32_t start,
3852 int32_t thisLength,
3853 const UnicodeString &srcText,
3854 int32_t srcStart,
3855 int32_t srcLength,
3856 uint32_t options) const
3857 {
3858 if(srcText.isBogus()) {
3859 return (int8_t)!isBogus(); // 0 if both are bogus, 1 otherwise
3860 } else {
3861 srcText.pinIndices(srcStart, srcLength);
3862 return doCaseCompare(start, thisLength, srcText.getArrayStart(), srcStart, srcLength, options);
3863 }
3864 }
3865
3866 inline int8_t
3867 UnicodeString::caseCompare(const UnicodeString &text, uint32_t options) const {
3868 return doCaseCompare(0, length(), text, 0, text.length(), options);
3869 }
3870
3871 inline int8_t
3872 UnicodeString::caseCompare(int32_t start,
3873 int32_t _length,
3874 const UnicodeString &srcText,
3875 uint32_t options) const {
3876 return doCaseCompare(start, _length, srcText, 0, srcText.length(), options);
3877 }
3878
3879 inline int8_t
3880 UnicodeString::caseCompare(const UChar *srcChars,
3881 int32_t srcLength,
3882 uint32_t options) const {
3883 return doCaseCompare(0, length(), srcChars, 0, srcLength, options);
3884 }
3885
3886 inline int8_t
3887 UnicodeString::caseCompare(int32_t start,
3888 int32_t _length,
3889 const UnicodeString &srcText,
3890 int32_t srcStart,
3891 int32_t srcLength,
3892 uint32_t options) const {
3893 return doCaseCompare(start, _length, srcText, srcStart, srcLength, options);
3894 }
3895
3896 inline int8_t
3897 UnicodeString::caseCompare(int32_t start,
3898 int32_t _length,
3899 const UChar *srcChars,
3900 uint32_t options) const {
3901 return doCaseCompare(start, _length, srcChars, 0, _length, options);
3902 }
3903
3904 inline int8_t
3905 UnicodeString::caseCompare(int32_t start,
3906 int32_t _length,
3907 const UChar *srcChars,
3908 int32_t srcStart,
3909 int32_t srcLength,
3910 uint32_t options) const {
3911 return doCaseCompare(start, _length, srcChars, srcStart, srcLength, options);
3912 }
3913
3914 inline int8_t
3915 UnicodeString::caseCompareBetween(int32_t start,
3916 int32_t limit,
3917 const UnicodeString &srcText,
3918 int32_t srcStart,
3919 int32_t srcLimit,
3920 uint32_t options) const {
3921 return doCaseCompare(start, limit - start, srcText, srcStart, srcLimit - srcStart, options);
3922 }
3923
3924 inline int32_t
3925 UnicodeString::indexOf(const UnicodeString& srcText,
3926 int32_t srcStart,
3927 int32_t srcLength,
3928 int32_t start,
3929 int32_t _length) const
3930 {
3931 if(!srcText.isBogus()) {
3932 srcText.pinIndices(srcStart, srcLength);
3933 if(srcLength > 0) {
3934 return indexOf(srcText.getArrayStart(), srcStart, srcLength, start, _length);
3935 }
3936 }
3937 return -1;
3938 }
3939
3940 inline int32_t
3941 UnicodeString::indexOf(const UnicodeString& text) const
3942 { return indexOf(text, 0, text.length(), 0, length()); }
3943
3944 inline int32_t
3945 UnicodeString::indexOf(const UnicodeString& text,
3946 int32_t start) const {
3947 pinIndex(start);
3948 return indexOf(text, 0, text.length(), start, length() - start);
3949 }
3950
3951 inline int32_t
3952 UnicodeString::indexOf(const UnicodeString& text,
3953 int32_t start,
3954 int32_t _length) const
3955 { return indexOf(text, 0, text.length(), start, _length); }
3956
3957 inline int32_t
3958 UnicodeString::indexOf(const UChar *srcChars,
3959 int32_t srcLength,
3960 int32_t start) const {
3961 pinIndex(start);
3962 return indexOf(srcChars, 0, srcLength, start, length() - start);
3963 }
3964
3965 inline int32_t
3966 UnicodeString::indexOf(const UChar *srcChars,
3967 int32_t srcLength,
3968 int32_t start,
3969 int32_t _length) const
3970 { return indexOf(srcChars, 0, srcLength, start, _length); }
3971
3972 inline int32_t
3973 UnicodeString::indexOf(UChar c,
3974 int32_t start,
3975 int32_t _length) const
3976 { return doIndexOf(c, start, _length); }
3977
3978 inline int32_t
3979 UnicodeString::indexOf(UChar32 c,
3980 int32_t start,
3981 int32_t _length) const
3982 { return doIndexOf(c, start, _length); }
3983
3984 inline int32_t
3985 UnicodeString::indexOf(UChar c) const
3986 { return doIndexOf(c, 0, length()); }
3987
3988 inline int32_t
3989 UnicodeString::indexOf(UChar32 c) const
3990 { return indexOf(c, 0, length()); }
3991
3992 inline int32_t
3993 UnicodeString::indexOf(UChar c,
3994 int32_t start) const {
3995 pinIndex(start);
3996 return doIndexOf(c, start, length() - start);
3997 }
3998
3999 inline int32_t
4000 UnicodeString::indexOf(UChar32 c,
4001 int32_t start) const {
4002 pinIndex(start);
4003 return indexOf(c, start, length() - start);
4004 }
4005
4006 inline int32_t
4007 UnicodeString::lastIndexOf(const UChar *srcChars,
4008 int32_t srcLength,
4009 int32_t start,
4010 int32_t _length) const
4011 { return lastIndexOf(srcChars, 0, srcLength, start, _length); }
4012
4013 inline int32_t
4014 UnicodeString::lastIndexOf(const UChar *srcChars,
4015 int32_t srcLength,
4016 int32_t start) const {
4017 pinIndex(start);
4018 return lastIndexOf(srcChars, 0, srcLength, start, length() - start);
4019 }
4020
4021 inline int32_t
4022 UnicodeString::lastIndexOf(const UnicodeString& srcText,
4023 int32_t srcStart,
4024 int32_t srcLength,
4025 int32_t start,
4026 int32_t _length) const
4027 {
4028 if(!srcText.isBogus()) {
4029 srcText.pinIndices(srcStart, srcLength);
4030 if(srcLength > 0) {
4031 return lastIndexOf(srcText.getArrayStart(), srcStart, srcLength, start, _length);
4032 }
4033 }
4034 return -1;
4035 }
4036
4037 inline int32_t
4038 UnicodeString::lastIndexOf(const UnicodeString& text,
4039 int32_t start,
4040 int32_t _length) const
4041 { return lastIndexOf(text, 0, text.length(), start, _length); }
4042
4043 inline int32_t
4044 UnicodeString::lastIndexOf(const UnicodeString& text,
4045 int32_t start) const {
4046 pinIndex(start);
4047 return lastIndexOf(text, 0, text.length(), start, length() - start);
4048 }
4049
4050 inline int32_t
4051 UnicodeString::lastIndexOf(const UnicodeString& text) const
4052 { return lastIndexOf(text, 0, text.length(), 0, length()); }
4053
4054 inline int32_t
4055 UnicodeString::lastIndexOf(UChar c,
4056 int32_t start,
4057 int32_t _length) const
4058 { return doLastIndexOf(c, start, _length); }
4059
4060 inline int32_t
4061 UnicodeString::lastIndexOf(UChar32 c,
4062 int32_t start,
4063 int32_t _length) const {
4064 return doLastIndexOf(c, start, _length);
4065 }
4066
4067 inline int32_t
4068 UnicodeString::lastIndexOf(UChar c) const
4069 { return doLastIndexOf(c, 0, length()); }
4070
4071 inline int32_t
4072 UnicodeString::lastIndexOf(UChar32 c) const {
4073 return lastIndexOf(c, 0, length());
4074 }
4075
4076 inline int32_t
4077 UnicodeString::lastIndexOf(UChar c,
4078 int32_t start) const {
4079 pinIndex(start);
4080 return doLastIndexOf(c, start, length() - start);
4081 }
4082
4083 inline int32_t
4084 UnicodeString::lastIndexOf(UChar32 c,
4085 int32_t start) const {
4086 pinIndex(start);
4087 return lastIndexOf(c, start, length() - start);
4088 }
4089
4090 inline UBool
4091 UnicodeString::startsWith(const UnicodeString& text) const
4092 { return compare(0, text.length(), text, 0, text.length()) == 0; }
4093
4094 inline UBool
4095 UnicodeString::startsWith(const UnicodeString& srcText,
4096 int32_t srcStart,
4097 int32_t srcLength) const
4098 { return doCompare(0, srcLength, srcText, srcStart, srcLength) == 0; }
4099
4100 inline UBool
4101 UnicodeString::startsWith(const UChar *srcChars, int32_t srcLength) const {
4102 if(srcLength < 0) {
4103 srcLength = u_strlen(srcChars);
4104 }
4105 return doCompare(0, srcLength, srcChars, 0, srcLength) == 0;
4106 }
4107
4108 inline UBool
4109 UnicodeString::startsWith(const UChar *srcChars, int32_t srcStart, int32_t srcLength) const {
4110 if(srcLength < 0) {
4111 srcLength = u_strlen(srcChars);
4112 }
4113 return doCompare(0, srcLength, srcChars, srcStart, srcLength) == 0;
4114 }
4115
4116 inline UBool
4117 UnicodeString::endsWith(const UnicodeString& text) const
4118 { return doCompare(length() - text.length(), text.length(),
4119 text, 0, text.length()) == 0; }
4120
4121 inline UBool
4122 UnicodeString::endsWith(const UnicodeString& srcText,
4123 int32_t srcStart,
4124 int32_t srcLength) const {
4125 srcText.pinIndices(srcStart, srcLength);
4126 return doCompare(length() - srcLength, srcLength,
4127 srcText, srcStart, srcLength) == 0;
4128 }
4129
4130 inline UBool
4131 UnicodeString::endsWith(const UChar *srcChars,
4132 int32_t srcLength) const {
4133 if(srcLength < 0) {
4134 srcLength = u_strlen(srcChars);
4135 }
4136 return doCompare(length() - srcLength, srcLength,
4137 srcChars, 0, srcLength) == 0;
4138 }
4139
4140 inline UBool
4141 UnicodeString::endsWith(const UChar *srcChars,
4142 int32_t srcStart,
4143 int32_t srcLength) const {
4144 if(srcLength < 0) {
4145 srcLength = u_strlen(srcChars + srcStart);
4146 }
4147 return doCompare(length() - srcLength, srcLength,
4148 srcChars, srcStart, srcLength) == 0;
4149 }
4150
4151 //========================================
4152 // replace
4153 //========================================
4154 inline UnicodeString&
4155 UnicodeString::replace(int32_t start,
4156 int32_t _length,
4157 const UnicodeString& srcText)
4158 { return doReplace(start, _length, srcText, 0, srcText.length()); }
4159
4160 inline UnicodeString&
4161 UnicodeString::replace(int32_t start,
4162 int32_t _length,
4163 const UnicodeString& srcText,
4164 int32_t srcStart,
4165 int32_t srcLength)
4166 { return doReplace(start, _length, srcText, srcStart, srcLength); }
4167
4168 inline UnicodeString&
4169 UnicodeString::replace(int32_t start,
4170 int32_t _length,
4171 const UChar *srcChars,
4172 int32_t srcLength)
4173 { return doReplace(start, _length, srcChars, 0, srcLength); }
4174
4175 inline UnicodeString&
4176 UnicodeString::replace(int32_t start,
4177 int32_t _length,
4178 const UChar *srcChars,
4179 int32_t srcStart,
4180 int32_t srcLength)
4181 { return doReplace(start, _length, srcChars, srcStart, srcLength); }
4182
4183 inline UnicodeString&
4184 UnicodeString::replace(int32_t start,
4185 int32_t _length,
4186 UChar srcChar)
4187 { return doReplace(start, _length, &srcChar, 0, 1); }
4188
4189 inline UnicodeString&
4190 UnicodeString::replaceBetween(int32_t start,
4191 int32_t limit,
4192 const UnicodeString& srcText)
4193 { return doReplace(start, limit - start, srcText, 0, srcText.length()); }
4194
4195 inline UnicodeString&
4196 UnicodeString::replaceBetween(int32_t start,
4197 int32_t limit,
4198 const UnicodeString& srcText,
4199 int32_t srcStart,
4200 int32_t srcLimit)
4201 { return doReplace(start, limit - start, srcText, srcStart, srcLimit - srcStart); }
4202
4203 inline UnicodeString&
4204 UnicodeString::findAndReplace(const UnicodeString& oldText,
4205 const UnicodeString& newText)
4206 { return findAndReplace(0, length(), oldText, 0, oldText.length(),
4207 newText, 0, newText.length()); }
4208
4209 inline UnicodeString&
4210 UnicodeString::findAndReplace(int32_t start,
4211 int32_t _length,
4212 const UnicodeString& oldText,
4213 const UnicodeString& newText)
4214 { return findAndReplace(start, _length, oldText, 0, oldText.length(),
4215 newText, 0, newText.length()); }
4216
4217 // ============================
4218 // extract
4219 // ============================
4220 inline void
4221 UnicodeString::doExtract(int32_t start,
4222 int32_t _length,
4223 UnicodeString& target) const
4224 { target.replace(0, target.length(), *this, start, _length); }
4225
4226 inline void
4227 UnicodeString::extract(int32_t start,
4228 int32_t _length,
4229 UChar *target,
4230 int32_t targetStart) const
4231 { doExtract(start, _length, target, targetStart); }
4232
4233 inline void
4234 UnicodeString::extract(int32_t start,
4235 int32_t _length,
4236 UnicodeString& target) const
4237 { doExtract(start, _length, target); }
4238
4239 #if !UCONFIG_NO_CONVERSION
4240
4241 inline int32_t
4242 UnicodeString::extract(int32_t start,
4243 int32_t _length,
4244 char *dst,
4245 const char *codepage) const
4246
4247 {
4248 // This dstSize value will be checked explicitly
4249 return extract(start, _length, dst, dst!=0 ? 0xffffffff : 0, codepage);
4250 }
4251
4252 #endif
4253
4254 inline void
4255 UnicodeString::extractBetween(int32_t start,
4256 int32_t limit,
4257 UChar *dst,
4258 int32_t dstStart) const {
4259 pinIndex(start);
4260 pinIndex(limit);
4261 doExtract(start, limit - start, dst, dstStart);
4262 }
4263
4264 inline UnicodeString
4265 UnicodeString::tempSubStringBetween(int32_t start, int32_t limit) const {
4266 return tempSubString(start, limit - start);
4267 }
4268
4269 inline UChar
4270 UnicodeString::doCharAt(int32_t offset) const
4271 {
4272 if((uint32_t)offset < (uint32_t)length()) {
4273 return getArrayStart()[offset];
4274 } else {
4275 return kInvalidUChar;
4276 }
4277 }
4278
4279 inline UChar
4280 UnicodeString::charAt(int32_t offset) const
4281 { return doCharAt(offset); }
4282
4283 inline UChar
4284 UnicodeString::operator[] (int32_t offset) const
4285 { return doCharAt(offset); }
4286
4287 inline UBool
4288 UnicodeString::isEmpty() const {
4289 // Arithmetic or logical right shift does not matter: only testing for 0.
4290 return (fUnion.fFields.fLengthAndFlags>>kLengthShift) == 0;
4291 }
4292
4293 //========================================
4294 // Write implementation methods
4295 //========================================
4296 inline void
4297 UnicodeString::setZeroLength() {
4298 fUnion.fFields.fLengthAndFlags &= kAllStorageFlags;
4299 }
4300
4301 inline void
4302 UnicodeString::setShortLength(int32_t len) {
4303 // requires 0 <= len <= kMaxShortLength
4304 fUnion.fFields.fLengthAndFlags =
4305 (int16_t)((fUnion.fFields.fLengthAndFlags & kAllStorageFlags) | (len << kLengthShift));
4306 }
4307
4308 inline void
4309 UnicodeString::setLength(int32_t len) {
4310 if(len <= kMaxShortLength) {
4311 setShortLength(len);
4312 } else {
4313 fUnion.fFields.fLengthAndFlags |= kLengthIsLarge;
4314 fUnion.fFields.fLength = len;
4315 }
4316 }
4317
4318 inline void
4319 UnicodeString::setToEmpty() {
4320 fUnion.fFields.fLengthAndFlags = kShortString;
4321 }
4322
4323 inline void
4324 UnicodeString::setArray(UChar *array, int32_t len, int32_t capacity) {
4325 setLength(len);
4326 fUnion.fFields.fArray = array;
4327 fUnion.fFields.fCapacity = capacity;
4328 }
4329
4330 inline UnicodeString&
4331 UnicodeString::operator= (UChar ch)
4332 { return doReplace(0, length(), &ch, 0, 1); }
4333
4334 inline UnicodeString&
4335 UnicodeString::operator= (UChar32 ch)
4336 { return replace(0, length(), ch); }
4337
4338 inline UnicodeString&
4339 UnicodeString::setTo(const UnicodeString& srcText,
4340 int32_t srcStart,
4341 int32_t srcLength)
4342 {
4343 unBogus();
4344 return doReplace(0, length(), srcText, srcStart, srcLength);
4345 }
4346
4347 inline UnicodeString&
4348 UnicodeString::setTo(const UnicodeString& srcText,
4349 int32_t srcStart)
4350 {
4351 unBogus();
4352 srcText.pinIndex(srcStart);
4353 return doReplace(0, length(), srcText, srcStart, srcText.length() - srcStart);
4354 }
4355
4356 inline UnicodeString&
4357 UnicodeString::setTo(const UnicodeString& srcText)
4358 {
4359 return copyFrom(srcText);
4360 }
4361
4362 inline UnicodeString&
4363 UnicodeString::setTo(const UChar *srcChars,
4364 int32_t srcLength)
4365 {
4366 unBogus();
4367 return doReplace(0, length(), srcChars, 0, srcLength);
4368 }
4369
4370 inline UnicodeString&
4371 UnicodeString::setTo(UChar srcChar)
4372 {
4373 unBogus();
4374 return doReplace(0, length(), &srcChar, 0, 1);
4375 }
4376
4377 inline UnicodeString&
4378 UnicodeString::setTo(UChar32 srcChar)
4379 {
4380 unBogus();
4381 return replace(0, length(), srcChar);
4382 }
4383
4384 inline UnicodeString&
4385 UnicodeString::append(const UnicodeString& srcText,
4386 int32_t srcStart,
4387 int32_t srcLength)
4388 { return doReplace(length(), 0, srcText, srcStart, srcLength); }
4389
4390 inline UnicodeString&
4391 UnicodeString::append(const UnicodeString& srcText)
4392 { return doReplace(length(), 0, srcText, 0, srcText.length()); }
4393
4394 inline UnicodeString&
4395 UnicodeString::append(const UChar *srcChars,
4396 int32_t srcStart,
4397 int32_t srcLength)
4398 { return doReplace(length(), 0, srcChars, srcStart, srcLength); }
4399
4400 inline UnicodeString&
4401 UnicodeString::append(const UChar *srcChars,
4402 int32_t srcLength)
4403 { return doReplace(length(), 0, srcChars, 0, srcLength); }
4404
4405 inline UnicodeString&
4406 UnicodeString::append(UChar srcChar)
4407 { return doReplace(length(), 0, &srcChar, 0, 1); }
4408
4409 inline UnicodeString&
4410 UnicodeString::operator+= (UChar ch)
4411 { return doReplace(length(), 0, &ch, 0, 1); }
4412
4413 inline UnicodeString&
4414 UnicodeString::operator+= (UChar32 ch) {
4415 return append(ch);
4416 }
4417
4418 inline UnicodeString&
4419 UnicodeString::operator+= (const UnicodeString& srcText)
4420 { return doReplace(length(), 0, srcText, 0, srcText.length()); }
4421
4422 inline UnicodeString&
4423 UnicodeString::insert(int32_t start,
4424 const UnicodeString& srcText,
4425 int32_t srcStart,
4426 int32_t srcLength)
4427 { return doReplace(start, 0, srcText, srcStart, srcLength); }
4428
4429 inline UnicodeString&
4430 UnicodeString::insert(int32_t start,
4431 const UnicodeString& srcText)
4432 { return doReplace(start, 0, srcText, 0, srcText.length()); }
4433
4434 inline UnicodeString&
4435 UnicodeString::insert(int32_t start,
4436 const UChar *srcChars,
4437 int32_t srcStart,
4438 int32_t srcLength)
4439 { return doReplace(start, 0, srcChars, srcStart, srcLength); }
4440
4441 inline UnicodeString&
4442 UnicodeString::insert(int32_t start,
4443 const UChar *srcChars,
4444 int32_t srcLength)
4445 { return doReplace(start, 0, srcChars, 0, srcLength); }
4446
4447 inline UnicodeString&
4448 UnicodeString::insert(int32_t start,
4449 UChar srcChar)
4450 { return doReplace(start, 0, &srcChar, 0, 1); }
4451
4452 inline UnicodeString&
4453 UnicodeString::insert(int32_t start,
4454 UChar32 srcChar)
4455 { return replace(start, 0, srcChar); }
4456
4457
4458 inline UnicodeString&
4459 UnicodeString::remove()
4460 {
4461 // remove() of a bogus string makes the string empty and non-bogus
4462 if(isBogus()) {
4463 setToEmpty();
4464 } else {
4465 setZeroLength();
4466 }
4467 return *this;
4468 }
4469
4470 inline UnicodeString&
4471 UnicodeString::remove(int32_t start,
4472 int32_t _length)
4473 {
4474 if(start <= 0 && _length == INT32_MAX) {
4475 // remove(guaranteed everything) of a bogus string makes the string empty and non-bogus
4476 return remove();
4477 }
4478 return doReplace(start, _length, NULL, 0, 0);
4479 }
4480
4481 inline UnicodeString&
4482 UnicodeString::removeBetween(int32_t start,
4483 int32_t limit)
4484 { return doReplace(start, limit - start, NULL, 0, 0); }
4485
4486 inline UnicodeString &
4487 UnicodeString::retainBetween(int32_t start, int32_t limit) {
4488 truncate(limit);
4489 return doReplace(0, start, NULL, 0, 0);
4490 }
4491
4492 inline UBool
4493 UnicodeString::truncate(int32_t targetLength)
4494 {
4495 if(isBogus() && targetLength == 0) {
4496 // truncate(0) of a bogus string makes the string empty and non-bogus
4497 unBogus();
4498 return FALSE;
4499 } else if((uint32_t)targetLength < (uint32_t)length()) {
4500 setLength(targetLength);
4501 return TRUE;
4502 } else {
4503 return FALSE;
4504 }
4505 }
4506
4507 inline UnicodeString&
4508 UnicodeString::reverse()
4509 { return doReverse(0, length()); }
4510
4511 inline UnicodeString&
4512 UnicodeString::reverse(int32_t start,
4513 int32_t _length)
4514 { return doReverse(start, _length); }
4515
4516 U_NAMESPACE_END
4517
4518 #endif