// ----------------------------------------------------------------------------
// FILE NAME: istring.hpp
//
// DESCRIPTION:
//   Declaration of the classes:
//     IString
//
// COPYRIGHT:
//   IBM Open Class Library
//   Licensed Materials - Property of IBM
//
//   5645-001
//   (C) Copyright IBM Corporation 1992, 1997  All Rights Reserved.
//
// Revision: 81 1.7.1.7 source/core/base/istring.hpp, appsupport, ioc.v400, 980918 
// ----------------------------------------------------------------------------

#ifndef _ISTRING_
#define _ISTRING_

#include <istream.hpp>
#include <ibase.hpp>
#include <istrenum.hpp>
#include <idatstrm.hpp>

extern "C"
{
    #include <limits.h>
}

#if __IBMCPP__ >= 400
#pragma namemangling(compat)
#endif

class IStringTest;
class IBuffer;
class IText;

#pragma enum(4)
#pragma pack(push,4)

class IC_EXPORTB IString
{
public:
/*------------------------- Constructors -------------------------------------*/
  IString           ( );
  IString           ( const IString &aString );
  IString           ( const IString *pIString );

  IString           ( int  anInt );
  IString           ( unsigned  anUnsigned );
  IString           ( long  aLong );
  IString           ( unsigned long  anUnsignedLong );
#ifdef _LONG_LONG
  IString           ( long long  aLongLong );
  IString           ( unsigned long long  anUnsignedLongLong );
#endif
  IString           ( short  aShort );
  IString           ( unsigned short  anUnsignedShort );
  IString           ( double  aDouble );

  IString           ( char  aChar );
  IString           ( unsigned char  anUnsignedChar );
  IString           ( signed char  aSignedChar);

  IString           ( const char  *pChar );
  IString           ( const unsigned char  *pUnsignedChar );
  IString           ( const signed char  *pSignedChar );

  IString           ( const void *pBuffer1,
                      unsigned    lenBuffer1,
                      char        padCharacter = ' ' );
  IString           ( const void *pBuffer1,
                      unsigned     lenBuffer1,
                      const void  *pBuffer2,
                      unsigned     lenBuffer2,
                      char         padCharacter = ' ' );
  IString           ( const void *pBuffer1,
                      unsigned     lenBuffer1,
                      const void  *pBuffer2,
                      unsigned     lenBuffer2,
                      const void  *pBuffer3,
                      unsigned     lenBuffer3,
                      char         padCharacter = ' ' );
  IString           ( const IText &anIText );
  ~IString          ( );

/*------------------------- Diagnostics --------------------------------------*/
IString
  asString          ( ) const,
  asDebugInfo       ( ) const;

friend ostream& IC_EXPORTB
  operator <<       ( ostream       &aStream,
                      const IString &aString );

/*------------------------- Stream Input -------------------------------------*/
friend istream& IC_EXPORTB
  operator >>       ( istream &aStream,
                      IString &aString );

static IString
  lineFrom          ( istream &aStream,
                      char     delim = '\n' );

/*------------------------- Testing ------------------------------------------*/
bool
  isAlphanumeric    ( ) const,
  isAlphabetic      ( ) const,
  isASCII           ( ) const,
  isBinaryDigits    ( ) const,
  isControl         ( ) const,
  isDigits          ( ) const,
  isGraphics        ( ) const,
  isHexDigits       ( ) const,
  isLowerCase       ( ) const,
  isPrintable       ( ) const,
  isPunctuation     ( ) const,
  isUpperCase       ( ) const,
  isWhiteSpace      ( ) const;

/*------------------------- NLS Testing --------------------------------------*/
bool
  isMBCS            ( ) const,
  isDBCS            ( ) const,
  isSBCS            ( ) const,
  isValidMBCS       ( ) const,
  isValidDBCS       ( ) const,
  includesMBCS      ( ) const,
  includesDBCS      ( ) const,
  includesSBCS      ( ) const;


/*------------------------- Pattern Matching ---------------------------------*/
bool
  isLike            ( const IString &aPattern,
                      char           zeroOrMore = '*',
                      char           anyChar    = '?' ) const,
  isLike            ( const char    *pPattern,
                      char           zeroOrMore = '*',
                      char           anyChar    = '?' ) const,

