Main Page   Class Hierarchy   Compound List   File List   Header Files   Sources   Compound Members   File Members  

unistr.h

This is the verbatim text of the unistr.h include file.
/*
**********************************************************************
*   Copyright (C) 1998-1999, International Business Machines
*   Corporation and others.  All Rights Reserved.
**********************************************************************
*
* File unistr.h
*
* Modification History:
*
*   Date        Name        Description
*   09/25/98    stephen     Creation.
*   11/11/98    stephen     Changed per 11/9 code review.
*   04/20/99    stephen     Overhauled per 4/16 code review.
*   11/18/99    aliu        Made to inherit from Replaceable.  Added method
*                           handleReplaceBetween(); other methods unchanged.
*******************************************************************************
*/

#ifndef UNISTR_H
#define UNISTR_H

#include <limits.h>

#include "unicode/utypes.h"
#include "unicode/unicode.h"
#include "unicode/ucnv.h"
#include "unicode/rep.h"

class Locale;
class UCharReference;
class UnicodeStringStreamer;
class UnicodeConverter;

// for unistrm.h
#if U_IOSTREAM_SOURCE >= 199711
#include <iostream>
U_COMMON_API std::ostream &operator<<(std::ostream& stream, const UnicodeString& s);
#elif U_IOSTREAM_SOURCE >= 198506
#include <iostream.h>
U_COMMON_API ostream &operator<<(ostream& stream, const UnicodeString& s);
#endif

#if U_SIZEOF_WCHAR_T==U_SIZEOF_UCHAR && U_CHARSET_FAMILY==U_ASCII_FAMILY
#   define UNICODE_STRING(cs, length) UnicodeString(TRUE, (UChar *)L ## cs, length)
#elif U_SIZEOF_UCHAR==1 && U_CHARSET_FAMILY==U_ASCII_FAMILY
#   define UNICODE_STRING(cs, length) UnicodeString(TRUE, (UChar *)cs, length)
#else
#   define UNICODE_STRING(cs, length) UnicodeString(cs, length, "")
#endif

class U_COMMON_API UnicodeString : public Replaceable
{
public:

  //========================================
  // Read-only operations
  //========================================
  
  /* Comparison - bitwise only - for international comparison use collation */
  
  inline UBool operator== (const UnicodeString& text) const;
  
  inline UBool operator!= (const UnicodeString& text) const;

  inline UBool operator> (const UnicodeString& text) const;

  inline UBool operator< (const UnicodeString& text) const;

  inline UBool operator>= (const UnicodeString& text) const;

  inline UBool operator<= (const UnicodeString& text) const;

  inline int8_t compare(const UnicodeString& text) const;

  inline int8_t compare(UTextOffset start,
         int32_t length,
         const UnicodeString& srcText) const;

   inline int8_t compare(UTextOffset start,
         int32_t length,
         const UnicodeString& srcText,
         UTextOffset srcStart,
         int32_t srcLength) const;

  inline int8_t compare(const UChar *srcChars,
         int32_t srcLength) const;

  inline int8_t compare(UTextOffset start,
         int32_t length,
         const UChar *srcChars) const;

  inline int8_t compare(UTextOffset start,
         int32_t length,
         const UChar *srcChars,
         UTextOffset srcStart,
         int32_t srcLength) const;

  inline int8_t compareBetween(UTextOffset start,
            UTextOffset limit,
            const UnicodeString& srcText,
            UTextOffset srcStart,
            UTextOffset srcLimit) const;

  inline UBool startsWith(const UnicodeString& text) const;

  inline UBool startsWith(const UnicodeString& srcText,
            UTextOffset srcStart,
            int32_t srcLength) const;
  
  inline UBool startsWith(const UChar *srcChars,
            int32_t srcLength) const;
 
  inline UBool startsWith(const UChar *srcChars,
            UTextOffset srcStart,
            int32_t srcLength) const;

  inline UBool endsWith(const UnicodeString& text) const;

  inline UBool endsWith(const UnicodeString& srcText,
          UTextOffset srcStart,
          int32_t srcLength) const;

  inline UBool endsWith(const UChar *srcChars,
          int32_t srcLength) const;
 
  inline UBool endsWith(const UChar *srcChars,
          UTextOffset srcStart,
          int32_t srcLength) const;

 
  /* Searching - bitwise only */

  inline UTextOffset indexOf(const UnicodeString& text) const;

  inline UTextOffset indexOf(const UnicodeString& text,
              UTextOffset start) const;

  inline UTextOffset indexOf(const UnicodeString& text,
              UTextOffset start,
              int32_t length) const;

  inline UTextOffset indexOf(const UnicodeString& srcText,
              UTextOffset srcStart,
              int32_t srcLength,
              UTextOffset start,
              int32_t length) const;

  inline UTextOffset indexOf(const UChar *srcChars,
              int32_t srcLength,
              UTextOffset start) const;

  inline UTextOffset indexOf(const UChar *srcChars,
              int32_t srcLength,
              UTextOffset start,
              int32_t length) const;
 
  UTextOffset indexOf(const UChar *srcChars,
              UTextOffset srcStart,
              int32_t srcLength,
              UTextOffset start,
              int32_t length) const;

  inline UTextOffset indexOf(UChar c) const;

  inline UTextOffset indexOf(UChar32 c) const;

  inline UTextOffset indexOf(UChar c,
              UTextOffset start) const;

  inline UTextOffset indexOf(UChar32 c,
              UTextOffset start) const;

  inline UTextOffset indexOf(UChar c,
              UTextOffset start,
              int32_t length) const;

  inline UTextOffset indexOf(UChar32 c,
              UTextOffset start,
              int32_t length) const;

  inline UTextOffset lastIndexOf(const UnicodeString& text) const;

  inline UTextOffset lastIndexOf(const UnicodeString& text,
              UTextOffset start) const;

