1099 lines
37 KiB
C++
1099 lines
37 KiB
C++
|
/**********************************************************************/
|
||
|
/** Microsoft Windows/NT **/
|
||
|
/** Copyright(c) Microsoft Corp., 1991 **/
|
||
|
/**********************************************************************/
|
||
|
|
||
|
/*
|
||
|
string.hxx
|
||
|
String classes: definition
|
||
|
|
||
|
This file contains the basic string classes for the Thor UI.
|
||
|
Its requirements are:
|
||
|
|
||
|
- provide a modestly object-oriented interface to string
|
||
|
manipulation, the better to work with the rest of our code;
|
||
|
|
||
|
- encapsulate NLS and DBCS support as much as possible;
|
||
|
|
||
|
- ensure that apps get correct form of library support,
|
||
|
particularly with possible interference from intrinsics;
|
||
|
|
||
|
The current solution consists of two classes: NLS_STR, and ISTR.
|
||
|
|
||
|
class NLS_STR: use wherever NLS/DBCS support is needed.
|
||
|
Most strings (in the UI, anyway) should be
|
||
|
of this class.
|
||
|
|
||
|
class ISTR: Indexes an NLS_STR in a DBCS safe manner. All
|
||
|
positioning within an NLS_STR is done with ISTRs
|
||
|
|
||
|
|
||
|
The class hierarchy looks like:
|
||
|
|
||
|
BASE
|
||
|
NLS_STR
|
||
|
ALLOC_STR
|
||
|
ALIAS_STR
|
||
|
RESOURCE_STR
|
||
|
|
||
|
ISTR
|
||
|
|
||
|
This file also contains the STACK_NLS_STR macro and the
|
||
|
strcpy( TCHAR *, const NLS_STR& ) prototype.
|
||
|
|
||
|
FILE HISTORY:
|
||
|
beng 21-Oct-1990 Created from email memo of last week
|
||
|
johnl 13-Nov-1990 Removed references to EB_STRING
|
||
|
johnl 28-Nov-1990 Release fully functional version
|
||
|
johnl 7-Dec-1990 Numerous revisions after code review
|
||
|
(Removed SZ_STR, ISTR must associate
|
||
|
w/a string upon decl etc.)
|
||
|
beng 05-Feb-1991 Replaced PCH with TCHAR * for
|
||
|
const-placement
|
||
|
beng 26-Apr-1991 Expunged of CB, IB types; relocated
|
||
|
inline functions to string/strmisc.cxx
|
||
|
beng 23-Jul-1991 Added more *_STR types
|
||
|
KeithMo 09-Oct-1991 Win32 Conversion.
|
||
|
beng 22-Oct-1991 Patch for NT C runtimes
|
||
|
KeithMo 23-Oct-1991 Added forward references.
|
||
|
beng 14-Nov-1991 Fixed CT_NLS_STR
|
||
|
beng 21-Nov-1991 Removed STR_OWNERALLOC opcodes
|
||
|
terryk 17-Apr-1992 Added atoul
|
||
|
beng 24-Apr-1992 Added CBNLSMAGIC
|
||
|
beng 28-Jul-1992 MAX_RES_STR_LEN is now advisory only;
|
||
|
update MAX_INSERT_PARAMS
|
||
|
KeithMo 24-Aug-1992 Added <string.h> for very bizarre reasons.
|
||
|
KeithMo 16-Nov-1992 Performance tuning.
|
||
|
*/
|
||
|
|
||
|
#ifndef _STRING_HXX_
|
||
|
#define _STRING_HXX_
|
||
|
|
||
|
#include "base.hxx"
|
||
|
|
||
|
//
|
||
|
// We *MUST* include string.h here!
|
||
|
//
|
||
|
// Why you ask? Simple. The "standard" string.h #defines a number of
|
||
|
// nonstandard string functions, such as:
|
||
|
//
|
||
|
// #define strupr _strupr
|
||
|
//
|
||
|
// This keeps the "real" _strupr out of the normal app namespace.
|
||
|
//
|
||
|
// Unfortunately, the C preprocess phase applies this #define to
|
||
|
// NLS_STR's member functions. So, if you include <string.h> *after*
|
||
|
// you include <string.hxx>, you won't be able to access any of the
|
||
|
// members with nonstandard names (such as strupr).
|
||
|
//
|
||
|
|
||
|
#include <string.h>
|
||
|
|
||
|
|
||
|
//
|
||
|
// CODEWORK: IS_LEAD_BYTE was ripped out of our hacked
|
||
|
// string.h. We need a more proper definition,
|
||
|
// especially for DBCS builds (such as Win32s).
|
||
|
//
|
||
|
|
||
|
#define IS_LEAD_BYTE(x) FALSE
|
||
|
|
||
|
|
||
|
// Maximum resource string size. At one time, owneralloc strings had be at
|
||
|
// least MAX_RES_STR_LEN characters long. While this is no longer the
|
||
|
// case, it's easier to keep the symbol than to change all the client code.
|
||
|
//
|
||
|
#define MAX_RES_STR_LEN 255
|
||
|
|
||
|
// The maximum number of parameters the InsertParams method can handle
|
||
|
//
|
||
|
#define MAX_INSERT_PARAMS 99
|
||
|
|
||
|
/* Magic number used for overloading cbCopy member functions */
|
||
|
|
||
|
#define CBNLSMAGIC ((UINT)-1)
|
||
|
|
||
|
|
||
|
// A token for "use the default base DLL HMODULE" for resource lookup.
|
||
|
#define NLS_BASE_DLL_HMOD 0
|
||
|
|
||
|
//
|
||
|
// Forward references.
|
||
|
//
|
||
|
|
||
|
DLL_CLASS NLS_STR;
|
||
|
DLL_CLASS ISTR;
|
||
|
DLL_CLASS RESOURCE_STR;
|
||
|
DLL_CLASS ALLOC_STR;
|
||
|
DLL_CLASS ALIAS_STR;
|
||
|
|
||
|
//
|
||
|
// Special debugging manifest for string class
|
||
|
//
|
||
|
// #define NLS_DEBUG
|
||
|
//
|
||
|
|
||
|
/*************************************************************************
|
||
|
|
||
|
NAME: ISTR
|
||
|
|
||
|
SYNOPSIS: String index object, used in conjunction with NLS_STR
|
||
|
|
||
|
INTERFACE:
|
||
|
ISTR() - this ISTR gets associated with
|
||
|
the passed string and can only be used
|
||
|
on this string (NOTE: on non-debug
|
||
|
versions this turns into a nop, can still
|
||
|
be useful for decl. clarity however).
|
||
|
|
||
|
ISTR() - Initialize to passed ISTR;
|
||
|
this ISTR will be associated with
|
||
|
the same string that the passed ISTR
|
||
|
is associated with.
|
||
|
|
||
|
operator=() - Copy passed ISTR (see prev.)
|
||
|
|
||
|
operator-() - Returns Cch diff. between *this & Param.
|
||
|
(must both belong to the same string)
|
||
|
|
||
|
operator++() - Advance the ISTR to the next logical
|
||
|
character (use only where absolutely
|
||
|
necessary). Stops at end of string
|
||
|
|
||
|
operator+=() - Advance the ISTR to the ith logical
|
||
|
character (call operator++ i times)
|
||
|
Stops at end of string.
|
||
|
|
||
|
operator==() - Returns TRUE if the two ISTRs point to
|
||
|
the same position in the string (causes
|
||
|
an assertion failure if the two ISTRs
|
||
|
don't point to the same string).
|
||
|
|
||
|
operator>() - Returns true of *this is greater then
|
||
|
the passed ISTR (i.e., further along
|
||
|
in the string).
|
||
|
|
||
|
operator<() - Same as operator>, only less then.
|
||
|
|
||
|
Reset() - Resets ISTR to beginning of string and
|
||
|
updates the ISTR version number with the
|
||
|
string's current version number
|
||
|
|
||
|
IsLastPos() - TRUE if istr indexes last character in
|
||
|
its string. (This would seem to belong
|
||
|
more properly as NLS_STR::QueryLastPos;
|
||
|
however, it's more efficient under DBCS
|
||
|
as a property of ISTR.)
|
||
|
|
||
|
USES:
|
||
|
|
||
|
CAVEATS:
|
||
|
Each NLS_STR has a version number associated with it. When
|
||
|
an operation is performed that modifies the string, the
|
||
|
version number is updated. It is invalid to use an ISTR
|
||
|
after its associated NLS_STR has been modified (can use
|
||
|
Reset to resync it with the NLS_STR, the index gets reset
|
||
|
to zero).
|
||
|
|
||
|
You must associate an NLS_STR with an ISTR at the
|
||
|
declaration of the ISTR.
|
||
|
|
||
|
Subtraction returns a signed difference, where it should probably
|
||
|
return an unsigned difference.
|
||
|
|
||
|
NOTES:
|
||
|
The version checking and string association checking goes
|
||
|
away in the non-debug version.
|
||
|
|
||
|
HISTORY:
|
||
|
johnl 16-Nov-1990 Created
|
||
|
johnl 7-Dec-1990 Modified after code review
|
||
|
yi-hsins 14-Oct-1991 Added IsLastPos
|
||
|
beng 19-Nov-1991 Unicode fixes
|
||
|
anirudhs 22-Apr-1995 Added operator INT, as in Win95
|
||
|
|
||
|
**************************************************************************/
|
||
|
|
||
|
DLL_CLASS ISTR
|
||
|
{
|
||
|
friend class NLS_STR;
|
||
|
|
||
|
public:
|
||
|
ISTR( const ISTR& istr );
|
||
|
ISTR( const NLS_STR& nls );
|
||
|
ISTR& operator=( const ISTR& istr );
|
||
|
|
||
|
INT operator-( const ISTR& istr ) const;
|
||
|
|
||
|
ISTR& operator++();
|
||
|
VOID operator+=( INT iChars );
|
||
|
|
||
|
BOOL operator==( const ISTR& istr ) const;
|
||
|
BOOL operator>( const ISTR& istr ) const;
|
||
|
BOOL operator<( const ISTR& istr ) const;
|
||
|
|
||
|
operator INT() const
|
||
|
{ return _ichString; }
|
||
|
|
||
|
VOID Reset();
|
||
|
BOOL IsLastPos() const;
|
||
|
|
||
|
private:
|
||
|
INT _ichString; // Index (in TCHAR) into an NLS_STR
|
||
|
const NLS_STR *_pnls; // Pointer to "owner" NLS
|
||
|
|
||
|
INT QueryIch() const
|
||
|
{ return _ichString; }
|
||
|
VOID SetIch( INT ich )
|
||
|
{ _ichString = ich; }
|
||
|
|
||
|
const NLS_STR* QueryString() const
|
||
|
{ return _pnls; }
|
||
|
VOID SetString( const NLS_STR * pnls )
|
||
|
{ _pnls = (NLS_STR*)pnls; }
|
||
|
|
||
|
#ifdef NLS_DEBUG
|
||
|
// Version number of NLS_STR this ISTR is associated with
|
||
|
//
|
||
|
UINT _nVersion;
|
||
|
|
||
|
UINT QueryVersion() const { return _nVersion; }
|
||
|
VOID SetVersion( UINT nVers ) { _nVersion = nVers; }
|
||
|
#endif
|
||
|
|
||
|
// This constructor does not exist, it is intended to make certain that
|
||
|
// no one tries to construct an ISTR like this. JonN 1/11/96
|
||
|
ISTR( LPTSTR str );
|
||
|
|
||
|
};
|
||
|
|
||
|
|
||
|
/*************************************************************************
|
||
|
|
||
|
NAME: NLS_STR (nls)
|
||
|
|
||
|
SYNOPSIS: Provide a better string abstraction than the standard ASCIIZ
|
||
|
representation offered by C (and C++). The abstraction is
|
||
|
better mainly because it handles double-byte characters
|
||
|
(DBCS) in the string and makes intelligent use of operator
|
||
|
overloading.
|
||
|
|
||
|
INTERFACE:
|
||
|
NLS_STR() Construct a NLS_STR (initialized to a TCHAR *,
|
||
|
NLS_STR or NULL). Reports errors via BASE.
|
||
|
|
||
|
~NLS_STR() Destructor
|
||
|
|
||
|
operator=() Assign one NLS_STR (or TCHAR *) value
|
||
|
to another (old string is deleted, new
|
||
|
string is allocated and copies source).
|
||
|
See also NLS_STR::CopyFrom().
|
||
|
operator+=() Concatenate with assignment (equivalent to
|
||
|
strcat - see strcat).
|
||
|
operator==() Compare two NLS_STRs for equality
|
||
|
operator!=() Compare two NLS_STRs for inequality
|
||
|
|
||
|
QueryPch() Access operator, returning a "const TCHAR *"
|
||
|
aliased to the string. DO NOT MODIFY
|
||
|
THE STRING USING THIS METHOD (or pass
|
||
|
it to procedures that might modify it).
|
||
|
Synonym: operator const TCHAR *().
|
||
|
|
||
|
C-runtime-style methods.
|
||
|
|
||
|
strlen() Return the length of the string in bytes,
|
||
|
less terminator. Provided only for crt
|
||
|
compatibility; please use a Query method
|
||
|
(QueryTextLength()
|
||
|
|
||
|
strcat() Append an NLS_STR. Will cause *this to be
|
||
|
reallocated if the appended string is larger
|
||
|
then this->QueryCb() and this is not an
|
||
|
STR_OWNERALLOC string
|
||
|
|
||
|
strcmp() Compare two NLS_STRs
|
||
|
stricmp()
|
||
|
strncmp() Compare a portion of two NLS_STRs
|
||
|
strnicmp()
|
||
|
|
||
|
strcspn() Find first char in *this that is in arg
|
||
|
strspn() Find first char in *this that is NOT in arg
|
||
|
strtok() Returns a token from the string
|
||
|
strstr() Search for a NLS_STR.
|
||
|
|
||
|
strchr() Search for a TCHAR from beginning.
|
||
|
Returns offset.
|
||
|
strrchr() Search for a TCHAR from end.
|
||
|
strupr() Convert NLS_STR to upper case.
|
||
|
RtlOemUpcase() Convert to upper case using
|
||
|
RplUpcaseUnicodeStringToOemString
|
||
|
atoi() Returns integer numeric value
|
||
|
atol() Returns long value
|
||
|
atoul() Returns unsigned long value
|
||
|
|
||
|
Other methods.
|
||
|
|
||
|
QueryTextLength() Returns the number of TCHAR, less
|
||
|
terminator.
|
||
|
|
||
|
QueryTextSize() Returns the number of bytes, including
|
||
|
terminator. Denotes amount of storage
|
||
|
needed to dup string into a bytevector.
|
||
|
|
||
|
QueryNumChar() Returns total number of logical characters
|
||
|
within the string. Rarely needed.
|
||
|
|
||
|
QueryAllocSize() Returns total # of bytes allocated (i.e.,
|
||
|
number new was called with, or size of
|
||
|
memory block if STR_OWNERALLOC
|
||
|
IsOwnerAlloc() Returns TRUE if this string is an owner
|
||
|
allocated string
|
||
|
QuerySubStr() Return a substring
|
||
|
InsertStr() Insert a NLS_STR at given index.
|
||
|
DelSubStr() Delete a substring
|
||
|
ReplSubStr() Replace a substring (given start and
|
||
|
NLS_STR)
|
||
|
|
||
|
InsertParams() Replace %1-%9 params in *this with the
|
||
|
corresponding NLS_STRs contained in the
|
||
|
array of pointers
|
||
|
|
||
|
Load() Load the string associated with the passed
|
||
|
resource into *this (OWNER_ALLOC strings must
|
||
|
be at least MAX_RES_STR_LEN).
|
||
|
|
||
|
Reset() After an operation fails (due to memory
|
||
|
failure), it is invalid to use the string
|
||
|
until Reset has been called. If the object
|
||
|
wasn't successfully constructed, Reset will
|
||
|
fail.
|
||
|
|
||
|
Append() Appends a string to the current string,
|
||
|
like strcat.
|
||
|
AppendChar() Appends a single character.
|
||
|
|
||
|
Compare() As strcmp(). Used by collection classes.
|
||
|
|
||
|
CopyFrom() As operator=(), but returns an APIERR.
|
||
|
CopyTo() Similar to strcpy, returning an APIERR.
|
||
|
|
||
|
MapCopyFrom() As CopyFrom(), but does Unicode/MBCS conversion
|
||
|
as appropriate to argument type and host env.
|
||
|
MapCopyTo() As MapCopyFrom(), but the other way around.
|
||
|
|
||
|
|
||
|
PARENT: BASE
|
||
|
|
||
|
USES: ISTR
|
||
|
|
||
|
CAVEATS:
|
||
|
A NLS_STR object can enter an error state for various
|
||
|
reasons - typically a memory allocation failure. Using
|
||
|
an object in such a state is theoretically an error.
|
||
|
Since string operations frequently occur in groups,
|
||
|
we define operations on an erroneous string as no-op,
|
||
|
so that the check for an error may be postponed until
|
||
|
the end of the complex operation. Most member functions
|
||
|
which calculate a value will treat an erroneous string
|
||
|
as having zero length; however, clients should not depend
|
||
|
on this.
|
||
|
|
||
|
Attempting to use an ISTR that is registered with another
|
||
|
string will cause an assertion failure.
|
||
|
|
||
|
Each NLS_STR has a version/modification flag that is also
|
||
|
stored in the the ISTR. An attempt to use an ISTR on an
|
||
|
NLS_STR that has been modified (by calling one of the methods
|
||
|
listed below) will cause an assertion failure. To use the
|
||
|
ISTR after a modifying method, you must first call ISTR::Reset
|
||
|
which will update the version in the ISTR. See the
|
||
|
method definition for more detail.
|
||
|
|
||
|
List of modifying methods:
|
||
|
All NLS::operator= methods
|
||
|
NLS::DelSubStr
|
||
|
NLS::ReplSubStr
|
||
|
NLS::InsertSubStr
|
||
|
|
||
|
N.b. The ISTR used as a starting index on the Substring
|
||
|
methods remains valid after the call.
|
||
|
|
||
|
NOTES:
|
||
|
The lack of a strlwr() method comes from a shortcoming
|
||
|
in the casemap tables. Sorry.
|
||
|
|
||
|
"Owner-alloc" strings are a special type of NLS_STR, available
|
||
|
only through certain derived classes. The client must supply
|
||
|
a buffer where the string data will reside, plus the size of
|
||
|
that block. NLS_STR will never resize or delete this buffer,
|
||
|
and performs no checking for writing beyond the end of the
|
||
|
string.
|
||
|
|
||
|
Valid uses of owner-alloc strings include static strings,
|
||
|
severe optimization, owner controlled memory allocation
|
||
|
or stack controlled memory allocation.
|
||
|
|
||
|
CODEWORK: Should add a fReadOnly flag.
|
||
|
|
||
|
HISTORY:
|
||
|
johnl 28-Nov-1990 First fully functioning version
|
||
|
johnl 7-Dec-1990 Incorporated code review changes
|
||
|
terryk 05-Apr-1991 add QueryNumChar method
|
||
|
beng 22-Jul-1991 Added more methods; separated fOwnerAlloc
|
||
|
from cbData
|
||
|
beng 07-Oct-1991 LoadString takes MSGID and uses APIERR
|
||
|
beng 18-Oct-1991 Renamed LoadString to Load (for Win32)
|
||
|
beng 14-Nov-1991 Unicode fixes
|
||
|
beng 21-Nov-1991 Withdrew stristr member function, some ctors;
|
||
|
made owner-alloc ctor protected
|
||
|
beng 27-Feb-1992 Create protected members for manipulation
|
||
|
of buffer by derived classes; add additional
|
||
|
InsertParams forms; withdrew Load+Insert
|
||
|
comb. form
|
||
|
beng 02-Mar-1992 Added MapCopy fcns, CopyTo
|
||
|
beng 28-Mar-1992 Withdrew strtok member from Unicode; give
|
||
|
{Map}CopyFrom an optional cbCopy param
|
||
|
beng 24-Apr-1992 Changed MapCopyTo magic cbCopy value
|
||
|
beng 05-Aug-1992 Added LoadSystem
|
||
|
jonn 04-Sep-1992 Compare() must be _CRTAPI1
|
||
|
|
||
|
**************************************************************************/
|
||
|
|
||
|
DLL_CLASS NLS_STR : public BASE
|
||
|
{
|
||
|
// Istr needs access to CheckIstr.
|
||
|
//
|
||
|
friend class ISTR;
|
||
|
|
||
|
// Alias-string op= needs r/w access to all ivars.
|
||
|
//
|
||
|
friend class ALIAS_STR;
|
||
|
|
||
|
public:
|
||
|
// Default constructor, creating an empty string.
|
||
|
//
|
||
|
NLS_STR();
|
||
|
|
||
|
// Create an empty string, but preallocated to accomodate "cchInitLen"
|
||
|
// characters, plus trailing NUL.
|
||
|
//
|
||
|
NLS_STR( UINT cchInit );
|
||
|
|
||
|
// Initialize from a NUL-terminated character vector.
|
||
|
//
|
||
|
NLS_STR( const TCHAR * pchInit );
|
||
|
|
||
|
// Initialize from an existing x_STRING.
|
||
|
//
|
||
|
NLS_STR( const NLS_STR & nlsInit );
|
||
|
|
||
|
#ifdef UNICODE
|
||
|
// Initialize from a non-NULL-terminated UNICODE character vector.
|
||
|
//
|
||
|
NLS_STR( const WCHAR * pchInit, USHORT cchInit );
|
||
|
#endif
|
||
|
|
||
|
~NLS_STR();
|
||
|
|
||
|
|
||
|
// Number of bytes the string uses (not including terminator)
|
||
|
// Cf. QueryTextLength and QueryTextSize.
|
||
|
//
|
||
|
UINT strlen() const;
|
||
|
|
||
|
// Number of logical characters within the string
|
||
|
//
|
||
|
UINT QueryNumChar() const;
|
||
|
|
||
|
// Number of printing TCHAR in the string.
|
||
|
// This number does not include the termination character.
|
||
|
//
|
||
|
// Cf. QueryNumChar, which returns a count of glyphs.
|
||
|
//
|
||
|
UINT _QueryTextLength() const;
|
||
|
UINT QueryTextLength() const
|
||
|
#if defined(DEBUG)
|
||
|
{ return _QueryTextLength(); }
|
||
|
#else // !DEBUG
|
||
|
{ return _cchLen; }
|
||
|
#endif // DEBUG
|
||
|
|
||
|
// Number of BYTES occupied by the string's representation.
|
||
|
// Cf. QueryAllocSize, which returns the total amount alloc'd.
|
||
|
//
|
||
|
UINT QueryTextSize() const;
|
||
|
|
||
|
#if defined(UNICODE) && defined(FE_SB)
|
||
|
// Number of bytes required for buffer.
|
||
|
// (just calling nls function)
|
||
|
//
|
||
|
UINT QueryAnsiTextLength() const;
|
||
|
#endif
|
||
|
|
||
|
// Return a read-only TCHAR vector, for the APIs.
|
||
|
//
|
||
|
const TCHAR * QueryPch( const ISTR & istr ) const;
|
||
|
const TCHAR * _QueryPch() const;
|
||
|
const TCHAR * QueryPch() const
|
||
|
#if defined(DEBUG)
|
||
|
{ return _QueryPch(); }
|
||
|
#else // !DEBUG
|
||
|
{ return _pchData; }
|
||
|
#endif // DEBUG
|
||
|
|
||
|
WCHAR QueryChar( const ISTR & istr ) const;
|
||
|
|
||
|
operator const TCHAR *() const
|
||
|
#if defined(DEBUG)
|
||
|
{ return _QueryPch(); }
|
||
|
#else // !DEBUG
|
||
|
{ return _pchData; }
|
||
|
#endif // DEBUG
|
||
|
|
||
|
const TCHAR * operator[]( const ISTR & istr ) const
|
||
|
{ return QueryPch(istr); }
|
||
|
|
||
|
APIERR Append( const NLS_STR & nls );
|
||
|
APIERR AppendChar( WCHAR wch );
|
||
|
|
||
|
// Total allocated storage
|
||
|
//
|
||
|
|
||
|
UINT _QueryAllocSize() const;
|
||
|
UINT QueryAllocSize() const
|
||
|
#if defined(DEBUG)
|
||
|
{ return _QueryAllocSize(); }
|
||
|
#else // !DEBUG
|
||
|
{ return _cbData; }
|
||
|
#endif // DEBUG
|
||
|
|
||
|
BOOL _IsOwnerAlloc() const;
|
||
|
BOOL IsOwnerAlloc() const
|
||
|
#if defined(DEBUG)
|
||
|
{ return _IsOwnerAlloc(); }
|
||
|
#else // !DEBUG
|
||
|
{ return _fOwnerAlloc; }
|
||
|
#endif // DEBUG
|
||
|
|
||
|
// Returns TRUE if error was successfully cleared (string is
|
||
|
// now in valid state), FALSE otherwise.
|
||
|
//
|
||
|
BOOL Reset();
|
||
|
|
||
|
|
||
|
NLS_STR & operator = ( const NLS_STR & nlsSource );
|
||
|
NLS_STR & operator = ( const TCHAR * achSource );
|
||
|
|
||
|
APIERR CopyFrom( const NLS_STR & nlsSource );
|
||
|
APIERR CopyFrom( const TCHAR * achSource, UINT cbCopy = CBNLSMAGIC );
|
||
|
APIERR CopyTo( TCHAR * pchDest, UINT cbAvailable ) const;
|
||
|
|
||
|
NLS_STR & operator += ( const NLS_STR & nls );
|
||
|
|
||
|
NLS_STR & strcat( const NLS_STR & nls );
|
||
|
|
||
|
BOOL operator == ( const NLS_STR & nls ) const;
|
||
|
BOOL operator != ( const NLS_STR & nls ) const;
|
||
|
|
||
|
INT strcmp( const NLS_STR & nls ) const;
|
||
|
INT strcmp( const NLS_STR & nls,
|
||
|
const ISTR & istrThis ) const;
|
||
|
INT strcmp( const NLS_STR & nls,
|
||
|
const ISTR & istrThis,
|
||
|
const ISTR & istrStart2 ) const;
|
||
|
|
||
|
INT _stricmp( const NLS_STR & nls ) const;
|
||
|
INT _stricmp( const NLS_STR & nls,
|
||
|
const ISTR & istrThis ) const;
|
||
|
INT _stricmp( const NLS_STR & nls,
|
||
|
const ISTR & istrThis,
|
||
|
const ISTR & istrStart2 ) const;
|
||
|
|
||
|
INT strncmp( const NLS_STR & nls,
|
||
|
const ISTR & istrLen ) const;
|
||
|
INT strncmp( const NLS_STR & nls,
|
||
|
const ISTR & istrLen,
|
||
|
const ISTR & istrThis ) const;
|
||
|
INT strncmp( const NLS_STR & nls,
|
||
|
const ISTR & istrLen,
|
||
|
const ISTR & istrThis ,
|
||
|
const ISTR & istrStart2 ) const;
|
||
|
|
||
|
INT _strnicmp( const NLS_STR & nls,
|
||
|
const ISTR & istrLen ) const;
|
||
|
INT _strnicmp( const NLS_STR & nls,
|
||
|
const ISTR & istrLen,
|
||
|
const ISTR & istrThis ) const;
|
||
|
INT _strnicmp( const NLS_STR & nls,
|
||
|
const ISTR & istrLen,
|
||
|
const ISTR & istrThis ,
|
||
|
const ISTR & istrStart2 ) const;
|
||
|
|
||
|
// The following str* functions return TRUE if successful (istrPos has
|
||
|
// meaningful data), false otherwise.
|
||
|
//
|
||
|
BOOL strcspn( ISTR * istrPos,
|
||
|
const NLS_STR & nls ) const;
|
||
|
BOOL strcspn( ISTR * istrPos,
|
||
|
const NLS_STR & nls,
|
||
|
const ISTR & istrStart ) const;
|
||
|
BOOL strspn( ISTR * istrPos,
|
||
|
const NLS_STR & nls ) const;
|
||
|
BOOL strspn( ISTR * istrPos,
|
||
|
const NLS_STR & nls,
|
||
|
const ISTR & istrStart ) const;
|
||
|
|
||
|
BOOL strstr( ISTR * istrPos,
|
||
|
const NLS_STR & nls ) const;
|
||
|
BOOL strstr( ISTR * istrPos,
|
||
|
const NLS_STR & nls,
|
||
|
const ISTR & istrStart ) const;
|
||
|
|
||
|
BOOL strchr( ISTR * istrPos,
|
||
|
const TCHAR ch ) const;
|
||
|
BOOL strchr( ISTR * istrPos,
|
||
|
const TCHAR ch,
|
||
|
const ISTR & istrStart ) const;
|
||
|
|
||
|
BOOL strrchr( ISTR * istrPos,
|
||
|
const TCHAR ch ) const;
|
||
|
BOOL strrchr( ISTR * istrPos,
|
||
|
const TCHAR ch,
|
||
|
const ISTR & istrStart ) const;
|
||
|
#if !defined(UNICODE)
|
||
|
// Runtime support currently not available
|
||
|
BOOL strtok( ISTR * istrPos,
|
||
|
const NLS_STR & nlsBreak,
|
||
|
BOOL fFirst = FALSE );
|
||
|
#endif
|
||
|
|
||
|
LONG atol() const;
|
||
|
LONG atol( const ISTR &istrStart ) const;
|
||
|
|
||
|
ULONG atoul() const;
|
||
|
ULONG atoul( const ISTR &istrStart ) const;
|
||
|
|
||
|
INT atoi() const;
|
||
|
INT atoi( const ISTR &istrStart ) const;
|
||
|
|
||
|
NLS_STR& _strupr();
|
||
|
|
||
|
// Upcase the string using RtlUpcaseUnicodeStringToOemString and
|
||
|
// then converting back to Unicode. This method of uppercasing
|
||
|
// works better than strupr() when the string is sent to a client
|
||
|
// which wants OEM.
|
||
|
//
|
||
|
APIERR RtlOemUpcase();
|
||
|
|
||
|
// Return a pointer to a new NLS_STR that contains the contents
|
||
|
// of *this from istrStart to:
|
||
|
// End of string if no istrEnd is passed
|
||
|
// istrStart + istrEnd
|
||
|
//
|
||
|
NLS_STR *QuerySubStr( const ISTR & istrStart ) const;
|
||
|
NLS_STR *QuerySubStr( const ISTR & istrStart,
|
||
|
const ISTR & istrEnd ) const;
|
||
|
|
||
|
// Collapse the string by removing the characters from istrStart to:
|
||
|
// End of string
|
||
|
// istrStart + istrEnd
|
||
|
// The string is not reallocated
|
||
|
//
|
||
|
VOID DelSubStr( ISTR & istrStart );
|
||
|
VOID DelSubStr( ISTR & istrStart,
|
||
|
const ISTR & istrEnd );
|
||
|
|
||
|
BOOL InsertStr( const NLS_STR & nlsIns,
|
||
|
ISTR & istrStart );
|
||
|
|
||
|
// Replace till End of string of either *this or replacement string
|
||
|
// (or istrEnd in the 2nd form) starting at istrStart
|
||
|
//
|
||
|
VOID ReplSubStr( const NLS_STR & nlsRepl,
|
||
|
ISTR & istrStart );
|
||
|
VOID ReplSubStr( const NLS_STR & nlsRepl,
|
||
|
ISTR & istrStart,
|
||
|
const ISTR & istrEnd );
|
||
|
|
||
|
// Replace %1-%9 in *this with corresponding index from apnlsParams
|
||
|
// Ex. if *this="Error %1" and apnlsParams[0]="Foo" the resultant
|
||
|
// string would be "Error Foo"
|
||
|
//
|
||
|
APIERR InsertParams( const NLS_STR ** apnlsParams );
|
||
|
|
||
|
// Use varargs on stack instead of vector of pointers
|
||
|
//
|
||
|
APIERR InsertParams( UINT cpnlsArgs, const NLS_STR * arg1, ... );
|
||
|
|
||
|
// Other forms of InsertParams
|
||
|
//
|
||
|
APIERR InsertParams( const NLS_STR & arg )
|
||
|
{ return InsertParams( 1, &arg ); }
|
||
|
APIERR InsertParams( const NLS_STR & arg1, const NLS_STR & arg2 )
|
||
|
{ return InsertParams( 2, &arg1, &arg2 ); }
|
||
|
APIERR InsertParams( const NLS_STR & arg1, const NLS_STR & arg2,
|
||
|
const NLS_STR & arg3 )
|
||
|
{ return InsertParams( 3, &arg1, &arg2, &arg3 ); }
|
||
|
APIERR InsertParams( const NLS_STR & arg1, const NLS_STR & arg2,
|
||
|
const NLS_STR & arg3, const NLS_STR & arg4 )
|
||
|
{ return InsertParams( 4, &arg1, &arg2, &arg3, &arg4 ); }
|
||
|
APIERR InsertParams( const NLS_STR & arg1, const NLS_STR & arg2,
|
||
|
const NLS_STR & arg3, const NLS_STR & arg4,
|
||
|
const NLS_STR & arg5 )
|
||
|
{ return InsertParams( 5, &arg1, &arg2, &arg3, &arg4, &arg5 ); }
|
||
|
|
||
|
// Load a message from a resource file into *this. If string is an
|
||
|
// OWNER_ALLOC string, then must be at least MAX_RES_STR_LEN. Heap
|
||
|
// NLS_STRs will be reallocated as necessary.
|
||
|
//
|
||
|
APIERR Load( MSGID msgid );
|
||
|
#if defined(WIN32)
|
||
|
APIERR LoadSystem( MSGID msgid );
|
||
|
#endif
|
||
|
|
||
|
// Load a message from the given resource file. If NULL, the base
|
||
|
// NETUI DLL's HMODULE is used.
|
||
|
APIERR Load( MSGID msgid, HMODULE hmod );
|
||
|
|
||
|
// Used by collection classes
|
||
|
//
|
||
|
INT __cdecl Compare( const NLS_STR * pnls ) const;
|
||
|
|
||
|
#if defined(WIN32)
|
||
|
// Functions for MBCS/Unicode conversion (Win32 environment only).
|
||
|
// Note that these explicitly reference CHAR and WCHAR instead of the
|
||
|
// transmutable TCHAR type.
|
||
|
//
|
||
|
APIERR MapCopyFrom( const WCHAR * pwszSource, UINT cbCopy = CBNLSMAGIC );
|
||
|
APIERR MapCopyFrom( const CHAR * pszSource, UINT cbCopy = CBNLSMAGIC );
|
||
|
APIERR MapCopyTo( WCHAR * pwchDest, UINT cb ) const;
|
||
|
APIERR MapCopyTo( CHAR * pchDest, UINT cb ) const;
|
||
|
#endif
|
||
|
|
||
|
protected:
|
||
|
// The "owner-alloc" form:
|
||
|
// Initialize an NLS_STR to memory position passed as achInit.
|
||
|
// No memory allocation of any type will be performed on this string.
|
||
|
// cbSize should be the total memory size of the buffer. Set fClear
|
||
|
// to reset the buffer to the empty string.
|
||
|
//
|
||
|
NLS_STR( TCHAR * pchInit, UINT cbSize, BOOL fClear );
|
||
|
|
||
|
// (more protected members follow the "private" section)
|
||
|
|
||
|
private:
|
||
|
BOOL _fOwnerAlloc; // Set if owner-alloc string
|
||
|
|
||
|
UINT _cchLen; // Number of TCHAR string uses, less terminator
|
||
|
UINT _cbData; // Total storage allocated, in bytes
|
||
|
TCHAR * _pchData; // Pointer to Storage
|
||
|
|
||
|
#ifdef NLS_DEBUG
|
||
|
UINT _nVersion; // Version count (inc. after each change)
|
||
|
#endif
|
||
|
|
||
|
// The following substring functions are used internally (can't be
|
||
|
// exposed since they take an INT cchLen parameter,
|
||
|
// possibly referencing half a double-byte character).
|
||
|
//
|
||
|
VOID DelSubStr( ISTR & istrStart,
|
||
|
UINT cchLen );
|
||
|
|
||
|
NLS_STR *QuerySubStr( const ISTR & istrStart,
|
||
|
UINT cchLen ) const;
|
||
|
|
||
|
VOID ReplSubStr( const NLS_STR & nlsRepl,
|
||
|
ISTR & istrStart,
|
||
|
UINT cchLen );
|
||
|
|
||
|
// Helper function for InsertParams
|
||
|
//
|
||
|
APIERR InsertParamsAux( const NLS_STR ** apnlsParams,
|
||
|
UINT cParams, BOOL fDoReplace,
|
||
|
UINT * pcchRequired );
|
||
|
|
||
|
// Allocate memory for a string
|
||
|
//
|
||
|
BOOL Alloc( UINT cchRequested );
|
||
|
|
||
|
// Increase the size of a string preserving its contents.
|
||
|
// Returns TRUE if successful, false otherwise.
|
||
|
//
|
||
|
// Reallocations to a smaller size always succeed (no-op).
|
||
|
// Reallocations to a larger size hit the allocator; even in failure,
|
||
|
// the contents of the string remain.
|
||
|
//
|
||
|
// If called on an owner-alloc string, the request must not exceed the
|
||
|
// original allocation.
|
||
|
//
|
||
|
BOOL Realloc( UINT cchRequested );
|
||
|
|
||
|
// CheckIstr checks whether istr is associated with this, asserts out
|
||
|
// if it is not. Also checks version numbers in debug version.
|
||
|
//
|
||
|
VOID CheckIstr( const ISTR& istr ) const;
|
||
|
|
||
|
// UpdateIstr syncs the version number between *this and the passed
|
||
|
// ISTR. This is for operations that cause an update to the string
|
||
|
// but the ISTR that was passed in is still valid (see InsertSubStr).
|
||
|
//
|
||
|
VOID UpdateIstr( ISTR *pistr ) const
|
||
|
#ifdef NLS_DEBUG
|
||
|
{ pistr->SetVersion( QueryVersion() ); }
|
||
|
#else
|
||
|
{ UNREFERENCED(pistr); }
|
||
|
#endif
|
||
|
|
||
|
// QueryVersion returns the current version number of this string
|
||
|
//
|
||
|
UINT QueryVersion() const
|
||
|
#ifdef NLS_DEBUG
|
||
|
{ return _nVersion; }
|
||
|
#else
|
||
|
{ return 0xBAD0; }
|
||
|
#endif
|
||
|
|
||
|
protected:
|
||
|
// These let derived strings manipulate the buffer directly.
|
||
|
// On their own head be it if they overwrite end-of-buffer.
|
||
|
//
|
||
|
TCHAR * QueryData() const
|
||
|
{ return _pchData; }
|
||
|
VOID SetTextLength( UINT cch )
|
||
|
{ _cchLen = cch; }
|
||
|
|
||
|
// IncVers adds one to this strings version number because the previous
|
||
|
// operation caused the contents to change thus possibly rendering
|
||
|
// ISTRs on this string as invalid.
|
||
|
//
|
||
|
VOID IncVers()
|
||
|
#ifdef NLS_DEBUG
|
||
|
{ _nVersion++; }
|
||
|
#else
|
||
|
{ ; }
|
||
|
#endif
|
||
|
|
||
|
// InitializeVers sets the version number to 0
|
||
|
//
|
||
|
VOID InitializeVers()
|
||
|
#ifdef NLS_DEBUG
|
||
|
{ _nVersion = 0; }
|
||
|
#else
|
||
|
{ ; }
|
||
|
#endif
|
||
|
|
||
|
private:
|
||
|
//
|
||
|
// All "empty" strings will initially contain this pointer.
|
||
|
//
|
||
|
|
||
|
static TCHAR * _pszEmptyString;
|
||
|
};
|
||
|
|
||
|
|
||
|
/********************************************************************
|
||
|
|
||
|
strcpy( TCHAR *, const NLS_STR & )
|
||
|
|
||
|
Copies the contents of a string into a char buffer.
|
||
|
Returns the destination string.
|
||
|
|
||
|
*********************************************************************/
|
||
|
|
||
|
DLL_BASED
|
||
|
TCHAR * strcpy( TCHAR * pchDest, const NLS_STR& nls );
|
||
|
|
||
|
|
||
|
/*************************************************************************
|
||
|
|
||
|
NAME: RESOURCE_STR
|
||
|
|
||
|
SYNOPSIS: String loaded from a resourcefile
|
||
|
|
||
|
INTERFACE: RESOURCE_STR() - ctor, taking only the resource ID.
|
||
|
|
||
|
PARENT: NLS_STR
|
||
|
|
||
|
CAVEATS:
|
||
|
These strings may not be owner-alloc. Clients who
|
||
|
desire an owner-alloc string - say, perhaps where the
|
||
|
string will be locked down for a very long time and
|
||
|
might fragment the heap - should create the RESOURCE_STR,
|
||
|
then cons up a new ALLOC_STR and copy this into that.
|
||
|
That way the client doesn't have to fool with
|
||
|
MAX_RES_STR_LEN.
|
||
|
|
||
|
HISTORY:
|
||
|
beng 22-Jul-1991 Created
|
||
|
beng 07-Oct-1991 Uses MSGID
|
||
|
beng 13-Nov-1991 Added op=
|
||
|
|
||
|
**************************************************************************/
|
||
|
|
||
|
DLL_CLASS RESOURCE_STR: public NLS_STR
|
||
|
{
|
||
|
public:
|
||
|
RESOURCE_STR( MSGID idResource );
|
||
|
|
||
|
RESOURCE_STR( MSGID idResource, HMODULE hmod );
|
||
|
|
||
|
RESOURCE_STR & operator=( const TCHAR * pszSource )
|
||
|
{ return (RESOURCE_STR&) NLS_STR::operator=( pszSource ); }
|
||
|
};
|
||
|
|
||
|
|
||
|
/*************************************************************************
|
||
|
|
||
|
NAME: ALLOC_STR
|
||
|
|
||
|
SYNOPSIS: String w/ storage allocated by client.
|
||
|
Such a string has fixed maximum length, of course.
|
||
|
|
||
|
INTERFACE: ALLOC_STR() - ctor
|
||
|
|
||
|
PARENT: NLS_STR
|
||
|
|
||
|
NOTES:
|
||
|
This class replaces the public STR_OWNERALLOC constructors
|
||
|
of NLS_STR.
|
||
|
|
||
|
CAVEATS:
|
||
|
The forms which take a byte-count always clear their
|
||
|
string to empty.
|
||
|
|
||
|
HISTORY:
|
||
|
beng 22-Jul-1991 Separated from NLS_STR
|
||
|
beng 13-Nov-1991 Added op=
|
||
|
beng 21-Nov-1991 Removed STR_OWNERALLOC
|
||
|
|
||
|
**************************************************************************/
|
||
|
|
||
|
DLL_CLASS ALLOC_STR: public NLS_STR
|
||
|
{
|
||
|
public:
|
||
|
ALLOC_STR( TCHAR * pszBuffer )
|
||
|
: NLS_STR( pszBuffer, 0, FALSE ) { }
|
||
|
ALLOC_STR( TCHAR * pchBuffer, UINT cbBuffer )
|
||
|
: NLS_STR(pchBuffer, cbBuffer, TRUE) { }
|
||
|
ALLOC_STR( TCHAR * pchBuffer, UINT cbBuffer, const TCHAR * pchInit );
|
||
|
// (implementation moved outline)
|
||
|
|
||
|
ALLOC_STR & operator=( const TCHAR * pszSource )
|
||
|
{ return (ALLOC_STR&) NLS_STR::operator=( pszSource ); }
|
||
|
};
|
||
|
|
||
|
|
||
|
/*************************************************************************
|
||
|
|
||
|
NAME: ALIAS_STR
|
||
|
|
||
|
SYNOPSIS: A NLS_STR alias to a static, readonly string.
|
||
|
|
||
|
INTERFACE: ALIAS_STR() - constructor, taking the string to
|
||
|
alias as its sole parameter
|
||
|
|
||
|
PARENT: NLS_STR
|
||
|
|
||
|
CAVEATS:
|
||
|
All instances of this class should be created "const."
|
||
|
|
||
|
NOTES:
|
||
|
This class replaces STR_OWNERALLOC et al.
|
||
|
|
||
|
HISTORY:
|
||
|
beng 23-Jul-1991 Created
|
||
|
beng 13-Nov-1991 Added op=
|
||
|
beng 21-Nov-1991 Removed STR_OWNERALLOC
|
||
|
|
||
|
**************************************************************************/
|
||
|
|
||
|
DLL_CLASS ALIAS_STR: public NLS_STR
|
||
|
{
|
||
|
friend class NLS_STR ; // BUGBUG: Why does STRCAT.CXX require this?
|
||
|
public:
|
||
|
ALIAS_STR( const TCHAR * pszSource )
|
||
|
: NLS_STR( (TCHAR*)pszSource, 0, FALSE ) { }
|
||
|
|
||
|
// Assignment to an alias string sets it to alias the new argument.
|
||
|
//
|
||
|
const ALIAS_STR & operator=( const TCHAR * pszSource );
|
||
|
|
||
|
// If you assign a nlsstr to an aliasstr, that nlsstr must have been
|
||
|
// owner-alloc (i.e. an allocstr or another aliasstr), in which case
|
||
|
// it will alias that string's data.
|
||
|
//
|
||
|
const ALIAS_STR & operator=( const NLS_STR & nlsSource );
|
||
|
};
|
||
|
|
||
|
|
||
|
/********************************************************************
|
||
|
|
||
|
Macros with which to define owner-alloc strings on the stack.
|
||
|
|
||
|
STACK_NLS_STR(name, cchLen): define a string on the stack with
|
||
|
the given name and available length in characters. It will
|
||
|
be initialized to empty.
|
||
|
|
||
|
E.g.: STACK_NLS_STR(nlsUnc, MAX_PATH)
|
||
|
|
||
|
ISTACK_NLS_STR(name, cchLen, pszInit): same as STACK_NLS_STR,
|
||
|
except it takes an initializer.
|
||
|
|
||
|
*********************************************************************/
|
||
|
|
||
|
#define STACK_NLS_STR( name, len ) \
|
||
|
TCHAR _tmp##name[ len+1 ] ; \
|
||
|
ALLOC_STR name( _tmp##name, sizeof(_tmp##name) );
|
||
|
|
||
|
#define ISTACK_NLS_STR( name, len, pszInit ) \
|
||
|
TCHAR _tmp##name[ len+1 ] ; \
|
||
|
ALLOC_STR name( _tmp##name, sizeof(_tmp##name), pszInit ); \
|
||
|
|
||
|
|
||
|
/********************************************************************
|
||
|
|
||
|
Macros with which to define owner-alloc strings within a class
|
||
|
definition.
|
||
|
|
||
|
DECL_CLASS_NLS_STR( name, cchLen ): creates a string as part of
|
||
|
the declaration's class. Creates a suitable character buffer
|
||
|
as well.
|
||
|
|
||
|
CT_NLS_STR( name ): member constructor for a string declared
|
||
|
with DECL_CLASS_NLS_STR.
|
||
|
|
||
|
CT_INIT_NLS_STR( name, pszInit ): same as CT_NLS_STR, except it
|
||
|
takes an initializer.
|
||
|
|
||
|
E.g.:
|
||
|
|
||
|
class FOO
|
||
|
{
|
||
|
public:
|
||
|
FOO();
|
||
|
|
||
|
private:
|
||
|
DECL_CLASS_NLS_STR( nlsComment, MAX_COMMENT_SIZE );
|
||
|
...
|
||
|
};
|
||
|
|
||
|
FOO::FOO() : CT_NLS_STR( nlsComment )
|
||
|
{
|
||
|
....
|
||
|
}
|
||
|
|
||
|
*********************************************************************/
|
||
|
|
||
|
#define DECL_CLASS_NLS_STR( name, len ) \
|
||
|
TCHAR __sz_##name[len+1] ; \
|
||
|
ALLOC_STR name
|
||
|
|
||
|
#define CT_NLS_STR( name ) \
|
||
|
name( __sz_##name, sizeof( __sz_##name ) )
|
||
|
|
||
|
#define CT_INIT_NLS_STR( name, pszInit ) \
|
||
|
name( __sz_##name, sizeof( __sz_##name ), pszInit )
|
||
|
|
||
|
|
||
|
#endif // _STRING_HXX_
|