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.
486 lines
14 KiB
486 lines
14 KiB
/*++
|
|
|
|
Copyright (c) 1997 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
membag.h
|
|
|
|
Abstract:
|
|
|
|
This module contains the definition for the
|
|
ISEODictionary object in memory.
|
|
|
|
Author:
|
|
|
|
Andy Jacobs ([email protected])
|
|
|
|
Revision History:
|
|
|
|
andyj 02/10/97 created
|
|
andyj 02/12/97 Converted PropertyBag's to Dictonary's
|
|
|
|
--*/
|
|
|
|
// MEMBAG.h : Declaration of the CSEOMemDictionary
|
|
|
|
#include "tfdlist.h"
|
|
#include "rwnew.h"
|
|
|
|
|
|
enum DataType {Empty, DWord, String, Interface};
|
|
class DataItem {
|
|
public:
|
|
|
|
typedef DLIST_ENTRY* (*PFNDLIST)( class DataItem*);
|
|
|
|
DataItem() {
|
|
m_pszKey = NULL;
|
|
eType = Empty;
|
|
};
|
|
DataItem(DWORD d) {
|
|
eType = DWord;
|
|
dword = d;
|
|
};
|
|
DataItem(LPCSTR s, int iSize = -1) {
|
|
eType = String;
|
|
iStringSize = ((iSize >= 0) ? iSize : (lstrlen(s) + 1));
|
|
pStr = (LPSTR) MyMalloc(iStringSize);
|
|
if (pStr) {
|
|
strncpy(pStr, s, iStringSize);
|
|
}
|
|
m_pszKey = NULL;
|
|
};
|
|
DataItem(LPCWSTR s, int iSize = -1) {
|
|
eType = String;
|
|
iStringSize = sizeof(WCHAR) * ((iSize >= 0) ? iSize : (wcslen(s) + 1));
|
|
pStr = (LPSTR) MyMalloc(iStringSize);
|
|
if (pStr) {
|
|
ATLW2AHELPER(pStr, s, iStringSize);
|
|
}
|
|
m_pszKey = NULL;
|
|
};
|
|
DataItem(IUnknown *p) {
|
|
eType = Interface;
|
|
pUnk = p;
|
|
if(pUnk) pUnk->AddRef();
|
|
m_pszKey = NULL;
|
|
}
|
|
DataItem(const DataItem &diItem) {
|
|
eType = diItem.eType;
|
|
if(eType == DWord) dword = diItem.dword;
|
|
else if(eType == String) {
|
|
iStringSize = diItem.iStringSize;
|
|
pStr = (LPSTR) MyMalloc(iStringSize);
|
|
if (pStr) {
|
|
strncpy(pStr, diItem.pStr, iStringSize);
|
|
}
|
|
} else if(eType == Interface) {
|
|
pUnk = diItem.pUnk;
|
|
if(pUnk) pUnk->AddRef();
|
|
}
|
|
if (diItem.m_pszKey) {
|
|
m_pszKey = (LPSTR) MyMalloc(lstrlen(diItem.m_pszKey) + 1);
|
|
if (m_pszKey) {
|
|
strcpy(m_pszKey, diItem.m_pszKey);
|
|
}
|
|
} else {
|
|
m_pszKey = NULL;
|
|
}
|
|
};
|
|
DataItem &operator=(const DataItem &diItem) {
|
|
eType = diItem.eType;
|
|
if(eType == DWord) dword = diItem.dword;
|
|
else if(eType == String) {iStringSize = diItem.iStringSize;
|
|
pStr = (LPSTR) MyMalloc(iStringSize);
|
|
if (pStr) {
|
|
strncpy(pStr, diItem.pStr, iStringSize);}
|
|
}
|
|
else if(eType == Interface) {pUnk = diItem.pUnk;
|
|
if(pUnk) pUnk->AddRef();}
|
|
if (diItem.m_pszKey) {
|
|
m_pszKey = (LPSTR) MyMalloc(lstrlen(diItem.m_pszKey) + 1);
|
|
if (m_pszKey) {
|
|
strcpy(m_pszKey, diItem.m_pszKey);
|
|
}
|
|
} else {
|
|
m_pszKey = NULL;
|
|
}
|
|
return *this;
|
|
};
|
|
DataItem(VARIANT *pVar);
|
|
~DataItem() {
|
|
if(eType == String) MyFree(pStr);
|
|
else if((eType == Interface) && pUnk) pUnk->Release();
|
|
eType = Empty;
|
|
if (m_pszKey) {
|
|
MyFree(m_pszKey);
|
|
m_pszKey = NULL;
|
|
}
|
|
};
|
|
|
|
BOOL SetKey(LPCSTR pszKey) {
|
|
if (m_pszKey) {
|
|
MyFree(m_pszKey);
|
|
m_pszKey = NULL;
|
|
}
|
|
m_pszKey = (LPSTR) MyMalloc(lstrlen(pszKey) + 1);
|
|
if (!m_pszKey) return FALSE;
|
|
|
|
strcpy(m_pszKey, pszKey);
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL IsEmpty() const {return (eType == Empty);};
|
|
BOOL IsDWORD() const {return (eType == DWord);};
|
|
BOOL IsString() const {return (eType == String);};
|
|
BOOL IsInterface() const {return (eType == Interface);};
|
|
|
|
operator DWORD() const {return (const) (IsDWORD() ? dword : 0);};
|
|
operator LPCSTR() const {return (IsString() ? pStr : NULL);};
|
|
LPCSTR GetString() const {return (IsString() ? pStr : NULL);};
|
|
operator LPUNKNOWN() const {return (IsInterface() ? pUnk : NULL);};
|
|
HRESULT AsVARIANT(VARIANT *pVar) const;
|
|
int StringSize() const {return iStringSize;};
|
|
|
|
static DLIST_ENTRY *GetListEntry(DataItem *p) {
|
|
return &p->m_listentry;
|
|
}
|
|
|
|
LPCSTR GetKey() {
|
|
return m_pszKey;
|
|
}
|
|
|
|
private:
|
|
DataType eType;
|
|
int iStringSize;
|
|
union {
|
|
DWORD dword;
|
|
LPSTR pStr;
|
|
LPUNKNOWN pUnk;
|
|
};
|
|
DLIST_ENTRY m_listentry;
|
|
LPSTR m_pszKey;
|
|
};
|
|
|
|
class ComparableString {
|
|
public:
|
|
ComparableString(LPCSTR p = NULL) : m_ptr(0), m_bAlloc(TRUE) {
|
|
if(!p) return;
|
|
m_ptr = (LPSTR) MyMalloc(lstrlen(p) + 1);
|
|
if (m_ptr) {
|
|
lstrcpy(m_ptr, p);
|
|
}
|
|
};
|
|
ComparableString(const ComparableString &csOther) : m_ptr(0) {
|
|
LPCSTR p = csOther.m_ptr;
|
|
m_ptr = (LPSTR) MyMalloc(lstrlen(p) + 1);
|
|
if (m_ptr) {
|
|
lstrcpy(m_ptr, p);
|
|
}
|
|
};
|
|
~ComparableString() {if(m_bAlloc&&m_ptr) MyFree(m_ptr);};
|
|
LPCSTR Data() const {return m_ptr;};
|
|
bool operator<(const ComparableString &csOther) const {
|
|
if (!m_ptr || !csOther.m_ptr) {
|
|
if (csOther.m_ptr) {
|
|
return (true);
|
|
}
|
|
return (false);
|
|
}
|
|
return (lstrcmpi(m_ptr, csOther.m_ptr) < 0);};
|
|
|
|
protected:
|
|
LPSTR m_ptr;
|
|
BOOL m_bAlloc;
|
|
};
|
|
|
|
class ComparableStringRef : public ComparableString {
|
|
public:
|
|
ComparableStringRef(LPCSTR p) {
|
|
m_ptr = (LPSTR) p;
|
|
m_bAlloc = FALSE;
|
|
};
|
|
};
|
|
|
|
typedef TDListHead<DataItem, &DataItem::GetListEntry> OurList;
|
|
|
|
class OurMap {
|
|
public:
|
|
class iterator : public TDListIterator<OurList> {
|
|
public:
|
|
iterator(OurList *pHead)
|
|
: TDListIterator<OurList>(pHead)
|
|
{
|
|
m_fFound = FALSE;
|
|
}
|
|
|
|
// get the key for the current item
|
|
LPCSTR GetKey() {
|
|
return Current()->GetKey();
|
|
}
|
|
|
|
// get the data for the current item
|
|
DataItem *GetData() {
|
|
return Current();
|
|
}
|
|
|
|
void operator++() {
|
|
Next();
|
|
}
|
|
|
|
DataItem *operator*() {
|
|
return Current();
|
|
}
|
|
|
|
void SetList(OurMap *pMap) {
|
|
ReBind(&(pMap->m_list));
|
|
}
|
|
|
|
// point the iterator to a specific item in the list
|
|
// arguments:
|
|
// pszKey - key to find
|
|
// iMatchType - -1 == point at first item with smaller key
|
|
// 0 == point at item with key
|
|
// 1 == point at first item with larger key
|
|
// returns:
|
|
// TRUE if a match was found, FALSE otherwise
|
|
BOOL find(LPCSTR pszKey, DWORD iMatchType = 0) {
|
|
if (strncmp(pszKey, "-1", 2) == 0) DebugBreak();
|
|
// reset the iterator
|
|
Front();
|
|
|
|
// walk until we match the key
|
|
while (!AtEnd()) {
|
|
const char *pszCurrentKey = Current()->GetKey();
|
|
if (lstrcmpi(pszCurrentKey, pszKey) == iMatchType) {
|
|
m_fFound = TRUE;
|
|
return TRUE;
|
|
}
|
|
Next();
|
|
}
|
|
m_fFound = FALSE;
|
|
return FALSE;
|
|
};
|
|
|
|
// did the last search succeed?
|
|
BOOL Found() {
|
|
return m_fFound;
|
|
}
|
|
private:
|
|
BOOL m_fFound;
|
|
};
|
|
|
|
friend iterator;
|
|
|
|
OurMap() {
|
|
m_cList = 0;
|
|
}
|
|
|
|
~OurMap() {
|
|
// remove all items from the list
|
|
while (m_cList) {
|
|
delete m_list.PopFront();
|
|
m_cList--;
|
|
}
|
|
_ASSERT(m_list.IsEmpty());
|
|
}
|
|
|
|
void erase(iterator i) {
|
|
m_cList--;
|
|
delete i.RemoveItem();
|
|
}
|
|
|
|
BOOL insert(LPCSTR pszKey, DataItem di) {
|
|
char buf[255];
|
|
|
|
OurMap::iterator it(&m_list);
|
|
|
|
DataItem *pDI = new DataItem();
|
|
if (pDI == NULL) return FALSE;
|
|
|
|
// copy the data item to the one that we will insert into
|
|
// our list
|
|
*pDI = di;
|
|
if (!pDI->SetKey(pszKey)) {
|
|
delete pDI;
|
|
return FALSE;
|
|
}
|
|
|
|
// find the first item with a larger key. if no such item was
|
|
// found then insert at head of list
|
|
if (it.find(pszKey, 1)) {
|
|
it.InsertBefore(pDI);
|
|
} else {
|
|
m_list.PushFront(pDI);
|
|
}
|
|
m_cList++;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
iterator find(LPCSTR pszKey) {
|
|
OurMap::iterator it(&m_list);
|
|
|
|
it.find(pszKey);
|
|
|
|
return it;
|
|
}
|
|
|
|
iterator begin() {
|
|
OurMap::iterator it(&m_list);
|
|
|
|
return it;
|
|
}
|
|
|
|
long size() {
|
|
return m_cList;
|
|
}
|
|
|
|
private:
|
|
OurList m_list;
|
|
long m_cList;
|
|
};
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CSEOMemDictionary
|
|
|
|
class ATL_NO_VTABLE CSEOMemDictionary :
|
|
public CComObjectRootEx<CComMultiThreadModelNoCS>,
|
|
public CComCoClass<CSEOMemDictionary, &CLSID_CSEOMemDictionary>,
|
|
public IDispatchImpl<ISEODictionary, &IID_ISEODictionary, &LIBID_SEOLib>,
|
|
public IPropertyBag,
|
|
public IDispatchImpl<IEventPropertyBag, &IID_IEventPropertyBag, &LIBID_SEOLib>
|
|
{
|
|
friend class CSEOMemDictionaryEnum; // Helper class
|
|
|
|
public:
|
|
HRESULT FinalConstruct();
|
|
void FinalRelease();
|
|
|
|
DECLARE_PROTECT_FINAL_CONSTRUCT();
|
|
|
|
DECLARE_REGISTRY_RESOURCEID_EX(IDR_StdAfx,
|
|
L"SEOMemDictionary Class",
|
|
L"SEO.SEOMemDictionary.1",
|
|
L"SEO.SEOMemDictionary");
|
|
|
|
BEGIN_COM_MAP(CSEOMemDictionary)
|
|
COM_INTERFACE_ENTRY(ISEODictionary)
|
|
COM_INTERFACE_ENTRY(IPropertyBag)
|
|
COM_INTERFACE_ENTRY(IEventPropertyBag)
|
|
COM_INTERFACE_ENTRY_IID(IID_IDispatch, IEventPropertyBag)
|
|
COM_INTERFACE_ENTRY_AGGREGATE(IID_IMarshal, m_pUnkMarshaler.p)
|
|
END_COM_MAP()
|
|
|
|
// ISEODictionary
|
|
public:
|
|
virtual /* [id][propget][helpstring] */ HRESULT STDMETHODCALLTYPE get_Item(
|
|
/* [in] */ VARIANT __RPC_FAR *pvarName,
|
|
/* [retval][out] */ VARIANT __RPC_FAR *pvarResult);
|
|
|
|
virtual /* [propput][helpstring] */ HRESULT STDMETHODCALLTYPE put_Item(
|
|
/* [in] */ VARIANT __RPC_FAR *pvarName,
|
|
/* [in] */ VARIANT __RPC_FAR *pvarValue);
|
|
|
|
virtual /* [hidden][id][propget][helpstring] */ HRESULT STDMETHODCALLTYPE get__NewEnum(
|
|
/* [retval][out] */ IUnknown __RPC_FAR *__RPC_FAR *ppunkResult);
|
|
|
|
virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetVariantA(
|
|
/* [in] */ LPCSTR pszName,
|
|
/* [retval][out] */ VARIANT __RPC_FAR *pvarResult);
|
|
|
|
virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetVariantW(
|
|
/* [in] */ LPCWSTR pszName,
|
|
/* [retval][out] */ VARIANT __RPC_FAR *pvarResult);
|
|
|
|
virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE SetVariantA(
|
|
/* [in] */ LPCSTR pszName,
|
|
/* [in] */ VARIANT __RPC_FAR *pvarValue);
|
|
|
|
virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE SetVariantW(
|
|
/* [in] */ LPCWSTR pszName,
|
|
/* [in] */ VARIANT __RPC_FAR *pvarValue);
|
|
|
|
virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetStringA(
|
|
/* [in] */ LPCSTR pszName,
|
|
/* [out][in] */ DWORD __RPC_FAR *pchCount,
|
|
/* [retval][size_is][out] */ LPSTR pszResult);
|
|
|
|
virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetStringW(
|
|
/* [in] */ LPCWSTR pszName,
|
|
/* [out][in] */ DWORD __RPC_FAR *pchCount,
|
|
/* [retval][size_is][out] */ LPWSTR pszResult);
|
|
|
|
virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE SetStringA(
|
|
/* [in] */ LPCSTR pszName,
|
|
/* [in] */ DWORD chCount,
|
|
/* [size_is][in] */ LPCSTR pszValue);
|
|
|
|
virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE SetStringW(
|
|
/* [in] */ LPCWSTR pszName,
|
|
/* [in] */ DWORD chCount,
|
|
/* [size_is][in] */ LPCWSTR pszValue);
|
|
|
|
virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetDWordA(
|
|
/* [in] */ LPCSTR pszName,
|
|
/* [retval][out] */ DWORD __RPC_FAR *pdwResult);
|
|
|
|
virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetDWordW(
|
|
/* [in] */ LPCWSTR pszName,
|
|
/* [retval][out] */ DWORD __RPC_FAR *pdwResult);
|
|
|
|
virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE SetDWordA(
|
|
/* [in] */ LPCSTR pszName,
|
|
/* [in] */ DWORD dwValue);
|
|
|
|
virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE SetDWordW(
|
|
/* [in] */ LPCWSTR pszName,
|
|
/* [in] */ DWORD dwValue);
|
|
|
|
virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetInterfaceA(
|
|
/* [in] */ LPCSTR pszName,
|
|
/* [in] */ REFIID iidDesired,
|
|
/* [retval][iid_is][out] */ IUnknown __RPC_FAR *__RPC_FAR *ppunkResult);
|
|
|
|
virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetInterfaceW(
|
|
/* [in] */ LPCWSTR pszName,
|
|
/* [in] */ REFIID iidDesired,
|
|
/* [retval][iid_is][out] */ IUnknown __RPC_FAR *__RPC_FAR *ppunkResult);
|
|
|
|
virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE SetInterfaceA(
|
|
/* [in] */ LPCSTR pszName,
|
|
/* [in] */ IUnknown __RPC_FAR *punkValue);
|
|
|
|
virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE SetInterfaceW(
|
|
/* [in] */ LPCWSTR pszName,
|
|
/* [in] */ IUnknown __RPC_FAR *punkValue);
|
|
|
|
DECLARE_GET_CONTROLLING_UNKNOWN();
|
|
|
|
// IPropertyBag
|
|
public:
|
|
HRESULT STDMETHODCALLTYPE Read(LPCOLESTR pszPropName, VARIANT *pVar, IErrorLog *pErrorLog);
|
|
HRESULT STDMETHODCALLTYPE Write(LPCOLESTR pszPropName, VARIANT *pVar);
|
|
|
|
// IEventPropertyBag
|
|
public:
|
|
HRESULT STDMETHODCALLTYPE Item(VARIANT *pvarPropDesired, VARIANT *pvarPropValue);
|
|
HRESULT STDMETHODCALLTYPE Name(long lPropIndex, BSTR *pbstrPropName);
|
|
HRESULT STDMETHODCALLTYPE Add(BSTR pszPropName, VARIANT *pvarPropValue);
|
|
HRESULT STDMETHODCALLTYPE Remove(VARIANT *pvarPropDesired);
|
|
HRESULT STDMETHODCALLTYPE get_Count(long *plCount);
|
|
/* Just use the get__NewEnum from ISEODictionary
|
|
HRESULT STDMETHODCALLTYPE get__NewEnum(IUnknown **ppUnkEnum); */
|
|
|
|
protected:
|
|
HRESULT Insert(LPCSTR pszName, const DataItem &diItem);
|
|
|
|
private: // Private data
|
|
OurMap m_mData;
|
|
CShareLockNH m_lock;
|
|
|
|
CComPtr<IUnknown> m_pUnkMarshaler;
|
|
};
|
|
|