|
|
/**************************************************************************\
* * Copyright (c) 1999 Microsoft Corporation * * Module Name: * * Unicode strings * * Abstract: * * Functions and classes which deal with Unicode strings * * Revision History: * * 02/22/1999 davidx * Created it. * 09/08/1999 agodfrey * Moved to Runtime\unicode.hpp * \**************************************************************************/
#ifndef _UNICODE_HPP
#define _UNICODE_HPP
namespace GpRuntime { // These are replacements for some of the C runtime functions.
size_t UnicodeStringLength(const WCHAR *str); WCHAR * UnicodeStringDuplicate(const WCHAR *strSource); INT UnicodeStringCompare(const WCHAR *str1, const WCHAR *str2); extern "C" INT UnicodeStringCompareCI(const WCHAR *str1, const WCHAR *str2); INT UnicodeStringCompareCount(const WCHAR* str1, const WCHAR* str2, size_t count); INT UnicodeStringCompareCICount(const WCHAR* str1, const WCHAR* str2, size_t count); void UnicodeStringCopy(WCHAR *dest, const WCHAR *src); void UnicodeStringCopyCount(WCHAR *dest, const WCHAR *src, size_t count); void UnicodeStringToUpper(WCHAR* dest, WCHAR* src); WCHAR * UnicodeStringConcat(WCHAR *dest, const WCHAR *src); WCHAR * UnicodeStringReverseSearch(const WCHAR* str, WCHAR ch); BOOL UnicodeStringIIsEqual( const WCHAR* str1, const WCHAR* str2u, const WCHAR* str2l );
inline BOOL UnicodeToAnsiStr( const WCHAR* unicodeStr, CHAR* ansiStr, INT ansiSize ) { return WideCharToMultiByte( CP_ACP, 0, unicodeStr, -1, ansiStr, ansiSize, NULL, NULL) > 0; }
class AnsiStrFromUnicode { private: // We now use an ObjectTag to determine if the object is valid
// instead of using a BOOL. This is much more robust and helps
// with debugging. It also enables us to version our objects
// more easily with a version number in the ObjectTag.
ObjectTag Tag; // Keep this as the 1st value in the object!
VOID SetValid(BOOL valid) { Tag = valid ? ObjectTagAnsiStrFromUnicode : ObjectTagInvalid; }
public:
AnsiStrFromUnicode(const WCHAR* unicodeStr) { if (unicodeStr == NULL) { SetValid(TRUE); ansiStr = NULL; } else { SetValid(UnicodeToAnsiStr(unicodeStr, buf, MAX_PATH)); ansiStr = IsValid() ? buf : NULL; } }
~AnsiStrFromUnicode() { SetValid(FALSE); // so we don't use a deleted object
}
BOOL IsValid() const { ASSERT((Tag == ObjectTagAnsiStrFromUnicode) || (Tag == ObjectTagInvalid)); #if DBG
if (Tag == ObjectTagInvalid) { WARNING1("Invalid AnsiStrFromUnicode"); } #endif
return (Tag == ObjectTagAnsiStrFromUnicode); }
operator CHAR*() { return ansiStr; }
private:
CHAR* ansiStr; CHAR buf[MAX_PATH]; };
inline BOOL AnsiToUnicodeStr( const CHAR* ansiStr, WCHAR* unicodeStr, INT unicodeSize ) { return MultiByteToWideChar( CP_ACP, 0, ansiStr, -1, unicodeStr, unicodeSize) > 0; }
class UnicodeStrFromAnsi { private: // We now use an ObjectTag to determine if the object is valid
// instead of using a BOOL. This is much more robust and helps
// with debugging. It also enables us to version our objects
// more easily with a version number in the ObjectTag.
ObjectTag Tag; // Keep this as the 1st value in the object!
VOID SetValid(BOOL valid) { Tag = valid ? ObjectTagUnicodeStrFromAnsi : ObjectTagInvalid; }
public:
UnicodeStrFromAnsi(const CHAR* ansiStr) { if (ansiStr == NULL) { SetValid(TRUE); unicodeStr = NULL; } else { SetValid(AnsiToUnicodeStr(ansiStr, buf, MAX_PATH)); unicodeStr = IsValid() ? buf : NULL; } }
~UnicodeStrFromAnsi() { SetValid(FALSE); // so we don't use a deleted object
}
BOOL IsValid() const { ASSERT((Tag == ObjectTagUnicodeStrFromAnsi) || (Tag == ObjectTagInvalid)); #if DBG
if (Tag == ObjectTagInvalid) { WARNING1("Invalid UnicodeStrFromAnsi"); } #endif
return (Tag == ObjectTagUnicodeStrFromAnsi); }
operator WCHAR*() { return unicodeStr; }
private:
WCHAR* unicodeStr; WCHAR buf[MAX_PATH]; };
//--------------------------------------------------------------------------
// Represent a simple immutable Unicode string object used internally
// by GDI+ implementation. A string is represented by pieces of
// information:
// - pointer to the character buffer
// - number of characters in the string
//
// [agodfrey] Ack! Yet another string class. I'm just moving it here
// to be with its mates. It came from BaseTypes.hpp.
//--------------------------------------------------------------------------
class GpString { public:
// NOTE:
// We're not making a copy of the characters here. Instead,
// we simply remember the character pointer. We assume the
// caller will ensure the input pointer's lifetime is longer
// than that of the newly constructed GpString object.
GpString(const WCHAR* str, UINT len) { Buf = str; Len = len; }
GpString(const WCHAR* str) { Buf = str; Len = UnicodeStringLength(str); }
BOOL IsNull() const { return Buf == NULL; }
const WCHAR* GetBuf() const { return Buf; }
UINT GetLen() const { return Len; }
// Return a copy of the string as a NUL-terminated C string.
// Caller should call GpFree on the returned pointer after
// it finishes using the C string.
WCHAR* GetCString() const;
protected:
const WCHAR* Buf; UINT Len; };
}
#endif // !_UNICODE_HPP
|