#include "stdafx.h" #include "value.h" ///////////////////////////////////////////////////////////////////////////// class CEmptyValue : IValue { public: static HRESULT Create(OUT IValue ** ppValue) { if (ppValue == NULL) { return E_POINTER; } else { *ppValue = NULL; } CEmptyValue * pEmptyValue = new CEmptyValue(); if (pEmptyValue == NULL) { return E_OUTOFMEMORY; } pEmptyValue->m_cRefs = 1; *ppValue = static_cast(pEmptyValue); return S_OK; } STDMETHOD_(ULONG, AddRef)(void) { return InterlockedIncrement(&m_cRefs); } STDMETHOD_(ULONG, Release)(void) { LONG cRefs = InterlockedDecrement(&m_cRefs); if (cRefs == 0) { delete this; } return cRefs; } STDMETHOD(QueryInterface)(IN REFIID riid, OUT void **ppvObject) { HRESULT hr = S_OK; if (ppvObject == NULL) { return E_POINTER; } else { *ppvObject = NULL; } if (riid == __uuidof(IUnknown)) { *ppvObject = reinterpret_cast(static_cast(this)); } else if (riid == __uuidof(IValue)) { *ppvObject = reinterpret_cast(static_cast(this)); } else { hr = E_NOINTERFACE; } if (SUCCEEDED(hr)) { AddRef(); } return hr; } STDMETHOD(GetValue)(IN TYPEID idType, OUT void * pValue) { UNREFERENCED_PARAMETER(idType); UNREFERENCED_PARAMETER(pValue); return E_NOTIMPL; } STDMETHOD(GetNativeType)(OUT TYPEID * pidType) { if (pidType == NULL) { return E_POINTER; } *pidType = TYPEID_EMPTY; return S_OK; } private: ~CEmptyValue() { } LONG m_cRefs; }; ///////////////////////////////////////////////////////////////////////////// template class TStandardValue : IValue { public: static HRESULT Create(IN TYPEID idInitType, IN void *pInitValue, OUT IValue ** ppValue) { if (ppValue != NULL) { *ppValue = NULL; } if (idInitType != (*__typeid) || pInitValue == NULL) { return E_INVALIDARG; } if (ppValue == NULL) { return E_POINTER; } TStandardValue * pStandardValue = new TStandardValue(); if (pStandardValue == NULL) { return E_OUTOFMEMORY; } pStandardValue->m_value = *(reinterpret_cast(pInitValue)); pStandardValue->m_cRefs = 1; *ppValue = static_cast(pStandardValue); return S_OK; } STDMETHOD_(ULONG, AddRef)(void) { return InterlockedIncrement(&m_cRefs); } STDMETHOD_(ULONG, Release)(void) { LONG cRefs = InterlockedDecrement(&m_cRefs); if (cRefs == 0) { delete this; } return cRefs; } STDMETHOD(QueryInterface)(IN REFIID riid, OUT void **ppvObject) { HRESULT hr = S_OK; if (ppvObject == NULL) { return E_POINTER; } else { *ppvObject = NULL; } if (riid == __uuidof(IUnknown)) { *ppvObject = reinterpret_cast(static_cast(this)); } else if (riid == __uuidof(IValue)) { *ppvObject = reinterpret_cast(static_cast(this)); } else { hr = E_NOINTERFACE; } if (SUCCEEDED(hr)) { AddRef(); } return hr; } STDMETHOD(GetValue)(IN TYPEID idType, OUT void * pValue) { if (pValue == NULL) { return E_INVALIDARG; } if (idType != (*__typeid)) { return E_NOTIMPL; } *(reinterpret_cast(pValue)) = m_value; return S_OK; } STDMETHOD(GetNativeType)(OUT TYPEID * pidType) { if (pidType == NULL) { return E_POINTER; } *pidType = (*__typeid); return S_OK; } private: ~TStandardValue() { } LONG m_cRefs; T m_value; }; ///////////////////////////////////////////////////////////////////////////// class CStandardValueFactory : IValueFactory { public: STDMETHOD_(ULONG, AddRef)(void) { return 0; } STDMETHOD_(ULONG, Release)(void) { return 0; } STDMETHOD(QueryInterface)(IN REFIID riid, OUT void **ppvObject) { UNREFERENCED_PARAMETER(riid); UNREFERENCED_PARAMETER(ppvObject); return E_NOTIMPL; } STDMETHOD(CreateValue)(IN VALUEID idValue, IN TYPEID idInitType, IN void *pInitValue, OUT IValue ** ppValue) { HRESULT hr = S_OK; if (idValue == VALUEID_EMPTY) { hr = CEmptyValue::Create(ppValue); } else if(idValue == VALUEID_LUINT8) { hr = TStandardValue::Create(idInitType, pInitValue, ppValue); } else if(idValue == VALUEID_LSINT8) { hr = TStandardValue::Create(idInitType, pInitValue, ppValue); } else if(idValue == VALUEID_LUINT16) { hr = TStandardValue::Create(idInitType, pInitValue, ppValue); } else if(idValue == VALUEID_LSINT16) { hr = TStandardValue::Create(idInitType, pInitValue, ppValue); } else if(idValue == VALUEID_LUINT32) { hr = TStandardValue::Create(idInitType, pInitValue, ppValue); } else if(idValue == VALUEID_LSINT32) { hr = TStandardValue::Create(idInitType, pInitValue, ppValue); } return hr; } }; ///////////////////////////////////////////////////////////////////////////// CStandardValueFactory g_StandardValueFactory; ///////////////////////////////////////////////////////////////////////////// // Extend as reasonable in the future. Actual value factories that implement // IValueFactory... HRESULT CoCreateValue(IN VALUEID idValue, IN TYPEID idInitType, IN void * pInitValue, OUT IValue ** ppValue) { return g_StandardValueFactory.CreateValue(idValue, idInitType, pInitValue, ppValue); }