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.
 
 
 
 
 
 

496 lines
12 KiB

//*************************************************************
//
// Copyright (c) Microsoft Corporation 1999 - 2000
// All rights reserved
//
// variant.hxx
//
//*************************************************************
#include "rsop.hxx"
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
// Function: CVariant::CVariant
//
// Purpose: Constructor for CVariant class. Initializes the
// storage of the variant data.
//
// Params: none
//
// Return value: none
//
// Notes:
//
//------------------------------------------------------------
CVariant::CVariant() :
_iCurrentArrayIndex(0),
_cMaxArrayElements(0)
{
VariantInit(&_var);
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
// Function: CVariant::~CVariant
//
// Purpose: Denstructor for CVariant class. Frees any data
// allocated to store variant data.
//
// Params: none
//
// Return value: none
//
// Notes:
//
//------------------------------------------------------------
CVariant::~CVariant()
{
HRESULT hr;
hr = VariantClear(&_var);
ASSERT(SUCCEEDED(hr));
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
// Function: CVariant::SetStringValue
//
// Purpose: Sets the type of the variant to VT_BSTR and creates
// a bstr to store the string.
//
// Params: wszValue -- this unicode string is the value to
// which we want to set this variant
//
// Return value: returns S_OK if successful, other
// error code if not
//
// Notes: The variant should not be set to a value after
// this is called -- otherwise, you may lose reference
// to allocated memory -- the value is meant to be set
// only once.
//
//------------------------------------------------------------
HRESULT CVariant::SetStringValue(WCHAR* wszValue)
{
XBStr xString;
ASSERT(VT_EMPTY == _var.vt);
xString = wszValue;
if (!xString)
{
return E_OUTOFMEMORY;
}
_var.vt = VT_BSTR;
_var.bstrVal = xString.Acquire();
return S_OK;
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
// Function: CVariant::SetLongValue
//
// Purpose: Sets the type of the variant to VT_I4 and creates
// a bstr to store the string.
//
// Params: lValue -- this LONG value is the value to
// which we want to set this variant
//
// Return value: returns S_OK if successful, other
// error code if not
//
// Notes: The variant should not be set to a value after
// this is called -- otherwise, you may lose reference
// to allocated memory -- the value is meant to be set
// only once.
//
//------------------------------------------------------------
HRESULT CVariant::SetLongValue(LONG lValue)
{
ASSERT(VT_EMPTY == _var.vt);
_var.vt = VT_I4;
_var.lVal = lValue;
return S_OK;
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
// Function: CVariant::SetBoolValue
//
// Purpose: Sets the type of the variant to VT_BOOL and stores the value
//
// Params: bValue -- this boolean value is the value to
// which we want to set this variant
//
// Return value: returns S_OK if successful, other
// error code if not
//
// Notes: The variant should not be set to a value after
// this is called -- otherwise, you may lose reference
// to allocated memory -- the value is meant to be set
// only once.
//
//------------------------------------------------------------
HRESULT CVariant::SetBoolValue(BOOL bValue)
{
ASSERT(VT_EMPTY == _var.vt);
_var.vt = VT_BOOL;
_var.boolVal = bValue ? VARIANT_TRUE : VARIANT_FALSE;
return S_OK;
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
// Function: CVariant::SetNextLongArrayElement
//
// Purpose: Adds an element in an array of strings to a
// specified string
//
// Params: Value -- the value to which to add as an element
// cMaxElements (optional) -- the maximum number
// of elements in this array -- must be specified
// the first time this method is called on this object
//
// Return value: returns S_OK if successful, other
// error code if not
//
// Notes:
//
//------------------------------------------------------------
HRESULT CVariant::SetNextLongArrayElement(
LONG Value,
DWORD cMaxElements)
{
HRESULT hr;
//
// Add the long to the correct index
// in the array
//
hr = SetNextArrayElement(
VT_I4,
cMaxElements,
&Value);
return hr;
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
// Function: CVariant::SetNextStringArrayElement
//
// Purpose: Adds an element to an array of strings
//
// Params: wszValue -- the value to which to add as an element
// cMaxElements (optional) -- the maximum number
// of elements in this array -- must be specified
// the first time this method is called on this object
//
// Return value: returns S_OK if successful, other
// error code if not
//
// Notes:
//
//------------------------------------------------------------
HRESULT CVariant::SetNextStringArrayElement(
WCHAR* wszValue,
DWORD cMaxElements)
{
HRESULT hr;
XBStr xString;
//
// Create a bstr from the supplied unicode string
//
xString = wszValue;
if (!xString)
{
return E_OUTOFMEMORY;
}
//
// Now add the unicode string to the correct index
// in the array
//
hr = SetNextArrayElement(
VT_BSTR,
cMaxElements,
xString);
//
// If we've succeeded in setting the element, it now
// owns the reference, so we release our reference
//
if (SUCCEEDED(hr))
{
(void) xString.Acquire();
}
return hr;
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
// Function: CVariant::SetNextByteArrayElement
//
// Purpose: Adds an element in an array of bytes to a byte array
//
// Params: byteValue -- the value to which to add as an element
// cMaxElements (optional) -- the maximum number
// of elements in this array -- must be specified
// the first time this method is called on this object
//
// Return value: returns S_OK if successful, other
// error code if not
//
// Notes:
//
//------------------------------------------------------------
HRESULT CVariant::SetNextByteArrayElement(
BYTE byteValue,
DWORD cMaxElements)
{
HRESULT hr;
//
// Add the long to the correct index
// in the array
//
hr = SetNextArrayElement(
VT_UI1,
cMaxElements,
&byteValue);
return hr;
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
// Function: CVariant::IsStringValue
//
// Purpose: Determines whether this variant represents a string
//
// Params:
//
// Return value: returns TRUE if this is a string, FALSE if not
//
//------------------------------------------------------------
BOOL CVariant::IsStringValue()
{
return VT_BSTR == _var.vt;
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
// Function: CVariant::IsLongValue
//
// Purpose: Determines whether this variant represents a long
//
// Params:
//
// Return value: returns TRUE if this is a long, FALSE if not
//
//------------------------------------------------------------
BOOL CVariant::IsLongValue()
{
return VT_I4 == _var.vt;
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
// Function: CVariant::operator VARIANT*()
//
// Purpose: Casts this object into a VARIANT structure pointer
//
// Params:
//
// Return value: returns a pointer to a VARIANT structure
//
// Notes:
//
//------------------------------------------------------------
CVariant::operator VARIANT*()
{
return &_var;
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
// Function: CVariant::SetNextArrayElement
//
// Purpose: Adds an element to an array of objects of arbitrary
// type
//
// Params: wszValue -- the value to which to set the element
// cMaxElements (optional) -- the maximum number
// of elements in this array -- must be specified
// the first time this method is called on this object
//
// Return value: returns S_OK if successful, other
// error code if not
//
// Notes:
//
//------------------------------------------------------------
HRESULT CVariant::SetNextArrayElement(
VARTYPE varType,
DWORD cMaxElements,
LPVOID pvData)
{
HRESULT hr;
//
// If this array contains no elements, return the hr
// that lets the caller know that this array is full
//
if ( 0 == cMaxElements )
{
return S_FALSE;
}
//
// The first time this method is called on this object,
// we should allocate space for the array
//
if ( !_iCurrentArrayIndex )
{
ASSERT( cMaxElements );
ASSERT( VT_EMPTY == _var.vt );
//
// Allocate space for the array with elements
// of the caller specifed type and number
//
hr = InitializeArray(
varType,
cMaxElements);
if (FAILED(hr))
{
return hr;
}
_cMaxArrayElements = cMaxElements;
}
ASSERT( ((DWORD) _iCurrentArrayIndex) < _cMaxArrayElements );
//
// Now add the polymorphic object's IUnknown
// into the array
//
hr = SafeArrayPutElement(
_var.parray,
&_iCurrentArrayIndex,
pvData);
//
// If we've filled up the array, return S_FALSE to
// signal that no more elements can be added
//
if (SUCCEEDED(hr))
{
//
// Increment our cursor into the array to the
// next element
//
_iCurrentArrayIndex++;
//
// Check our current index -- if it's the same
// as our maximum, we're full
//
if ( ((DWORD) _iCurrentArrayIndex) == _cMaxArrayElements)
{
hr = S_FALSE;
}
}
return hr;
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
// Function: CVariant::InitializeArray
//
// Purpose: Private method that allocates space for an array
// of a specified size and element type
//
// Params: varType -- type of elements that will be in the array
// cMaxElements -- the size, in elements, of the array
//
// Return value: returns ERROR_SUCCESS if successful, other
// win32 error code if not
//
// Notes:
//
//------------------------------------------------------------
HRESULT CVariant::InitializeArray(
VARTYPE varType,
DWORD cMaxElements)
{
SAFEARRAY* pSafeArray;
SAFEARRAYBOUND arrayBound;
//
// Set the bounds of the array to be zero-based
//
arrayBound.lLbound = 0;
arrayBound.cElements = cMaxElements;
//
// Allocate the array
//
pSafeArray = SafeArrayCreate(
varType,
1, // 1 dimension
&arrayBound);
if (!pSafeArray)
{
return E_OUTOFMEMORY;
}
//
// Set our state to refer to the allocated memory
// with the specified type
//
_var.vt = VT_ARRAY | varType;
_var.parray = pSafeArray;
return S_OK;
}