unistr.h

Go to the documentation of this file.
00001 /*
00002 **********************************************************************
00003 *   Copyright (C) 1998-2008, International Business Machines
00004 *   Corporation and others.  All Rights Reserved.
00005 **********************************************************************
00006 *
00007 * File unistr.h
00008 *
00009 * Modification History:
00010 *
00011 *   Date        Name        Description
00012 *   09/25/98    stephen     Creation.
00013 *   11/11/98    stephen     Changed per 11/9 code review.
00014 *   04/20/99    stephen     Overhauled per 4/16 code review.
00015 *   11/18/99    aliu        Made to inherit from Replaceable.  Added method
00016 *                           handleReplaceBetween(); other methods unchanged.
00017 *   06/25/01    grhoten     Remove dependency on iostream.
00018 ******************************************************************************
00019 */
00020 
00021 #ifndef UNISTR_H
00022 #define UNISTR_H
00023 
00029 #include "unicode/rep.h"
00030 
00031 struct UConverter;          // unicode/ucnv.h
00032 class  StringThreadTest;
00033 
00034 #ifndef U_COMPARE_CODE_POINT_ORDER
00035 /* see also ustring.h and unorm.h */
00041 #define U_COMPARE_CODE_POINT_ORDER  0x8000
00042 #endif
00043 
00044 #ifndef USTRING_H
00045 
00048 U_STABLE int32_t U_EXPORT2
00049 u_strlen(const UChar *s);
00050 #endif
00051 
00052 U_NAMESPACE_BEGIN
00053 
00054 class Locale;               // unicode/locid.h
00055 class StringCharacterIterator;
00056 class BreakIterator;        // unicode/brkiter.h
00057 
00058 /* The <iostream> include has been moved to unicode/ustream.h */
00059 
00070 #define US_INV U_NAMESPACE_QUALIFIER UnicodeString::kInvariant
00071 
00089 #if defined(U_DECLARE_UTF16)
00090 #   define UNICODE_STRING(cs, _length) U_NAMESPACE_QUALIFIER UnicodeString(TRUE, (const UChar *)U_DECLARE_UTF16(cs), _length)
00091 #elif U_SIZEOF_WCHAR_T==U_SIZEOF_UCHAR && (U_CHARSET_FAMILY==U_ASCII_FAMILY || (U_SIZEOF_UCHAR == 2 && defined(U_WCHAR_IS_UTF16)))
00092 #   define UNICODE_STRING(cs, _length) U_NAMESPACE_QUALIFIER UnicodeString(TRUE, (const UChar *)L ## cs, _length)
00093 #elif U_SIZEOF_UCHAR==1 && U_CHARSET_FAMILY==U_ASCII_FAMILY
00094 #   define UNICODE_STRING(cs, _length) U_NAMESPACE_QUALIFIER UnicodeString(TRUE, (const UChar *)cs, _length)
00095 #else
00096 #   define UNICODE_STRING(cs, _length) U_NAMESPACE_QUALIFIER UnicodeString(cs, _length, US_INV)
00097 #endif
00098 
00112 #define UNICODE_STRING_SIMPLE(cs) UNICODE_STRING(cs, -1)
00113 
00183 class U_COMMON_API UnicodeString : public Replaceable
00184 {
00185 public:
00186 
00195   enum EInvariant {
00200     kInvariant
00201   };
00202 
00203   //========================================
00204   // Read-only operations
00205   //========================================
00206 
00207   /* Comparison - bitwise only - for international comparison use collation */
00208 
00216   inline UBool operator== (const UnicodeString& text) const;
00217 
00225   inline UBool operator!= (const UnicodeString& text) const;
00226 
00234   inline UBool operator> (const UnicodeString& text) const;
00235 
00243   inline UBool operator< (const UnicodeString& text) const;
00244 
00252   inline UBool operator>= (const UnicodeString& text) const;
00253 
00261   inline UBool operator<= (const UnicodeString& text) const;
00262 
00274   inline int8_t compare(const UnicodeString& text) const;
00275 
00290   inline int8_t compare(int32_t start,
00291          int32_t length,
00292          const UnicodeString& text) const;
00293 
00311    inline int8_t compare(int32_t start,
00312          int32_t length,
00313          const UnicodeString& srcText,
00314          int32_t srcStart,
00315          int32_t srcLength) const;
00316 
00329   inline int8_t compare(const UChar *srcChars,
00330          int32_t srcLength) const;
00331 
00346   inline int8_t compare(int32_t start,
00347          int32_t length,
00348          const UChar *srcChars) const;
00349 
00367   inline int8_t compare(int32_t start,
00368          int32_t length,
00369          const UChar *srcChars,
00370          int32_t srcStart,
00371          int32_t srcLength) const;
00372 
00390   inline int8_t compareBetween(int32_t start,
00391             int32_t limit,
00392             const UnicodeString& srcText,
00393             int32_t srcStart,
00394             int32_t srcLimit) const;
00395 
00413   inline int8_t compareCodePointOrder(const UnicodeString& text) const;
00414 
00434   inline int8_t compareCodePointOrder(int32_t start,
00435                                       int32_t length,
00436                                       const UnicodeString& srcText) const;
00437 
00459    inline int8_t compareCodePointOrder(int32_t start,
00460                                        int32_t length,
00461                                        const UnicodeString& srcText,
00462                                        int32_t srcStart,
00463                                        int32_t srcLength) const;
00464 
00483   inline int8_t compareCodePointOrder(const UChar *srcChars,
00484                                       int32_t srcLength) const;
00485 
00505   inline int8_t compareCodePointOrder(int32_t start,
00506                                       int32_t length,
00507                                       const UChar *srcChars) const;
00508 
00530   inline int8_t compareCodePointOrder(int32_t start,
00531                                       int32_t length,
00532                                       const UChar *srcChars,
00533                                       int32_t srcStart,
00534                                       int32_t srcLength) const;
00535 
00557   inline int8_t compareCodePointOrderBetween(int32_t start,
00558                                              int32_t limit,
00559                                              const UnicodeString& srcText,
00560                                              int32_t srcStart,
00561                                              int32_t srcLimit) const;
00562 
00581   inline int8_t caseCompare(const UnicodeString& text, uint32_t options) const;
00582 
00603   inline int8_t caseCompare(int32_t start,
00604          int32_t length,
00605          const UnicodeString& srcText,
00606          uint32_t options) const;
00607 
00630   inline int8_t caseCompare(int32_t start,
00631          int32_t length,
00632          const UnicodeString& srcText,
00633          int32_t srcStart,
00634          int32_t srcLength,
00635          uint32_t options) const;
00636 
00656   inline int8_t caseCompare(const UChar *srcChars,
00657          int32_t srcLength,
00658          uint32_t options) const;
00659 
00680   inline int8_t caseCompare(int32_t start,
00681          int32_t length,
00682          const UChar *srcChars,
00683          uint32_t options) const;
00684 
00707   inline int8_t caseCompare(int32_t start,
00708          int32_t length,
00709          const UChar *srcChars,
00710          int32_t srcStart,
00711          int32_t srcLength,
00712          uint32_t options) const;
00713 
00736   inline int8_t caseCompareBetween(int32_t start,
00737             int32_t limit,
00738             const UnicodeString& srcText,
00739             int32_t srcStart,
00740             int32_t srcLimit,
00741             uint32_t options) const;
00742 
00750   inline UBool startsWith(const UnicodeString& text) const;
00751 
00762   inline UBool startsWith(const UnicodeString& srcText,
00763             int32_t srcStart,
00764             int32_t srcLength) const;
00765 
00774   inline UBool startsWith(const UChar *srcChars,
00775             int32_t srcLength) const;
00776 
00786   inline UBool startsWith(const UChar *srcChars,
00787             int32_t srcStart,
00788             int32_t srcLength) const;
00789 
00797   inline UBool endsWith(const UnicodeString& text) const;
00798 
00809   inline UBool endsWith(const UnicodeString& srcText,
00810           int32_t srcStart,
00811           int32_t srcLength) const;
00812 
00821   inline UBool endsWith(const UChar *srcChars,
00822           int32_t srcLength) const;
00823 
00834   inline UBool endsWith(const UChar *srcChars,
00835           int32_t srcStart,
00836           int32_t srcLength) const;
00837 
00838 
00839   /* Searching - bitwise only */
00840 
00849   inline int32_t indexOf(const UnicodeString& text) const;
00850 
00860   inline int32_t indexOf(const UnicodeString& text,
00861               int32_t start) const;
00862 
00874   inline int32_t indexOf(const UnicodeString& text,
00875               int32_t start,
00876               int32_t length) const;
00877 
00894   inline int32_t indexOf(const UnicodeString& srcText,
00895               int32_t srcStart,
00896               int32_t srcLength,
00897               int32_t start,
00898               int32_t length) const;
00899 
00911   inline int32_t indexOf(const UChar *srcChars,
00912               int32_t srcLength,
00913               int32_t start) const;
00914 
00927   inline int32_t indexOf(const UChar *srcChars,
00928               int32_t srcLength,
00929               int32_t start,
00930               int32_t length) const;
00931 
00948   int32_t indexOf(const UChar *srcChars,
00949               int32_t srcStart,
00950               int32_t srcLength,
00951               int32_t start,
00952               int32_t length) const;
00953 
00961   inline int32_t indexOf(UChar c) const;
00962 
00971   inline int32_t indexOf(UChar32 c) const;
00972 
00981   inline int32_t indexOf(UChar c,
00982               int32_t start) const;
00983 
00993   inline int32_t indexOf(UChar32 c,
00994               int32_t start) const;
00995 
01006   inline int32_t indexOf(UChar c,
01007               int32_t start,
01008               int32_t length) const;
01009 
01021   inline int32_t indexOf(UChar32 c,
01022               int32_t start,
01023               int32_t length) const;
01024 
01033   inline int32_t lastIndexOf(const UnicodeString& text) const;
01034 
01044   inline int32_t lastIndexOf(const UnicodeString& text,
01045               int32_t start) const;
01046 
01058   inline int32_t lastIndexOf(const UnicodeString& text,
01059               int32_t start,
01060               int32_t length) const;
01061 
01078   inline int32_t lastIndexOf(const UnicodeString& srcText,
01079               int32_t srcStart,
01080               int32_t srcLength,
01081               int32_t start,
01082               int32_t length) const;
01083 
01094   inline int32_t lastIndexOf(const UChar *srcChars,
01095               int32_t srcLength,
01096               int32_t start) const;
01097 
01110   inline int32_t lastIndexOf(const UChar *srcChars,
01111               int32_t srcLength,
01112               int32_t start,
01113               int32_t length) const;
01114 
01131   int32_t lastIndexOf(const UChar *srcChars,
01132               int32_t srcStart,
01133               int32_t srcLength,
01134               int32_t start,
01135               int32_t length) const;
01136 
01144   inline int32_t lastIndexOf(UChar c) const;
01145 
01154   inline int32_t lastIndexOf(UChar32 c) const;
01155 
01164   inline int32_t lastIndexOf(UChar c,
01165               int32_t start) const;
01166 
01176   inline int32_t lastIndexOf(UChar32 c,
01177               int32_t start) const;
01178 
01189   inline int32_t lastIndexOf(UChar c,
01190               int32_t start,
01191               int32_t length) const;
01192 
01204   inline int32_t lastIndexOf(UChar32 c,
01205               int32_t start,
01206               int32_t length) const;
01207 
01208 
01209   /* Character access */
01210 
01219   inline UChar charAt(int32_t offset) const;
01220 
01228   inline UChar operator[] (int32_t offset) const;
01229 
01241   inline UChar32 char32At(int32_t offset) const;
01242 
01258   inline int32_t getChar32Start(int32_t offset) const;
01259 
01276   inline int32_t getChar32Limit(int32_t offset) const;
01277 
01328   int32_t moveIndex32(int32_t index, int32_t delta) const;
01329 
01330   /* Substring extraction */
01331 
01347   inline void extract(int32_t start,
01348            int32_t length,
01349            UChar *dst,
01350            int32_t dstStart = 0) const;
01351 
01373   int32_t
01374   extract(UChar *dest, int32_t destCapacity,
01375           UErrorCode &errorCode) const;
01376 
01387   inline void extract(int32_t start,
01388            int32_t length,
01389            UnicodeString& target) const;
01390 
01402   inline void extractBetween(int32_t start,
01403               int32_t limit,
01404               UChar *dst,
01405               int32_t dstStart = 0) const;
01406 
01416   virtual void extractBetween(int32_t start,
01417               int32_t limit,
01418               UnicodeString& target) const;
01419 
01441   int32_t extract(int32_t start,
01442            int32_t startLength,
01443            char *target,
01444            int32_t targetCapacity,
01445            enum EInvariant inv) const;
01446 
01447 #if !UCONFIG_NO_CONVERSION
01448 
01474   inline int32_t extract(int32_t start,
01475                  int32_t startLength,
01476                  char *target,
01477                  const char *codepage = 0) const;
01478 
01508   int32_t extract(int32_t start,
01509            int32_t startLength,
01510            char *target,
01511            uint32_t targetLength,
01512            const char *codepage = 0) const;
01513 
01531   int32_t extract(char *dest, int32_t destCapacity,
01532                   UConverter *cnv,
01533                   UErrorCode &errorCode) const;
01534 
01535 #endif
01536 
01537   /* Length operations */
01538 
01547   inline int32_t length(void) const;
01548 
01562   int32_t
01563   countChar32(int32_t start=0, int32_t length=INT32_MAX) const;
01564 
01588   UBool
01589   hasMoreChar32Than(int32_t start, int32_t length, int32_t number) const;
01590 
01596   inline UBool isEmpty(void) const;
01597 
01607   inline int32_t getCapacity(void) const;
01608 
01609   /* Other operations */
01610 
01616   inline int32_t hashCode(void) const;
01617 
01629   inline UBool isBogus(void) const;
01630 
01631 
01632   //========================================
01633   // Write operations
01634   //========================================
01635 
01636   /* Assignment operations */
01637 
01645   UnicodeString &operator=(const UnicodeString &srcText);
01646 
01667   UnicodeString &fastCopyFrom(const UnicodeString &src);
01668 
01676   inline UnicodeString& operator= (UChar ch);
01677 
01685   inline UnicodeString& operator= (UChar32 ch);
01686 
01698   inline UnicodeString& setTo(const UnicodeString& srcText,
01699                int32_t srcStart);
01700 
01714   inline UnicodeString& setTo(const UnicodeString& srcText,
01715                int32_t srcStart,
01716                int32_t srcLength);
01717 
01726   inline UnicodeString& setTo(const UnicodeString& srcText);
01727 
01736   inline UnicodeString& setTo(const UChar *srcChars,
01737                int32_t srcLength);
01738 
01747   UnicodeString& setTo(UChar srcChar);
01748 
01757   UnicodeString& setTo(UChar32 srcChar);
01758 
01779   UnicodeString &setTo(UBool isTerminated,
01780                        const UChar *text,
01781                        int32_t textLength);
01782 
01802   UnicodeString &setTo(UChar *buffer,
01803                        int32_t buffLength,
01804                        int32_t buffCapacity);
01805 
01846   void setToBogus();
01847 
01855   UnicodeString& setCharAt(int32_t offset,
01856                UChar ch);
01857 
01858 
01859   /* Append operations */
01860 
01868  inline  UnicodeString& operator+= (UChar ch);
01869 
01877  inline  UnicodeString& operator+= (UChar32 ch);
01878 
01887   inline UnicodeString& operator+= (const UnicodeString& srcText);
01888 
01903   inline UnicodeString& append(const UnicodeString& srcText,
01904             int32_t srcStart,
01905             int32_t srcLength);
01906 
01914   inline UnicodeString& append(const UnicodeString& srcText);
01915 
01929   inline UnicodeString& append(const UChar *srcChars,
01930             int32_t srcStart,
01931             int32_t srcLength);
01932 
01941   inline UnicodeString& append(const UChar *srcChars,
01942             int32_t srcLength);
01943 
01950   inline UnicodeString& append(UChar srcChar);
01951 
01958   inline UnicodeString& append(UChar32 srcChar);
01959 
01960 
01961   /* Insert operations */
01962 
01976   inline UnicodeString& insert(int32_t start,
01977             const UnicodeString& srcText,
01978             int32_t srcStart,
01979             int32_t srcLength);
01980 
01989   inline UnicodeString& insert(int32_t start,
01990             const UnicodeString& srcText);
01991 
02005   inline UnicodeString& insert(int32_t start,
02006             const UChar *srcChars,
02007             int32_t srcStart,
02008             int32_t srcLength);
02009 
02019   inline UnicodeString& insert(int32_t start,
02020             const UChar *srcChars,
02021             int32_t srcLength);
02022 
02031   inline UnicodeString& insert(int32_t start,
02032             UChar srcChar);
02033 
02042   inline UnicodeString& insert(int32_t start,
02043             UChar32 srcChar);
02044 
02045 
02046   /* Replace operations */
02047 
02065   UnicodeString& replace(int32_t start,
02066              int32_t length,
02067              const UnicodeString& srcText,
02068              int32_t srcStart,
02069              int32_t srcLength);
02070 
02083   UnicodeString& replace(int32_t start,
02084              int32_t length,
02085              const UnicodeString& srcText);
02086 
02104   UnicodeString& replace(int32_t start,
02105              int32_t length,
02106              const UChar *srcChars,
02107              int32_t srcStart,
02108              int32_t srcLength);
02109 
02122   inline UnicodeString& replace(int32_t start,
02123              int32_t length,
02124              const UChar *srcChars,
02125              int32_t srcLength);
02126 
02138   inline UnicodeString& replace(int32_t start,
02139              int32_t length,
02140              UChar srcChar);
02141 
02153   inline UnicodeString& replace(int32_t start,
02154              int32_t length,
02155              UChar32 srcChar);
02156 
02166   inline UnicodeString& replaceBetween(int32_t start,
02167                 int32_t limit,
02168                 const UnicodeString& srcText);
02169 
02184   inline UnicodeString& replaceBetween(int32_t start,
02185                 int32_t limit,
02186                 const UnicodeString& srcText,
02187                 int32_t srcStart,
02188                 int32_t srcLimit);
02189 
02200   virtual void handleReplaceBetween(int32_t start,
02201                                     int32_t limit,
02202                                     const UnicodeString& text);
02203 
02209   virtual UBool hasMetaData() const;
02210 
02226   virtual void copy(int32_t start, int32_t limit, int32_t dest);
02227 
02228   /* Search and replace operations */
02229 
02238   inline UnicodeString& findAndReplace(const UnicodeString& oldText,
02239                 const UnicodeString& newText);
02240 
02252   inline UnicodeString& findAndReplace(int32_t start,
02253                 int32_t length,
02254                 const UnicodeString& oldText,
02255                 const UnicodeString& newText);
02256 
02274   UnicodeString& findAndReplace(int32_t start,
02275                 int32_t length,
02276                 const UnicodeString& oldText,
02277                 int32_t oldStart,
02278                 int32_t oldLength,
02279                 const UnicodeString& newText,
02280                 int32_t newStart,
02281                 int32_t newLength);
02282 
02283 
02284   /* Remove operations */
02285 
02291   inline UnicodeString& remove(void);
02292 
02301   inline UnicodeString& remove(int32_t start,
02302                                int32_t length = (int32_t)INT32_MAX);
02303 
02312   inline UnicodeString& removeBetween(int32_t start,
02313                                       int32_t limit = (int32_t)INT32_MAX);
02314 
02315 
02316   /* Length operations */
02317 
02329   UBool padLeading(int32_t targetLength,
02330                     UChar padChar = 0x0020);
02331 
02343   UBool padTrailing(int32_t targetLength,
02344                      UChar padChar = 0x0020);
02345 
02352   inline UBool truncate(int32_t targetLength);
02353 
02359   UnicodeString& trim(void);
02360 
02361 
02362   /* Miscellaneous operations */
02363 
02369   inline UnicodeString& reverse(void);
02370 
02379   inline UnicodeString& reverse(int32_t start,
02380              int32_t length);
02381 
02388   UnicodeString& toUpper(void);
02389 
02397   UnicodeString& toUpper(const Locale& locale);
02398 
02405   UnicodeString& toLower(void);
02406 
02414   UnicodeString& toLower(const Locale& locale);
02415 
02416 #if !UCONFIG_NO_BREAK_ITERATION
02417 
02444   UnicodeString &toTitle(BreakIterator *titleIter);
02445 
02473   UnicodeString &toTitle(BreakIterator *titleIter, const Locale &locale);
02474 
02506   UnicodeString &toTitle(BreakIterator *titleIter, const Locale &locale, uint32_t options);
02507 
02508 #endif
02509 
02521   UnicodeString &foldCase(uint32_t options=0 /*U_FOLD_CASE_DEFAULT*/);
02522 
02523   //========================================
02524   // Access to the internal buffer
02525   //========================================
02526 
02570   UChar *getBuffer(int32_t minCapacity);
02571 
02592   void releaseBuffer(int32_t newLength=-1);
02593 
02624   inline const UChar *getBuffer() const;
02625 
02659   inline const UChar *getTerminatedBuffer();
02660 
02661   //========================================
02662   // Constructors
02663   //========================================
02664 
02668   UnicodeString();
02669 
02681   UnicodeString(int32_t capacity, UChar32 c, int32_t count);
02682 
02688   UnicodeString(UChar ch);
02689 
02695   UnicodeString(UChar32 ch);
02696 
02703   UnicodeString(const UChar *text);
02704 
02712   UnicodeString(const UChar *text,
02713         int32_t textLength);
02714 
02734   UnicodeString(UBool isTerminated,
02735                 const UChar *text,
02736                 int32_t textLength);
02737 
02756   UnicodeString(UChar *buffer, int32_t buffLength, int32_t buffCapacity);
02757 
02758 #if !UCONFIG_NO_CONVERSION
02759 
02777   UnicodeString(const char *codepageData,
02778         const char *codepage = 0);
02779 
02797   UnicodeString(const char *codepageData,
02798         int32_t dataLength,
02799         const char *codepage = 0);
02800 
02822   UnicodeString(
02823         const char *src, int32_t srcLength,
02824         UConverter *cnv,
02825         UErrorCode &errorCode);
02826 
02827 #endif
02828 
02853   UnicodeString(const char *src, int32_t length, enum EInvariant inv);
02854 
02855 
02861   UnicodeString(const UnicodeString& that);
02862 
02869   UnicodeString(const UnicodeString& src, int32_t srcStart);
02870 
02878   UnicodeString(const UnicodeString& src, int32_t srcStart, int32_t srcLength);
02879 
02896   virtual Replaceable *clone() const;
02897 
02901   virtual ~UnicodeString();
02902 
02903 
02904   /* Miscellaneous operations */
02905 
02940   UnicodeString unescape() const;
02941 
02961   UChar32 unescapeAt(int32_t &offset) const;
02962 
02968   static UClassID U_EXPORT2 getStaticClassID();
02969 
02975   virtual UClassID getDynamicClassID() const;
02976 
02977   //========================================
02978   // Implementation methods
02979   //========================================
02980 
02981 protected:
02986   virtual int32_t getLength() const;
02987 
02993   virtual UChar getCharAt(int32_t offset) const;
02994 
03000   virtual UChar32 getChar32At(int32_t offset) const;
03001 
03002 private:
03003 
03004   inline int8_t
03005   doCompare(int32_t start,
03006            int32_t length,
03007            const UnicodeString& srcText,
03008            int32_t srcStart,
03009            int32_t srcLength) const;
03010 
03011   int8_t doCompare(int32_t start,
03012            int32_t length,
03013            const UChar *srcChars,
03014            int32_t srcStart,
03015            int32_t srcLength) const;
03016 
03017   inline int8_t
03018   doCompareCodePointOrder(int32_t start,
03019                           int32_t length,
03020                           const UnicodeString& srcText,
03021                           int32_t srcStart,
03022                           int32_t srcLength) const;
03023 
03024   int8_t doCompareCodePointOrder(int32_t start,
03025                                  int32_t length,
03026                                  const UChar *srcChars,
03027                                  int32_t srcStart,
03028                                  int32_t srcLength) const;
03029 
03030   inline int8_t
03031   doCaseCompare(int32_t start,
03032                 int32_t length,
03033                 const UnicodeString &srcText,
03034                 int32_t srcStart,
03035                 int32_t srcLength,
03036                 uint32_t options) const;
03037 
03038   int8_t
03039   doCaseCompare(int32_t start,
03040                 int32_t length,
03041                 const UChar *srcChars,
03042                 int32_t srcStart,
03043                 int32_t srcLength,
03044                 uint32_t options) const;
03045 
03046   int32_t doIndexOf(UChar c,
03047             int32_t start,
03048             int32_t length) const;
03049 
03050   int32_t doIndexOf(UChar32 c,
03051                         int32_t start,
03052                         int32_t length) const;
03053 
03054   int32_t doLastIndexOf(UChar c,
03055                 int32_t start,
03056                 int32_t length) const;
03057 
03058   int32_t doLastIndexOf(UChar32 c,
03059                             int32_t start,
03060                             int32_t length) const;
03061 
03062   void doExtract(int32_t start,
03063          int32_t length,
03064          UChar *dst,
03065          int32_t dstStart) const;
03066 
03067   inline void doExtract(int32_t start,
03068          int32_t length,
03069          UnicodeString& target) const;
03070 
03071   inline UChar doCharAt(int32_t offset)  const;
03072 
03073   UnicodeString& doReplace(int32_t start,
03074                int32_t length,
03075                const UnicodeString& srcText,
03076                int32_t srcStart,
03077                int32_t srcLength);
03078 
03079   UnicodeString& doReplace(int32_t start,
03080                int32_t length,
03081                const UChar *srcChars,
03082                int32_t srcStart,
03083                int32_t srcLength);
03084 
03085   UnicodeString& doReverse(int32_t start,
03086                int32_t length);
03087 
03088   // calculate hash code
03089   int32_t doHashCode(void) const;
03090 
03091   // get pointer to start of array
03092   // these do not check for kOpenGetBuffer, unlike the public getBuffer() function
03093   inline UChar* getArrayStart(void);
03094   inline const UChar* getArrayStart(void) const;
03095 
03096   // A UnicodeString object (not necessarily its current buffer)
03097   // is writable unless it isBogus() or it has an "open" getBuffer(minCapacity).
03098   inline UBool isWritable() const;
03099 
03100   // Is the current buffer writable?
03101   inline UBool isBufferWritable() const;
03102 
03103   // None of the following does releaseArray().
03104   inline void setLength(int32_t len);        // sets only fShortLength and fLength
03105   inline void setToEmpty();                  // sets fFlags=kShortString
03106   inline void setToStackBuffer(int32_t len); // sets fFlags=kShortString
03107   inline void setArray(UChar *array, int32_t len, int32_t capacity); // does not set fFlags
03108 
03109   // allocate the array; result may be fStackBuffer
03110   // sets refCount to 1 if appropriate
03111   // sets fArray, fCapacity, and fFlags
03112   // returns boolean for success or failure
03113   UBool allocate(int32_t capacity);
03114 
03115   // release the array if owned
03116   void releaseArray(void);
03117 
03118   // turn a bogus string into an empty one
03119   void unBogus();
03120 
03121   // implements assigment operator, copy constructor, and fastCopyFrom()
03122   UnicodeString &copyFrom(const UnicodeString &src, UBool fastCopy=FALSE);
03123 
03124   // Pin start and limit to acceptable values.
03125   inline void pinIndex(int32_t& start) const;
03126   inline void pinIndices(int32_t& start,
03127                          int32_t& length) const;
03128 
03129 #if !UCONFIG_NO_CONVERSION
03130 
03131   /* Internal extract() using UConverter. */
03132   int32_t doExtract(int32_t start, int32_t length,
03133                     char *dest, int32_t destCapacity,
03134                     UConverter *cnv,
03135                     UErrorCode &errorCode) const;
03136 
03137   /*
03138    * Real constructor for converting from codepage data.
03139    * It assumes that it is called with !fRefCounted.
03140    *
03141    * If <code>codepage==0</code>, then the default converter
03142    * is used for the platform encoding.
03143    * If <code>codepage</code> is an empty string (<code>""</code>),
03144    * then a simple conversion is performed on the codepage-invariant
03145    * subset ("invariant characters") of the platform encoding. See utypes.h.
03146    */
03147   void doCodepageCreate(const char *codepageData,
03148                         int32_t dataLength,
03149                         const char *codepage);
03150 
03151   /*
03152    * Worker function for creating a UnicodeString from
03153    * a codepage string using a UConverter.
03154    */
03155   void
03156   doCodepageCreate(const char *codepageData,
03157                    int32_t dataLength,
03158                    UConverter *converter,
03159                    UErrorCode &status);
03160 
03161 #endif
03162 
03163   /*
03164    * This function is called when write access to the array
03165    * is necessary.
03166    *
03167    * We need to make a copy of the array if
03168    * the buffer is read-only, or
03169    * the buffer is refCounted (shared), and refCount>1, or
03170    * the buffer is too small.
03171    *
03172    * Return FALSE if memory could not be allocated.
03173    */
03174   UBool cloneArrayIfNeeded(int32_t newCapacity = -1,
03175                             int32_t growCapacity = -1,
03176                             UBool doCopyArray = TRUE,
03177                             int32_t **pBufferToDelete = 0,
03178                             UBool forceClone = FALSE);
03179 
03180   // common function for case mappings
03181   UnicodeString &
03182   caseMap(BreakIterator *titleIter,
03183           const char *locale,
03184           uint32_t options,
03185           int32_t toWhichCase);
03186 
03187   // ref counting
03188   void addRef(void);
03189   int32_t removeRef(void);
03190   int32_t refCount(void) const;
03191 
03192   // constants
03193   enum {
03194     // Set the stack buffer size so that sizeof(UnicodeString) is a multiple of sizeof(pointer):
03195     // 32-bit pointers: 4+1+1+13*2 = 32 bytes
03196     // 64-bit pointers: 8+1+1+15*2 = 40 bytes
03197     US_STACKBUF_SIZE= sizeof(void *)==4 ? 13 : 15, // Size of stack buffer for small strings
03198     kInvalidUChar=0xffff, // invalid UChar index
03199     kGrowSize=128, // grow size for this buffer
03200     kInvalidHashCode=0, // invalid hash code
03201     kEmptyHashCode=1, // hash code for empty string
03202 
03203     // bit flag values for fFlags
03204     kIsBogus=1,         // this string is bogus, i.e., not valid or NULL
03205     kUsingStackBuffer=2,// fArray==fStackBuffer
03206     kRefCounted=4,      // there is a refCount field before the characters in fArray
03207     kBufferIsReadonly=8,// do not write to this buffer
03208     kOpenGetBuffer=16,  // getBuffer(minCapacity) was called (is "open"),
03209                         // and releaseBuffer(newLength) must be called
03210 
03211     // combined values for convenience
03212     kShortString=kUsingStackBuffer,
03213     kLongString=kRefCounted,
03214     kReadonlyAlias=kBufferIsReadonly,
03215     kWritableAlias=0
03216   };
03217 
03218   friend class StringThreadTest;
03219 
03220   union StackBufferOrFields;        // forward declaration necessary before friend declaration
03221   friend union StackBufferOrFields; // make US_STACKBUF_SIZE visible inside fUnion
03222 
03223   /*
03224    * The following are all the class fields that are stored
03225    * in each UnicodeString object.
03226    * Note that UnicodeString has virtual functions,
03227    * therefore there is an implicit vtable pointer
03228    * as the first real field.
03229    * The fields should be aligned such that no padding is
03230    * necessary, mostly by having larger types first.
03231    * On 32-bit machines, the size should be 32 bytes,
03232    * on 64-bit machines (8-byte pointers), it should be 40 bytes.
03233    */
03234   // (implicit) *vtable;
03235   int8_t    fShortLength;   // 0..127: length  <0: real length is in fUnion.fFields.fLength
03236   uint8_t   fFlags;         // bit flags: see constants above
03237   union StackBufferOrFields {
03238     // fStackBuffer is used iff (fFlags&kUsingStackBuffer)
03239     // else fFields is used
03240     UChar     fStackBuffer [US_STACKBUF_SIZE]; // buffer for small strings
03241     struct {
03242       uint16_t  fPadding;   // align the following field at 8B (32b pointers) or 12B (64b)
03243       int32_t   fLength;    // number of characters in fArray if >127; else undefined
03244       UChar     *fArray;    // the Unicode data (aligned at 12B (32b pointers) or 16B (64b))
03245       int32_t   fCapacity;  // sizeof fArray
03246     } fFields;
03247   } fUnion;
03248 };
03249 
03258 U_COMMON_API UnicodeString U_EXPORT2
03259 operator+ (const UnicodeString &s1, const UnicodeString &s2);
03260 
03261 //========================================
03262 // Inline members
03263 //========================================
03264 
03265 //========================================
03266 // Privates
03267 //========================================
03268 
03269 inline void
03270 UnicodeString::pinIndex(int32_t& start) const
03271 {
03272   // pin index
03273   if(start < 0) {
03274     start = 0;
03275   } else if(start > length()) {
03276     start = length();
03277   }
03278 }
03279 
03280 inline void
03281 UnicodeString::pinIndices(int32_t& start,
03282                           int32_t& _length) const
03283 {
03284   // pin indices
03285   int32_t len = length();
03286   if(start < 0) {
03287     start = 0;
03288   } else if(start > len) {
03289     start = len;
03290   }
03291   if(_length < 0) {
03292     _length = 0;
03293   } else if(_length > (len - start)) {
03294     _length = (len - start);
03295   }
03296 }
03297 
03298 inline UChar*
03299 UnicodeString::getArrayStart()
03300 { return (fFlags&kUsingStackBuffer) ? fUnion.fStackBuffer : fUnion.fFields.fArray; }
03301 
03302 inline const UChar*
03303 UnicodeString::getArrayStart() const
03304 { return (fFlags&kUsingStackBuffer) ? fUnion.fStackBuffer : fUnion.fFields.fArray; }
03305 
03306 //========================================
03307 // Read-only implementation methods
03308 //========================================
03309 inline int32_t
03310 UnicodeString::length() const
03311 { return fShortLength>=0 ? fShortLength : fUnion.fFields.fLength; }
03312 
03313 inline int32_t
03314 UnicodeString::getCapacity() const
03315 { return (fFlags&kUsingStackBuffer) ? US_STACKBUF_SIZE : fUnion.fFields.fCapacity; }
03316 
03317 inline int32_t
03318 UnicodeString::hashCode() const
03319 { return doHashCode(); }
03320 
03321 inline UBool
03322 UnicodeString::isBogus() const
03323 { return (UBool)(fFlags & kIsBogus); }
03324 
03325 inline UBool
03326 UnicodeString::isWritable() const
03327 { return (UBool)!(fFlags&(kOpenGetBuffer|kIsBogus)); }
03328 
03329 inline UBool
03330 UnicodeString::isBufferWritable() const
03331 {
03332   return (UBool)(
03333       !(fFlags&(kOpenGetBuffer|kIsBogus|kBufferIsReadonly)) &&
03334       (!(fFlags&kRefCounted) || refCount()==1));
03335 }
03336 
03337 inline const UChar *
03338 UnicodeString::getBuffer() const {
03339   if(fFlags&(kIsBogus|kOpenGetBuffer)) {
03340     return 0;
03341   } else if(fFlags&kUsingStackBuffer) {
03342     return fUnion.fStackBuffer;
03343   } else {
03344     return fUnion.fFields.fArray;
03345   }
03346 }
03347 
03348 //========================================
03349 // Read-only alias methods
03350 //========================================
03351 inline int8_t
03352 UnicodeString::doCompare(int32_t start,
03353               int32_t thisLength,
03354               const UnicodeString& srcText,
03355               int32_t srcStart,
03356               int32_t srcLength) const
03357 {
03358   if(srcText.isBogus()) {
03359     return (int8_t)!isBogus(); // 0 if both are bogus, 1 otherwise
03360   } else {
03361     srcText.pinIndices(srcStart, srcLength);
03362     return doCompare(start, thisLength, srcText.getArrayStart(), srcStart, srcLength);
03363   }
03364 }
03365 
03366 inline UBool
03367 UnicodeString::operator== (const UnicodeString& text) const
03368 {
03369   if(isBogus()) {
03370     return text.isBogus();
03371   } else {
03372     int32_t len = length(), textLength = text.length();
03373     return
03374       !text.isBogus() &&
03375       len == textLength &&
03376       doCompare(0, len, text, 0, textLength) == 0;
03377   }
03378 }
03379 
03380 inline UBool
03381 UnicodeString::operator!= (const UnicodeString& text) const
03382 { return (! operator==(text)); }
03383 
03384 inline UBool
03385 UnicodeString::operator> (const UnicodeString& text) const
03386 { return doCompare(0, length(), text, 0, text.length()) == 1; }
03387 
03388 inline UBool
03389 UnicodeString::operator< (const UnicodeString& text) const
03390 { return doCompare(0, length(), text, 0, text.length()) == -1; }
03391 
03392 inline UBool
03393 UnicodeString::operator>= (const UnicodeString& text) const
03394 { return doCompare(0, length(), text, 0, text.length()) != -1; }
03395 
03396 inline UBool
03397 UnicodeString::operator<= (const UnicodeString& text) const
03398 { return doCompare(0, length(), text, 0, text.length()) != 1; }
03399 
03400 inline int8_t
03401 UnicodeString::compare(const UnicodeString& text) const
03402 { return doCompare(0, length(), text, 0, text.length()); }
03403 
03404 inline int8_t
03405 UnicodeString::compare(int32_t start,
03406                int32_t _length,
03407                const UnicodeString& srcText) const
03408 { return doCompare(start, _length, srcText, 0, srcText.length()); }
03409 
03410 inline int8_t
03411 UnicodeString::compare(const UChar *srcChars,
03412                int32_t srcLength) const
03413 { return doCompare(0, length(), srcChars, 0, srcLength); }
03414 
03415 inline int8_t
03416 UnicodeString::compare(int32_t start,
03417                int32_t _length,
03418                const UnicodeString& srcText,
03419                int32_t srcStart,
03420                int32_t srcLength) const
03421 { return doCompare(start, _length, srcText, srcStart, srcLength); }
03422 
03423 inline int8_t
03424 UnicodeString::compare(int32_t start,
03425                int32_t _length,
03426                const UChar *srcChars) const
03427 { return doCompare(start, _length, srcChars, 0, _length); }
03428 
03429 inline int8_t
03430 UnicodeString::compare(int32_t start,
03431                int32_t _length,
03432                const UChar *srcChars,
03433                int32_t srcStart,
03434                int32_t srcLength) const
03435 { return doCompare(start, _length, srcChars, srcStart, srcLength); }
03436 
03437 inline int8_t
03438 UnicodeString::compareBetween(int32_t start,
03439                   int32_t limit,
03440                   const UnicodeString& srcText,
03441                   int32_t srcStart,
03442                   int32_t srcLimit) const
03443 { return doCompare(start, limit - start,
03444            srcText, srcStart, srcLimit - srcStart); }
03445 
03446 inline int8_t
03447 UnicodeString::doCompareCodePointOrder(int32_t start,
03448                                        int32_t thisLength,
03449                                        const UnicodeString& srcText,
03450                                        int32_t srcStart,
03451                                        int32_t srcLength) const
03452 {
03453   if(srcText.isBogus()) {
03454     return (int8_t)!isBogus(); // 0 if both are bogus, 1 otherwise
03455   } else {
03456     srcText.pinIndices(srcStart, srcLength);
03457     return doCompareCodePointOrder(start, thisLength, srcText.getArrayStart(), srcStart, srcLength);
03458   }
03459 }
03460 
03461 inline int8_t
03462 UnicodeString::compareCodePointOrder(const UnicodeString& text) const
03463 { return doCompareCodePointOrder(0, length(), text, 0, text.length()); }
03464 
03465 inline int8_t
03466 UnicodeString::compareCodePointOrder(int32_t start,
03467                                      int32_t _length,
03468                                      const UnicodeString& srcText) const
03469 { return doCompareCodePointOrder(start, _length, srcText, 0, srcText.length()); }
03470 
03471 inline int8_t
03472 UnicodeString::compareCodePointOrder(const UChar *srcChars,
03473                                      int32_t srcLength) const
03474 { return doCompareCodePointOrder(0, length(), srcChars, 0, srcLength); }
03475 
03476 inline int8_t
03477 UnicodeString::compareCodePointOrder(int32_t start,
03478                                      int32_t _length,
03479                                      const UnicodeString& srcText,
03480                                      int32_t srcStart,
03481                                      int32_t srcLength) const
03482 { return doCompareCodePointOrder(start, _length, srcText, srcStart, srcLength); }
03483 
03484 inline int8_t
03485 UnicodeString::compareCodePointOrder(int32_t start,
03486                                      int32_t _length,
03487                                      const UChar *srcChars) const
03488 { return doCompareCodePointOrder(start, _length, srcChars, 0, _length); }
03489 
03490 inline int8_t
03491 UnicodeString::compareCodePointOrder(int32_t start,
03492                                      int32_t _length,
03493                                      const UChar *srcChars,
03494                                      int32_t srcStart,
03495                                      int32_t srcLength) const
03496 { return doCompareCodePointOrder(start, _length, srcChars, srcStart, srcLength); }
03497 
03498 inline int8_t
03499 UnicodeString::compareCodePointOrderBetween(int32_t start,
03500                                             int32_t limit,
03501                                             const UnicodeString& srcText,
03502                                             int32_t srcStart,
03503                                             int32_t srcLimit) const
03504 { return doCompareCodePointOrder(start, limit - start,
03505            srcText, srcStart, srcLimit - srcStart); }
03506 
03507 inline int8_t
03508 UnicodeString::doCaseCompare(int32_t start,
03509                              int32_t thisLength,
03510                              const UnicodeString &srcText,
03511                              int32_t srcStart,
03512                              int32_t srcLength,
03513                              uint32_t options) const
03514 {
03515   if(srcText.isBogus()) {
03516     return (int8_t)!isBogus(); // 0 if both are bogus, 1 otherwise
03517   } else {
03518     srcText.pinIndices(srcStart, srcLength);
03519     return doCaseCompare(start, thisLength, srcText.getArrayStart(), srcStart, srcLength, options);
03520   }
03521 }
03522 
03523 inline int8_t
03524 UnicodeString::caseCompare(const UnicodeString &text, uint32_t options) const {
03525   return doCaseCompare(0, length(), text, 0, text.length(), options);
03526 }
03527 
03528 inline int8_t
03529 UnicodeString::caseCompare(int32_t start,
03530                            int32_t _length,
03531                            const UnicodeString &srcText,
03532                            uint32_t options) const {
03533   return doCaseCompare(start, _length, srcText, 0, srcText.length(), options);
03534 }
03535 
03536 inline int8_t
03537 UnicodeString::caseCompare(const UChar *srcChars,
03538                            int32_t srcLength,
03539                            uint32_t options) const {
03540   return doCaseCompare(0, length(), srcChars, 0, srcLength, options);
03541 }
03542 
03543 inline int8_t
03544 UnicodeString::caseCompare(int32_t start,
03545                            int32_t _length,
03546                            const UnicodeString &srcText,
03547                            int32_t srcStart,
03548                            int32_t srcLength,
03549                            uint32_t options) const {
03550   return doCaseCompare(start, _length, srcText, srcStart, srcLength, options);
03551 }
03552 
03553 inline int8_t
03554 UnicodeString::caseCompare(int32_t start,
03555                            int32_t _length,
03556                            const UChar *srcChars,
03557                            uint32_t options) const {
03558   return doCaseCompare(start, _length, srcChars, 0, _length, options);
03559 }
03560 
03561 inline int8_t
03562 UnicodeString::caseCompare(int32_t start,
03563                            int32_t _length,
03564                            const UChar *srcChars,
03565                            int32_t srcStart,
03566                            int32_t srcLength,
03567                            uint32_t options) const {
03568   return doCaseCompare(start, _length, srcChars, srcStart, srcLength, options);
03569 }
03570 
03571 inline int8_t
03572 UnicodeString::caseCompareBetween(int32_t start,
03573                                   int32_t limit,
03574                                   const UnicodeString &srcText,
03575                                   int32_t srcStart,
03576                                   int32_t srcLimit,
03577                                   uint32_t options) const {
03578   return doCaseCompare(start, limit - start, srcText, srcStart, srcLimit - srcStart, options);
03579 }
03580 
03581 inline int32_t
03582 UnicodeString::indexOf(const UnicodeString& srcText,
03583                int32_t srcStart,
03584                int32_t srcLength,
03585                int32_t start,
03586                int32_t _length) const
03587 {
03588   if(!srcText.isBogus()) {
03589     srcText.pinIndices(srcStart, srcLength);
03590     if(srcLength > 0) {
03591       return indexOf(srcText.getArrayStart(), srcStart, srcLength, start, _length);
03592     }
03593   }
03594   return -1;
03595 }
03596 
03597 inline int32_t
03598 UnicodeString::indexOf(const UnicodeString& text) const
03599 { return indexOf(text, 0, text.length(), 0, length()); }
03600 
03601 inline int32_t
03602 UnicodeString::indexOf(const UnicodeString& text,
03603                int32_t start) const {
03604   pinIndex(start);
03605   return indexOf(text, 0, text.length(), start, length() - start);
03606 }
03607 
03608 inline int32_t
03609 UnicodeString::indexOf(const UnicodeString& text,
03610                int32_t start,
03611                int32_t _length) const
03612 { return indexOf(text, 0, text.length(), start, _length); }
03613 
03614 inline int32_t
03615 UnicodeString::indexOf(const UChar *srcChars,
03616                int32_t srcLength,
03617                int32_t start) const {
03618   pinIndex(start);
03619   return indexOf(srcChars, 0, srcLength, start, length() - start);
03620 }
03621 
03622 inline int32_t
03623 UnicodeString::indexOf(const UChar *srcChars,
03624                int32_t srcLength,
03625                int32_t start,
03626                int32_t _length) const
03627 { return indexOf(srcChars, 0, srcLength, start, _length); }
03628 
03629 inline int32_t
03630 UnicodeString::indexOf(UChar c,
03631                int32_t start,
03632                int32_t _length) const
03633 { return doIndexOf(c, start, _length); }
03634 
03635 inline int32_t
03636 UnicodeString::indexOf(UChar32 c,
03637                int32_t start,
03638                int32_t _length) const
03639 { return doIndexOf(c, start, _length); }
03640 
03641 inline int32_t
03642 UnicodeString::indexOf(UChar c) const
03643 { return doIndexOf(c, 0, length()); }
03644 
03645 inline int32_t
03646 UnicodeString::indexOf(UChar32 c) const
03647 { return indexOf(c, 0, length()); }
03648 
03649 inline int32_t
03650 UnicodeString::indexOf(UChar c,
03651                int32_t start) const {
03652   pinIndex(start);
03653   return doIndexOf(c, start, length() - start);
03654 }
03655 
03656 inline int32_t
03657 UnicodeString::indexOf(UChar32 c,
03658                int32_t start) const {
03659   pinIndex(start);
03660   return indexOf(c, start, length() - start);
03661 }
03662 
03663 inline int32_t
03664 UnicodeString::lastIndexOf(const UChar *srcChars,
03665                int32_t srcLength,
03666                int32_t start,
03667                int32_t _length) const
03668 { return lastIndexOf(srcChars, 0, srcLength, start, _length); }
03669 
03670 inline int32_t
03671 UnicodeString::lastIndexOf(const UChar *srcChars,
03672                int32_t srcLength,
03673                int32_t start) const {
03674   pinIndex(start);
03675   return lastIndexOf(srcChars, 0, srcLength, start, length() - start);
03676 }
03677 
03678 inline int32_t
03679 UnicodeString::lastIndexOf(const UnicodeString& srcText,
03680                int32_t srcStart,
03681                int32_t srcLength,
03682                int32_t start,
03683                int32_t _length) const
03684 {
03685   if(!srcText.isBogus()) {
03686     srcText.pinIndices(srcStart, srcLength);
03687     if(srcLength > 0) {
03688       return lastIndexOf(srcText.getArrayStart(), srcStart, srcLength, start, _length);
03689     }
03690   }
03691   return -1;
03692 }
03693 
03694 inline int32_t
03695 UnicodeString::lastIndexOf(const UnicodeString& text,
03696                int32_t start,
03697                int32_t _length) const
03698 { return lastIndexOf(text, 0, text.length(), start, _length); }
03699 
03700 inline int32_t
03701 UnicodeString::lastIndexOf(const UnicodeString& text,
03702                int32_t start) const {
03703   pinIndex(start);
03704   return lastIndexOf(text, 0, text.length(), start, length() - start);
03705 }
03706 
03707 inline int32_t
03708 UnicodeString::lastIndexOf(const UnicodeString& text) const
03709 { return lastIndexOf(text, 0, text.length(), 0, length()); }
03710 
03711 inline int32_t
03712 UnicodeString::lastIndexOf(UChar c,
03713                int32_t start,
03714                int32_t _length) const
03715 { return doLastIndexOf(c, start, _length); }
03716 
03717 inline int32_t
03718 UnicodeString::lastIndexOf(UChar32 c,
03719                int32_t start,
03720                int32_t _length) const {
03721   return doLastIndexOf(c, start, _length);
03722 }
03723 
03724 inline int32_t
03725 UnicodeString::lastIndexOf(UChar c) const
03726 { return doLastIndexOf(c, 0, length()); }
03727 
03728 inline int32_t
03729 UnicodeString::lastIndexOf(UChar32 c) const {
03730   return lastIndexOf(c, 0, length());
03731 }
03732 
03733 inline int32_t
03734 UnicodeString::lastIndexOf(UChar c,
03735                int32_t start) const {
03736   pinIndex(start);
03737   return doLastIndexOf(c, start, length() - start);
03738 }
03739 
03740 inline int32_t
03741 UnicodeString::lastIndexOf(UChar32 c,
03742                int32_t start) const {
03743   pinIndex(start);
03744   return lastIndexOf(c, start, length() - start);
03745 }
03746 
03747 inline UBool
03748 UnicodeString::startsWith(const UnicodeString& text) const
03749 { return compare(0, text.length(), text, 0, text.length()) == 0; }
03750 
03751 inline UBool
03752 UnicodeString::startsWith(const UnicodeString& srcText,
03753               int32_t srcStart,
03754               int32_t srcLength) const
03755 { return doCompare(0, srcLength, srcText, srcStart, srcLength) == 0; }
03756 
03757 inline UBool
03758 UnicodeString::startsWith(const UChar *srcChars,
03759               int32_t srcLength) const
03760 { return doCompare(0, srcLength, srcChars, 0, srcLength) == 0; }
03761 
03762 inline UBool
03763 UnicodeString::startsWith(const UChar *srcChars,
03764               int32_t srcStart,
03765               int32_t srcLength) const
03766 { return doCompare(0, srcLength, srcChars, srcStart, srcLength) == 0;}
03767 
03768 inline UBool
03769 UnicodeString::endsWith(const UnicodeString& text) const
03770 { return doCompare(length() - text.length(), text.length(),
03771            text, 0, text.length()) == 0; }
03772 
03773 inline UBool
03774 UnicodeString::endsWith(const UnicodeString& srcText,
03775             int32_t srcStart,
03776             int32_t srcLength) const {
03777   srcText.pinIndices(srcStart, srcLength);
03778   return doCompare(length() - srcLength, srcLength,
03779                    srcText, srcStart, srcLength) == 0;
03780 }
03781 
03782 inline UBool
03783 UnicodeString::endsWith(const UChar *srcChars,
03784             int32_t srcLength) const {
03785   if(srcLength < 0) {
03786     srcLength = u_strlen(srcChars);
03787   }
03788   return doCompare(length() - srcLength, srcLength,
03789                    srcChars, 0, srcLength) == 0;
03790 }
03791 
03792 inline UBool
03793 UnicodeString::endsWith(const UChar *srcChars,
03794             int32_t srcStart,
03795             int32_t srcLength) const {
03796   if(srcLength < 0) {
03797     srcLength = u_strlen(srcChars + srcStart);
03798   }
03799   return doCompare(length() - srcLength, srcLength,
03800                    srcChars, srcStart, srcLength) == 0;
03801 }
03802 
03803 //========================================
03804 // replace
03805 //========================================
03806 inline UnicodeString&
03807 UnicodeString::replace(int32_t start,
03808                int32_t _length,
03809                const UnicodeString& srcText)
03810 { return doReplace(start, _length, srcText, 0, srcText.length()); }
03811 
03812 inline UnicodeString&
03813 UnicodeString::replace(int32_t start,
03814                int32_t _length,
03815                const UnicodeString& srcText,
03816                int32_t srcStart,
03817                int32_t srcLength)
03818 { return doReplace(start, _length, srcText, srcStart, srcLength); }
03819 
03820 inline UnicodeString&
03821 UnicodeString::replace(int32_t start,
03822                int32_t _length,
03823                const UChar *srcChars,
03824                int32_t srcLength)
03825 { return doReplace(start, _length, srcChars, 0, srcLength); }
03826 
03827 inline UnicodeString&
03828 UnicodeString::replace(int32_t start,
03829                int32_t _length,
03830                const UChar *srcChars,
03831                int32_t srcStart,
03832                int32_t srcLength)
03833 { return doReplace(start, _length, srcChars, srcStart, srcLength); }
03834 
03835 inline UnicodeString&
03836 UnicodeString::replace(int32_t start,
03837                int32_t _length,
03838                UChar srcChar)
03839 { return doReplace(start, _length, &srcChar, 0, 1); }
03840 
03841 inline UnicodeString&
03842 UnicodeString::replace(int32_t start,
03843                int32_t _length,
03844                UChar32 srcChar) {
03845   UChar buffer[U16_MAX_LENGTH];
03846   int32_t count = 0;
03847   UBool isError = FALSE;
03848   U16_APPEND(buffer, count, U16_MAX_LENGTH, srcChar, isError);
03849   return doReplace(start, _length, buffer, 0, count);
03850 }
03851 
03852 inline UnicodeString&
03853 UnicodeString::replaceBetween(int32_t start,
03854                   int32_t limit,
03855                   const UnicodeString& srcText)
03856 { return doReplace(start, limit - start, srcText, 0, srcText.length()); }
03857 
03858 inline UnicodeString&
03859 UnicodeString::replaceBetween(int32_t start,
03860                   int32_t limit,
03861                   const UnicodeString& srcText,
03862                   int32_t srcStart,
03863                   int32_t srcLimit)
03864 { return doReplace(start, limit - start, srcText, srcStart, srcLimit - srcStart); }
03865 
03866 inline UnicodeString&
03867 UnicodeString::findAndReplace(const UnicodeString& oldText,
03868                   const UnicodeString& newText)
03869 { return findAndReplace(0, length(), oldText, 0, oldText.length(),
03870             newText, 0, newText.length()); }
03871 
03872 inline UnicodeString&
03873 UnicodeString::findAndReplace(int32_t start,
03874                   int32_t _length,
03875                   const UnicodeString& oldText,
03876                   const UnicodeString& newText)
03877 { return findAndReplace(start, _length, oldText, 0, oldText.length(),
03878             newText, 0, newText.length()); }
03879 
03880 // ============================
03881 // extract
03882 // ============================
03883 inline void
03884 UnicodeString::doExtract(int32_t start,
03885              int32_t _length,
03886              UnicodeString& target) const
03887 { target.replace(0, target.length(), *this, start, _length); }
03888 
03889 inline void
03890 UnicodeString::extract(int32_t start,
03891                int32_t _length,
03892                UChar *target,
03893                int32_t targetStart) const
03894 { doExtract(start, _length, target, targetStart); }
03895 
03896 inline void
03897 UnicodeString::extract(int32_t start,
03898                int32_t _length,
03899                UnicodeString& target) const
03900 { doExtract(start, _length, target); }
03901 
03902 #if !UCONFIG_NO_CONVERSION
03903 
03904 inline int32_t
03905 UnicodeString::extract(int32_t start,
03906                int32_t _length,
03907                char *dst,
03908                const char *codepage) const
03909 
03910 {
03911   // This dstSize value will be checked explicitly
03912   return extract(start, _length, dst, dst!=0 ? 0xffffffff : 0, codepage);
03913 }
03914 
03915 #endif
03916 
03917 inline void
03918 UnicodeString::extractBetween(int32_t start,
03919                   int32_t limit,
03920                   UChar *dst,
03921                   int32_t dstStart) const {
03922   pinIndex(start);
03923   pinIndex(limit);
03924   doExtract(start, limit - start, dst, dstStart);
03925 }
03926 
03927 inline UChar
03928 UnicodeString::doCharAt(int32_t offset) const
03929 {
03930   if((uint32_t)offset < (uint32_t)length()) {
03931     return getArrayStart()[offset];
03932   } else {
03933     return kInvalidUChar;
03934   }
03935 }
03936 
03937 inline UChar
03938 UnicodeString::charAt(int32_t offset) const
03939 { return doCharAt(offset); }
03940 
03941 inline UChar
03942 UnicodeString::operator[] (int32_t offset) const
03943 { return doCharAt(offset); }
03944 
03945 inline UChar32
03946 UnicodeString::char32At(int32_t offset) const
03947 {
03948   int32_t len = length();
03949   if((uint32_t)offset < (uint32_t)len) {
03950     const UChar *array = getArrayStart();
03951     UChar32 c;
03952     U16_GET(array, 0, offset, len, c);
03953     return c;
03954   } else {
03955     return kInvalidUChar;
03956   }
03957 }
03958 
03959 inline int32_t
03960 UnicodeString::getChar32Start(int32_t offset) const {
03961   if((uint32_t)offset < (uint32_t)length()) {
03962     const UChar *array = getArrayStart();
03963     U16_SET_CP_START(array, 0, offset);
03964     return offset;
03965   } else {
03966     return 0;
03967   }
03968 }
03969 
03970 inline int32_t
03971 UnicodeString::getChar32Limit(int32_t offset) const {
03972   int32_t len = length();
03973   if((uint32_t)offset < (uint32_t)len) {
03974     const UChar *array = getArrayStart();
03975     U16_SET_CP_LIMIT(array, 0, offset, len);
03976     return offset;
03977   } else {
03978     return len;
03979   }
03980 }
03981 
03982 inline UBool
03983 UnicodeString::isEmpty() const {
03984   return fShortLength == 0;
03985 }
03986 
03987 //========================================
03988 // Write implementation methods
03989 //========================================
03990 inline void
03991 UnicodeString::setLength(int32_t len) {
03992   if(len <= 127) {
03993     fShortLength = (int8_t)len;
03994   } else {
03995     fShortLength = (int8_t)-1;
03996     fUnion.fFields.fLength = len;
03997   }
03998 }
03999 
04000 inline void
04001 UnicodeString::setToEmpty() {
04002   fShortLength = 0;
04003   fFlags = kShortString;
04004 }
04005 
04006 inline void
04007 UnicodeString::setToStackBuffer(int32_t len) {
04008   fShortLength = (int8_t)len;
04009   fFlags = kShortString;
04010 }
04011 
04012 inline void
04013 UnicodeString::setArray(UChar *array, int32_t len, int32_t capacity) {
04014   setLength(len);
04015   fUnion.fFields.fArray = array;
04016   fUnion.fFields.fCapacity = capacity;
04017 }
04018 
04019 inline const UChar *
04020 UnicodeString::getTerminatedBuffer() {
04021   if(!isWritable()) {
04022     return 0;
04023   } else {
04024     UChar *array = getArrayStart();
04025     int32_t len = length();
04026     if(len < getCapacity() && array[len] == 0) {
04027       return array;
04028     } else if(cloneArrayIfNeeded(len+1)) {
04029       array = getArrayStart();
04030       array[len] = 0;
04031       return array;
04032     } else {
04033       return 0;
04034     }
04035   }
04036 }
04037 
04038 inline UnicodeString&
04039 UnicodeString::operator= (UChar ch)
04040 { return doReplace(0, length(), &ch, 0, 1); }
04041 
04042 inline UnicodeString&
04043 UnicodeString::operator= (UChar32 ch)
04044 { return replace(0, length(), ch); }
04045 
04046 inline UnicodeString&
04047 UnicodeString::setTo(const UnicodeString& srcText,
04048              int32_t srcStart,
04049              int32_t srcLength)
04050 {
04051   unBogus();
04052   return doReplace(0, length(), srcText, srcStart, srcLength);
04053 }
04054 
04055 inline UnicodeString&
04056 UnicodeString::setTo(const UnicodeString& srcText,
04057              int32_t srcStart)
04058 {
04059   unBogus();
04060   srcText.pinIndex(srcStart);
04061   return doReplace(0, length(), srcText, srcStart, srcText.length() - srcStart);
04062 }
04063 
04064 inline UnicodeString&
04065 UnicodeString::setTo(const UnicodeString& srcText)
04066 {
04067   unBogus();
04068   return doReplace(0, length(), srcText, 0, srcText.length());
04069 }
04070 
04071 inline UnicodeString&
04072 UnicodeString::setTo(const UChar *srcChars,
04073              int32_t srcLength)
04074 {
04075   unBogus();
04076   return doReplace(0, length(), srcChars, 0, srcLength);
04077 }
04078 
04079 inline UnicodeString&
04080 UnicodeString::setTo(UChar srcChar)
04081 {
04082   unBogus();
04083   return doReplace(0, length(), &srcChar, 0, 1);
04084 }
04085 
04086 inline UnicodeString&
04087 UnicodeString::setTo(UChar32 srcChar)
04088 {
04089   unBogus();
04090   return replace(0, length(), srcChar);
04091 }
04092 
04093 inline UnicodeString&
04094 UnicodeString::append(const UnicodeString& srcText,
04095               int32_t srcStart,
04096               int32_t srcLength)
04097 { return doReplace(length(), 0, srcText, srcStart, srcLength); }
04098 
04099 inline UnicodeString&
04100 UnicodeString::append(const UnicodeString& srcText)
04101 { return doReplace(length(), 0, srcText, 0, srcText.length()); }
04102 
04103 inline UnicodeString&
04104 UnicodeString::append(const UChar *srcChars,
04105               int32_t srcStart,
04106               int32_t srcLength)
04107 { return doReplace(length(), 0, srcChars, srcStart, srcLength); }
04108 
04109 inline UnicodeString&
04110 UnicodeString::append(const UChar *srcChars,
04111               int32_t srcLength)
04112 { return doReplace(length(), 0, srcChars, 0, srcLength); }
04113 
04114 inline UnicodeString&
04115 UnicodeString::append(UChar srcChar)
04116 { return doReplace(length(), 0, &srcChar, 0, 1); }
04117 
04118 inline UnicodeString&
04119 UnicodeString::append(UChar32 srcChar) {
04120   UChar buffer[U16_MAX_LENGTH];
04121   int32_t _length = 0;
04122   UBool isError = FALSE;
04123   U16_APPEND(buffer, _length, U16_MAX_LENGTH, srcChar, isError);
04124   return doReplace(length(), 0, buffer, 0, _length);
04125 }
04126 
04127 inline UnicodeString&
04128 UnicodeString::operator+= (UChar ch)
04129 { return doReplace(length(), 0, &ch, 0, 1); }
04130 
04131 inline UnicodeString&
04132 UnicodeString::operator+= (UChar32 ch) {
04133   return append(ch);
04134 }
04135 
04136 inline UnicodeString&
04137 UnicodeString::operator+= (const UnicodeString& srcText)
04138 { return doReplace(length(), 0, srcText, 0, srcText.length()); }
04139 
04140 inline UnicodeString&
04141 UnicodeString::insert(int32_t start,
04142               const UnicodeString& srcText,
04143               int32_t srcStart,
04144               int32_t srcLength)
04145 { return doReplace(start, 0, srcText, srcStart, srcLength); }
04146 
04147 inline UnicodeString&
04148 UnicodeString::insert(int32_t start,
04149               const UnicodeString& srcText)
04150 { return doReplace(start, 0, srcText, 0, srcText.length()); }
04151 
04152 inline UnicodeString&
04153 UnicodeString::insert(int32_t start,
04154               const UChar *srcChars,
04155               int32_t srcStart,
04156               int32_t srcLength)
04157 { return doReplace(start, 0, srcChars, srcStart, srcLength); }
04158 
04159 inline UnicodeString&
04160 UnicodeString::insert(int32_t start,
04161               const UChar *srcChars,
04162               int32_t srcLength)
04163 { return doReplace(start, 0, srcChars, 0, srcLength); }
04164 
04165 inline UnicodeString&
04166 UnicodeString::insert(int32_t start,
04167               UChar srcChar)
04168 { return doReplace(start, 0, &srcChar, 0, 1); }
04169 
04170 inline UnicodeString&
04171 UnicodeString::insert(int32_t start,
04172               UChar32 srcChar)
04173 { return replace(start, 0, srcChar); }
04174 
04175 
04176 inline UnicodeString&
04177 UnicodeString::remove()
04178 {
04179   // remove() of a bogus string makes the string empty and non-bogus
04180   if(isBogus()) {
04181     unBogus();
04182   } else {
04183     setLength(0);
04184   }
04185   return *this;
04186 }
04187 
04188 inline UnicodeString&
04189 UnicodeString::remove(int32_t start,
04190              int32_t _length)
04191 {
04192     if(start <= 0 && _length == INT32_MAX) {
04193         // remove(guaranteed everything) of a bogus string makes the string empty and non-bogus
04194         return remove();
04195     }
04196     return doReplace(start, _length, NULL, 0, 0);
04197 }
04198 
04199 inline UnicodeString&
04200 UnicodeString::removeBetween(int32_t start,
04201                 int32_t limit)
04202 { return doReplace(start, limit - start, NULL, 0, 0); }
04203 
04204 inline UBool
04205 UnicodeString::truncate(int32_t targetLength)
04206 {
04207   if(isBogus() && targetLength == 0) {
04208     // truncate(0) of a bogus string makes the string empty and non-bogus
04209     unBogus();
04210     return FALSE;
04211   } else if((uint32_t)targetLength < (uint32_t)length()) {
04212     setLength(targetLength);
04213     return TRUE;
04214   } else {
04215     return FALSE;
04216   }
04217 }
04218 
04219 inline UnicodeString&
04220 UnicodeString::reverse()
04221 { return doReverse(0, length()); }
04222 
04223 inline UnicodeString&
04224 UnicodeString::reverse(int32_t start,
04225                int32_t _length)
04226 { return doReverse(start, _length); }
04227 
04228 U_NAMESPACE_END
04229 
04230 #endif

Generated on Sat Oct 3 23:25:34 2009 for ICU 4.0 by  doxygen 1.4.7