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