  isAbbreviationFor ( const IString &fullString,
                      unsigned       minAbbrevLength = 0 ) const,
  isAbbreviationFor ( const char    *pFullString,
                      unsigned       minAbbrevLength = 0 ) const,

  includes          ( const IString     &aString ) const,
  includes          ( const char        *pString ) const,
  includes          ( char               aChar   ) const,
  includes          ( const IStringTest &aTest   ) const;

/*------------------------- Comparisons --------------------------------------*/
friend bool
  operator ==      ( const IString &string1,
                     const IString &string2  ),
  operator ==      ( const IString &string1,
                     const char    *pString2 ),
  operator ==      ( const char    *pString1,
                     const IString &string2  ),

  operator !=      ( const IString &string1,
                     const IString &string2  ),
  operator !=      ( const IString &string1,
                     const char    *pString2 ),
  operator !=      ( const char    *pString1,
                     const IString &string2  ),

  operator <       ( const IString &string1,
                     const IString &string2  ),
  operator <       ( const IString &string1,
                     const char    *pString2 ),
  operator <       ( const char    *pString1,
                     const IString &string2  ),

  operator <=      ( const IString &string1,
                     const IString &string2  ),
  operator <=      ( const IString &string1,
                     const char    *pString2 ),
  operator <=      ( const char    *pString1,
                     const IString &string2  ),

  operator >       ( const IString &string1,
                     const IString &string2  ),
  operator >       ( const IString &string1,
                     const char    *pString2 ),
  operator >       ( const char    *pString1,
                     const IString &string2  ),

  operator >=      ( const IString &string1,
                     const IString &string2  ),
  operator >=      ( const IString &string1,
                     const char    *pString2 ),
  operator >=      ( const char    *pString1,
                     const IString &string2  );

/*------------------------- Type Conversions ---------------------------------*/
  operator char*          ( ) const;
  operator unsigned char* ( ) const;
  operator signed char*   ( ) const;


long
  asInt                   ( ) const;

unsigned long
  asUnsigned              ( ) const;

#ifdef _LONG_LONG
long long
  asLongLong              ( ) const;

unsigned long long
  asUnsignedLongLong      ( ) const;
#endif

double
  asDouble                ( ) const;

/*------------------------- Binary Conversions -------------------------------*/
IString
 &b2c              ( ),
 &b2d              ( ),
 &b2x              ( );

static IString
  b2c              ( const IString &aString ),
  b2d              ( const IString &aString ),
  b2x              ( const IString &aString );

/*------------------------- Character Conversions ----------------------------*/
IString
 &c2b              ( ),
 &c2d              ( ),
 &c2x              ( );

static IString
  c2b              ( const IString &aString ),
  c2d              ( const IString &aString ),
  c2x              ( const IString &aString );

/*------------------------- Numeric Conversions ------------------------------*/
IString
 &d2b              ( ),
 &d2c              ( ),
 &d2x              ( );

static IString
  d2b              ( const IString &aString ),
  d2c              ( const IString &aString ),
  d2x              ( const IString &aString );

/*------------------------- Hex Conversions ----------------------------------*/
IString
 &x2b              ( ),
 &x2c              ( ),
 &x2d              ( );

static IString
  x2b              ( const IString &aString ),
  x2c              ( const IString &aString ),
  x2d              ( const IString &aString );


/*------------------------- Manipulations ------------------------------------*/
IString
 &operator =       ( const IString &aString ),
  operator ~       (                        ) const,
  operator +       ( const IString &aString ) const,
  operator +       ( const char    *pString ) const,
 &operator +=      ( const IString &aString ),
 &operator +=      ( const char    *pString ),
  operator &       ( const IString &aString ) const,
  operator &       ( const char    *pString ) const,
 &operator &=      ( const IString &aString ),
 &operator &=      ( const char    *pString ),
  operator |       ( const IString &aString ) const,
  operator |       ( const char    *pString ) const,
 &operator |=      ( const IString &aString ),
 &operator |=      ( const char    *pString ),
  operator ^       ( const IString &aString ) const,
  operator ^       ( const char    *pString ) const,
 &operator ^=      ( const IString &aString ),
 &operator ^=      ( const char    *pString );

friend IString
  IC_EXPORTB operator +       ( const char    *pString,
                                const IString &aString ),
  IC_EXPORTB operator &       ( const char    *pString,
                                const IString &aString ),
  IC_EXPORTB operator |       ( const char    *pString,
                                const IString &aString ),
  IC_EXPORTB operator ^       ( const char    *pString,
                                const IString &aString );

/*------------------------- Queries ------------------------------------------*/
unsigned
  size              ( ) const,
  length            ( ) const;

IString
  subString         ( unsigned startPos ) const,
  subString         ( unsigned startPos,
                      unsigned length,
                      char     padCharacter = ' ' ) const;

char
 &operator []       ( unsigned index );

const char
 &operator []       ( unsigned index ) const;

char
 &operator []       ( signed index );

const char
 &operator []       ( signed index ) const;

char
 &operator []       ( unsigned long index );

const char
 &operator []       ( unsigned long index ) const;

char
 &operator []       ( signed long index );

const char
 &operator []       ( signed long index ) const;

IStringEnum::CharType
  charType          ( unsigned index ) const;

/*------------------------- Forward Searches ---------------------------------*/
unsigned
  indexOf           ( const IString     &aString,
                      unsigned           startPos = 1 ) const,
  indexOf           ( const char        *pString,
                      unsigned           startPos = 1 ) const,
  indexOf           ( char              aCharacter,
                      unsigned           startPos = 1 ) const,
  indexOf           ( const IStringTest &aTest,
                      unsigned           startPos = 1 ) const,

