home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Chip 1997 October
/
Chip_1997-10_cd.bin
/
tema
/
sybase
/
powerj
/
hpp.z
/
WSTRING.HPP
< prev
next >
Wrap
C/C++ Source or Header
|
1996-12-18
|
30KB
|
918 lines
/*************************************************************************
*
* WString
*
* This class defines the basic string type used by the library.
* The class is DBCS-enabled when running on a DBCS version of the
* operating system.
*
* Some important terms to know:
*
* length: number of characters (not bytes) in a string, excluding
* terminating null
*
* size: number of bytes (not characters) in a string, excluding
* terminating null
*
* empty string: string of length 0
*
* null string: a string with no length or data
*
*************************************************************************/
#ifndef _WSTRING_HPP_INCLUDED
#define _WSTRING_HPP_INCLUDED
#ifndef _WNO_PRAGMA_PUSH
#pragma pack(push,8);
#pragma enum int;
#endif
#ifndef _WOBJECT_HPP_INCLUDED
# include "wobject.hpp"
#endif
#ifndef _WARRAY_HPP_INCLUDED
# include "warray.hpp"
#endif
extern "C" {
#include <string.h>
#ifndef _SBCS
#include <mbstring.h>
#endif
#include <stdarg.h>
};
class ostream;
class istream;
class WResourceID;
class WModule;
class WStringReference;
class WString;
class WMessageID;
// this is used for multibyte strings where the index of a character is
// not the same as its actual position
struct StringIndex {
WAnsiChar * pointer;
WLong index; // the index the user wants
};
enum WStringType {
WAnsiString = 0,
WUnicodeString = 1,
#ifdef _UNICODE
WDefaultString = WUnicodeString
#else
WDefaultString = WAnsiString
#endif
};
#define USE_STR_LEN 0xFFFFFFFF
#define NOT_FOUND 0xFFFFFFFF
#define WSTRING_DEFAULT_QUOTELIST __WTEXT("\"\"''")
#ifndef _WIN16
#undef LoadString
#if defined( _UNICODE )
#define LoadString LoadStringW
#else
#define LoadString LoadStringA
#endif
#endif
//
// WString
//
extern template WArrayReference<WString>;
extern template WArray<WString>;
typedef WArray<WString> WStringArray;
class WCMCLASS WString : public WObject {
WDeclareSubclass( WString, WObject )
friend class WStringReference;
public:
/**********************************************************
* WStringElement
*********************************************************/
//
// WStringElement
//
// This class represents an individual character in a string
// and is used in conjunction with the [] operator on WString
// to ensure that characters get inserted into the proper
// area in the string (mostly for DBCS strings).
//
class WCMCLASS WStringElement {
friend class WString;
public:
WStringElement& operator=( const WWidestChar ch )
{ string->SetCharacter( index, ch ); return *this; }
WStringElement& operator=( const WStringElement & e )
{ string->SetCharacter( index,
e.string->GetCharacter( e.index ) );
return *this; }
operator WWidestChar() const
{ return string->GetCharacter( index ); }
private:
WStringElement( WString *str ) : string( str ), index( 0 ) {}
WStringElement( const WStringElement & e );
~WStringElement() {}
private:
WString *string;
WULong index;
};
/**********************************************************
* Constructors and Destructors
*********************************************************/
WString();
WString( const WChar *string, WULong numChars=USE_STR_LEN );
WString( const WResourceID & id, WModuleHandle module=_ApplicationModule );
WString( const WMessageID & id, WModuleHandle module=_ApplicationModule );
WString( const WString & s, WBool makeCopy=FALSE );
~WString();
/**********************************************************
* Properties
*********************************************************/
// Character
//
// Set/get an individual character in the string. Forces
// the string to be the default type.
WWidestChar GetCharacter( WULong index ) const;
WBool SetCharacter( WULong index, WWidestChar ch );
// Dirty
WBool GetDirty() const { return _dirty; }
virtual WBool SetDirty( WBool dirty=TRUE );
// Double
//
// Convert the string to a WDouble, optionally setting an error
// flag.
WDouble WCMRETURNSFLOAT GetDouble( WBool *ok=NULL ) const;
// Empty
//
// TRUE if the string is null or is empty.
WBool GetEmpty() const;
// Length
//
// Returns the length of the string in characters, not
// including the null terminator.
WULong GetAnsiLength() const;
WULong GetUnicodeLength() const;
#ifdef _UNICODE
WULong GetLength() const { return GetUnicodeLength(); }
#else
WULong GetLength() const { return GetAnsiLength(); }
#endif
// Long
//
// Convert the string to a WLong, optionally setting an error
// flag.
WLong GetLong( WBool *ok=NULL ) const;
// Null
//
// TRUE if the string is a null (but not an empty) string.
WBool GetNull() const;
// Size
//
// Returns the size of the string in bytes, not including
// the null terminator.
WULong GetAnsiSize() const;
WULong GetUnicodeSize() const;
#ifdef _UNICODE
WULong GetSize() const { return GetUnicodeSize(); }
#else
WULong GetSize() const { return GetAnsiSize(); }
#endif
// Text
//
// Set/get the actual text of the string. The optional parm
// on the set controls whether or not the string should store
// just a pointer to the text or make a copy of the text.
const WAnsiChar *const GetAnsiText() const;
WBool SetAnsiText( const WAnsiChar *text,
WBool makeCopy=TRUE );
const WUnicodeChar *const GetUnicodeText() const;
WBool SetUnicodeText( const WUnicodeChar *text,
WBool makeCopy=TRUE );
#ifdef _UNICODE
const WChar *const GetText() const { return GetUnicodeText(); }
WBool SetText( const WChar *str, WBool makeCopy=TRUE )
{ return SetUnicodeText( str, makeCopy ); }
#else
const WChar *const GetText() const { return GetAnsiText(); }
WBool SetText( const WChar *str, WBool makeCopy=TRUE )
{ return SetAnsiText( str, makeCopy ); }
#endif
// Type
//
// Sets/gets the primary type of a string.
WStringType GetType() const;
WBool SetType( WStringType type ) const;
// ULong
//
// Convert the string to a WULong, optionally setting an error
// flag.
WULong GetULong( WBool *ok=NULL ) const;
/**********************************************************
* Methods
*********************************************************/
// Chop
//
// If given a non-negative value, removes all the characters
// up to but not including charPos. If given a negative value,
// removes the last charPos*-1 characters.
WBool Chop( WLong charPos );
// Clear
//
// Frees the string, leaving a null string.
void Clear();
// Compare
static int Compare( const WString & a, const WString & b,
WBool caseSensitive=TRUE, WULong numChars=0 );
static int Compare( const WString & a, const WAnsiChar *b );
static int Compare( const WString & a, const WUnicodeChar *b );
static int Compare( const WAnsiChar *a, const WString & b );
static int Compare( const WUnicodeChar *a, const WString & b );
// CompareToSelf
//
// Used by WVector/WMTVector for sorting.
int CompareToSelf( const WString & obj ) const;
// Concat
//
// Concatenate a string onto another.
WBool Concat( const WString & suffix );
WBool Concat( const WAnsiChar *string );
WBool Concat( const WUnicodeChar *string );
WBool Concat( WWidestChar singleChar );
// Concatf
WBool Concatf( const WAnsiChar *parms, ... );
WBool Concatf( const WUnicodeChar *parms, ... );
// ConvertToInteger
WInt ConvertToInteger() const;
// ConvertToLong
WLong ConvertToLong() const;
// Create
//
// Various constructors for building a new string. First
// frees the old string.
WBool Create();
WBool Create( const WResourceID & id, WModuleHandle module=_ApplicationModule );
WBool Create( const WMessageID & id, WModuleHandle module=_ApplicationModule );
WBool Create( const WString & s, WBool makeCopy=FALSE );
WBool CreateAnsi( const WAnsiChar *string,
WULong numChars=USE_STR_LEN );
WBool CreateUnicode( const WUnicodeChar *string,
WULong numChars=USE_STR_LEN );
#ifdef _UNICODE
WBool Create( const WChar *string, WULong numChars=USE_STR_LEN )
{ return CreateUnicode( string, numChars ); }
#else
WBool Create( const WChar *string, WULong numChars=USE_STR_LEN )
{ return CreateAnsi( string, numChars ); }
#endif
// Format
//
// Formats a message.
// Returns number of characters
// (not bytes) copied into the string.
WULong Format( const WChar *format, ... );
WULong Format( WULong messageID, WULong langID, ... );
WULong Format( const WModule *module, WULong messageID,
WULong langID, ... );
// FormatEx
//
// Formats a message, but with more options.
#define WSTRF_NOFORMAT 0x0200
#define WSTRF_FROMSTRING 0x0400
#define WSTRF_FROMMODULE 0x0800
#define WSTRF_FROMSYSTEM 0x1000
#define WSTRF_USEARRAY 0x2000
WULong FormatEx( WULong flags, const WChar *format,
WByte maxWidth, ... );
WULong FormatEx( WULong flags, const WModule *module,
WULong messageID, WULong langID,
WByte maxWidth, ... );
// FormatV
//
// The basic form of Format/FormatEx.
WULong FormatV( WULong flags, const WChar *format,
WByte maxWidth, va_list args );
WULong FormatV( WULong flags, const WModule *module,
WULong messageID, WULong langID,
WByte maxWidth, va_list args );
// Left
//
// Returns the n leftmost characters of a string. If string
// is smaller than n, just returns the string.
WString Left( WULong numChars ) const;
// Lock
//
// Call this if you want to work directly on the buffer
// inside the WString. It will ensure that no one else
// is referencing it, that it has a minimum size (in bytes),
// return its pointer. Call Unlock when you're done.
WChar *Lock( WULong minimumSize=0, WStringType type=WDefaultString );
// Parse
//
// Parse a string into an array of substrings. The original
// string is left unchanged. The delimeterList specifies
// the list of characters that delimit the substrings
// (default is whitespace). If quoteList is non-NULL,
// it consists of pairs of begin-end characters which are
// used to declare a substring with delimiter characters
// embedded in it. If ignoreMultiple is TRUE, multiple
// delimiter characters (such as multiple spaces) are
// ignored. You can specify an index to start and end at.
// Finally, if allowEscapes is TRUE, you can use a backslash
// within a quoted string as an escape character to escape
// either delimiter character or a backslash itself.
WStringArray Parse( const WChar *delimiterList=NULL,
WBool ignoreMultiples=TRUE,
const WChar *quoteList=WSTRING_DEFAULT_QUOTELIST,
WBool stripQuotes=TRUE,
WULong startAt=0,
WULong endAt=USE_STR_LEN,
WBool allowEscapes=TRUE ) const;
// Position
//
// Search for a given character or substring in the string
// and return its position. NOT_FOUND is returned if not
// found.
WULong Position( const WWidestChar character, WULong startAt=0,
WBool ignoreCase=FALSE ) const;
WULong Position( const WChar *substring, WULong startAt=0,
WBool ignoreCase=FALSE ) const;
WULong Position( const WString & substring, WULong startAt=0,
WBool ignoreCase=FALSE ) const;
// Right
//
// Return the n rightmost characters of a string. If string
// is smaller than n, just returns the string.
WString Right( WULong numChars ) const;
// Sprintf
//
// Calls with the C function sprintf functionality.
WULong Sprintf( const WAnsiChar *parms, ... );
WULong Sprintf( const WUnicodeChar *parms, ... );
// Strip
//
// Remove spaces from one or both ends.
WString Strip( WBool fromBeg=TRUE, WBool fromEnd=TRUE ) const;
// SubString
//
// Returns the substring starting at position start and
// of length n. Start is 0-based. If n is not specified,
// the rest of the string is returned.
WString Substring( WULong startAt, WULong numChars=USE_STR_LEN ) const;
// ToLowercase
//
// Convert the string (in-place) to lowercase.
WBool ToLowercase();
// ToUppercase
//
// Convert the string (in-place) to uppercase.
WBool ToUppercase();
// Trim
//
// Strip the string in place.
WBool Trim( WBool fromBeg=TRUE, WBool fromEnd=TRUE );
// Truncate
//
// Truncate the string to the given length.
WBool Truncate( WULong length );
// Unlock
//
// Call this when done writing directly to the buffer.
// The string then recalculates its size and length.
WBool Unlock();
// OSIsMultiByte
static WBool OSIsMultiByte();
// OSIsUnicode
static WBool OSIsUnicode();
// StringLength
//
// Returns length in characters, not including null.
static WULong StringLength( const WAnsiChar *str );
static WULong StringLength( const WUnicodeChar *str );
// StringSize
//
// Returns size in bytes, not including null.
static WULong StringSize( const WAnsiChar *str );
static WULong StringSize( const WUnicodeChar *str );
/**********************************************************
* Static Methods
*********************************************************/
// LoadString
//
// Load a string directly into a user-allocated buffer.
static WBool LoadString( const WResourceID & id, WChar *buffer,
WULong bufferLength,
WModuleHandle module=_ApplicationModule );
/**********************************************************
* Static Properties
*********************************************************/
// DefaultDelimiterList
static const WChar *const GetDefaultDelimiterList();
// DefaultQuoteList
static const WChar *const GetDefaultQuoteList();
// EmptyAnsiCString
static const WAnsiChar *const GetEmptyAnsiCString();
// EmptyCString
static const WChar *const GetEmptyCString();
// EmptyString
static const WString & GetEmptyString();
// EmptyUnicodeCString
static const WUnicodeChar *const GetEmptyUnicodeCString();
// NullString
static const WString & GetNullString();
/*********************************************************
* Operators
*********************************************************/
//
// [] operator -- Note that a WWidestChar is always used,
// not a WChar, to ensure that the result
// can handle the largest type of char.
const WStringElement& operator[]( int index ) const {
((WString *) this)->_element.index = index;
return _element;
}
WStringElement& operator[]( int index ) {
_element.index = index;
return _element;
}
//
// casting operators
//
operator const WAnsiChar*() const { return GetAnsiText(); }
operator const WUnicodeChar*() const { return GetUnicodeText(); }
/*********************************************************
* Cache
*********************************************************/
// CacheSize
static WULong GetCacheSize();
static WBool SetCacheSize( WULong size );
// FlushCache
static void FlushCache();
#if 0
private:
// Note: This operator should not be used. Instead, call Lock().
operator WChar*() const;
#endif
public:
//
// = operator
//
WString & operator=( const WAnsiChar *s );
WString & operator=( const WUnicodeChar *s );
WString & operator=( const WString & s );
//
// == operator
//
friend int WEXPORT operator==( const WString & a, const WString & b );
friend int WEXPORT operator==( const WString & a, WAnsiChar * b );
friend int WEXPORT operator==( const WString & a, WUnicodeChar * b );
friend int WEXPORT operator==( WAnsiChar * a, const WString & b );
friend int WEXPORT operator==( WUnicodeChar * a, const WString & b );
friend int WEXPORT operator==( const WString & a, const WAnsiChar * b );
friend int WEXPORT operator==( const WString & a, const WUnicodeChar *b );
friend int WEXPORT operator==( const WAnsiChar * a, const WString & b );
friend int WEXPORT operator==( const WUnicodeChar * a, const WString & b );
//
// <= operator
//
friend int WEXPORT operator<=( const WString & a, const WString & b );
friend int WEXPORT operator<=( const WString & a, const WAnsiChar *b );
friend int WEXPORT operator<=( const WString & a, const WUnicodeChar *b );
friend int WEXPORT operator<=( const WAnsiChar *a, const WString & b );
friend int WEXPORT operator<=( const WUnicodeChar *a, const WString & b );
//
// < operator
//
friend int WEXPORT operator<( const WString & a, const WString & b );
friend int WEXPORT operator<( const WString & a, const WAnsiChar *b );
friend int WEXPORT operator<( const WString & a, const WUnicodeChar *b );
friend int WEXPORT operator<( const WAnsiChar *a, const WString & b );
friend int WEXPORT operator<( const WUnicodeChar *a, const WString & b );
//
// >= operator
//
friend int WEXPORT operator>=( const WString & a, const WString & b );
friend int WEXPORT operator>=( const WString & a, const WAnsiChar *b );
friend int WEXPORT operator>=( const WString & a, const WUnicodeChar *b );
friend int WEXPORT operator>=( const WAnsiChar *a, const WString & b );
friend int WEXPORT operator>=( const WUnicodeChar *a, const WString & b );
//
// > operator
//
friend int WEXPORT operator>( const WString & a, const WString & b );
friend int WEXPORT operator>( const WString & a, const WAnsiChar *b );
friend int WEXPORT operator>( const WString & a, const WUnicodeChar *b );
friend int WEXPORT operator>( const WAnsiChar *a, const WString & b );
friend int WEXPORT operator>( const WUnicodeChar *a, const WString & b );
//
// != operator
//
friend int WEXPORT operator!=( const WString & a, const WString & b );
friend int WEXPORT operator!=( const WString & a, const WAnsiChar *b );
friend int WEXPORT operator!=( const WString & a, const WUnicodeChar *b );
friend int WEXPORT operator!=( const WAnsiChar *a, const WString & b );
friend int WEXPORT operator!=( const WUnicodeChar *a, const WString & b );
friend int WEXPORT operator!=( const WString & a, WAnsiChar * b );
friend int WEXPORT operator!=( const WString & a, WUnicodeChar * b );
friend int WEXPORT operator!=( WAnsiChar * a, const WString & b );
friend int WEXPORT operator!=( WUnicodeChar * a, const WString & b );
//
// << operator
//
friend ostream& WEXPORT operator<<( ostream & out, const WString & str );
friend ostream& WEXPORT operator<<( ostream & out, const WUnicodeChar *str );
//
// >> operator
//
friend istream& WEXPORT operator>>( istream & in, WString & str );
friend istream& WEXPORT operator>>( istream & in, WUnicodeChar *str );
//
// += operator
//
WString& operator+=( const WString & a );
WString& operator+=( const WAnsiChar * a );
WString& operator+=( const WUnicodeChar * a );
WString& operator+=( WAnsiChar a );
WString& operator+=( WUnicodeChar a );
//
// + operator
//
WString operator+( const WString & a ) const;
WString operator+( const WAnsiChar * a ) const;
WString operator+( const WUnicodeChar * a ) const;
WString operator+( WAnsiChar a ) const;
WString operator+( WUnicodeChar a ) const;
friend WString WEXPORT operator+( const WAnsiChar * a, const WString & b );
friend WString WEXPORT operator+( const WUnicodeChar * a, const WString & b );
/**********************************************************
* Private
*********************************************************/
protected:
virtual WBool CopyOnWrite( WStringType type=WDefaultString );
virtual WBool PrepareForRead() const;
WBool ReallocateRef( WByte newType, WULong minimumSize );
WBool GrowTo( WULong size );
WULong SearchFor( const WChar *buf, WULong size, WULong at,
WBool ignoreCase ) const;
protected:
WStringReference *_ref;
const WChar *_stringData; // for easier debugging only!
WStringElement _element;
#ifdef __BUILDING_WCM__
public:
#else
protected:
#endif
static WBool _osIsMultiByte;
static WBool _osIsUnicode;
private:
WBool _locked; // TRUE if string is locked
WBool _dirty;
StringIndex _lastIndex; // used for direct accessing of an
// element in the string (usually
// through the array [] operator)
private:
#define WSTRING_INVALID_INDEX -1
void InvalidateLastIndex( void ) {
_lastIndex.pointer = NULL;
_lastIndex.index = WSTRING_INVALID_INDEX;
}
WBool IsLastIndexValid( void ) const {
return( _lastIndex.index != WSTRING_INVALID_INDEX );
}
protected:
static const WString _NullString;
static const WString _EmptyString;
static const WChar *const _EmptyCString;
static const WAnsiChar *const _EmptyAnsiCString;
static const WUnicodeChar *const _EmptyUnicodeCString;
static const WChar *_NotYetLoaded;
static WULong StringCacheSize;
public:
typedef WStringReference * WCMDEF CacheRemoveFunc();
typedef CacheRemoveFunc *CacheRemoveFuncPtr;
typedef WBool WCMDEF CacheAddFunc( WStringReference *ref );
typedef CacheAddFunc *CacheAddFuncPtr;
typedef WULong WCMDEF CacheCountFunc();
typedef CacheCountFunc *CacheCountFuncPtr;
protected:
static CacheAddFuncPtr _cacheAdd;
static CacheRemoveFuncPtr _cacheRemove;
static CacheCountFuncPtr _cacheCount;
};
//
// WResourceString
//
class WCMCLASS WResourceString : public WString {
WDeclareSubclass( WResourceString, WString )
public:
WResourceString( const WResourceID & id, WModuleHandle module=_ApplicationModule );
WResourceString( const WResourceString & other );
~WResourceString();
WResourceString & operator=( const WResourceString & other );
WResourceString & operator=( const WAnsiChar *s );
WResourceString & operator=( const WUnicodeChar *s );
WResourceString & operator=( const WString & s );
protected:
virtual WBool PrepareForRead() const;
WULong _id;
WModuleHandle _handle;
};
//
// WConstantString
//
class WCMCLASS WConstantString : public WString {
WDeclareSubclass( WConstantString, WString )
public:
WConstantString( const WChar *fixedString );
WConstantString( const WConstantString & other );
~WConstantString();
WConstantString & operator=( const WConstantString & other );
WConstantString & operator=( const WAnsiChar *s );
WConstantString & operator=( const WUnicodeChar *s );
WConstantString & operator=( const WString & s );
/**********************************************************
* Overrides
*********************************************************/
};
/*******************************************************************
*
* Library functions and macros
*
* The following macros and functions are covers for the appropriate
* C library functions and expand out to the correct function
* depending on the _UNICODE, _DBCS and _SBCS macro settings.
*
* You should use the functions wherever possible, not the macros,
* as the functions provide type checking.
*
* Remember that the length of a string is not necessarily the
* same as its size!
*
******************************************************************/
#define _MBCast1(x) ((const unsigned char *)(x))
#define _MBCast2(x) ((unsigned char *)(x))
#ifdef _SBCS
#define A_StrLen(x) strlen(x)
#define A_StrSize(x) strlen(x)
#define A_StrCpy(d,s) strcpy(d,s)
#else
#define A_StrLen(x) (WString::OSIsMultiByte()?_mbslen(_MBCast1(x)):strlen(x))
#define A_StrSize(x) strlen(x)
#define A_StrCpy(d,s) (WString::OSIsMultiByte()?(WChar *)_mbscpy(_MBCast2(d),_MBCast1(s)):\
(WChar *)strcpy(d,s))
#endif
#define U_StrLen(x) wcslen(x)
#define U_StrSize(x) (wcslen(x)*sizeof(WUnicodeChar))
#define U_StrCpy(d,s) wcscpy(d,s)
#ifdef _UNICODE
#define D_StrLen(x) U_StrLen(x)
#define D_StrSize(x) U_StrSize(x)
#define D_StrCpy(d,s) U_StrCpy(d,s)
#else
#define D_StrLen(x) A_StrLen(x)
#define D_StrSize(x) A_StrSize(x)
#define D_StrCpy(d,s) A_StrCpy(d,s)
#endif
//
// WStrLen -- Return length of string in characters. (See StrSize for bytes.)
//
inline WULong WStrLen( const WChar *string ){
return D_StrLen( string );
}
//
// WStrSize -- Return length of string in bytes. (See StrLen for characters.)
//
inline WULong WStrSize( const WChar *string ){
return D_StrSize( string );
}
//
// WStrCpy -- Cover for strcpy.
//
inline WChar *WStrCpy( WChar *dst, const WChar *src ){
return D_StrCpy( dst, src );
}
#define WNullString WString::GetNullString()
#define WEmptyString WString::GetEmptyString()
#ifndef _WNO_PRAGMA_PUSH
#pragma enum pop;
#pragma pack(pop);
#endif
#endif // _WSTRING_HPP_INCLUDED