  inline UTextOffset lastIndexOf(const UnicodeString& text,
              UTextOffset start,
              int32_t length) const;

  inline UTextOffset lastIndexOf(const UnicodeString& srcText,
              UTextOffset srcStart,
              int32_t srcLength,
              UTextOffset start,
              int32_t length) const;

  inline UTextOffset lastIndexOf(const UChar *srcChars,
              int32_t srcLength,
              UTextOffset start) const;

  inline UTextOffset lastIndexOf(const UChar *srcChars,
              int32_t srcLength,
              UTextOffset start,
              int32_t length) const;
 
  UTextOffset lastIndexOf(const UChar *srcChars,
              UTextOffset srcStart,
              int32_t srcLength,
              UTextOffset start,
              int32_t length) const;

  inline UTextOffset lastIndexOf(UChar c) const;

  inline UTextOffset lastIndexOf(UChar32 c) const;

  inline UTextOffset lastIndexOf(UChar c,
              UTextOffset start) const;

  inline UTextOffset lastIndexOf(UChar32 c,
              UTextOffset start) const;

  inline UTextOffset lastIndexOf(UChar c,
              UTextOffset start,
              int32_t length) const;

  inline UTextOffset lastIndexOf(UChar32 c,
              UTextOffset start,
              int32_t length) const;


  /* Character access */

  inline UChar charAt(UTextOffset offset) const;

  inline UChar operator [] (UTextOffset offset) const;

  inline UChar32 char32At(UTextOffset offset) const;

  inline UTextOffset getCharStart(UTextOffset offset);

  inline UTextOffset getCharLimit(UTextOffset offset);

  /* Substring extraction */

  inline void extract(UTextOffset start, 
           int32_t length, 
           UChar *dst, 
           UTextOffset dstStart = 0) const;
  
  inline void extract(UTextOffset start,
           int32_t length,
           UnicodeString& target) const;

  inline void extractBetween(UTextOffset start, 
              UTextOffset limit, 
              UChar *dst, 
              UTextOffset dstStart = 0) const;

  inline void extractBetween(UTextOffset start,
              UTextOffset limit,
              UnicodeString& target) const;

  int32_t extract(UTextOffset start,
           int32_t length,
           char *dst,
           const char *codepage = 0) const;
  

  /* Length operations */

  inline int32_t  length(void) const;

  inline UBool empty(void) const;

 
  /* Other operations */

  inline int32_t hashCode(void) const;

  inline UBool isBogus(void) const;

  
  //========================================
  // Write operations
  //========================================

  /* Assignment operations */

   UnicodeString& operator= (const UnicodeString& srcText);

  inline UnicodeString& operator= (UChar ch);

  inline UnicodeString& operator= (UChar32 ch);

  inline UnicodeString& setTo(const UnicodeString& srcText, 
               UTextOffset srcStart, 
               int32_t srcLength);

  inline UnicodeString& setTo(const UnicodeString& srcText);

  inline UnicodeString& setTo(const UChar *srcChars,
               int32_t srcLength);

  UnicodeString& setTo(UChar srcChar);

  UnicodeString& setTo(UChar32 srcChar);

  UnicodeString &setTo(UBool isTerminated,
                       const UChar *text,
                       int32_t textLength);

  UnicodeString &setTo(UChar *buffer,
                       int32_t buffLength,
                       int32_t buffCapacity);

  UnicodeString& setCharAt(UTextOffset offset, 
               UChar ch);


  /* Append operations */

 inline  UnicodeString& operator+= (UChar ch);

 inline  UnicodeString& operator+= (UChar32 ch);

  inline UnicodeString& operator+= (const UnicodeString& srcText);

  inline UnicodeString& append(const UnicodeString& srcText, 
            UTextOffset srcStart, 
            int32_t srcLength);

  inline UnicodeString& append(const UnicodeString& srcText);

  inline UnicodeString& append(const UChar *srcChars, 
            UTextOffset srcStart, 
            int32_t srcLength);

  inline UnicodeString& append(const UChar *srcChars,
            int32_t srcLength);

  inline UnicodeString& append(UChar srcChar);

  inline UnicodeString& append(UChar32 srcChar);


  /* Insert operations */

  inline UnicodeString& insert(UTextOffset start, 
            const UnicodeString& srcText, 
            UTextOffset srcStart, 
            int32_t srcLength);

  inline UnicodeString& insert(UTextOffset start, 
            const UnicodeString& srcText);

  inline UnicodeString& insert(UTextOffset start, 
            const UChar *srcChars, 
            UTextOffset srcStart, 
            int32_t srcLength);

  inline UnicodeString& insert(UTextOffset start, 
            const UChar *srcChars,
            int32_t srcLength);

  inline UnicodeString& insert(UTextOffset start, 
            UChar srcChar);

  inline UnicodeString& insert(UTextOffset start, 
            UChar32 srcChar);


  /* Replace operations */

  UnicodeString& replace(UTextOffset start, 
             int32_t length, 
             const UnicodeString& srcText, 
             UTextOffset srcStart, 
             int32_t srcLength);

  UnicodeString& replace(UTextOffset start, 
             int32_t length, 
             const UnicodeString& srcText);

  UnicodeString& replace(UTextOffset start, 
             int32_t length, 
             const UChar *srcChars, 
             UTextOffset srcStart, 
             int32_t srcLength);

  inline UnicodeString& replace(UTextOffset start, 
             int32_t length, 
             const UChar *srcChars,
             int32_t srcLength);

  inline UnicodeString& replace(UTextOffset start, 
             int32_t length, 
             UChar srcChar);

  inline UnicodeString& replace(UTextOffset start, 
             int32_t length, 
             UChar32 srcChar);

  inline UnicodeString& replaceBetween(UTextOffset start, 
                UTextOffset limit, 
                const UnicodeString& srcText);

  inline UnicodeString& replaceBetween(UTextOffset start, 
                UTextOffset limit, 
                const UnicodeString& srcText, 
                UTextOffset srcStart, 
                UTextOffset srcLimit);