  indexOfAnyBut     ( const IString     &validChars,
                      unsigned           startPos = 1 ) const,
  indexOfAnyBut     ( const char        *pValidChars,
                      unsigned           startPos = 1 ) const,
  indexOfAnyBut     ( char               validChar,
                     unsigned           startPos = 1 ) const,
  indexOfAnyBut     ( const IStringTest &aTest,
                      unsigned           startPos = 1 ) const,

  indexOfAnyOf      ( const IString     &searchChars,
                      unsigned           startPos = 1 ) const,
  indexOfAnyOf      ( const char        *pSearchChars,
                      unsigned           startPos = 1 ) const,
  indexOfAnyOf      ( char               searchChar,
                      unsigned           startPos = 1 ) const,
  indexOfAnyOf      ( const IStringTest &aTest,
                      unsigned           startPos = 1 ) const,

  occurrencesOf     ( const IString     &aString,
                      unsigned           startPos = 1 ) const,
  occurrencesOf     ( const char        *pString,
                      unsigned           startPos = 1 ) const,
  occurrencesOf     ( char              aCharacter,
                      unsigned           startPos = 1 ) const,
  occurrencesOf     ( const IStringTest &aTest,
                      unsigned           startPos = 1 ) const;


/*------------------------- Reverse Searches ---------------------------------*/
unsigned
  lastIndexOf       ( const IString &aString,
                      unsigned       startPos = (unsigned)UINT_MAX ) const,
  lastIndexOf       ( const char    *pString,
                      unsigned       startPos = (unsigned)UINT_MAX ) const,
  lastIndexOf       ( char          aCharacter,
                      unsigned       startPos = (unsigned)UINT_MAX ) const,
  lastIndexOf       ( const IStringTest &aTest,
                      unsigned           startPos = (unsigned)UINT_MAX ) const,

  lastIndexOfAnyBut ( const IString     &validChars,
                      unsigned           startPos = (unsigned)UINT_MAX ) const,
  lastIndexOfAnyBut ( const char        *pValidChars,
                      unsigned           startPos = (unsigned)UINT_MAX ) const,
  lastIndexOfAnyBut ( char               validChar,
                      unsigned           startPos = (unsigned)UINT_MAX ) const,
  lastIndexOfAnyBut ( const IStringTest &aTest,
                      unsigned           startPos = (unsigned)UINT_MAX ) const,

