|
|
/*++
Copyright (C) 1996-2001 Microsoft Corporation
Module Name:
VAR.H
Abstract:
CVar & CVarVector.
These are thread-safe translators for VARIANT and SAFEARRAY and represent all types support by WBEM.
These are mutually nestable to any level. A CVarVector can contain an array of CVar, and a CVar can contain a CVarVector. One CVar can therefore contain a whole tree of CVar objects, themselves containing homogeneous or heterogeneous arrays of CVar objects.
Note: CVar should not be bound to one type and then immediately coerced to a new type. This object is designed for speed, not safety, so there is no checking to see if this has been done. A memory leak is likely to occur.
The assignment operator and copy constructors are the only method of changing the type on a CVar. Do NOT construct the object as a BSTR, for example, and then call SetDWORD.
History:
16-Apr-96 a-raymcc Created. 12//17/98 sanjes - Partially Reviewed for Out of Memory.
18-Mar-99 a-dcrews Added out-of-memory exception handling
--*/
#ifndef _VAR_H_
#define _VAR_H_
#include <flexarry.h>
#include <safearry.h>
#include <algorithm>
#include <autobstr.h>
#define VT_EX_CVAR (VT_USERDEFINED | 0x80010000)
#define VT_EX_CVARVECTOR (VT_USERDEFINED | 0x80010002)
class CVarVector;
typedef union { char cVal; // VT_I1
BYTE bVal; // VT_UI1
SHORT iVal; // VT_I2
WORD wVal; // VT_UI2
LONG lVal; // VT_I4
DWORD dwVal; // VT_UI4
VARIANT_BOOL boolVal; // VT_BOOL
float fltVal; // VT_R4
double dblVal; // VT_R8
LPSTR pStr; // VT_LPSTR
LPWSTR pWStr; // VT_LPWSTR
BSTR Str; // VT_BSTR (stored as VT_LPWSTR)
FILETIME Time; // VT_FILETIME
BLOB Blob; // VT_BLOB
LPCLSID pClsId; // VT_CLSID
IUnknown* pUnk; // VT_UNKNOWN
IDispatch* pDisp; // VT_DISPATCH
CVarVector *pVarVector; // VT_EX_CVARVECTOR
} METAVALUE;
class POLARITY CVar { private: int m_vt; METAVALUE m_value; int m_nStatus; BOOL m_bCanDelete; void Init(); public: enum { no_error, unsupported, failed }; CVar() { Init(); } ~CVar(); CVar(const CVar &); CVar& operator =(const CVar &);
CVar(char c) { Init(); SetChar(c); } CVar(BYTE b) { Init(); SetByte(b); } CVar(SHORT s) { Init(); SetShort(s); } CVar(WORD w) { Init(); SetWord(w); } CVar(LONG l) { Init(); SetLong(l); } CVar(DWORD dw) { Init(); SetDWORD(dw); } CVar(float f) { Init(); SetFloat(f); } CVar(double d) { Init(); SetDouble(d); } CVar(VARIANT_BOOL b,int){ Init(); SetBool(b); }
CVar(LPSTR p, BOOL bAcquire = FALSE) { Init(); SetLPSTR(p, bAcquire); }
CVar(LPWSTR p, BOOL bAcquire = FALSE) { Init(); SetLPWSTR(p, bAcquire); } CVar(int, auto_bstr b) { Init(); SetBSTR(b); }
CVar(int, BSTR b) { Init(); SetBSTR(b); } // Dummy int required for context, since BSTR is also LPWSTR
// from Win32 point of view, although the VT_ indicators differ.
CVar(CLSID *p, BOOL bAcquire = FALSE) { Init(); SetClsId(p, bAcquire); }
CVar(BLOB *p, BOOL bAcquire = FALSE) { Init(); SetBlob(p, bAcquire); } CVar(FILETIME *p) { Init(); SetFileTime(p); }
CVar(CVarVector *p, BOOL bAcquire = FALSE) { Init(); SetVarVector(p, bAcquire); } CVar(VARIANT *p) { Init(); SetVariant(p); } CVar(int nType, SAFEARRAY *p) { Init(); SetSafeArray(nType, p); } int Status() { return m_nStatus; }
int DumpText(FILE *fStream); int GetType() { return m_vt; } int GetOleType(); void Empty();
int operator ==(CVar &Other); BOOL CompareTo(CVar& Other, BOOL bIgnoreCase);
void SetRaw(int vt, void* pvData, int nDataLen); void* GetRawData() {return (void*)&m_value;} BOOL CanDelete() {return m_bCanDelete;} void SetCanDelete(BOOL bCanDelete) {m_bCanDelete = bCanDelete;}
// Numeric types.
// ==============
void SetAsNull() { m_vt = VT_NULL; m_value.lVal = 0; } BOOL IsNull() {return m_vt == VT_NULL;} BOOL IsDataNull(); void SetChar(char c) { m_vt = VT_I1; m_value.cVal = c; } char GetChar() { return m_value.cVal; } operator char() { return m_value.cVal; } void SetByte(BYTE b) { m_vt = VT_UI1; m_value.bVal = b; } BYTE GetByte() { return m_value.bVal; } operator BYTE() { return m_value.bVal; } void SetShort(SHORT iVal) { m_vt = VT_I2; m_value.iVal = iVal; } SHORT GetShort() { return m_value.iVal; } operator SHORT() { return m_value.iVal; } void SetWord(WORD wVal) { m_vt = VT_UI2; m_value.wVal = wVal; } WORD GetWord() { return m_value.wVal; } operator WORD() { return m_value.wVal; } void SetLong(LONG lVal) { m_value.lVal = lVal; m_vt = VT_I4; } LONG GetLong() { return m_value.lVal; } operator LONG() { return m_value.lVal; } void SetDWORD(DWORD dwVal) { m_value.dwVal = dwVal; m_vt = VT_UI4; } DWORD GetDWORD() { return m_value.dwVal; } operator DWORD() { return m_value.dwVal; } void SetBool(VARIANT_BOOL b) { m_value.boolVal = b; m_vt = VT_BOOL; } VARIANT_BOOL GetBool() { return m_value.boolVal; }
void SetFloat(float f) { m_value.fltVal = f; m_vt = VT_R4; } float GetFloat() { return m_value.fltVal; } operator float() { return m_value.fltVal; } void SetDouble(double dblVal) { m_value.dblVal = dblVal; m_vt = VT_R8; } double GetDouble() { return m_value.dblVal; } operator double() { return m_value.dblVal; }
void SetDispatch(IDispatch* pDisp); IDispatch* GetDispatch() {if(m_value.pDisp) m_value.pDisp->AddRef(); return m_value.pDisp;} void SetUnknown(IUnknown* pUnk); IUnknown* GetUnknown() {if(m_value.pUnk) m_value.pUnk->AddRef(); return m_value.pUnk;}
void SetEmbeddedObject(IUnknown* pUnk) {SetUnknown(pUnk);} IUnknown* GetEmbeddedObject() {return GetUnknown();}
int SetVariant(VARIANT *pSrc, BOOL fOptimize = FALSE);
void FillVariant(VARIANT* pDest, BOOL fOptimized = FALSE); VARIANT *GetNewVariant(); // String types.
// =============
BOOL SetLPWSTR(LPWSTR pVal, BOOL bAcquire = FALSE); wchar_t *GetLPWSTR() { return m_value.pWStr; } operator LPWSTR() { return m_value.pWStr; } BOOL SetLPSTR(LPSTR pStr, BOOL bAcquire = FALSE); LPSTR GetLPSTR() { return m_value.pStr; } operator LPSTR() { return m_value.pStr; } BOOL SetBSTR(auto_bstr str); BOOL SetBSTR(BSTR str); BSTR GetBSTR(); // Makes a dynamic copy which must be freed.
// Misc. types.
// ============
void SetFileTime(FILETIME *pft) { m_value.Time = *pft; m_vt = VT_FILETIME; } FILETIME GetFileTime() { return m_value.Time; } operator FILETIME() { return m_value.Time; } void SetBlob(BLOB *pBlob, BOOL bAcquire = FALSE); BLOB *GetBlob() { return &m_value.Blob; } operator BLOB *() { return &m_value.Blob; } void SetClsId(CLSID *pClsId, BOOL bAcquire); CLSID* GetClsId() { return m_value.pClsId; } // Return value is read-only
operator CLSID*() { return m_value.pClsId; } // Return value is read-only
void SetVarVector(CVarVector *pVec, BOOL bAcquire); CVarVector *GetVarVector() { return m_value.pVarVector; } operator CVarVector *() { return m_value.pVarVector; } void SetSafeArray(int nType, SAFEARRAY *pArray); // Copies the source
SAFEARRAY *GetNewSafeArray(); // New SAFEARRAY which must be released
void SetOptimizedSafeArray(int nType, SAFEARRAY *pArray, BOOL fAcquire = FALSE); SAFEARRAY* GetOptimizedSafeArray( void );
static BSTR TypeToText(int nType); BSTR GetTypeText(); BSTR GetText(long lFlags, long lType = 0, LPCWSTR szFormat = NULL);
BOOL ChangeTypeTo(VARTYPE vtNew); BOOL ChangeTypeToEx(VARTYPE vtNew, LCID lcid = 0x409 ); BOOL ToSingleChar(); BOOL ToUI4(); };
class POLARITY CVarVector { int m_nType; CFlexArray m_Array; int m_nStatus; CSafeArray* m_pSafeArray; void* m_pRawData;
public: enum { no_error, failed, unsupported };
CVarVector(); CVarVector(int nVarType, int nInitSize = 32, int nGrowBy = 32);
// These two only support limited SAFEARRAY types.
// ===============================================
CVarVector(int nVarType, SAFEARRAY *pSrc, BOOL fOptimized = FALSE); SAFEARRAY *GetNewSafeArray(); SAFEARRAY* GetSafeArray( BOOL fAcquire = FALSE );
int GetType() { return m_nType; } int Status() { return m_nStatus; } void Empty(); ~CVarVector(); CVarVector(CVarVector &Src); CVarVector& operator =(CVarVector &Src); int operator ==(CVarVector &Src); BOOL CompareTo(CVarVector& Other, BOOL bIgnoreCase); int Size();
int Add(CVar &Value); int Add(CVar *pAcquiredPtr);
CVar& GetAt(int nIndex); CVar& operator [](int nIndex);
int RemoveAt(int nIndex); int InsertAt(int nIndex, CVar &Value);
BSTR GetText(long lFlags, long lType = 0); BOOL ToSingleChar(); BOOL ToUI4();
BOOL IsOptimized( void ) { return NULL != m_pSafeArray; } BOOL MakeOptimized( int nVarType, int nInitSize = 32, int nGrowBy = 32 ); void SetRawArrayBinding( int nBinding ); HRESULT AccessRawArray( void** ppv ); HRESULT UnaccessRawArray( void );
// We access raw data using internal data member.
HRESULT InternalRawArrayAccess( void );
static BOOL IsValidVectorType( int nVarType ); static BOOL IsValidVectorArray( int nVarType, SAFEARRAY* pArray );
void FillCVarAt(int nIndex, CVar& vTemp);
BOOL DoesVectorTypeMatchArrayType( void ); HRESULT SetRawArrayData( void* pvData, int nNumElements, int nElementSize ); HRESULT GetRawArrayData( void* pvDest, int nBuffSize );
BOOL SetRawArraySize( int nSize ); int GetElementSize( void ); };
class CUnaccessVarVector { private: CVarVector* m_pVV;
public:
CUnaccessVarVector( CVarVector* pvv = NULL ) : m_pVV( pvv ) {} ~CUnaccessVarVector() { Unaccess(); }
void SetVV( CVarVector* pvv ) { m_pVV = pvv; } void Unaccess( void ) { if ( NULL != m_pVV ) m_pVV->UnaccessRawArray(); m_pVV = NULL; } };
#endif
|