  virtual void handleReplaceBetween(UTextOffset start,
                                    UTextOffset limit,
                                    const UnicodeString& text);

  virtual void copy(int32_t start, int32_t limit, int32_t dest);

  /* Search and replace operations */

  inline UnicodeString& findAndReplace(const UnicodeString& oldText,
                const UnicodeString& newText);

  inline UnicodeString& findAndReplace(UTextOffset start,
                int32_t length,
                const UnicodeString& oldText,
                const UnicodeString& newText);

  UnicodeString& findAndReplace(UTextOffset start,
                int32_t length,
                const UnicodeString& oldText,
                UTextOffset oldStart,
                int32_t oldLength,
                const UnicodeString& newText,
                UTextOffset newStart,
                int32_t newLength);


  /* Remove operations */

  inline UnicodeString& remove(void);

  inline UnicodeString& remove(UTextOffset start, 
                               int32_t length = INT32_MAX);

  inline UnicodeString& removeBetween(UTextOffset start,
                                      UTextOffset limit = INT32_MAX);


  /* Length operations */

  UBool padLeading(int32_t targetLength,
                    UChar padChar = 0x0020);

  UBool padTrailing(int32_t targetLength,
                     UChar padChar = 0x0020);

  inline UBool truncate(int32_t targetLength);

  UnicodeString& trim(void);


  /* Miscellaneous operations */

  inline UnicodeString& reverse(void);

  inline UnicodeString& reverse(UTextOffset start,
             int32_t length);

  UnicodeString& toUpper(void);

  UnicodeString& toUpper(const Locale& locale);

  UnicodeString& toLower(void);

  UnicodeString& toLower(const Locale& locale);


  //========================================
  // Constructors
  //========================================

  UnicodeString();

  UnicodeString(int32_t capacity, UChar32 c, int32_t count);

  UnicodeString(UChar ch);

  UnicodeString(UChar32 ch);

  UnicodeString(const UChar *text);

  UnicodeString(const UChar *text,
        int32_t textLength);

  UnicodeString(UBool isTerminated,
                const UChar *text,
                int32_t textLength);

  UnicodeString(UChar *buffer, int32_t buffLength, int32_t buffCapacity);

  UnicodeString(const char *codepageData,
        const char *codepage = 0);

  UnicodeString(const char *codepageData,
        int32_t dataLength,
        const char *codepage = 0);

  UnicodeString(const UnicodeString& that);

  ~UnicodeString();


  /* Miscellaneous operations */

  int32_t numDisplayCells(UTextOffset start = 0,
              int32_t length = INT32_MAX,
              UBool asian = TRUE) const;


  UCharReference operator[] (UTextOffset pos);

  UnicodeString unescape() const;

  UChar32 unescapeAt(int32_t &offset) const;

  //========================================
  // Implementation methods
  //========================================
  
private:

  inline int8_t
  doCompare(UTextOffset start,
           int32_t length,
           const UnicodeString& srcText,
           UTextOffset srcStart,
           int32_t srcLength) const;
  
  int8_t doCompare(UTextOffset start,
           int32_t length,
           const UChar *srcChars,
           UTextOffset srcStart,
           int32_t srcLength) const;

  UTextOffset doIndexOf(UChar c,
            UTextOffset start,
            int32_t length) const;

  UTextOffset doLastIndexOf(UChar c,
                UTextOffset start,
                int32_t length) const;

  void doExtract(UTextOffset start, 
         int32_t length, 
         UChar *dst, 
         UTextOffset dstStart) const;
  
  inline void doExtract(UTextOffset start,
         int32_t length,
         UnicodeString& target) const;
  
  inline UChar doCharAt(UTextOffset offset)  const;

  UnicodeString& doReplace(UTextOffset start, 
               int32_t length, 
               const UnicodeString& srcText, 
               UTextOffset srcStart, 
               int32_t srcLength);

  UnicodeString& doReplace(UTextOffset start, 
               int32_t length, 
               const UChar *srcChars, 
               UTextOffset srcStart, 
               int32_t srcLength);

  UnicodeString& doReverse(UTextOffset start,
               int32_t length);

  // calculate hash code
  int32_t doHashCode(void) const;
  
  // get pointer to start of array
  inline UChar* getArrayStart(void);
  inline const UChar* getArrayStart(void) const;

  // get the "real" capacity of the array, adjusted for ref count
  inline int32_t getCapacity(void) const;

  // allocate the array; result may be fStackBuffer
  // sets refCount to 1 if appropriate
  // sets fArray, fCapacity, and fFlags
  // returns boolean for success or failure
  UBool allocate(int32_t capacity);

  // release the array if owned
  inline void releaseArray();

  // utility method to get around lack of exception handling
  void setToBogus(void);

  // Pin start and limit to acceptable values.
  inline void pinIndices(UTextOffset& start,
                         int32_t& length) const;

  /*
   * Real constructor for converting from codepage data.
   * It assumes that it is called with !fRefCounted.
   *
   * If <code>codepage==0</code>, then the default converter
   * is used for the platform encoding.
   * If <code>codepage</code> is an empty string (<code>""</code>),
   * then a simple conversion is performed on the codepage-invariant
   * subset ("invariant characters") of the platform encoding. See utypes.h.
   */
  void doCodepageCreate(const char *codepageData,
                        int32_t dataLength,
                        const char *codepage);

  /*
   * This function is called when write access to the array
   * is necessary.
   *
   * We need to make a copy of the array if
   * the buffer is read-only, or
   * the buffer is refCounted (shared), and refCount>1, or
   * the buffer is too small.
   *
   * Return FALSE if memory could not be allocated.
   */
  UBool cloneArrayIfNeeded(int32_t newCapacity = -1,
                            int32_t growCapacity = -1,
                            UBool doCopyArray = TRUE,
                            int32_t **pBufferToDelete = 0);

