264 lines
6.3 KiB
C++
264 lines
6.3 KiB
C++
/**************************************************************************\
|
|
*
|
|
* 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
|
|
|