Source code of Windows XP (NT5)
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.
 
 
 
 
 
 

274 lines
6.4 KiB

/*++
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;
}