274 lines
6.4 KiB
C++
274 lines
6.4 KiB
C++
|
/*++
|
||
|
|
||
|
Copyright (C) 1996-2001 Microsoft Corporation
|
||
|
|
||
|
Module Name:
|
||
|
|
||
|
CLASSINF.CPP
|
||
|
|
||
|
Abstract:
|
||
|
|
||
|
History:
|
||
|
|
||
|
--*/
|
||
|
|
||
|
#include "classinf.h"
|
||
|
#include "lazy.h"
|
||
|
|
||
|
void CHmmClassInfo::Load(HMM_CLASS_INFO ci)
|
||
|
{
|
||
|
m_wsClassName = ci.m_wszClassName;
|
||
|
m_bIncludeChildren = ci.m_bIncludeChildren;
|
||
|
m_Selected.RemoveAllProperties();
|
||
|
m_Selected.AddProperties(ci.m_lNumSelectedProperties,
|
||
|
ci.m_awszSelected);
|
||
|
}
|
||
|
|
||
|
void CHmmClassInfo::Save(HMM_CLASS_INFO& ci)
|
||
|
{
|
||
|
ci.m_wszClassName = HmmStringCopy((LPCWSTR)m_wsClassName);
|
||
|
ci.m_bIncludeChildren = m_bIncludeChildren;
|
||
|
m_Selected.GetList(0, &ci.m_lNumSelectedProperties,
|
||
|
&ci.m_awszSelected);
|
||
|
}
|
||
|
|
||
|
HRESULT CHmmClassInfo::CheckObjectAgainstMany(
|
||
|
IN long lNumInfos,
|
||
|
IN CHmmClassInfo** apInfos,
|
||
|
IN IHmmPropertySource* pSource,
|
||
|
OUT IHmmPropertyList** ppList,
|
||
|
OUT long* plIndex)
|
||
|
{
|
||
|
if(ppList) *ppList = NULL;
|
||
|
|
||
|
CLazyClassName ClassName(pSource);
|
||
|
|
||
|
// Go through our tokens one by one
|
||
|
// ================================
|
||
|
|
||
|
BOOL bFound = FALSE;
|
||
|
for(int i = 0; !bFound && i < lNumInfos; i++)
|
||
|
{
|
||
|
CHmmClassInfo* pToken = apInfos[i];
|
||
|
|
||
|
if(pToken->m_bIncludeChildren)
|
||
|
{
|
||
|
bFound = (pSource->IsDerivedFrom(pToken->m_wsClassName) ==
|
||
|
HMM_S_NO_ERROR);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
bFound = !wcsicmp(ClassName.GetName(), pToken->m_wsClassName);
|
||
|
}
|
||
|
|
||
|
if(bFound && ppList)
|
||
|
{
|
||
|
pToken->GetSelected().QueryInterface(IID_IHmmPropertyList,
|
||
|
(void**)ppList);
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
if(bFound)
|
||
|
{
|
||
|
return HMM_S_NO_ERROR;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
return HMM_S_FALSE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
CHmmNode* CHmmClassInfo::GetTree()
|
||
|
{
|
||
|
CSql1Token* pExpr = new CSql1Token;
|
||
|
|
||
|
V_VT(&pExpr->m_vConstValue) = VT_BSTR;
|
||
|
V_BSTR(&pExpr->m_vConstValue) = SysAllocString(m_wsClassName);
|
||
|
|
||
|
if(m_bIncludeChildren)
|
||
|
{
|
||
|
pExpr->m_lOperator = SQL1_OPERATOR_INHERITSFROM;
|
||
|
pExpr->m_wsProperty.Empty();
|
||
|
pExpr->m_lPropertyFunction = pExpr->m_lConstFunction =
|
||
|
SQL1_FUNCTION_NONE;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
pExpr->m_lOperator = SQL1_OPERATOR_EQUALS;
|
||
|
pExpr->m_wsProperty = L"__CLASS";
|
||
|
pExpr->m_lPropertyFunction = pExpr->m_lConstFunction =
|
||
|
SQL1_FUNCTION_UPPER;
|
||
|
}
|
||
|
|
||
|
pExpr->AddRef();
|
||
|
return pExpr;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
CClassInfoFilter::~CClassInfoFilter()
|
||
|
{
|
||
|
if(m_pTree)
|
||
|
m_pTree->Release();
|
||
|
}
|
||
|
|
||
|
void* CClassInfoFilter::GetInterface(REFIID riid)
|
||
|
{
|
||
|
if(riid == IID_IHmmFilter || riid == IID_IHmmClassInfoFilter)
|
||
|
return (IHmmClassInfoFilter*)&m_XFilter;
|
||
|
else if(riid == IID_IConfigureHmmClassInfoFilter)
|
||
|
return (IConfigureHmmClassInfoFilter*)&m_XConfigure;
|
||
|
else
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP CClassInfoFilter::XFilter::
|
||
|
CheckObject(IN IHmmPropertySource* pSource, OUT IHmmPropertyList** ppList,
|
||
|
OUT IUnknown** ppHint)
|
||
|
{
|
||
|
if(ppHint) *ppHint = NULL;
|
||
|
|
||
|
return CHmmClassInfo::CheckObjectAgainstMany(
|
||
|
m_pObject->m_apTokens.GetSize(),
|
||
|
m_pObject->m_apTokens.begin(),
|
||
|
pSource, ppList, NULL);
|
||
|
}
|
||
|
|
||
|
|
||
|
STDMETHODIMP CClassInfoFilter::XFilter::
|
||
|
IsSpecial()
|
||
|
{
|
||
|
if(m_pObject->m_apTokens.GetSize() == 0)
|
||
|
return HMM_S_ACCEPTS_NOTHING;
|
||
|
else
|
||
|
return HMM_S_FALSE;
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP CClassInfoFilter::XFilter::
|
||
|
GetSelectedPropertyList(IN long lFlags, OUT IHmmPropertyList** ppList)
|
||
|
{
|
||
|
// Only implemented if one class info is present
|
||
|
// =============================================
|
||
|
|
||
|
if(m_pObject->m_apTokens.GetSize() == 1)
|
||
|
{
|
||
|
return m_pObject->m_apTokens[0]->GetSelected().
|
||
|
QueryInterface(IID_IHmmPropertyList, (void**)ppList);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// Stubbed out
|
||
|
// ===========
|
||
|
|
||
|
CPropertyList* pList = new CPropertyList(m_pObject->m_pControl, NULL);
|
||
|
pList->QueryInterface(IID_IHmmPropertyList, (void**)ppList);
|
||
|
|
||
|
if(lFlags == HMM_FLAG_NECESSARY)
|
||
|
{
|
||
|
pList->RemoveAllProperties(); // no properties are "necessary"
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
pList->AddAllProperties();
|
||
|
}
|
||
|
|
||
|
return HMM_S_NO_ERROR;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP CClassInfoFilter::XFilter::
|
||
|
GetType(OUT IID* piid)
|
||
|
{
|
||
|
if(piid == NULL)
|
||
|
return HMM_E_INVALID_PARAMETER;
|
||
|
*piid = IID_IHmmClassInfoFilter;
|
||
|
return HMM_S_NO_ERROR;
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP CClassInfoFilter::XFilter::
|
||
|
GetClassInfos(IN long lFirstIndex,
|
||
|
IN long lNumInfos,
|
||
|
OUT long* plInfosReturned,
|
||
|
OUT HMM_CLASS_INFO* aInfos)
|
||
|
{
|
||
|
if(plInfosReturned == NULL || aInfos == NULL || lFirstIndex < 0 ||
|
||
|
lNumInfos < 0)
|
||
|
{
|
||
|
return HMM_E_INVALID_PARAMETER;
|
||
|
}
|
||
|
|
||
|
long lCurrentSize = m_pObject->m_apTokens.GetSize();
|
||
|
if(lFirstIndex >= lCurrentSize)
|
||
|
return HMM_S_NO_MORE_DATA;
|
||
|
|
||
|
long lEndIndex = lFirstIndex + lNumInfos;
|
||
|
if(lEndIndex > lCurrentSize)
|
||
|
lEndIndex = lCurrentSize;
|
||
|
|
||
|
for(long l = lFirstIndex; l < lEndIndex; l++)
|
||
|
{
|
||
|
m_pObject->m_apTokens[l]->Save(aInfos[l-lFirstIndex]);
|
||
|
}
|
||
|
|
||
|
*plInfosReturned = lEndIndex - lFirstIndex;
|
||
|
return HMM_S_NO_ERROR;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
STDMETHODIMP CClassInfoFilter::XConfigure::
|
||
|
AddClassInfos(long lNumInfos, IN HMM_CLASS_INFO* aInfos)
|
||
|
{
|
||
|
if(lNumInfos <= 0 || aInfos == NULL)
|
||
|
return HMM_E_INVALID_PARAMETER;
|
||
|
|
||
|
m_pObject->InvalidateTree();
|
||
|
for(long l = 0; l < lNumInfos; l++)
|
||
|
{
|
||
|
// Create a new info object, setting our MemberLife as its life control
|
||
|
// object. This will propagate his AddRef and Release calls to us.
|
||
|
CHmmClassInfo* pNew = new CHmmClassInfo(&m_pObject->m_MemberLife);
|
||
|
pNew->Load(aInfos[l]);
|
||
|
m_pObject->m_apTokens.Add(pNew);
|
||
|
}
|
||
|
return HMM_S_NO_ERROR;
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP CClassInfoFilter::XConfigure::
|
||
|
RemoveAllInfos()
|
||
|
{
|
||
|
m_pObject->InvalidateTree();
|
||
|
m_pObject->m_apTokens.RemoveAll();
|
||
|
return HMM_S_NO_ERROR;
|
||
|
}
|
||
|
|
||
|
CHmmNode* CClassInfoFilter::GetTree()
|
||
|
{
|
||
|
if(m_pTree)
|
||
|
{
|
||
|
m_pTree->AddRef();
|
||
|
return m_pTree;
|
||
|
}
|
||
|
|
||
|
// Build it
|
||
|
// ========
|
||
|
|
||
|
CLogicalNode* pOr = new CLogicalNode;
|
||
|
pOr->m_lTokenType = SQL1_OR;
|
||
|
|
||
|
for(int i = 0; i < m_apTokens.GetSize(); i++)
|
||
|
{
|
||
|
CHmmClassInfo* pInfo = m_apTokens[i];
|
||
|
CHmmNode* pExpr = pInfo->GetTree();
|
||
|
pOr->Add(pExpr);
|
||
|
pExpr->Release();
|
||
|
}
|
||
|
|
||
|
m_pTree = pOr;
|
||
|
m_pTree->AddRef(); // for storage
|
||
|
m_pTree->AddRef(); // for return
|
||
|
return m_pTree;
|
||
|
}
|
||
|
|
||
|
|