  lastIndexOfAnyOf  ( const IString     &searchChars,
                      unsigned           startPos = (unsigned)UINT_MAX ) const,
  lastIndexOfAnyOf  ( const char        *pSearchChars,
                      unsigned           startPos = (unsigned)UINT_MAX ) const,
  lastIndexOfAnyOf  ( char               searchChar,
                      unsigned           startPos = (unsigned)UINT_MAX ) const,
  lastIndexOfAnyOf  ( const IStringTest &aTest,
                      unsigned           startPos = (unsigned)UINT_MAX ) const;

/*------------------------- Editing ------------------------------------------*/
IString
 &center            ( unsigned length,
                      char     padCharacter = ' ' ),

 &change            ( const IString &inputString,
                      const IString &outputString,
                      unsigned       startPos = 1,
                      unsigned       numChanges = (unsigned)UINT_MAX ),
 &change            ( const IString &inputString,
                      const char    *pOutputString,
                      unsigned       startPos = 1,
                      unsigned       numChanges = (unsigned)UINT_MAX ),
 &change            ( const char    *pInputString,
                      const IString &outputString,
                      unsigned       startPos = 1,
                      unsigned       numChanges = (unsigned)UINT_MAX ),
 &change            ( const char    *pInputString,
                      const char    *pOutputString,
                      unsigned       startPos = 1,
                      unsigned       numChanges = (unsigned)UINT_MAX ),

 &copy              ( unsigned numCopies ),

 &insert            ( const IString &aString,
                      unsigned       index = 0,
                      char           padCharacter = ' ' ),
 &insert            ( const char    *pString,
                      unsigned       index = 0,
                      char           padCharacter = ' ' ),

 &leftJustify       ( unsigned length,
                      char     padCharacter = ' ' ),

 &lowerCase         ( ),

 &overlayWith       ( const IString &aString,
                      unsigned       index        = 1,
                      char           padCharacter = ' ' ),
 &overlayWith       ( const char    *pString,
                      unsigned       index        = 1,
                      char           padCharacter = ' ' ),

 &remove            ( unsigned startPos ),
 &remove            ( unsigned startPos,
                      unsigned numChars ),

 &reverse           ( ),

 &rightJustify      ( unsigned length,
                      char     padCharacter = ' ' ),

 &strip             ( ),
 &strip             ( char               aCharacter ),
 &strip             ( const IString     &aString ),
 &strip             ( const char        *pString ),
 &strip             ( const IStringTest &aTest ),

 &stripLeading      ( ),
 &stripLeading      ( char               aCharacter ),
 &stripLeading      ( const IString     &aString ),
 &stripLeading      ( const char        *pString ),
 &stripLeading      ( const IStringTest &aTest ),

 &stripTrailing     ( ),
 &stripTrailing     ( char               aCharacter ),
 &stripTrailing     ( const IString     &aString ),
 &stripTrailing     ( const char        *pString ),
 &stripTrailing     ( const IStringTest &aTest ),

 &translate         ( const IString &inputChars,
                      const IString &outputChars,
                      char           padCharacter = ' ' ),
 &translate         ( const IString &inputChars,
                      const char    *pOutputChars,
                      char           padCharacter = ' ' ),
 &translate         ( const char    *pInputChars,
                      const IString &outputChars,
                      char           padCharacter = ' ' ),
 &translate         ( const char    *pInputChars,
                      const char    *pOutputChars,
                      char           padCharacter = ' ' ),

 &upperCase         ( );

static IString
  center            ( const IString &aString,
                      unsigned       length,
                      char           padCharacter = ' ' ),

  change            ( const IString &aString,
                      const IString &inputString,
                      const IString &outputString,
                      unsigned       startPos = 1,
                      unsigned       numChanges = (unsigned)UINT_MAX ),
  change            ( const IString &aString,
                      const IString &inputString,
                      const char    *pOutputString,
                      unsigned       startPos = 1,
                      unsigned       numChanges = (unsigned)UINT_MAX ),
  change            ( const IString &aString,
                      const char    *pInputString,
                      const IString &outputString,
                      unsigned       startPos = 1,
                      unsigned       numChanges = (unsigned)UINT_MAX ),
  change            ( const IString &aString,
                      const char    *pInputString,
                      const char    *pOutputString,
                      unsigned       startPos = 1,
                      unsigned       numChanges = (unsigned)UINT_MAX ),

  copy              ( const IString &aString,
                      unsigned       numCopies ),