  // ref counting
  inline int32_t addRef(void);
  inline int32_t removeRef(void);
  inline int32_t refCount(void) const;
  inline int32_t setRefCount(int32_t count);

  // constants
  enum {
#if UTF_SIZE==8
    US_STACKBUF_SIZE=14, // Size of stack buffer for small strings
#elif UTF_SIZE==16
    US_STACKBUF_SIZE=7, // Size of stack buffer for small strings
#else // UTF_SIZE==32
    US_STACKBUF_SIZE=3, // Size of stack buffer for small strings
#endif
    kInvalidUChar=0xffff, // invalid UChar index
    kGrowSize=128, // grow size for this buffer
    kInvalidHashCode=0, // invalid hash code
    kEmptyHashCode=1, // hash code for empty string

    // bit flag values for fFlags
    kIsBogus=1, // this string is bogus, i.e., not valid
    kUsingStackBuffer=2, // fArray==fStackBuffer
    kRefCounted=4, // there is a refCount field before the characters in fArray
    kBufferIsReadonly=8, // do not write to this buffer

    // combined values for convenience
    kShortString=kUsingStackBuffer,
    kLongString=kRefCounted,
    kReadonlyAlias=kBufferIsReadonly,
    kWriteableAlias=0
  };

  // statics

  // default converter cache
  static UConverter* getDefaultConverter(UErrorCode& status);
  static void releaseDefaultConverter(UConverter *converter);

  static UConverter *fgDefaultConverter;

  friend class UnicodeStringStreamer;
  friend class UnicodeConverter;

#if U_IOSTREAM_SOURCE >= 199711
  friend U_COMMON_API std::ostream &operator<<(std::ostream& stream, const UnicodeString& s);
#elif U_IOSTREAM_SOURCE >= 198506
  friend U_COMMON_API ostream &operator<<(ostream& stream, const UnicodeString& s);
#endif

  friend class StringCharacterIterator;

  /*
   * The following are all the class fields that are stored
   * in each UnicodeString object.
   * Note that UnicodeString has virtual functions,
   * therefore there is an implicit vtable pointer
   * as the first real field.
   * The fields should be aligned such that no padding is
   * necessary, mostly by having larger types first.
   * On 32-bit machines, the size should be 32 bytes,
   * on 64-bit machines (8-byte pointers), it should be 40 bytes.
   */
  // (implicit) *vtable;
  UChar     *fArray;        // the Unicode data
  int32_t   fLength;        // number characters in fArray
  int32_t   fCapacity;      // sizeof fArray
  uint16_t  fFlags;         // bit flags: see constants above
#if UTF_SIZE==32
  uint16_t  fPadding;       // padding to align the fStackBuffer for UTF-32
#endif
  UChar     fStackBuffer [ US_STACKBUF_SIZE ]; // buffer for small strings

public:

  //========================================
  // Deprecated API
  //========================================

  /* size() -> length()
   * @deprecated */
  inline int32_t size(void) const;

  // parameters reordered for consistency
   /* @deprecated */
  inline UnicodeString& findAndReplace(const UnicodeString& oldText,
                const UnicodeString& newText,
                UTextOffset start,
                int32_t length);

   /* @deprecated */
  inline void* operator new(size_t size);
   /* @deprecated */
  inline void* operator new(size_t size, void *location);
   /* @deprecated */
  inline void operator delete(void *location);

  //========================================
  // Non-public API - will be removed!
  //========================================
  /* @deprecated */
  const UChar* getUChars() const;
};

//========================================
// Array copying
//========================================
// Copy an array of UnicodeString OBJECTS (not pointers).
inline void 
uprv_arrayCopy(const UnicodeString *src, UnicodeString *dst, int32_t count)
{ while(count-- > 0) *dst++ = *src++; }

inline void 
uprv_arrayCopy(const UnicodeString *src, int32_t srcStart, 
        UnicodeString *dst, int32_t dstStart, int32_t count)
{ uprv_arrayCopy(src+srcStart, dst+dstStart, count); }


//========================================
// Inline members
//========================================

//========================================
// Read-only alias methods
//========================================
inline UBool
UnicodeString::operator== (const UnicodeString& text) const
{
  if(isBogus()) {
    return text.isBogus();
  } else {
    return
      !text.isBogus() &&
      fLength == text.fLength &&
      doCompare(0, fLength, text, 0, text.fLength) == 0;
  }
}

inline UBool
UnicodeString::operator!= (const UnicodeString& text) const
{ return (! operator==(text)); }

inline UBool
UnicodeString::operator> (const UnicodeString& text) const
{ return doCompare(0, fLength, text, 0, text.fLength) == 1; }

inline UBool
UnicodeString::operator< (const UnicodeString& text) const
{ return doCompare(0, fLength, text, 0, text.fLength) == -1; }

inline UBool
UnicodeString::operator>= (const UnicodeString& text) const
{ return doCompare(0, fLength, text, 0, text.fLength) != -1; }

inline UBool
UnicodeString::operator<= (const UnicodeString& text) const
{ return doCompare(0, fLength, text, 0, text.fLength) != 1; }

inline int8_t 
UnicodeString::compare(const UnicodeString& text) const
{ return doCompare(0, fLength, text, 0, text.fLength); }

inline int8_t 
UnicodeString::compare(UTextOffset start,
               int32_t length,
               const UnicodeString& srcText) const
{ return doCompare(start, length, srcText, 0, srcText.fLength); }

inline int8_t 
UnicodeString::compare(const UChar *srcChars,
               int32_t srcLength) const
{ return doCompare(0, fLength, srcChars, 0, srcLength); }

inline int8_t 
UnicodeString::compare(UTextOffset start,
               int32_t length,
               const UnicodeString& srcText,
               UTextOffset srcStart,
               int32_t srcLength) const
{ return doCompare(start, length, srcText, srcStart, srcLength); }

