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.
 
 
 
 
 
 

432 lines
9.3 KiB

/*++
Copyright (C) 1996-1999 Microsoft Corporation
Module Name:
WBEMDNF.CPP
Abstract:
WBEM Evaluation Tree
History:
--*/
#include "precomp.h"
#include <stdio.h>
#pragma warning(disable:4786)
#include <wbemcomn.h>
#include <genutils.h>
#include <wbemdnf.h>
HRESULT CDNFExpression::CreateFromTokens(QL_LEVEL_1_TOKEN*& pLastToken,
BOOL bNegate, long& lTokensAllowed)
{
HRESULT hres;
QL_LEVEL_1_TOKEN& Head = *pLastToken;
if(Head.nTokenType == QL1_OP_EXPRESSION)
{
if(lTokensAllowed <= 0)
return WBEM_E_QUOTA_VIOLATION;
else
lTokensAllowed--;
if(!CreateFromToken(Head, bNegate))
return WBEM_E_OUT_OF_MEMORY;
pLastToken--;
return WBEM_S_NO_ERROR;
}
// Build arguments
// ===============
pLastToken--;
if(Head.nTokenType == QL1_NOT)
{
if(lTokensAllowed <= 0)
return WBEM_E_QUOTA_VIOLATION;
else
lTokensAllowed--;
hres = CreateFromTokens(pLastToken, !bNegate, lTokensAllowed);
return hres;
}
long lChildCount = lTokensAllowed;
CDNFExpression Arg1;
hres = Arg1.CreateFromTokens(pLastToken, bNegate, lChildCount);
if(FAILED(hres))
return hres;
CDNFExpression Arg2;
hres = Arg2.CreateFromTokens(pLastToken, bNegate, lChildCount);
if(FAILED(hres))
return hres;
if( Head.nTokenType == QL1_AND )
{
if ( !bNegate )
{
hres = CreateAnd( Arg1, Arg2, lTokensAllowed );
}
else
{
hres = CreateOr( Arg1, Arg2, lTokensAllowed );
}
}
else
{
if ( !bNegate )
{
hres = CreateOr( Arg1, Arg2, lTokensAllowed );
}
else
{
hres = CreateAnd( Arg1, Arg2, lTokensAllowed );
}
}
return hres;
}
HRESULT CDNFExpression::CreateAnd(CDNFExpression& Arg1, CDNFExpression& Arg2,
long& lTokensAllowed)
{
for(long lFirst = 0; lFirst < Arg1.GetNumTerms(); lFirst++)
{
for(long lSecond = 0; lSecond < Arg2.GetNumTerms(); lSecond++)
{
CConjunction* pNewTerm = NULL;
try
{
pNewTerm = new CConjunction(*Arg1.GetTermAt(lFirst),
*Arg2.GetTermAt(lSecond));
}
catch(...)
{
pNewTerm = NULL;
}
if(pNewTerm == NULL)
return WBEM_E_OUT_OF_MEMORY;
long lTokens = pNewTerm->GetNumTokens();
if(lTokens > lTokensAllowed)
{
delete pNewTerm;
return WBEM_E_QUOTA_VIOLATION;
}
else
{
lTokensAllowed -= lTokens;
}
m_apTerms.Add(pNewTerm);
}
}
return S_OK;
}
HRESULT CDNFExpression::CreateOr(CDNFExpression& Arg1, CDNFExpression& Arg2,
long& lTokensAllowed)
{
int i;
for(i = 0; i < Arg1.GetNumTerms(); i++)
{
CConjunction* pConj = NULL;
try
{
pConj = new CConjunction(*Arg1.GetTermAt(i));
}
catch(...)
{
pConj = NULL;
}
if(pConj == NULL)
return WBEM_E_OUT_OF_MEMORY;
long lTokens = pConj->GetNumTokens();
if(lTokens > lTokensAllowed)
{
delete pConj;
return WBEM_E_QUOTA_VIOLATION;
}
else
{
lTokensAllowed -= lTokens;
}
m_apTerms.Add(pConj);
}
for(i = 0; i < Arg2.GetNumTerms(); i++)
{
CConjunction* pConj = NULL;
try
{
pConj = new CConjunction(*Arg2.GetTermAt(i));
}
catch(...)
{
pConj = NULL;
}
if(pConj == NULL)
return WBEM_E_OUT_OF_MEMORY;
long lTokens = pConj->GetNumTokens();
if(lTokens > lTokensAllowed)
{
delete pConj;
return WBEM_E_QUOTA_VIOLATION;
}
else
{
lTokensAllowed -= lTokens;
}
m_apTerms.Add(pConj);
}
return S_OK;
}
BOOL CDNFExpression::CreateFromToken(QL_LEVEL_1_TOKEN& Token, BOOL bNegate)
{
try
{
CConjunction* pConj = new CConjunction(Token, bNegate);
if(pConj == NULL)
return FALSE;
if(m_apTerms.Add(pConj) < 0)
return FALSE;
}
catch(...)
{
return FALSE;
}
return TRUE;
}
void CDNFExpression::Sort()
{
for(int i = 0; i < m_apTerms.GetSize(); i++)
{
m_apTerms[i]->Sort();
}
}
HRESULT CDNFExpression::GetNecessaryProjection(CTokenFilter* pFilter,
CDNFExpression** ppResult)
{
*ppResult = NULL;
CDNFExpression* pResult = new CDNFExpression;
for(int i = 0; i < m_apTerms.GetSize(); i++)
{
CConjunction* pConj = NULL;
HRESULT hres = m_apTerms[i]->GetNecessaryProjection(pFilter, &pConj);
if(FAILED(hres))
{
delete pResult;
return hres;
}
if(pConj->GetNumTokens() == 0)
{
//
// This conjunction is empty, meaning that no necessary condition
// exists for the projection in question. That means that the
// entire projection is empty as well --- no restrictions.
//
pResult->m_apTerms.RemoveAll();
return WBEM_S_NO_ERROR;
}
else
{
pResult->m_apTerms.Add(pConj);
}
}
*ppResult = pResult;
return WBEM_S_NO_ERROR;
}
CReuseMemoryManager CConjunction::mstatic_Manager(sizeof CConjunction);
void *CConjunction::operator new(size_t nBlock)
{
return mstatic_Manager.Allocate();
}
void CConjunction::operator delete(void* p)
{
mstatic_Manager.Free(p);
}
CConjunction::CConjunction()
{
}
CConjunction::CConjunction(QL_LEVEL_1_TOKEN& Token, BOOL bNegate)
{
QL_LEVEL_1_TOKEN * pToken = new QL_LEVEL_1_TOKEN( Token );
if ( NULL == pToken )
{
throw CX_MemoryException();
}
m_apTokens.Add( pToken );
if(bNegate)
{
m_apTokens[0]->nOperator = NegateOperator(m_apTokens[0]->nOperator);
}
}
CConjunction::CConjunction(CConjunction& Other)
{
for(int i = 0; i < Other.GetNumTokens(); i++)
{
QL_LEVEL_1_TOKEN * pToken = new QL_LEVEL_1_TOKEN( *Other.GetTokenAt( i ) );
if ( NULL == pToken )
{
throw CX_MemoryException();
}
m_apTokens.Add( pToken );
}
}
CConjunction::CConjunction(CConjunction& Other1, CConjunction& Other2)
{
int i;
for(i = 0; i < Other1.GetNumTokens(); i++)
{
QL_LEVEL_1_TOKEN * pToken = new QL_LEVEL_1_TOKEN( *Other1.GetTokenAt( i ) );
if ( NULL == pToken )
{
throw CX_MemoryException();
}
m_apTokens.Add( pToken );
}
for(i = 0; i < Other2.GetNumTokens(); i++)
{
QL_LEVEL_1_TOKEN * pToken = new QL_LEVEL_1_TOKEN( *Other2.GetTokenAt( i ) );
if ( NULL == pToken )
{
throw CX_MemoryException();
}
m_apTokens.Add( pToken );
}
}
int CConjunction::NegateOperator(int nOperator)
{
switch(nOperator)
{
case QL1_OPERATOR_EQUALS:
return QL1_OPERATOR_NOTEQUALS;
case QL1_OPERATOR_NOTEQUALS:
return QL1_OPERATOR_EQUALS;
case QL1_OPERATOR_GREATER:
return QL1_OPERATOR_LESSOREQUALS;
case QL1_OPERATOR_LESS:
return QL1_OPERATOR_GREATEROREQUALS;
case QL1_OPERATOR_LESSOREQUALS:
return QL1_OPERATOR_GREATER;
case QL1_OPERATOR_GREATEROREQUALS:
return QL1_OPERATOR_LESS;
case QL1_OPERATOR_LIKE:
return QL1_OPERATOR_UNLIKE;
case QL1_OPERATOR_UNLIKE:
return QL1_OPERATOR_LIKE;
case QL1_OPERATOR_ISA:
return QL1_OPERATOR_ISNOTA;
case QL1_OPERATOR_ISNOTA:
return QL1_OPERATOR_ISA;
case QL1_OPERATOR_INV_ISA:
return QL1_OPERATOR_INV_ISNOTA;
case QL1_OPERATOR_INV_ISNOTA:
return QL1_OPERATOR_INV_ISA;
}
return nOperator;
}
#pragma optimize("", off)
void CConjunction::Sort()
{
int i = 0;
while(i < m_apTokens.GetSize() - 1)
{
int nLeft = m_apTokens[i]->PropertyName.GetNumElements();
int nRight = m_apTokens[i+1]->PropertyName.GetNumElements();
if(nLeft > nRight)
{
m_apTokens.Swap(i, i+1);
if(i != 0)
{
i--;
}
}
else
{
i++;
}
}
}
#pragma optimize("", on)
// returns an empty conjunction if no necessary condition exists
HRESULT CConjunction::GetNecessaryProjection(CTokenFilter* pFilter,
CConjunction** ppResult)
{
*ppResult = NULL;
CConjunction* pResult = new CConjunction;
if(pResult == NULL)
return WBEM_E_OUT_OF_MEMORY;
for(int i = 0; i < m_apTokens.GetSize(); i++)
{
if(pFilter->IsRelevant(m_apTokens[i]))
{
if(!pResult->AddToken(m_apTokens[i]))
{
delete pResult;
return WBEM_E_OUT_OF_MEMORY;
}
}
}
*ppResult = pResult;
return WBEM_S_NO_ERROR;
}