  insert            ( const IString &aString,
                      const IString &anInsert,
                      unsigned       index = 0,
                      char           padCharacter = ' ' ),
  insert            ( const IString &aString,
                      const char    *pInsert,
                      unsigned       index = 0,
                      char           padCharacter = ' ' ),

  leftJustify       ( const IString &aString,
                      unsigned       length,
                      char           padCharacter = ' ' ),

  lowerCase         ( const IString &aString ),

  overlayWith       ( const IString &aString,
                      const IString &anOverlay,
                      unsigned       index        = 1,
                      char           padCharacter = ' ' ),
  overlayWith       ( const IString &aString,
                      const char    *pOverlay,
                      unsigned       index        = 1,
                      char           padCharacter = ' ' ),

  remove            ( const IString &aString,
                      unsigned       startPos ),
  remove            ( const IString &aString,
                      unsigned       startPos,
                      unsigned       numChars ),

  reverse           ( const IString &aString ),

  rightJustify      ( const IString &aString,
                      unsigned       length,
                      char           padCharacter = ' ' ),

  stripBlanks       ( const IString &aString ),
  strip             ( const IString &aString,
                      char           aChar ),
  strip             ( const IString &aString,
                      const IString &aStringOfChars ),
  strip             ( const IString &aString,
                      const char    *pStringOfChars ),
  strip             ( const IString &aString,
                      const IStringTest &aTest ),

  stripLeadingBlanks ( const IString &aString ),
  stripLeading      ( const IString &aString,
                      char           aChar ),
  stripLeading      ( const IString &aString,
                      const IString &aStringOfChars ),
  stripLeading      ( const IString &aString,
                      const char    *pStringOfChars ),
  stripLeading      ( const IString &aString,
                      const IStringTest &aTest ),

  stripTrailingBlanks ( const IString &aString ),
  stripTrailing     ( const IString &aString,
                      char           aChar ),
  stripTrailing     ( const IString &aString,
                      const IString &aStringOfChars ),
  stripTrailing     ( const IString &aString,
                      const char    *pStringOfChars ),
  stripTrailing     ( const IString &aString,
                      const IStringTest &aTest ),

  translate         ( const IString &aString,
                      const IString &inputChars,
                      const IString &outputChars,
                      char           padCharacter = ' ' ),
  translate         ( const IString &aString,
                      const IString &inputChars,
                      const char    *pOutputChars,
                      char           padCharacter = ' ' ),
  translate         ( const IString &aString,
                      const char    *pInputChars,
                      const IString &outputChars,
                      char           padCharacter = ' ' ),
  translate         ( const IString &aString,
                      const char    *pInputChars,
                      const char    *pOutputChars,
                      char           padCharacter = ' ' ),

  upperCase         ( const IString &aString );

/*------------------------- Word Operations ----------------------------------*/
IString
 &removeWords       ( unsigned firstWord ),
 &removeWords       ( unsigned firstWord,
                      unsigned numWords ),

 &space             ( unsigned numSpaces = 1,
                      char     spaceChar = ' ' ),

  word              ( unsigned  wordNumber ) const,

  words             ( unsigned  firstWord ) const,
  words             ( unsigned  firstWord,
                      unsigned  numWords  ) const;

unsigned
  indexOfPhrase     ( const IString &wordString,
                      unsigned       startWord = 1 ) const,

  indexOfWord       ( unsigned wordNumber ) const,

  lengthOfWord      ( unsigned wordNumber ) const,

  numWords          ( ) const,

  wordIndexOfPhrase ( const IString &aPhrase,
                      unsigned       startWord = 1 ) const;

static IString
  space             ( const IString &aString,
                      unsigned       numSpaces = 1,
                      char           spaceChar = ' ' ),

  removeWords       ( const IString &aString,
                      unsigned       startWord ),
  removeWords       ( const IString &aString,
                      unsigned       startWord,
                      unsigned       numWords  );
#ifdef IC_NLS
static void enableInternationalization(bool enable = true);
static void disableInternationalization();
static bool isInternationalized();
#endif

/*------------------------- Streaming ----------------------------------------*/
void
  operator >>= ( IDataStream &toWhere );
void
  operator <<= ( IDataStream &fromWhere );

protected:
/*------------------------- Utility Data -------------------------------------*/
static const char
 IC_IMPORTB * const null,
 IC_IMPORTB * const zero,
 IC_IMPORTB * const maxLong;

/*-------------------------- To Get at the nullBuffer ------------------------*/
static const char * nullBuf();


/*-------------------------- Initialize --------------------------------------*/
IString
 &setBuffer         ( IBuffer *ibuff ),