inline int8_t
UnicodeString::compare(UTextOffset start,
               int32_t length,
               const UChar *srcChars) const
{ return doCompare(start, length, srcChars, 0, length); }

inline int8_t 
UnicodeString::compare(UTextOffset start,
               int32_t length,
               const UChar *srcChars,
               UTextOffset srcStart,
               int32_t srcLength) const
{ return doCompare(start, length, srcChars, srcStart, srcLength); }

inline int8_t
UnicodeString::compareBetween(UTextOffset start,
                  UTextOffset limit,
                  const UnicodeString& srcText,
                  UTextOffset srcStart,
                  UTextOffset srcLimit) const
{ return doCompare(start, limit - start, 
           srcText, srcStart, srcLimit - srcStart); }

inline int8_t
UnicodeString::doCompare(UTextOffset start,
              int32_t length,
              const UnicodeString& srcText,
              UTextOffset srcStart,
              int32_t srcLength) const
{
  const UChar *srcChars;
  if(!srcText.isBogus()) {
    srcText.pinIndices(srcStart, srcLength);
    srcChars=srcText.getArrayStart();
  } else {
    srcChars=0;
  }
  return doCompare(start, length, srcChars, srcStart, srcLength);
}

inline UTextOffset 
UnicodeString::indexOf(const UnicodeString& text) const
{ return indexOf(text, 0, text.fLength, 0, fLength); }

inline UTextOffset 
UnicodeString::indexOf(const UnicodeString& text,
               UTextOffset start) const
{ return indexOf(text, 0, text.fLength, start, fLength - start); }

inline UTextOffset 
UnicodeString::indexOf(const UnicodeString& text,
               UTextOffset start,
               int32_t length) const
{ return indexOf(text, 0, text.fLength, start, length); }

inline UTextOffset 
UnicodeString::indexOf(const UnicodeString& srcText,
               UTextOffset srcStart,
               int32_t srcLength,
               UTextOffset start,
               int32_t length) const
{
  if(!srcText.isBogus()) {
    srcText.pinIndices(srcStart, srcLength);
    if(srcLength > 0) {
      return indexOf(srcText.getArrayStart(), srcStart, srcLength, start, length);
    }
  }
  return -1;
}

inline UTextOffset 
UnicodeString::indexOf(const UChar *srcChars,
               int32_t srcLength,
               UTextOffset start) const
{ return indexOf(srcChars, 0, srcLength, start, fLength - start); }

inline UTextOffset 
UnicodeString::indexOf(const UChar *srcChars,
               int32_t srcLength,
               UTextOffset start,
               int32_t length) const
{ return indexOf(srcChars, 0, srcLength, start, length); }

inline UTextOffset 
UnicodeString::indexOf(UChar c) const
{ return doIndexOf(c, 0, fLength); }

inline UTextOffset 
UnicodeString::indexOf(UChar32 c) const {
  if(!UTF_NEED_MULTIPLE_UCHAR(c)) {
    return doIndexOf((UChar)c, 0, fLength);
  } else {
    UChar buffer[UTF_MAX_CHAR_LENGTH];
    int32_t length = 0;
    UTF_APPEND_CHAR_UNSAFE(buffer, length, c);
    return indexOf(buffer, length, 0);
  }
}

inline UTextOffset 
UnicodeString::indexOf(UChar c,
               UTextOffset start) const
{ return doIndexOf(c, start, fLength - start); }

inline UTextOffset 
UnicodeString::indexOf(UChar32 c,
               UTextOffset start) const {
  if(!UTF_NEED_MULTIPLE_UCHAR(c)) {
    return doIndexOf((UChar)c, start, fLength - start);
  } else {
    UChar buffer[UTF_MAX_CHAR_LENGTH];
    int32_t length = 0;
    UTF_APPEND_CHAR_UNSAFE(buffer, length, c);
    return indexOf(buffer, length, start);
  }
}

inline UTextOffset 
UnicodeString::indexOf(UChar c,
               UTextOffset start,
               int32_t length) const
{ return doIndexOf(c, start, length); }

inline UTextOffset 
UnicodeString::indexOf(UChar32 c,
               UTextOffset start,
               int32_t length) const {
  if(!UTF_NEED_MULTIPLE_UCHAR(c)) {
    return doIndexOf((UChar)c, start, length);
  } else {
    UChar buffer[UTF_MAX_CHAR_LENGTH];
    int32_t cLength = 0;
    UTF_APPEND_CHAR_UNSAFE(buffer, cLength, c);
    return indexOf(buffer, cLength, start, length);
  }
}

inline UTextOffset 
UnicodeString::lastIndexOf(const UnicodeString& text) const
{ return lastIndexOf(text, 0, text.fLength, 0, fLength); }

inline UTextOffset 
UnicodeString::lastIndexOf(const UnicodeString& text,
               UTextOffset start) const
{ return lastIndexOf(text, 0, text.fLength, start, fLength - start); }

inline UTextOffset 
UnicodeString::lastIndexOf(const UnicodeString& text,
               UTextOffset start,
               int32_t length) const
{ return lastIndexOf(text, 0, text.fLength, start, length); }

inline UTextOffset 
UnicodeString::lastIndexOf(const UnicodeString& srcText,
               UTextOffset srcStart,
               int32_t srcLength,
               UTextOffset start,
               int32_t length) const
{
  if(!srcText.isBogus()) {
    srcText.pinIndices(srcStart, srcLength);
    if(srcLength > 0) {
      return lastIndexOf(srcText.getArrayStart(), srcStart, srcLength, start, length);
    }
  }
  return -1;
}

inline UTextOffset 
UnicodeString::lastIndexOf(const UChar *srcChars,
               int32_t srcLength,
               UTextOffset start) const
{ return lastIndexOf(srcChars, 0, srcLength, start, fLength - start); }

