|
|
/*++
Copyright (c) 1996 Microsoft Corporation
Module Name:
item.cpp
Abstract:
This module contains the implementation for the Server Extension Object Item class.
Author:
Don Dumitru (dondu@microsoft.com)
Revision History:
dondu 02/18/97 created
--*/
// item.cpp : Implementation of CSEODictionaryItem
#include "stdafx.h"
#include "seodefs.h"
#include "item.h"
static HRESULT VarToIndex(DWORD *pdwIndex, VARIANT *pvarFrom, DWORD dwCount, BOOL bBoundsError=TRUE) { TraceFunctEnter("VarToIndex"); VARIANT varIndex; HRESULT hr;
if (!pvarFrom || (pvarFrom->vt == VT_ERROR)) { if (bBoundsError && !dwCount) { TraceFunctLeave(); return (SEO_E_NOTPRESENT); } *pdwIndex = 0; TraceFunctLeave(); return (S_OK); } if (!dwCount) { TraceFunctLeave(); return (SEO_E_NOTPRESENT); } VariantInit(&varIndex); if (pvarFrom->vt != VT_I4) { hr = VariantChangeTypeEx(&varIndex,pvarFrom,LOCALE_NEUTRAL,0,VT_I4); if (!SUCCEEDED(hr)) { VariantClear(&varIndex); TraceFunctLeave(); return (hr); } } else { varIndex.vt = VT_I4; varIndex.lVal = pvarFrom->lVal; } if ((varIndex.iVal < 0) || (bBoundsError && ((DWORD) varIndex.iVal >= dwCount))) { TraceFunctLeave(); return (SEO_E_NOTPRESENT); } *pdwIndex = min(dwCount,(DWORD) varIndex.iVal); TraceFunctLeave(); return (S_OK); }
/////////////////////////////////////////////////////////////////////////////
// CSEODictionaryItem
HRESULT CSEODictionaryItem::FinalConstruct() { HRESULT hrRes; TraceFunctEnter("CSEODictionaryItem::FinalConstruct");
m_dwCount = 0; m_pvcValues = NULL; hrRes = CoCreateFreeThreadedMarshaler(GetControllingUnknown(),&m_pUnkMarshaler.p); _ASSERTE(!SUCCEEDED(hrRes)||m_pUnkMarshaler); TraceFunctLeave(); return (SUCCEEDED(hrRes)?S_OK:hrRes); }
void CSEODictionaryItem::FinalRelease() { TraceFunctEnter("CSEODictionaryItem::FinalRelease");
if (m_pvcValues) { DWORD dwIdx;
for (dwIdx=0;dwIdx<m_dwCount;dwIdx++) { m_pvcValues[dwIdx].~ValueClass(); } CoTaskMemFree(m_pvcValues); m_pvcValues = NULL; } m_dwCount = 0; m_pUnkMarshaler.Release(); TraceFunctLeave(); }
HRESULT STDMETHODCALLTYPE CSEODictionaryItem::get_Value(VARIANT *pvarIndex, VARIANT *pvarResult) { TraceFunctEnter("CSEODictionaryItem::get_Value"); DWORD dwIndex; HRESULT hr;
if (!pvarResult) { TraceFunctLeave(); return (E_POINTER); } VariantInit(pvarResult); hr = VarToIndex(&dwIndex,pvarIndex,m_dwCount); if (!SUCCEEDED(hr)) { TraceFunctLeave(); return (hr); } TraceFunctLeave(); return (m_pvcValues[dwIndex].AsVariant(pvarResult)); }
HRESULT STDMETHODCALLTYPE CSEODictionaryItem::AddValue(VARIANT *pvarIndex, VARIANT *pvarValue) { TraceFunctEnter("CSEODictionaryItem::AddValue"); DWORD dwIndex; HRESULT hr; ValueClass *pvcValue;
if (!pvarValue) { TraceFunctLeave(); return (E_POINTER); } hr = VarToIndex(&dwIndex,pvarIndex,m_dwCount,FALSE); if (!SUCCEEDED(hr)) { TraceFunctLeave(); return (hr); } hr = AddSlot(&dwIndex,&pvcValue); if (!SUCCEEDED(hr)) { TraceFunctLeave(); return (hr); } hr = m_pvcValues[dwIndex].Assign(pvarValue); if (!SUCCEEDED(hr)) { VARIANT varIndex;
VariantInit(&varIndex); varIndex.vt = VT_I4; varIndex.lVal = dwIndex; DeleteValue(&varIndex); TraceFunctLeave(); return (hr); } TraceFunctLeave(); return (S_OK); }
HRESULT STDMETHODCALLTYPE CSEODictionaryItem::DeleteValue(VARIANT *pvarIndex) { TraceFunctEnter("CSEODictionaryItem::DeleteValue"); DWORD dwIndex; HRESULT hr;
if (!pvarIndex) { TraceFunctLeave(); return (E_POINTER); } hr = VarToIndex(&dwIndex,pvarIndex,m_dwCount); if (!SUCCEEDED(hr)) { TraceFunctLeave(); return (hr); } m_pvcValues[dwIndex].~ValueClass(); m_dwCount--; memcpy(&m_pvcValues[dwIndex-1],&m_pvcValues[dwIndex],sizeof(m_pvcValues[0])*(m_dwCount-dwIndex)); TraceFunctLeave(); return (S_OK); }
HRESULT STDMETHODCALLTYPE CSEODictionaryItem::get_Count(VARIANT *pvarResult) { TraceFunctEnter("CSEODictionaryItem::get_Count");
if (!pvarResult) { TraceFunctLeave(); return (E_POINTER); } VariantInit(pvarResult); pvarResult->vt = VT_I4; pvarResult->lVal = (LONG) m_dwCount; TraceFunctLeave(); return (S_OK); }
HRESULT STDMETHODCALLTYPE CSEODictionaryItem::GetStringA(DWORD dwIndex, DWORD *pchCount, LPSTR pszResult) { TraceFunctEnter("CSEODictionaryItem::GetStringA");
if (dwIndex >= m_dwCount) { TraceFunctLeave(); return (SEO_E_NOTPRESENT); } TraceFunctLeave(); return (m_pvcValues[dwIndex].AsStringA(pchCount,pszResult)); }
HRESULT STDMETHODCALLTYPE CSEODictionaryItem::GetStringW(DWORD dwIndex, DWORD *pchCount, LPWSTR pszResult) { TraceFunctEnter("CSEODictionaryItem::GetStringW");
if (dwIndex >= m_dwCount) { TraceFunctLeave(); return (SEO_E_NOTPRESENT); } TraceFunctLeave(); return (m_pvcValues[dwIndex].AsStringW(pchCount,pszResult)); }
HRESULT STDMETHODCALLTYPE CSEODictionaryItem::AddStringA(DWORD dwIndex, LPCSTR pszValue) { TraceFunctEnter("CSEODictionaryItem::AddStringA"); HRESULT hr; ValueClass *pvcValue;
if (!pszValue) { TraceFunctLeave(); return (E_POINTER); } hr = AddSlot(&dwIndex,&pvcValue); if (!SUCCEEDED(hr)) { TraceFunctLeave(); return (hr); } hr = m_pvcValues[dwIndex].Assign(pszValue); if (!SUCCEEDED(hr)) { VARIANT varIndex;
VariantInit(&varIndex); varIndex.vt = VT_I4; varIndex.lVal = dwIndex; DeleteValue(&varIndex); TraceFunctLeave(); return (hr); } TraceFunctLeave(); return (S_OK); }
HRESULT STDMETHODCALLTYPE CSEODictionaryItem::AddStringW(DWORD dwIndex, LPCWSTR pszValue) { TraceFunctEnter("CSEODictionaryItem::AddStringW"); HRESULT hr; ValueClass *pvcValue;
if (!pszValue) { TraceFunctLeave(); return (E_POINTER); } hr = AddSlot(&dwIndex,&pvcValue); if (!SUCCEEDED(hr)) { TraceFunctLeave(); return (hr); } hr = m_pvcValues[dwIndex].Assign(pszValue); if (!SUCCEEDED(hr)) { VARIANT varIndex;
VariantInit(&varIndex); varIndex.vt = VT_I4; varIndex.lVal = dwIndex; DeleteValue(&varIndex); TraceFunctLeave(); return (hr); } TraceFunctLeave(); return (S_OK); }
HRESULT CSEODictionaryItem::AddSlot(DWORD *pdwIndex, ValueClass **ppvcResult) { TraceFunctEnter("CSEODictionaryItem::AddSlot"); LPVOID pvRes;
if (*pdwIndex > m_dwCount) { *pdwIndex = m_dwCount; } pvRes = CoTaskMemRealloc(m_pvcValues,sizeof(m_pvcValues[0])*(m_dwCount+1)); if (!pvRes) { TraceFunctLeave(); return (E_OUTOFMEMORY); } m_pvcValues = (ValueClass *) pvRes; memcpy(&m_pvcValues[*pdwIndex+1],&m_pvcValues[*pdwIndex],sizeof(m_pvcValues[0])*(m_dwCount-*pdwIndex)); new(&m_pvcValues[*pdwIndex]) ValueClass(); m_dwCount++; *ppvcResult = &m_pvcValues[*pdwIndex]; TraceFunctLeave(); return (S_OK); }
CSEODictionaryItem::ValueClass::ValueClass() { TraceFunctEnter("CSEODictionaryItem::ValueClass::ValueClass");
Init(); TraceFunctLeave(); }
CSEODictionaryItem::ValueClass::ValueClass(ValueClass& vcFrom) { TraceFunctEnter("CSEODictionaryItem::ValueClass::ValueClass");
Init(); Assign(vcFrom); TraceFunctLeave(); }
CSEODictionaryItem::ValueClass::~ValueClass() { TraceFunctEnter("CSEODictionaryItem::ValueClass::~ValueClass");
Clear(); TraceFunctLeave(); }
void CSEODictionaryItem::ValueClass::Init() { TraceFunctEnter("CSEODictionaryItem::ValueClass::Init");
m_vtValue.veType = veNone; m_vtValue.pszStringA = NULL; VariantInit(&m_vtValue.varVARIANT); TraceFunctLeave(); }
void CSEODictionaryItem::ValueClass::Clear() { TraceFunctEnter("CSEODictionaryItem::ValueClass::Clear");
m_vtValue.veType = veNone; if (m_vtValue.pszStringA) { CoTaskMemFree(m_vtValue.pszStringA); m_vtValue.pszStringA = NULL; } VariantClear(&m_vtValue.varVARIANT); TraceFunctLeave(); }
HRESULT CSEODictionaryItem::ValueClass::Assign(ValueClass& vcFrom) { TraceFunctEnter("CSEODictionaryItem::ValueClass::Assign");
if (&vcFrom != this) { switch (m_vtValue.veType) {
case veStringA: TraceFunctLeave(); return (Assign(vcFrom.m_vtValue.pszStringA));
case veVARIANT: TraceFunctLeave(); return (Assign(&vcFrom.m_vtValue.varVARIANT)); } } TraceFunctLeave(); return (E_UNEXPECTED); }
HRESULT CSEODictionaryItem::ValueClass::Assign(LPCSTR pszFromA) { TraceFunctEnter("CSEODictionaryItem::ValueClass::Assign");
if (!pszFromA) { TraceFunctLeave(); return (E_POINTER); } Clear(); m_vtValue.pszStringA = (LPSTR) CoTaskMemAlloc(strlen(pszFromA)+1); if (!m_vtValue.pszStringA) { TraceFunctLeave(); return (E_OUTOFMEMORY); } m_vtValue.veType = veStringA; strcpy(m_vtValue.pszStringA,pszFromA); TraceFunctLeave(); return (S_OK); }
HRESULT CSEODictionaryItem::ValueClass::Assign(VARIANT *pvarFrom) { TraceFunctEnter("CSEODictionaryItem::ValueClass::Assign"); HRESULT hr;
if (!pvarFrom) { TraceFunctLeave(); return (E_POINTER); } Clear(); hr = VariantCopy(&m_vtValue.varVARIANT,pvarFrom); if (SUCCEEDED(hr)) { m_vtValue.veType = veVARIANT; } TraceFunctLeave(); return (hr); }
HRESULT CSEODictionaryItem::ValueClass::Assign(LPCWSTR pszFromW) { TraceFunctEnter("CSEODictionaryItem::ValueClass::Assign");
if (!pszFromW) { TraceFunctLeave(); return (E_POINTER); } Clear(); m_vtValue.varVARIANT.bstrVal = SysAllocString(pszFromW); if (!m_vtValue.varVARIANT.bstrVal) { TraceFunctLeave(); return (E_OUTOFMEMORY); } m_vtValue.varVARIANT.vt = VT_BSTR; m_vtValue.veType = veVARIANT; TraceFunctLeave(); return (S_OK); }
HRESULT CSEODictionaryItem::ValueClass::AsVariant(VARIANT *pvarResult) { TraceFunctEnter("CSEODictionaryItem::ValueClass::AsVariant");
if (!pvarResult) { TraceFunctLeave(); return (E_POINTER); } VariantInit(pvarResult); switch (m_vtValue.veType) {
case veStringA: { DWORD dwLen = strlen(m_vtValue.pszStringA);
pvarResult->bstrVal = SysAllocStringLen(NULL,dwLen); if (!pvarResult->bstrVal) { TraceFunctLeave(); return (E_OUTOFMEMORY); } ATLA2WHELPER(pvarResult->bstrVal,m_vtValue.pszStringA,dwLen); pvarResult->vt = VT_BSTR; TraceFunctLeave(); return (S_OK); }
case veVARIANT: TraceFunctLeave(); return (VariantCopy(pvarResult,&m_vtValue.varVARIANT)); } TraceFunctLeave(); return (E_UNEXPECTED); }
HRESULT CSEODictionaryItem::ValueClass::AsStringA(DWORD *pchCount, LPSTR pszResult) { TraceFunctEnter("CSEODictionaryItem::ValueClass::AsStringA");
if (!pchCount) { TraceFunctLeave(); return (E_POINTER); } switch (m_vtValue.veType) {
case veStringA: if (pszResult) { DWORD dwLen = strlen(m_vtValue.pszStringA); DWORD dwCopy = min(*pchCount,dwLen+1); BOOL bMoreData = FALSE;
memcpy(pszResult,m_vtValue.pszStringA,dwCopy); if (dwCopy == *pchCount) { pszResult[dwCopy-1] = 0; bMoreData = TRUE; } *pchCount = dwCopy; TraceFunctLeave(); return (bMoreData?SEO_S_MOREDATA:S_OK); } else { *pchCount = strlen(m_vtValue.pszStringA) + 1; TraceFunctLeave(); return (S_OK); }
case veVARIANT: { VARIANT varValue; LPCWSTR pszValue; HRESULT hr;
VariantInit(&varValue); if (m_vtValue.varVARIANT.vt != VT_BSTR) { hr = VariantChangeTypeEx(&varValue,&m_vtValue.varVARIANT,LOCALE_NEUTRAL,0,VT_BSTR); if (!SUCCEEDED(hr)) { VariantClear(&varValue); TraceFunctLeave(); return (hr); } pszValue = varValue.bstrVal; } else { pszValue = m_vtValue.varVARIANT.bstrVal; } if (pszResult) { DWORD dwLen = wcslen(pszValue); DWORD dwCopy = min(*pchCount,dwLen+1); BOOL bMoreData = FALSE;
ATLW2AHELPER(pszResult,pszValue,dwCopy); VariantClear(&varValue); if (dwCopy == *pchCount) { bMoreData = TRUE; } *pchCount = dwCopy; TraceFunctLeave(); return (bMoreData?SEO_S_MOREDATA:S_OK); } else { *pchCount = wcslen(pszValue) + 1; VariantClear(&varValue); TraceFunctLeave(); return (S_OK); } } } TraceFunctLeave(); return (E_UNEXPECTED); }
HRESULT CSEODictionaryItem::ValueClass::AsStringW(DWORD *pchCount, LPWSTR pszResult) { TraceFunctEnter("CSEODictionaryItem::ValueClass::AsStringW");
if (!pchCount) { TraceFunctLeave(); return (E_POINTER); } switch (m_vtValue.veType) {
case veStringA: if (pszResult) { DWORD dwLen = strlen(m_vtValue.pszStringA); DWORD dwCopy = min(*pchCount,dwLen+1); BOOL bMoreData = FALSE;
ATLA2WHELPER(pszResult,m_vtValue.pszStringA,dwCopy); if (dwCopy == *pchCount) { bMoreData = TRUE; } *pchCount = dwCopy; TraceFunctLeave(); return (bMoreData?SEO_S_MOREDATA:S_OK); } else { *pchCount = strlen(m_vtValue.pszStringA) + 1; TraceFunctLeave(); return (S_OK); }
case veVARIANT: { VARIANT varValue; LPCWSTR pszValue; HRESULT hr;
VariantInit(&varValue); if (m_vtValue.varVARIANT.vt != VT_BSTR) { hr = VariantChangeTypeEx(&varValue,&m_vtValue.varVARIANT,LOCALE_NEUTRAL,0,VT_BSTR); if (!SUCCEEDED(hr)) { VariantClear(&varValue); TraceFunctLeave(); return (hr); } pszValue = varValue.bstrVal; } else { pszValue = m_vtValue.varVARIANT.bstrVal; } if (pszResult) { DWORD dwLen = wcslen(pszValue); DWORD dwCopy = min(*pchCount,dwLen+1); BOOL bMoreData = FALSE;
memcpy(pszResult,pszValue,dwCopy); VariantClear(&varValue); if (dwCopy == *pchCount) { pszResult[dwCopy-1] = 0; bMoreData = TRUE; } *pchCount = dwCopy; TraceFunctLeave(); return (bMoreData?SEO_S_MOREDATA:S_OK); } else { *pchCount = wcslen(pszValue) + 1; VariantClear(&varValue); TraceFunctLeave(); return (S_OK); } } } TraceFunctLeave(); return (E_UNEXPECTED); }
void *CSEODictionaryItem::ValueClass::operator new(size_t cbSize, CSEODictionaryItem::ValueClass *pvcInPlace) { TraceFunctEnter("CSEODictionaryItem::ValueClass::operator new");
TraceFunctLeave(); return (pvcInPlace); }
|