Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

521 lines
13 KiB

////////////////////////////////////////////////////////////////////////////////
//
// Filename : VarStr.h
// Purpose : To hold definition for CVarString
//
// Project : Persistent Query
// Component: Common
//
// Author : urib
//
// Log:
// Feb 2 1997 urib Creation
// Jun 19 1997 urib Add counted operators.
// Jun 24 1997 urib Fix bad const declarations.
// Dec 29 1997 urib Add includes.
// Feb 2 1999 yairh fix bug in SetMinimalSize.
// Feb 8 1999 urib Enable different built in sizes.
// Feb 25 1999 urib Add SizedStringCopy.
// Jul 5 1999 urib Fix SizedStringCopy..
// May 1 2000 urib Cleanup.
// Nov 23 2000 urib Fix a bug in counted copy and cat.
//
////////////////////////////////////////////////////////////////////////////////
#ifndef VARSTR_H
#define VARSTR_H
#pragma once
#include "AutoPtr.h"
#include "Excption.h"
////////////////////////////////////////////////////////////////////////////////
//
// CVarString class definition
//
////////////////////////////////////////////////////////////////////////////////
template <ULONG ulStackSize = 0x10>
class TVarString
{
public:
// Constructor - tips the implementation on the string size.
TVarString(ULONG ulInitialSize = 0);
// Constructor - copy this string.
TVarString(PCWSTR);
// Constructor - convert to UNICODE and copy this string.
TVarString(const PSZ);
// Copy Constructor
TVarString(const TVarString&);
~TVarString();
// Copy/Convert and copy the string.
TVarString& Cpy(PCWSTR);
TVarString& Cpy(const ULONG, PCWSTR);
TVarString& Cpy(const PSZ);
// Concatenate/Convert and concatenate the string to the existing string.
TVarString& Cat(PCWSTR);
TVarString& Cat(const ULONG, PCWSTR);
TVarString& Cat(const PSZ);
// Compare/Convert and compare the string to the existing string.
int Cmp(PCWSTR) const;
int Cmp(const PSZ) const;
// Return the string length.
ULONG Len() const;
// Allow access to the string memory.
operator PWSTR() const;
// Hint the implementation about the string size.
void SetMinimalSize(ULONG);
// Set a specific character
void SetCharacter(ULONG, WCHAR);
// Appends a backslash to the string if the last character is not a
// backslash.
void AppendBackslash();
// Appends a slash to the string if the last character is not a
// slash.
void AppendSlash();
protected:
// A predicate to see if memory is allocated or not.
bool IsAllocated();
// The allocation size
ULONG m_ulSize;
// This is the place for the standard string.
WCHAR m_rwchNormalString[ulStackSize + 1];
// If the string is becoming too big we will allocate space for it.
WCHAR* m_pTheString;
private:
TVarString&
operator=(const TVarString& vsOther)
{
Cpy(vsOther);
return *this;
}
};
template <ULONG ulStackSize>
inline
TVarString<ulStackSize>::TVarString(ULONG ulInitialSize)
:m_pTheString(m_rwchNormalString)
,m_ulSize(ulStackSize)
{
SetMinimalSize(ulInitialSize);
m_pTheString[0] = L'\0';
}
template <ULONG ulStackSize>
inline
TVarString<ulStackSize>::TVarString(PCWSTR pwsz)
:m_pTheString(m_rwchNormalString)
,m_ulSize(ulStackSize)
{
Cpy(pwsz);
}
template <ULONG ulStackSize>
inline
TVarString<ulStackSize>::TVarString(const PSZ psz)
:m_pTheString(m_rwchNormalString)
,m_ulSize(ulStackSize)
{
Cpy(psz);
}
template <ULONG ulStackSize>
inline
TVarString<ulStackSize>::TVarString(const TVarString<ulStackSize>& vsOther)
:m_pTheString(m_rwchNormalString)
,m_ulSize(ulStackSize)
{
Cpy(vsOther);
}
template <ULONG ulStackSize>
inline
TVarString<ulStackSize>::~TVarString()
{
if (IsAllocated())
{
free(m_pTheString);
}
}
template <ULONG ulStackSize>
inline
bool
TVarString<ulStackSize>::IsAllocated()
{
return m_pTheString != m_rwchNormalString;
}
template <ULONG ulStackSize>
inline
void
TVarString<ulStackSize>::SetMinimalSize(ULONG ulNewSize)
{
// We allocate a little more so if someone would like to add a slash
// or something, it will not cause us to realocate.
// On debug builds, I want to check for string overflows so I don't
// want the extra memory. Activating the reallocation mechanism is also'
// a good thing in debug builds.
#if !(defined(DEBUG))
ulNewSize++;
#endif
//
// if the new size is smaller then what we have - bye bye
//
if (ulNewSize > m_ulSize)
{
//
// We already allocated a string. Should change it's size
//
if (IsAllocated())
{
PWSTR pwszTemp = (PWSTR) realloc(
m_pTheString,
(ulNewSize + 1) * sizeof(WCHAR));
if (NULL == pwszTemp)
{
THROW_MEMORY_EXCEPTION();
}
//
// Save the new memory block.
//
m_pTheString = pwszTemp;
}
else
{
//
// We move the string from the buffer to the allocation.
// Note that this is dangerous if someone took the buffer address.
// The user must always use the access method and never cache the
// string pointer.
//
m_pTheString = (PWSTR) malloc(sizeof(WCHAR) * (ulNewSize + 1));
if (NULL == m_pTheString)
{
THROW_MEMORY_EXCEPTION();
}
wcsncpy(m_pTheString, m_rwchNormalString, m_ulSize + 1);
}
m_ulSize = ulNewSize;
}
}
template <ULONG ulStackSize>
inline
TVarString<ulStackSize>&
TVarString<ulStackSize>::Cpy(PCWSTR pwsz)
{
return Cpy(wcslen(pwsz), pwsz);
}
template <ULONG ulStackSize>
inline
TVarString<ulStackSize>&
TVarString<ulStackSize>::Cpy(const ULONG ulCount, PCWSTR pwsz)
{
SetMinimalSize(ulCount + 1);
wcsncpy(m_pTheString, pwsz, ulCount);
m_pTheString[ulCount] = L'\0';
return *this;
}
template <ULONG ulStackSize>
inline
TVarString<ulStackSize>&
TVarString<ulStackSize>::Cpy(const PSZ psz)
{
int iLen;
iLen = MultiByteToWideChar(
CP_ACP,
MB_PRECOMPOSED | MB_ERR_INVALID_CHARS,
psz,
-1,
NULL,
0);
if (0 == iLen)
{
Assert(0 == iLen);
THROW_HRESULT_EXCEPTION(HRESULT_FROM_WIN32(GetLastError()));
}
SetMinimalSize(iLen);
iLen = MultiByteToWideChar(
CP_ACP,
MB_PRECOMPOSED | MB_ERR_INVALID_CHARS,
psz,
-1,
m_pTheString,
iLen);
if (0 == iLen)
{
Assert(0 == iLen);
THROW_HRESULT_EXCEPTION(HRESULT_FROM_WIN32(GetLastError()));
}
return *this;
}
template <ULONG ulStackSize>
inline
TVarString<ulStackSize>&
TVarString<ulStackSize>::Cat(PCWSTR pwsz)
{
ULONG ulLength = wcslen(pwsz);
return Cat(ulLength, pwsz);
}
template <ULONG ulStackSize>
inline
TVarString<ulStackSize>&
TVarString<ulStackSize>::Cat(const ULONG ulLength, PCWSTR pwsz)
{
ULONG ulCurrentLength = Len();
SetMinimalSize(ulCurrentLength + ulLength + 1);
wcsncpy(m_pTheString + ulCurrentLength, pwsz, ulLength);
m_pTheString[ulCurrentLength + ulLength] = L'\0';
return *this;
}
template <ULONG ulStackSize>
inline
TVarString<ulStackSize>&
TVarString<ulStackSize>::Cat(const PSZ psz)
{
ULONG ulCurrentLength = Len();
int iLen;
iLen = MultiByteToWideChar(
CP_ACP,
MB_PRECOMPOSED | MB_ERR_INVALID_CHARS,
psz,
-1,
NULL,
0);
if (0 == iLen)
{
Assert(0 == iLen);
THROW_HRESULT_EXCEPTION(HRESULT_FROM_WIN32(GetLastError()));
}
SetMinimalSize(iLen + ulCurrentLength);
iLen = MultiByteToWideChar(
CP_ACP,
MB_PRECOMPOSED | MB_ERR_INVALID_CHARS,
psz,
-1,
m_pTheString + ulCurrentLength,
iLen);
if (0 == iLen)
{
Assert(0 == iLen);
THROW_HRESULT_EXCEPTION(HRESULT_FROM_WIN32(GetLastError()));
}
return *this;
}
template <ULONG ulStackSize>
inline
int
TVarString<ulStackSize>::Cmp(PCWSTR pwsz) const
{
return wcscmp(m_pTheString, pwsz);
}
template <ULONG ulStackSize>
inline
int
TVarString<ulStackSize>::Cmp(const PSZ psz) const
{
int iLen;
iLen = MultiByteToWideChar(
CP_ACP,
MB_PRECOMPOSED | MB_ERR_INVALID_CHARS,
psz,
-1,
NULL,
0);
if (0 == iLen)
{
Assert(0 == iLen);
THROW_HRESULT_EXCEPTION(HRESULT_FROM_WIN32(GetLastError()));
}
CAutoMallocPointer<WCHAR> apBuffer = (PWSTR) malloc((iLen) * sizeof(WCHAR));
iLen = MultiByteToWideChar(
CP_ACP,
MB_PRECOMPOSED | MB_ERR_INVALID_CHARS,
psz,
-1,
apBuffer.Get(),
iLen);
if (0 == iLen)
{
Assert(0 == iLen);
THROW_HRESULT_EXCEPTION(HRESULT_FROM_WIN32(GetLastError()));
}
return Cmp(apBuffer.Get());
}
template <ULONG ulStackSize>
inline
ULONG
TVarString<ulStackSize>::Len() const
{
return wcslen(m_pTheString);
}
template <ULONG ulStackSize>
inline
TVarString<ulStackSize>::operator PWSTR() const
{
return m_pTheString;
}
template <ULONG ulStackSize>
inline
void
TVarString<ulStackSize>::SetCharacter(ULONG ulIndex, WCHAR wch)
{
SetMinimalSize(ulIndex + 2); // index to size + null
if (L'\0' == m_pTheString[ulIndex])
{
m_pTheString[ulIndex + 1] = L'\0';
}
else if (L'\0' == wch)
{
}
m_pTheString[ulIndex] = wch;
}
template <ULONG ulStackSize>
inline
void
TVarString<ulStackSize>::AppendSlash()
{
if (L'/' != m_pTheString[Len() - 1])
Cat(L"/");
}
template <ULONG ulStackSize>
inline
void
TVarString<ulStackSize>::AppendBackslash()
{
if (L'\\' != m_pTheString[Len() - 1])
Cat(L"\\");
}
typedef TVarString<4> CShortVarString;
typedef TVarString<16> CVarString;
typedef TVarString<256> CLongVarString;
typedef TVarString<1024> CHugeVarString;
////////////////////////////////////////////////////////////////////////////////
//
// String related utilities definition
//
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//
// Name : ::SizedStringCopy
// Purpose : This function copies ulSize wide characters from the source
// to the destination. It does not treat '\0' characters as
// end of string and does not append the end of string mark
// to the destination. Intended to be used instead of memcpy
// when copying wide string characters.
//
// Parameters:
// [in] PWSTR pwszTarget
// [in] PCWSTR pwszSource
// [in] ULONG ulSize
//
// Returns : PWSTR
//
// Log:
// Jan 2 2001 urib Creation
//
////////////////////////////////////////////////////////////////////////////////
inline
PWSTR
SizedStringCopy(PWSTR pwszTarget, PCWSTR pwszSource, ULONG ulSize)
{
return (PWSTR) memcpy(
(void*)pwszTarget,
(void*)pwszSource,
ulSize * sizeof(pwszSource[0]));
}
////////////////////////////////////////////////////////////////////////////////
//
// Name : ::CoTaskDuplicateString
// Purpose : strdup. Throwing though.
//
// Parameters:
// [in] PCWSTR pwsz
//
// Returns : PWSTR
//
// Log:
// Dec 25 2000 urib Creation
//
////////////////////////////////////////////////////////////////////////////////
inline
PWSTR CoTaskDuplicateString(PCWSTR pwsz)
{
CAutoTaskPointer<WCHAR> apTempName =
(PWSTR)CoTaskMemAlloc(sizeof(WCHAR) * (1 + wcslen(pwsz)));
if (!apTempName.IsValid())
{
THROW_MEMORY_EXCEPTION();
}
wcscpy(apTempName.Get(), pwsz);
return apTempName.Detach();
}
#endif /* VARSTR_H */