inline UTextOffset 
UnicodeString::lastIndexOf(const UChar *srcChars,
               int32_t srcLength,
               UTextOffset start,
               int32_t length) const
{ return lastIndexOf(srcChars, 0, srcLength, start, length); }

inline UTextOffset 
UnicodeString::lastIndexOf(UChar c) const
{ return doLastIndexOf(c, 0, fLength); }

inline UTextOffset 
UnicodeString::lastIndexOf(UChar32 c) const {
  if(!UTF_NEED_MULTIPLE_UCHAR(c)) {
    return doLastIndexOf((UChar)c, 0, fLength);
  } else {
    UChar buffer[UTF_MAX_CHAR_LENGTH];
    int32_t count = 0;
    UTF_APPEND_CHAR_UNSAFE(buffer, count, c);
    return lastIndexOf(buffer, count, 0);
  }
}

inline UTextOffset 
UnicodeString::lastIndexOf(UChar c,
               UTextOffset start) const
{ return doLastIndexOf(c, start, fLength - start); }

inline UTextOffset 
UnicodeString::lastIndexOf(UChar32 c,
               UTextOffset start) const {
  if(!UTF_NEED_MULTIPLE_UCHAR(c)) {
    return doLastIndexOf((UChar)c, start, fLength - start);
  } else {
    UChar buffer[UTF_MAX_CHAR_LENGTH];
    int32_t count = 0;
    UTF_APPEND_CHAR_UNSAFE(buffer, count, c);
    return lastIndexOf(buffer, count, start);
  }
}

inline UTextOffset 
UnicodeString::lastIndexOf(UChar c,
               UTextOffset start,
               int32_t length) const
{ return doLastIndexOf(c, start, length); }

inline UTextOffset 
UnicodeString::lastIndexOf(UChar32 c,
               UTextOffset start,
               int32_t length) const {
  if(!UTF_NEED_MULTIPLE_UCHAR(c)) {
    return doLastIndexOf((UChar)c, start, length);
  } else {
    UChar buffer[UTF_MAX_CHAR_LENGTH];
    int32_t count = 0;
    UTF_APPEND_CHAR_UNSAFE(buffer, count, c);
    return lastIndexOf(buffer, count, start, length);
  }
}

inline UBool 
UnicodeString::startsWith(const UnicodeString& text) const
{ return compare(0, text.fLength, text, 0, text.fLength) == 0; }

inline UBool 
UnicodeString::startsWith(const UnicodeString& srcText,
              UTextOffset srcStart,
              int32_t srcLength) const
{ return doCompare(0, srcLength, srcText, srcStart, srcLength) == 0; }

inline UBool 
UnicodeString::startsWith(const UChar *srcChars,
              int32_t srcLength) const
{ return doCompare(0, srcLength, srcChars, 0, srcLength) == 0; }

inline UBool 
UnicodeString::startsWith(const UChar *srcChars,
              UTextOffset srcStart,
              int32_t srcLength) const
{ return doCompare(0, srcLength, srcChars, srcStart, srcLength) == 0;}

inline UBool 
UnicodeString::endsWith(const UnicodeString& text) const
{ return doCompare(fLength - text.fLength, text.fLength, 
           text, 0, text.fLength) == 0; }

inline UBool 
UnicodeString::endsWith(const UnicodeString& srcText,
            UTextOffset srcStart,
            int32_t srcLength) const
{ return doCompare(fLength - srcLength, srcLength, 
           srcText, srcStart, srcLength) == 0; }

inline UBool 
UnicodeString::endsWith(const UChar *srcChars,
            int32_t srcLength) const
{ return doCompare(fLength - srcLength, srcLength, 
           srcChars, 0, srcLength) == 0; }

inline UBool 
UnicodeString::endsWith(const UChar *srcChars,
            UTextOffset srcStart,
            int32_t srcLength) const
{ return doCompare(fLength - srcLength, srcLength, 
           srcChars, srcStart, srcLength) == 0;}
//========================================
// replace
//========================================
inline UnicodeString& 
UnicodeString::replace(UTextOffset start, 
               int32_t length, 
               const UnicodeString& srcText) 
{ return doReplace(start, length, srcText, 0, srcText.fLength); }

inline UnicodeString& 
UnicodeString::replace(UTextOffset start, 
               int32_t length, 
               const UnicodeString& srcText, 
               UTextOffset srcStart, 
               int32_t srcLength)
{ return doReplace(start, length, srcText, srcStart, srcLength); }

inline UnicodeString& 
UnicodeString::replace(UTextOffset start, 
               int32_t length, 
               const UChar *srcChars,
               int32_t srcLength)
{ return doReplace(start, length, srcChars, 0, srcLength); }

inline UnicodeString& 
UnicodeString::replace(UTextOffset start, 
               int32_t length, 
               const UChar *srcChars, 
               UTextOffset srcStart, 
               int32_t srcLength)
{ return doReplace(start, length, srcChars, srcStart, srcLength); }

inline UnicodeString& 
UnicodeString::replace(UTextOffset start, 
               int32_t length, 
               UChar srcChar)
{ return doReplace(start, length, &srcChar, 0, 1); }

inline UnicodeString&
UnicodeString::replace(UTextOffset start, 
               int32_t length, 
               UChar32 srcChar) {
  UChar buffer[UTF_MAX_CHAR_LENGTH];
  int32_t count = 0;
  UTF_APPEND_CHAR_UNSAFE(buffer, count, srcChar);
  return doReplace(start, length, buffer, 0, count);
}

inline UnicodeString& 
UnicodeString::replaceBetween(UTextOffset start, 
                  UTextOffset limit, 
                  const UnicodeString& srcText)
{ return doReplace(start, limit - start, srcText, 0, srcText.fLength); }

inline UnicodeString&
UnicodeString::replaceBetween(UTextOffset start, 
                  UTextOffset limit, 
                  const UnicodeString& srcText, 
                  UTextOffset srcStart, 
                  UTextOffset srcLimit)
{ return doReplace(start, limit - start, srcText, srcStart, srcLimit - srcStart); }