 &initBuffer        ( const void *p1,
                      unsigned    len1,
                      const void *p2      = 0,
                      unsigned    len2    = 0,
                      const void *p3      = 0,
                      unsigned    len3    = 0,
                      char        padChar = 0 ),
 &initBuffer        ( long  aLong ),
 &initBuffer        ( unsigned long  anUnsignedLong ),
#ifdef _LONG_LONG
 &initBuffer        ( long long  aLongLong ),
 &initBuffer        ( unsigned long long  anUnsignedLongLong ),
#endif
 &initBuffer        ( double  aDouble );


/*-------------------------- Protected Queries -------------------------------*/
char
 *data              ( ) const;

IBuffer
 *buffer            ( ) const;

static unsigned
  lengthOf          ( const char *pChar );

static char
 *defaultBuffer     ( );


/*------------------------- Protected Searches/Testing -----------------------*/
typedef enum {
  charIndex,
  wordIndex
  } IndexType;

unsigned
  indexOfWord       ( unsigned wordNumber,
                      unsigned startPos,
                      unsigned numWords ) const,

  occurrencesOf     ( const char *pSearchString,
                      unsigned    searchLen,
                      unsigned    startPos ) const,


  findPhrase        ( const IString &aPhrase,
                      unsigned       startWord,
                      IndexType      charOrWord ) const;

bool
  isLike            ( const char *pPattern,
                      unsigned    patternLen,
                      char        zeroOrMore,
                      char        anyChar ) const,

  isAbbrevFor       ( const char *pFullString,
                      unsigned    fullLen,
                      unsigned    minLen ) const;

/*------------------------- Protected Editing --------------------------------*/
IString
 &change            ( const char *pPattern,
                      unsigned    patternLen,
                      const char *pReplacement,
                      unsigned    replacementLen,
                      unsigned    startPos,
                      unsigned    numChanges ),

 &insert            ( const char *pInsert,
                      unsigned    insertLen,
                      unsigned    startPos,
                      char        padCharacter ),

 &overlayWith       ( const char *pOverlay,
                      unsigned    overlayLen,
                      unsigned    index,
                      char        padCharacter ),

 &strip             ( const char             *pChar,
                      unsigned                len,
                      IStringEnum::StripMode  mode ),

 &strip             ( const IStringTest      &aTest,
                      IStringEnum::StripMode  mode ),

 &translate         ( const char *pInputChars,
                      unsigned    inputLen,
                      const char *pOutputChars,
                      unsigned    outputLen,
                      char        padCharacter );


/*------------------------- Bit Operations -----------------------------------*/
typedef enum {
  bitAnd,
  bitOr,
  bitExclusiveOr
#if ( IC_OBSOLETE <= IC_OBSOLETE_2 )
#ifndef __DIGRAPHS__
  ,
  and = bitAnd,
  or  = bitOr,
  exclusiveOr = bitExclusiveOr
#endif
#endif
  } BitOperator;

IString
 &applyBitOp        ( const char *pArg,
                      unsigned    argLen,
                      BitOperator op );

/*------------------------- Streaming ----------------------------------------*/
void
  writeToStream( IDataStream &toWhere ) const;
void
  readFromStream( IDataStream &fromWhere );

private:
/*----------------------------- Private --------------------------------------*/
  IString           ( IBuffer *pBuffer );
void
  binaryMath        ( unsigned char newDigit ),
  decimalMath       ( unsigned char newDigit );
IString
 &prepareToChange   ( );
char
 *pBuffer;

static void
  setDefaultBuffer  ( char * );

static char
  *nullBuffer;

friend class IBuffer;
};

#pragma pack(pop)
#pragma enum(pop)

#if __IBMCPP__ >= 400
#pragma namemangling()
#endif

#include <istring.inl>

#endif
