home *** CD-ROM | disk | FTP | other *** search
/ Chip 1997 October / Chip_1997-10_cd.bin / tema / sybase / powerj / hpp.z / WSTRING.HPP < prev    next >
C/C++ Source or Header  |  1996-12-18  |  30KB  |  918 lines

  1. /*************************************************************************
  2.  *
  3.  * WString
  4.  *
  5.  *    This class defines the basic string type used by the library.
  6.  *    The class is DBCS-enabled when running on a DBCS version of the
  7.  *    operating system.
  8.  *
  9.  *    Some important terms to know:
  10.  *
  11.  *        length: number of characters (not bytes) in a string, excluding
  12.  *                terminating null
  13.  *
  14.  *        size: number of bytes (not characters) in a string, excluding
  15.  *              terminating null
  16.  *
  17.  *        empty string: string of length 0
  18.  *
  19.  *        null string: a string with no length or data
  20.  *
  21.  *************************************************************************/
  22.  
  23. #ifndef _WSTRING_HPP_INCLUDED
  24. #define _WSTRING_HPP_INCLUDED
  25.  
  26. #ifndef _WNO_PRAGMA_PUSH
  27. #pragma pack(push,8);
  28. #pragma enum int;
  29. #endif
  30.  
  31. #ifndef _WOBJECT_HPP_INCLUDED
  32. #  include "wobject.hpp"
  33. #endif
  34. #ifndef _WARRAY_HPP_INCLUDED
  35. #  include "warray.hpp"
  36. #endif
  37.  
  38. extern "C" {
  39.     #include <string.h>
  40. #ifndef _SBCS
  41.     #include <mbstring.h>
  42. #endif
  43.     #include <stdarg.h>
  44. };
  45.  
  46. class ostream;
  47. class istream;
  48.  
  49. class WResourceID;
  50. class WModule;   
  51. class WStringReference;
  52. class WString;
  53. class WMessageID;
  54.  
  55. // this is used for multibyte strings where the index of a character is
  56. // not the same as its actual position
  57. struct StringIndex {
  58.         WAnsiChar *     pointer;
  59.         WLong           index;  // the index the user wants
  60. };
  61.  
  62. enum WStringType {
  63.     WAnsiString = 0,
  64.     WUnicodeString = 1,
  65.  
  66.     #ifdef _UNICODE
  67.         WDefaultString = WUnicodeString
  68.     #else
  69.         WDefaultString = WAnsiString
  70.     #endif
  71. };
  72.  
  73. #define USE_STR_LEN                 0xFFFFFFFF
  74. #define NOT_FOUND                   0xFFFFFFFF
  75. #define WSTRING_DEFAULT_QUOTELIST   __WTEXT("\"\"''")
  76.  
  77. #ifndef _WIN16
  78. #undef LoadString
  79. #if defined( _UNICODE )
  80.     #define LoadString LoadStringW
  81. #else
  82.     #define LoadString LoadStringA
  83. #endif
  84. #endif
  85.  
  86. //
  87. // WString
  88. //
  89.  
  90. extern template WArrayReference<WString>;
  91. extern template WArray<WString>;
  92.  
  93. typedef WArray<WString> WStringArray;
  94.  
  95. class WCMCLASS WString : public WObject {
  96.     WDeclareSubclass( WString, WObject )
  97.  
  98.     friend class WStringReference;
  99.  
  100.     public:
  101.  
  102.         /**********************************************************
  103.          * WStringElement
  104.          *********************************************************/
  105.  
  106.         //
  107.         // WStringElement
  108.         //
  109.         //    This class represents an individual character in a string
  110.         //    and is used in conjunction with the [] operator on WString
  111.         //    to ensure that characters get inserted into the proper
  112.         //    area in the string (mostly for DBCS strings).
  113.         //
  114.  
  115.         class WCMCLASS WStringElement {
  116.  
  117.             friend class WString;
  118.  
  119.             public:
  120.  
  121.                 WStringElement& operator=( const WWidestChar ch )
  122.                     { string->SetCharacter( index, ch ); return *this; }
  123.  
  124.                 WStringElement& operator=( const WStringElement & e )
  125.                     { string->SetCharacter( index,
  126.                                            e.string->GetCharacter( e.index ) );
  127.                       return *this; }
  128.  
  129.                 operator WWidestChar() const
  130.                     { return string->GetCharacter( index ); }
  131.  
  132.             private:
  133.                 WStringElement( WString *str ) : string( str ), index( 0 ) {}
  134.  
  135.                 WStringElement( const WStringElement & e );
  136.  
  137.                 ~WStringElement() {}
  138.  
  139.             private:
  140.                 WString *string;
  141.                 WULong   index;
  142.         };
  143.  
  144.         /**********************************************************
  145.          * Constructors and Destructors
  146.          *********************************************************/
  147.  
  148.         WString();
  149.         WString( const WChar *string, WULong numChars=USE_STR_LEN );
  150.         WString( const WResourceID & id, WModuleHandle module=_ApplicationModule );
  151.         WString( const WMessageID & id, WModuleHandle module=_ApplicationModule );
  152.         WString( const WString & s, WBool makeCopy=FALSE );
  153.  
  154.         ~WString();
  155.  
  156.         /**********************************************************
  157.          * Properties
  158.          *********************************************************/
  159.  
  160.         // Character
  161.         //
  162.         //    Set/get an individual character in the string.  Forces
  163.         //    the string to be the default type.
  164.  
  165.         WWidestChar GetCharacter( WULong index ) const;
  166.         WBool       SetCharacter( WULong index, WWidestChar ch );
  167.  
  168.         // Dirty
  169.  
  170.         WBool         GetDirty() const { return _dirty; }
  171.         virtual WBool SetDirty( WBool dirty=TRUE );
  172.  
  173.         // Double
  174.         //
  175.         //    Convert the string to a WDouble, optionally setting an error
  176.         //    flag.
  177.  
  178.         WDouble WCMRETURNSFLOAT GetDouble( WBool *ok=NULL ) const;
  179.  
  180.         // Empty
  181.         //
  182.         //    TRUE if the string is null or is empty.
  183.  
  184.         WBool GetEmpty() const;
  185.  
  186.         // Length
  187.         //
  188.         //    Returns the length of the string in characters, not
  189.         //    including the null terminator.
  190.  
  191.         WULong GetAnsiLength() const;
  192.         WULong GetUnicodeLength() const;
  193.  
  194.         #ifdef _UNICODE
  195.             WULong GetLength() const { return GetUnicodeLength(); }
  196.         #else
  197.             WULong GetLength() const { return GetAnsiLength(); }
  198.         #endif
  199.  
  200.         // Long
  201.         //
  202.         //    Convert the string to a WLong, optionally setting an error
  203.         //    flag.
  204.  
  205.         WLong GetLong( WBool *ok=NULL ) const;
  206.  
  207.         // Null
  208.         //
  209.         //    TRUE if the string is a null (but not an empty) string.
  210.  
  211.         WBool GetNull() const;
  212.  
  213.         // Size
  214.         //
  215.         //    Returns the size of the string in bytes, not including
  216.         //    the null terminator.
  217.  
  218.         WULong GetAnsiSize() const;
  219.         WULong GetUnicodeSize() const;
  220.  
  221.         #ifdef _UNICODE
  222.             WULong GetSize() const { return GetUnicodeSize(); }
  223.         #else
  224.             WULong GetSize() const { return GetAnsiSize(); }
  225.         #endif
  226.  
  227.         // Text
  228.         //
  229.         //    Set/get the actual text of the string.  The optional parm
  230.         //    on the set controls whether or not the string should store
  231.         //    just a pointer to the text or make a copy of the text.
  232.  
  233.         const WAnsiChar    *const GetAnsiText() const;
  234.         WBool                     SetAnsiText( const WAnsiChar *text,
  235.                                                WBool makeCopy=TRUE );
  236.  
  237.         const WUnicodeChar *const GetUnicodeText() const;
  238.         WBool                     SetUnicodeText( const WUnicodeChar *text,
  239.                                                   WBool makeCopy=TRUE );
  240.  
  241.         #ifdef _UNICODE
  242.         const WChar *const GetText() const { return GetUnicodeText(); }
  243.         WBool              SetText( const WChar *str, WBool makeCopy=TRUE )
  244.                                 { return SetUnicodeText( str, makeCopy ); }
  245.         #else
  246.         const WChar *const GetText() const { return GetAnsiText(); }
  247.         WBool              SetText( const WChar *str, WBool makeCopy=TRUE )
  248.                                 { return SetAnsiText( str, makeCopy ); }
  249.         #endif
  250.  
  251.         // Type
  252.         //
  253.         //    Sets/gets the primary type of a string.
  254.  
  255.         WStringType GetType() const;
  256.         WBool       SetType( WStringType type ) const;
  257.  
  258.         // ULong
  259.         //
  260.         //    Convert the string to a WULong, optionally setting an error
  261.         //    flag.
  262.  
  263.         WULong GetULong( WBool *ok=NULL ) const;
  264.  
  265.         /**********************************************************
  266.          * Methods
  267.          *********************************************************/
  268.  
  269.         // Chop
  270.         //
  271.         //    If given a non-negative value, removes all the characters
  272.         //    up to but not including charPos.  If given a negative value,
  273.         //    removes the last charPos*-1 characters.
  274.  
  275.         WBool Chop( WLong charPos );
  276.  
  277.         // Clear
  278.         //
  279.         //    Frees the string, leaving a null string.
  280.  
  281.         void Clear();
  282.     
  283.         // Compare
  284.  
  285.         static int Compare( const WString & a, const WString & b,
  286.                             WBool caseSensitive=TRUE, WULong numChars=0 );
  287.         static int Compare( const WString & a, const WAnsiChar *b );
  288.         static int Compare( const WString & a, const WUnicodeChar *b );
  289.         static int Compare( const WAnsiChar *a, const WString & b );
  290.         static int Compare( const WUnicodeChar *a, const WString & b );
  291.  
  292.         // CompareToSelf
  293.         //
  294.         //    Used by WVector/WMTVector for sorting.
  295.  
  296.         int CompareToSelf( const WString & obj ) const;
  297.  
  298.         // Concat
  299.         //
  300.         //    Concatenate a string onto another.
  301.  
  302.         WBool Concat( const WString & suffix );
  303.         WBool Concat( const WAnsiChar *string );
  304.         WBool Concat( const WUnicodeChar *string );
  305.         WBool Concat( WWidestChar singleChar );
  306.  
  307.         // Concatf
  308.  
  309.         WBool Concatf( const WAnsiChar *parms, ... );
  310.         WBool Concatf( const WUnicodeChar *parms, ... );
  311.  
  312.         // ConvertToInteger
  313.  
  314.         WInt ConvertToInteger() const;
  315.  
  316.         // ConvertToLong
  317.  
  318.         WLong ConvertToLong() const;
  319.  
  320.         // Create
  321.         //
  322.         //    Various constructors for building a new string.  First
  323.         //    frees the old string.  
  324.  
  325.         WBool Create();
  326.         WBool Create( const WResourceID & id, WModuleHandle module=_ApplicationModule );
  327.         WBool Create( const WMessageID & id, WModuleHandle module=_ApplicationModule );
  328.         WBool Create( const WString & s, WBool makeCopy=FALSE );
  329.  
  330.         WBool CreateAnsi( const WAnsiChar *string,
  331.                           WULong numChars=USE_STR_LEN );
  332.         WBool CreateUnicode( const WUnicodeChar *string,
  333.                              WULong numChars=USE_STR_LEN );
  334.  
  335.         #ifdef _UNICODE
  336.         WBool Create( const WChar *string, WULong numChars=USE_STR_LEN )
  337.             { return CreateUnicode( string, numChars ); }
  338.         #else
  339.         WBool Create( const WChar *string, WULong numChars=USE_STR_LEN )
  340.             { return CreateAnsi( string, numChars ); }
  341.         #endif
  342.  
  343.         // Format
  344.         //
  345.         //    Formats a message.  
  346.         //    Returns number of characters
  347.         //    (not bytes) copied into the string.
  348.  
  349.         WULong Format( const WChar *format, ... );
  350.         WULong Format( WULong messageID, WULong langID, ... );
  351.         WULong Format( const WModule *module, WULong messageID,
  352.                        WULong langID, ... );
  353.  
  354.         // FormatEx
  355.         //
  356.         //    Formats a message, but with more options.
  357.  
  358.         #define WSTRF_NOFORMAT   0x0200
  359.         #define WSTRF_FROMSTRING 0x0400
  360.         #define WSTRF_FROMMODULE 0x0800
  361.         #define WSTRF_FROMSYSTEM 0x1000
  362.         #define WSTRF_USEARRAY   0x2000
  363.  
  364.         WULong FormatEx( WULong flags, const WChar *format,
  365.                          WByte maxWidth, ... );
  366.         WULong FormatEx( WULong flags, const WModule *module,
  367.                          WULong messageID, WULong langID,
  368.                          WByte maxWidth, ... );
  369.  
  370.         // FormatV
  371.         //
  372.         //    The basic form of Format/FormatEx.
  373.  
  374.         WULong FormatV( WULong flags, const WChar *format,
  375.                         WByte maxWidth, va_list args );
  376.         WULong FormatV( WULong flags, const WModule *module,
  377.                         WULong messageID, WULong langID,
  378.                         WByte maxWidth, va_list args );
  379.         // Left
  380.         //
  381.         //    Returns the n leftmost characters of a string.  If string
  382.         //    is smaller than n, just returns the string.
  383.  
  384.         WString Left( WULong numChars ) const;
  385.  
  386.         // Lock
  387.         //
  388.         //    Call this if you want to work directly on the buffer
  389.         //    inside the WString.  It will ensure that no one else
  390.         //    is referencing it, that it has a minimum size (in bytes),
  391.         //    return its pointer.  Call Unlock when you're done.
  392.  
  393.         WChar *Lock( WULong minimumSize=0, WStringType type=WDefaultString );
  394.  
  395.         // Parse
  396.         //
  397.         //    Parse a string into an array of substrings.  The original
  398.         //    string is left unchanged.  The delimeterList specifies
  399.         //    the list of characters that delimit the substrings
  400.         //    (default is whitespace).  If quoteList is non-NULL,
  401.         //    it consists of pairs of begin-end characters which are
  402.         //    used to declare a substring with delimiter characters
  403.         //    embedded in it.  If ignoreMultiple is TRUE, multiple
  404.         //    delimiter characters (such as multiple spaces) are
  405.         //    ignored.  You can specify an index to start and end at.
  406.         //    Finally, if allowEscapes is TRUE, you can use a backslash
  407.         //    within a quoted string as an escape character to escape
  408.         //    either delimiter character or a backslash itself.
  409.  
  410.         WStringArray Parse( const WChar *delimiterList=NULL,
  411.                             WBool ignoreMultiples=TRUE,
  412.                             const WChar *quoteList=WSTRING_DEFAULT_QUOTELIST,
  413.                             WBool stripQuotes=TRUE,
  414.                             WULong startAt=0,
  415.                             WULong endAt=USE_STR_LEN,
  416.                             WBool allowEscapes=TRUE ) const;
  417.  
  418.         // Position
  419.         //
  420.         //    Search for a given character or substring in the string
  421.         //    and return its position. NOT_FOUND is returned if not
  422.         //    found.
  423.  
  424.         WULong Position( const WWidestChar character, WULong startAt=0,
  425.                          WBool ignoreCase=FALSE ) const;
  426.         WULong Position( const WChar *substring, WULong startAt=0,
  427.                          WBool ignoreCase=FALSE ) const;
  428.         WULong Position( const WString & substring, WULong startAt=0,
  429.                          WBool ignoreCase=FALSE ) const;
  430.  
  431.         // Right
  432.         //
  433.         //    Return the n rightmost characters of a string.  If string
  434.         //    is smaller than n, just returns the string.
  435.  
  436.         WString Right( WULong numChars ) const;
  437.  
  438.         // Sprintf
  439.         //
  440.         //    Calls with the C function sprintf functionality.
  441.  
  442.         WULong Sprintf( const WAnsiChar *parms, ... );
  443.         WULong Sprintf( const WUnicodeChar *parms, ... );
  444.  
  445.         // Strip
  446.         //
  447.         //    Remove spaces from one or both ends.
  448.  
  449.         WString Strip( WBool fromBeg=TRUE, WBool fromEnd=TRUE ) const;
  450.  
  451.         // SubString
  452.         //
  453.         //    Returns the substring starting at position start and
  454.         //    of length n.  Start is 0-based.  If n is not specified,
  455.         //    the rest of the string is returned.
  456.  
  457.         WString Substring( WULong startAt, WULong numChars=USE_STR_LEN ) const;
  458.  
  459.         // ToLowercase
  460.         //
  461.         //    Convert the string (in-place) to lowercase.
  462.  
  463.         WBool ToLowercase();
  464.  
  465.         // ToUppercase
  466.         //
  467.         //    Convert the string (in-place) to uppercase.
  468.  
  469.         WBool ToUppercase();
  470.  
  471.         // Trim
  472.         //
  473.         //    Strip the string in place.
  474.  
  475.         WBool Trim( WBool fromBeg=TRUE, WBool fromEnd=TRUE );
  476.  
  477.         // Truncate
  478.         //
  479.         //    Truncate the string to the given length.
  480.  
  481.         WBool Truncate( WULong length );
  482.  
  483.         // Unlock
  484.         //
  485.         //    Call this when done writing directly to the buffer.
  486.         //    The string then recalculates its size and length.
  487.  
  488.         WBool Unlock();
  489.  
  490.         // OSIsMultiByte
  491.  
  492.         static WBool OSIsMultiByte();
  493.  
  494.         // OSIsUnicode
  495.  
  496.         static WBool OSIsUnicode();
  497.  
  498.         // StringLength 
  499.         //
  500.         //    Returns length in characters, not including null.
  501.  
  502.         static WULong StringLength( const WAnsiChar *str );
  503.         static WULong StringLength( const WUnicodeChar *str );
  504.  
  505.         // StringSize 
  506.         //
  507.         //    Returns size in bytes, not including null.
  508.  
  509.         static WULong StringSize( const WAnsiChar *str );
  510.         static WULong StringSize( const WUnicodeChar *str );
  511.  
  512.         /**********************************************************
  513.          * Static Methods
  514.          *********************************************************/
  515.  
  516.         // LoadString
  517.         //
  518.         //    Load a string directly into a user-allocated buffer.
  519.  
  520.         static WBool LoadString( const WResourceID & id, WChar *buffer,
  521.                                  WULong bufferLength,
  522.                                  WModuleHandle module=_ApplicationModule );
  523.  
  524.         /**********************************************************
  525.          * Static Properties
  526.          *********************************************************/
  527.  
  528.         // DefaultDelimiterList
  529.  
  530.         static const WChar *const GetDefaultDelimiterList();
  531.  
  532.         // DefaultQuoteList
  533.  
  534.         static const WChar *const GetDefaultQuoteList();
  535.  
  536.         // EmptyAnsiCString
  537.  
  538.         static const WAnsiChar    *const GetEmptyAnsiCString();
  539.  
  540.         // EmptyCString
  541.  
  542.         static const WChar        *const GetEmptyCString();
  543.  
  544.         // EmptyString
  545.  
  546.         static const WString & GetEmptyString();
  547.  
  548.         // EmptyUnicodeCString
  549.  
  550.         static const WUnicodeChar *const GetEmptyUnicodeCString();
  551.  
  552.         // NullString
  553.  
  554.         static const WString & GetNullString();
  555.  
  556.         /*********************************************************
  557.          * Operators
  558.          *********************************************************/
  559.  
  560.         //
  561.         // [] operator -- Note that a WWidestChar is always used,
  562.         //                not a WChar, to ensure that the result
  563.         //                can handle the largest type of char.
  564.  
  565.         const WStringElement& operator[]( int index ) const {
  566.             ((WString *) this)->_element.index = index;
  567.             return _element;
  568.         }
  569.  
  570.         WStringElement& operator[]( int index ) {
  571.             _element.index = index;
  572.             return _element;
  573.         }
  574.  
  575.         //
  576.         // casting operators
  577.         //
  578.  
  579.         operator const WAnsiChar*() const { return GetAnsiText(); }
  580.         operator const WUnicodeChar*() const { return GetUnicodeText(); }
  581.  
  582.         /*********************************************************
  583.          * Cache
  584.          *********************************************************/
  585.  
  586.         // CacheSize
  587.  
  588.         static WULong GetCacheSize();
  589.         static WBool  SetCacheSize( WULong size );
  590.  
  591.         // FlushCache
  592.  
  593.         static void FlushCache();
  594.  
  595. #if 0
  596.     private:
  597.         // Note: This operator should not be used.  Instead, call Lock().
  598.         operator WChar*() const;
  599. #endif
  600.  
  601.     public:
  602.  
  603.         //
  604.         // = operator
  605.         //
  606.  
  607.         WString & operator=( const WAnsiChar *s );
  608.         WString & operator=( const WUnicodeChar *s );
  609.         WString & operator=( const WString & s );
  610.  
  611.         //
  612.         // == operator
  613.         //
  614.  
  615.         friend int WEXPORT operator==( const WString & a, const WString & b );
  616.         friend int WEXPORT operator==( const WString & a, WAnsiChar * b );
  617.         friend int WEXPORT operator==( const WString & a, WUnicodeChar * b );
  618.         friend int WEXPORT operator==( WAnsiChar * a, const WString & b );
  619.         friend int WEXPORT operator==( WUnicodeChar * a, const WString & b );
  620.         friend int WEXPORT operator==( const WString & a, const WAnsiChar * b );
  621.         friend int WEXPORT operator==( const WString & a, const WUnicodeChar *b );
  622.         friend int WEXPORT operator==( const WAnsiChar * a, const WString & b );
  623.         friend int WEXPORT operator==( const WUnicodeChar * a, const WString & b );
  624.  
  625.         //
  626.         // <= operator
  627.         //
  628.  
  629.         friend int WEXPORT operator<=( const WString & a, const WString & b );
  630.         friend int WEXPORT operator<=( const WString & a, const WAnsiChar *b );
  631.         friend int WEXPORT operator<=( const WString & a, const WUnicodeChar *b );
  632.         friend int WEXPORT operator<=( const WAnsiChar *a, const WString & b );
  633.         friend int WEXPORT operator<=( const WUnicodeChar *a, const WString & b );
  634.  
  635.         //
  636.         // < operator
  637.         //
  638.  
  639.         friend int WEXPORT operator<( const WString & a, const WString & b );
  640.         friend int WEXPORT operator<( const WString & a, const WAnsiChar *b );
  641.         friend int WEXPORT operator<( const WString & a, const WUnicodeChar *b );
  642.         friend int WEXPORT operator<( const WAnsiChar *a, const WString & b );
  643.         friend int WEXPORT operator<( const WUnicodeChar *a, const WString & b );
  644.  
  645.         //
  646.         // >= operator
  647.         //
  648.  
  649.         friend int WEXPORT operator>=( const WString & a, const WString & b );
  650.         friend int WEXPORT operator>=( const WString & a, const WAnsiChar *b );
  651.         friend int WEXPORT operator>=( const WString & a, const WUnicodeChar *b );
  652.         friend int WEXPORT operator>=( const WAnsiChar *a, const WString & b );
  653.         friend int WEXPORT operator>=( const WUnicodeChar *a, const WString & b );
  654.  
  655.         //
  656.         // > operator
  657.         //
  658.  
  659.         friend int WEXPORT operator>( const WString & a, const WString & b );
  660.         friend int WEXPORT operator>( const WString & a, const WAnsiChar *b );
  661.         friend int WEXPORT operator>( const WString & a, const WUnicodeChar *b );
  662.         friend int WEXPORT operator>( const WAnsiChar *a, const WString & b );
  663.         friend int WEXPORT operator>( const WUnicodeChar *a, const WString & b );
  664.  
  665.         //
  666.         // != operator
  667.         //
  668.  
  669.         friend int WEXPORT operator!=( const WString & a, const WString & b );
  670.         friend int WEXPORT operator!=( const WString & a, const WAnsiChar *b );
  671.         friend int WEXPORT operator!=( const WString & a, const WUnicodeChar *b );
  672.         friend int WEXPORT operator!=( const WAnsiChar *a, const WString & b );
  673.         friend int WEXPORT operator!=( const WUnicodeChar *a, const WString & b );
  674.         friend int WEXPORT operator!=( const WString & a, WAnsiChar * b );
  675.         friend int WEXPORT operator!=( const WString & a, WUnicodeChar * b );
  676.         friend int WEXPORT operator!=( WAnsiChar * a, const WString & b );
  677.         friend int WEXPORT operator!=( WUnicodeChar * a, const WString & b );
  678.  
  679.         //
  680.         // << operator
  681.         //
  682.  
  683.         friend ostream& WEXPORT operator<<( ostream & out, const WString & str );
  684.         friend ostream& WEXPORT operator<<( ostream & out, const WUnicodeChar *str );
  685.  
  686.         //
  687.         // >> operator
  688.         //
  689.  
  690.         friend istream& WEXPORT operator>>( istream & in, WString & str );
  691.         friend istream& WEXPORT operator>>( istream & in, WUnicodeChar *str );
  692.  
  693.         //
  694.         // += operator
  695.         //
  696.  
  697.         WString& operator+=( const WString & a );
  698.         WString& operator+=( const WAnsiChar * a );
  699.         WString& operator+=( const WUnicodeChar * a );
  700.         WString& operator+=( WAnsiChar a );
  701.         WString& operator+=( WUnicodeChar a );
  702.  
  703.         //
  704.         // + operator
  705.         //
  706.  
  707.         WString operator+( const WString & a ) const;
  708.         WString operator+( const WAnsiChar * a ) const;
  709.         WString operator+( const WUnicodeChar * a ) const;
  710.         WString operator+( WAnsiChar a ) const;
  711.         WString operator+( WUnicodeChar a ) const;
  712.         friend WString WEXPORT operator+( const WAnsiChar * a, const WString & b );
  713.         friend WString WEXPORT operator+( const WUnicodeChar * a, const WString & b );
  714.  
  715.         /**********************************************************
  716.          * Private
  717.          *********************************************************/
  718.  
  719.     protected:
  720.  
  721.         virtual WBool CopyOnWrite( WStringType type=WDefaultString );
  722.         virtual WBool PrepareForRead() const;
  723.  
  724.         WBool  ReallocateRef( WByte newType, WULong minimumSize );
  725.         WBool  GrowTo( WULong size );
  726.         WULong SearchFor( const WChar *buf, WULong size, WULong at,
  727.                           WBool ignoreCase ) const;
  728.  
  729.     protected:
  730.  
  731.         WStringReference *_ref;
  732.         const WChar      *_stringData;  // for easier debugging only!
  733.         WStringElement    _element;
  734.  
  735.     #ifdef __BUILDING_WCM__
  736.     public:
  737.     #else
  738.     protected:
  739.     #endif
  740.         static WBool      _osIsMultiByte;
  741.         static WBool      _osIsUnicode;
  742.  
  743.     private:
  744.  
  745.         WBool             _locked;      // TRUE if string is locked
  746.         WBool             _dirty;
  747.         StringIndex       _lastIndex;   // used for direct accessing of an
  748.                                         // element in the string (usually
  749.                                         // through the array [] operator)
  750.  
  751.     private:
  752.  
  753.         #define WSTRING_INVALID_INDEX   -1
  754.  
  755.         void              InvalidateLastIndex( void ) {
  756.                               _lastIndex.pointer = NULL;
  757.                               _lastIndex.index = WSTRING_INVALID_INDEX;
  758.                           }
  759.  
  760.         WBool             IsLastIndexValid( void ) const {
  761.                               return( _lastIndex.index != WSTRING_INVALID_INDEX );
  762.                           }
  763.  
  764.     protected:
  765.  
  766.         static const WString             _NullString;
  767.         static const WString             _EmptyString;
  768.         static const WChar     *const    _EmptyCString;
  769.         static const WAnsiChar *const    _EmptyAnsiCString;
  770.         static const WUnicodeChar *const _EmptyUnicodeCString;
  771.         static const WChar *_NotYetLoaded;
  772.  
  773.         static WULong StringCacheSize;
  774.  
  775.     public:
  776.  
  777.         typedef WStringReference * WCMDEF CacheRemoveFunc();
  778.         typedef CacheRemoveFunc *CacheRemoveFuncPtr;
  779.  
  780.         typedef WBool WCMDEF CacheAddFunc( WStringReference *ref );
  781.         typedef CacheAddFunc *CacheAddFuncPtr;
  782.  
  783.         typedef WULong WCMDEF CacheCountFunc();
  784.         typedef CacheCountFunc *CacheCountFuncPtr;
  785.  
  786.     protected:
  787.  
  788.         static CacheAddFuncPtr    _cacheAdd;
  789.         static CacheRemoveFuncPtr _cacheRemove;
  790.         static CacheCountFuncPtr  _cacheCount;
  791. };
  792.  
  793. //
  794. // WResourceString
  795. //
  796.  
  797. class WCMCLASS WResourceString : public WString {
  798.     WDeclareSubclass( WResourceString, WString )
  799.  
  800.     public:
  801.         WResourceString( const WResourceID & id, WModuleHandle module=_ApplicationModule );
  802.         WResourceString( const WResourceString & other );
  803.  
  804.         ~WResourceString();
  805.  
  806.         WResourceString & operator=( const WResourceString & other );
  807.         WResourceString & operator=( const WAnsiChar *s );
  808.         WResourceString & operator=( const WUnicodeChar *s );
  809.         WResourceString & operator=( const WString & s );
  810.  
  811.     protected:
  812.         virtual WBool    PrepareForRead() const;
  813.  
  814.         WULong           _id;
  815.         WModuleHandle    _handle;
  816. };
  817.  
  818. //
  819. // WConstantString
  820. //
  821.  
  822. class WCMCLASS WConstantString : public WString {
  823.     WDeclareSubclass( WConstantString, WString )
  824.  
  825.     public:
  826.         WConstantString( const WChar *fixedString );
  827.         WConstantString( const WConstantString & other );
  828.  
  829.         ~WConstantString();
  830.  
  831.         WConstantString & operator=( const WConstantString & other );
  832.         WConstantString & operator=( const WAnsiChar *s );
  833.         WConstantString & operator=( const WUnicodeChar *s );
  834.         WConstantString & operator=( const WString & s );
  835.  
  836.         /**********************************************************
  837.          * Overrides
  838.          *********************************************************/
  839. };
  840.  
  841. /*******************************************************************
  842.  *
  843.  * Library functions and macros
  844.  *
  845.  *   The following macros and functions are covers for the appropriate
  846.  *   C library functions and expand out to the correct function
  847.  *   depending on the _UNICODE, _DBCS and _SBCS macro settings.
  848.  *
  849.  *   You should use the functions wherever possible, not the macros,
  850.  *   as the functions provide type checking.
  851.  *
  852.  *   Remember that the length of a string is not necessarily the
  853.  *   same as its size!
  854.  *
  855.  ******************************************************************/
  856.  
  857. #define _MBCast1(x) ((const unsigned char *)(x))
  858. #define _MBCast2(x) ((unsigned char *)(x))
  859.  
  860. #ifdef _SBCS
  861. #define A_StrLen(x)   strlen(x)
  862. #define A_StrSize(x)  strlen(x)
  863. #define A_StrCpy(d,s) strcpy(d,s)
  864. #else
  865. #define A_StrLen(x)   (WString::OSIsMultiByte()?_mbslen(_MBCast1(x)):strlen(x))
  866. #define A_StrSize(x)  strlen(x)
  867. #define A_StrCpy(d,s) (WString::OSIsMultiByte()?(WChar *)_mbscpy(_MBCast2(d),_MBCast1(s)):\
  868.                        (WChar *)strcpy(d,s))
  869. #endif
  870.  
  871. #define U_StrLen(x)   wcslen(x)
  872. #define U_StrSize(x)  (wcslen(x)*sizeof(WUnicodeChar))
  873. #define U_StrCpy(d,s) wcscpy(d,s)
  874.  
  875. #ifdef _UNICODE
  876. #define D_StrLen(x)   U_StrLen(x)
  877. #define D_StrSize(x)  U_StrSize(x)
  878. #define D_StrCpy(d,s) U_StrCpy(d,s)
  879. #else
  880. #define D_StrLen(x)   A_StrLen(x)
  881. #define D_StrSize(x)  A_StrSize(x)
  882. #define D_StrCpy(d,s) A_StrCpy(d,s)
  883. #endif
  884.  
  885. //
  886. // WStrLen -- Return length of string in characters. (See StrSize for bytes.)
  887. //
  888.  
  889. inline WULong WStrLen( const WChar *string ){
  890.     return D_StrLen( string );
  891. }
  892.  
  893. //
  894. // WStrSize -- Return length of string in bytes.  (See StrLen for characters.)
  895. //
  896.  
  897. inline WULong WStrSize( const WChar *string ){
  898.     return D_StrSize( string );
  899. }
  900.  
  901. //
  902. // WStrCpy -- Cover for strcpy.
  903. //
  904.  
  905. inline WChar *WStrCpy( WChar *dst, const WChar *src ){
  906.     return D_StrCpy( dst, src );
  907. }
  908.  
  909. #define WNullString     WString::GetNullString()
  910. #define WEmptyString    WString::GetEmptyString()
  911.  
  912. #ifndef _WNO_PRAGMA_PUSH
  913. #pragma enum pop;
  914. #pragma pack(pop);
  915. #endif
  916.  
  917. #endif // _WSTRING_HPP_INCLUDED
  918.