inline UnicodeString& 
UnicodeString::findAndReplace(const UnicodeString& oldText,
                  const UnicodeString& newText)
{ return findAndReplace(0, fLength, oldText, 0, oldText.fLength, 
            newText, 0, newText.fLength); }

inline UnicodeString& 
UnicodeString::findAndReplace(UTextOffset start,
                  int32_t length,
                  const UnicodeString& oldText,
                  const UnicodeString& newText)
{ return findAndReplace(start, length, oldText, 0, oldText.fLength, 
            newText, 0, newText.fLength); }

// ============================
// extract
// ============================
inline void
UnicodeString::doExtract(UTextOffset start,
             int32_t length,
             UnicodeString& target) const
{ target.replace(0, target.fLength, *this, start, length); }

inline void  
UnicodeString::extract(UTextOffset start, 
               int32_t length, 
               UChar *dst, 
               UTextOffset dstStart) const
{ doExtract(start, length, dst, dstStart); }

inline void 
UnicodeString::extract(UTextOffset start,
               int32_t length,
               UnicodeString& target) const
{ doExtract(start, length, target); }

inline void  
UnicodeString::extractBetween(UTextOffset start, 
                  UTextOffset limit, 
                  UChar *dst, 
                  UTextOffset dstStart) const
{ doExtract(start, limit - start, dst, dstStart); }

inline void 
UnicodeString::extractBetween(UTextOffset start,
                  UTextOffset limit,
                  UnicodeString& target) const
{ doExtract(start, limit - start, target); }

inline UChar
UnicodeString::doCharAt(UTextOffset offset) const
{
  if((uint32_t)offset < (uint32_t)fLength) {
    return fArray[offset];
  } else {
    return kInvalidUChar;
  }
}

inline UChar
UnicodeString::charAt(UTextOffset offset) const
{ return doCharAt(offset); }

inline UChar
UnicodeString::operator[] (UTextOffset offset) const
{ return doCharAt(offset); }

inline UChar32
UnicodeString::char32At(UTextOffset offset) const
{
  if((uint32_t)offset < (uint32_t)fLength) {
    UChar32 c;
    UTF_GET_CHAR(fArray, 0, offset, fLength, c);
    return c;
  } else {
    return kInvalidUChar;
  }
}

inline UTextOffset
UnicodeString::getCharStart(UTextOffset offset) {
  if((uint32_t)offset < (uint32_t)fLength) {
    UTF_SET_CHAR_START(fArray, 0, offset);
    return offset;
  } else {
    return 0;
  }
}

inline UTextOffset
UnicodeString::getCharLimit(UTextOffset offset) {
  if((uint32_t)offset < (uint32_t)fLength) {
    UTF_SET_CHAR_LIMIT(fArray, 0, offset, fLength);
    return offset;
  } else {
    return fLength;
  }
}

inline UBool
UnicodeString::empty() const
{ return fLength == 0; }

//========================================
// Read-only implementation methods
//========================================
inline int32_t  
UnicodeString::length() const
{ return fLength; }

inline int32_t 
UnicodeString::hashCode() const
{ return doHashCode(); }

//========================================
// Write alias methods
//========================================
inline UnicodeString& 
UnicodeString::operator= (UChar ch) 
{ return doReplace(0, fLength, &ch, 0, 1); }

inline UnicodeString& 
UnicodeString::operator= (UChar32 ch) 
{ return replace(0, fLength, ch); }

inline UnicodeString& 
UnicodeString::setTo(const UnicodeString& srcText, 
             UTextOffset srcStart, 
             int32_t srcLength)
{ return doReplace(0, fLength, srcText, srcStart, srcLength); }

inline UnicodeString& 
UnicodeString::setTo(const UnicodeString& srcText)
{ return doReplace(0, fLength, srcText, 0, srcText.fLength); }

inline UnicodeString& 
UnicodeString::setTo(const UChar *srcChars,
             int32_t srcLength)
{ return doReplace(0, fLength, srcChars, 0, srcLength); }

inline UnicodeString& 
UnicodeString::setTo(UChar srcChar)
{ return doReplace(0, fLength, &srcChar, 0, 1); }

inline UnicodeString& 
UnicodeString::setTo(UChar32 srcChar)
{ return replace(0, fLength, srcChar); }

inline UnicodeString& 
UnicodeString::operator+= (UChar ch)
{ return doReplace(fLength, 0, &ch, 0, 1); }

inline UnicodeString& 
UnicodeString::operator+= (UChar32 ch) {
  UChar buffer[UTF_MAX_CHAR_LENGTH];
  int32_t length = 0;
  UTF_APPEND_CHAR_UNSAFE(buffer, length, ch);
  return doReplace(fLength, 0, buffer, 0, length);
}

inline UnicodeString& 
UnicodeString::operator+= (const UnicodeString& srcText)
{ return doReplace(fLength, 0, srcText, 0, srcText.fLength); }

inline UnicodeString& 
UnicodeString::append(const UnicodeString& srcText, 
              UTextOffset srcStart, 
              int32_t srcLength)
{ return doReplace(fLength, 0, srcText, srcStart, srcLength); }

inline UnicodeString& 
UnicodeString::append(const UnicodeString& srcText)
{ return doReplace(fLength, 0, srcText, 0, srcText.fLength); }

inline UnicodeString& 
UnicodeString::append(const UChar *srcChars, 
              UTextOffset srcStart, 
              int32_t srcLength)
{ return doReplace(fLength, 0, srcChars, srcStart, srcLength); }

inline UnicodeString& 
UnicodeString::append(const UChar *srcChars,
              int32_t srcLength)
{ return doReplace(fLength, 0, srcChars, 0, srcLength); }

inline UnicodeString& 
UnicodeString::append(UChar srcChar)
{ return doReplace(fLength, 0, &srcChar, 0, 1); }

inline UnicodeString& 
UnicodeString::append(UChar32 srcChar) {
  UChar buffer[UTF_MAX_CHAR_LENGTH];
  int32_t length = 0;
  UTF_APPEND_CHAR_UNSAFE(buffer, length, srcChar);
  return doReplace(fLength, 0, buffer, 0, length);
}

inline UnicodeString& 
UnicodeString::insert(UTextOffset start, 
              const UnicodeString& srcText, 
              UTextOffset srcStart, 
              int32_t srcLength)
{ return doReplace(start, 0, srcText, srcStart, srcLength); }

inline UnicodeString& 
UnicodeString::insert(UTextOffset start, 
              const UnicodeString& srcText)
{ return doReplace(start, 0, srcText, 0, srcText.fLength); }

inline UnicodeString& 
UnicodeString::insert(UTextOffset start, 
              const UChar *srcChars, 
              UTextOffset srcStart, 
              int32_t srcLength)
{ return doReplace(start, 0, srcChars, srcStart, srcLength); }

inline UnicodeString& 
UnicodeString::insert(UTextOffset start, 
              const UChar *srcChars,
              int32_t srcLength)
{ return doReplace(start, 0, srcChars, 0, srcLength); }

inline UnicodeString& 
UnicodeString::insert(UTextOffset start, 
              UChar srcChar)
{ return doReplace(start, 0, &srcChar, 0, 1); }

inline UnicodeString& 
UnicodeString::insert(UTextOffset start, 
              UChar32 srcChar)
{ return replace(start, 0, srcChar); }


inline UnicodeString& 
UnicodeString::remove(UTextOffset start, 
             int32_t length)
{ return doReplace(start, length, 0, 0, 0); }

inline UnicodeString& 
UnicodeString::remove()
{ return doReplace(0, fLength, 0, 0, 0); }

inline UnicodeString& 
UnicodeString::removeBetween(UTextOffset start,
                UTextOffset limit)
{ return doReplace(start, limit - start, 0, 0, 0); }

inline UBool 
UnicodeString::truncate(int32_t targetLength)
{
  if((uint32_t)targetLength < (uint32_t)fLength) {
    fLength = targetLength;
    return TRUE;
  } else {
    return FALSE;
  }
}

inline UnicodeString& 
UnicodeString::reverse()
{ return doReverse(0, fLength); }

inline UnicodeString& 
UnicodeString::reverse(UTextOffset start,
               int32_t length)
{ return doReverse(start, length); }


//========================================
// Write implementation methods
//========================================
inline UBool 
UnicodeString::isBogus() const
{ return (UBool)(fFlags & kIsBogus); }


//========================================
// Privates
//========================================

inline void
UnicodeString::pinIndices(UTextOffset& start,
                          int32_t& length) const
{
  // pin indices
  if(start < 0) {
    start = 0;
  } else if(start > fLength) {
    start = fLength;
  }
  if(length < 0) {
    length = 0;
  } else if(length > (fLength - start)) {
    length = (fLength - start);
  }
}

inline UChar* 
UnicodeString::getArrayStart()
{ return fArray; }

inline const UChar* 
UnicodeString::getArrayStart() const
{ return fArray; }

inline int32_t 
UnicodeString::getCapacity() const
{ return fCapacity; }

inline void
UnicodeString::releaseArray() {
  if((fFlags & kRefCounted) && removeRef() == 0) {
    delete [] ((int32_t *)fArray - 1);
  }
}

inline int32_t
UnicodeString::addRef()
{ return ++*((int32_t *)fArray - 1); }

inline int32_t
UnicodeString::removeRef()
{ return --*((int32_t *)fArray - 1); }

inline int32_t
UnicodeString::refCount() const
{ return *((int32_t *)fArray - 1); }

inline int32_t
UnicodeString::setRefCount(int32_t count)
{ return (*((int32_t *)fArray - 1) = count); }


// deprecated API - remove later
inline int32_t
UnicodeString::size() const
{ return fLength; }

inline UnicodeString& 
UnicodeString::findAndReplace(const UnicodeString& oldText,
                  const UnicodeString& newText,
                  UTextOffset start,
                  int32_t length)
{ return findAndReplace(start, length, oldText, newText); }

inline void*
UnicodeString::operator new(size_t size)
{ return ::operator new(size); }

inline void* 
UnicodeString::operator new(size_t, 
              void *location)
{ return location; }

inline void
UnicodeString::operator delete(void *location)
{ ::operator delete(location); }


//========================================
// Static members
//========================================

//========================================
// class UCharReference
//========================================
class UCharReference
{
public:
  UCharReference();
  inline UCharReference(UnicodeString *string,
         UTextOffset pos);
  inline UCharReference(const UCharReference& that);
  ~UCharReference();

  inline UCharReference& operator= (const UCharReference& that);
  inline UCharReference& operator= (UChar c);

  inline operator UChar();

private:
  UnicodeString *fString;
  UTextOffset fPos;
};


//========================================
// Inline members
//========================================
inline
UCharReference::UCharReference(UnicodeString *string, 
                   UTextOffset pos)
  : fString(string), fPos(pos)
{}

inline
UCharReference::UCharReference(const UCharReference& that)
{ this->operator=(that); }

inline
UCharReference::~UCharReference()
{}

inline UCharReference&
UCharReference::operator= (const UCharReference& that)
{ fString->setCharAt(fPos, that.fString->charAt(that.fPos)); return *this; }

inline UCharReference& 
UCharReference::operator= (UChar c)
{ fString->setCharAt(fPos, c); return *this; }

inline
UCharReference::operator UChar()
{ return fString->charAt(fPos); }

#endif

Generated at Wed Aug 16 16:05:56 2000 for ICU1.6 by doxygen 1.0.0 written by Dimitri van Heesch, © 1997-1999