|
|
#include "sqleval.h"
#include <stdio.h>
#include <genlex.h>
#include <sqllex.h>
#include <sql_1.h>
// CSqlWmiEvalee
CSqlWmiEvalee::~CSqlWmiEvalee() { if(m_pInstance) m_pInstance->Release(); }
CSqlWmiEvalee::CSqlWmiEvalee( IWbemClassObject* pInst) :m_pInstance(NULL) { m_pInstance = pInst; if(m_pInstance) m_pInstance->AddRef(); VariantInit(&m_v); }
const VARIANT* CSqlWmiEvalee::Get( WCHAR* wszName) { VariantClear(&m_v); BSTR bstr = SysAllocString(wszName); if (bstr != NULL) { SCODE sc = m_pInstance->Get( bstr, 0, &m_v, NULL, NULL); SysFreeString(bstr); if(sc != S_OK) throw sc; } return &m_v; } // CSqlEval
CSqlEval* CSqlEval::CreateClass( SQL_LEVEL_1_RPN_EXPRESSION* pExpr, int* pNumberOfToken) { if(pExpr== NULL || *pNumberOfToken<= 0) return NULL; SQL_LEVEL_1_TOKEN* pToken = pExpr->pArrayOfTokens+(*pNumberOfToken-1); // (*pNumberOfToken)--;
switch(pToken->nTokenType) { case SQL_LEVEL_1_TOKEN::TOKEN_AND: return new CSqlEvalAnd( pExpr, pNumberOfToken); case SQL_LEVEL_1_TOKEN::TOKEN_OR: return new CSqlEvalOr( pExpr, pNumberOfToken); case SQL_LEVEL_1_TOKEN::OP_EXPRESSION: return new CSqlEvalExp( pExpr, pNumberOfToken); } return NULL; }
BOOL CSqlEval::Evaluate( CSqlEvalee* pInst) { return TRUE; }
// CSqlEvalAnd
CSqlEvalAnd::~CSqlEvalAnd() { delete m_left; delete m_right; }
CSqlEvalAnd::CSqlEvalAnd( SQL_LEVEL_1_RPN_EXPRESSION* pExpr, int* pTokens) :m_left(NULL),m_right(NULL) { (*pTokens)-- ; m_left = CSqlEval::CreateClass( pExpr, pTokens); m_right = CSqlEval::CreateClass( pExpr, pTokens); }
BOOL CSqlEvalAnd::Evaluate( CSqlEvalee* pInst) { return m_left->Evaluate(pInst) && m_right->Evaluate(pInst); }
void CSqlEvalAnd::GenerateQueryEnum(CQueryEnumerator& qeInst) { CQueryEnumerator qeNew = qeInst; m_left->GenerateQueryEnum(qeNew);
m_right->GenerateQueryEnum(qeInst); qeInst.And(qeNew);
}
// CSqlEvalOR
CSqlEvalOr::~CSqlEvalOr() { delete m_left; delete m_right; }
CSqlEvalOr::CSqlEvalOr( SQL_LEVEL_1_RPN_EXPRESSION* pExpr, int* pTokens) :m_left(NULL),m_right(NULL) { (*pTokens)-- ; m_left = CSqlEval::CreateClass( pExpr, pTokens); m_right = CSqlEval::CreateClass( pExpr, pTokens); }
BOOL CSqlEvalOr::Evaluate( CSqlEvalee* pInst) { return m_left->Evaluate(pInst) || m_right->Evaluate(pInst); }
void CSqlEvalOr::GenerateQueryEnum(CQueryEnumerator& qeInst) { CQueryEnumerator qeNew = qeInst; m_left->GenerateQueryEnum(qeNew);
m_right->GenerateQueryEnum(qeInst); qeInst.Or(qeNew);
}
// CSqlEvalExp
CSqlEvalExp::~CSqlEvalExp() { SysFreeString(m_BstrName); VariantClear(&m_v); }
CSqlEvalExp::CSqlEvalExp( SQL_LEVEL_1_RPN_EXPRESSION* pExpr, int* pTokens) :m_BstrName(NULL) { VariantInit(&m_v); SQL_LEVEL_1_TOKEN* pToken = pExpr->pArrayOfTokens+(*pTokens-1); (*pTokens)--; m_BstrName = SysAllocString(pToken->pPropertyName); HRESULT hr = VariantCopy(&m_v, &(pToken->vConstValue)); if ( FAILED( hr ) ) { throw WBEM_E_OUT_OF_MEMORY; } m_op = pToken->nOperator; switch(m_v.vt) { case VT_I2: m_dw = m_v.iVal; m_DataType = IntergerType; break; case VT_I4: m_dw = m_v.lVal; m_DataType = IntergerType; break; case VT_BOOL: m_DataType = IntergerType; m_dw = m_v.boolVal; break; case VT_BSTR: m_DataType = StringType; m_bstr = m_v.bstrVal; break; default: throw WBEM_E_INVALID_PARAMETER; } }
BOOL CSqlEvalExp::Evaluate( CSqlEvalee* pInst) {
BOOL Result=FALSE; const VARIANT* pv = pInst->Get(m_BstrName); switch(m_DataType) { case IntergerType: DWORD dw; switch(pv->vt) { case VT_I2: dw = pv->iVal; break; case VT_I4: dw = pv->lVal; break; case VT_BOOL: dw = pv->boolVal; break; }
// compare
switch(m_op) { case SQL_LEVEL_1_TOKEN::OP_EQUAL: Result = (dw == m_dw); break; case SQL_LEVEL_1_TOKEN::OP_NOT_EQUAL: Result = !(dw == m_dw); break; case SQL_LEVEL_1_TOKEN::OP_EQUALorGREATERTHAN: Result = (dw >= m_dw); break; case SQL_LEVEL_1_TOKEN::OP_EQUALorLESSTHAN: Result = (dw <= m_dw); break; case SQL_LEVEL_1_TOKEN::OP_LESSTHAN: Result = (dw < m_dw); break; case SQL_LEVEL_1_TOKEN::OP_GREATERTHAN: Result = (dw > m_dw); break; } break; case StringType: int rt = _wcsicmp(pv->bstrVal, m_bstr); switch(m_op) { case SQL_LEVEL_1_TOKEN::OP_EQUAL: Result = (rt == 0); break; case SQL_LEVEL_1_TOKEN::OP_NOT_EQUAL: Result = !(rt == 0); break; case SQL_LEVEL_1_TOKEN::OP_EQUALorGREATERTHAN: Result = (rt > 0 || rt == 0); break; case SQL_LEVEL_1_TOKEN::OP_EQUALorLESSTHAN: Result = (rt < 0 || rt == 0); break; case SQL_LEVEL_1_TOKEN::OP_LESSTHAN: Result = (rt < 0); break; case SQL_LEVEL_1_TOKEN::OP_GREATERTHAN: Result = (rt > 0 ); break; } break; }
return Result; }
void CSqlEvalExp::GenerateQueryEnum(CQueryEnumerator& qeInst) { int nSize = qeInst.m_QueryFields.Size(); const WCHAR** ppName = qeInst.m_QueryFields.Data(); WCHAR** ppWstr = new WCHAR*[nSize]; if ( ppWstr ) { for(int i=0; i< nSize; i++) { if(_wcsicmp( m_BstrName, ppName[i]) == 0) { ppWstr[i] = m_v.bstrVal; } else ppWstr[i] = NULL; } CQueryEnumerator::CStringArray strArray( ppWstr, nSize); delete [] ppWstr; qeInst.ArrayAdd(strArray); } }
//CQueryEnumerator;
CQueryEnumerator::CQueryEnumerator( WCHAR** ppKeyName, int cArg ): m_index(0),m_cNumOfRecordInSet(0), m_QuerySet(NULL), m_MaxSize(INITIAL_SIZE) { m_QueryFields = CStringArray( ppKeyName, cArg);
}
CQueryEnumerator::CQueryEnumerator( CQueryEnumerator& instEnumerator) :m_index(0), m_MaxSize(INITIAL_SIZE), m_QuerySet(NULL), m_cNumOfRecordInSet(0) {
m_QueryFields = instEnumerator.m_QueryFields; int nSize = instEnumerator.m_cNumOfRecordInSet; for(int i=0; i< nSize; i++) { ArrayAdd(instEnumerator.m_QuerySet[i]); } }
CQueryEnumerator::~CQueryEnumerator() { ArrayDelete(); }
/*
DWORD CQueryEnumerator::InitEnumerator( WCHAR** wszFieldNames, int cArg, CSqlEval* pEval) { m_QueryFields = CStringArray( wszFieldNames, cArg);
return S_OK; } */ const WCHAR** CQueryEnumerator::GetNext(int& cElement) { if(m_index == m_cNumOfRecordInSet) { return NULL; } else { cElement = m_QuerySet[m_index].Size(); return m_QuerySet[m_index++].Data(); } }
void CQueryEnumerator::ArrayMerge( CQueryEnumerator::CStringArray& strArray) { for(int i=0; i< m_cNumOfRecordInSet; i++) { // if all element of strArray are null, no need to proceed
if( !strArray.IsNULL()) m_QuerySet[i].Merge(strArray); } }
void CQueryEnumerator::ArrayAdd( CQueryEnumerator::CStringArray & strArray ) { // if all elements are null for strArray, means no keys are
// selected,we should therefore replace M_querySet this StrArray
if ( strArray.IsNULL() ) { ArrayDelete(); }
if ( m_QuerySet == NULL ) { m_QuerySet = new CStringArray[ m_MaxSize ]; if ( !m_QuerySet ) { return; } }
// if array is full, then expand
if ( m_index == m_MaxSize ) { CStringArray * pOldSet = m_QuerySet; m_MaxSize = m_MaxSize * 2; m_QuerySet = new CStringArray[ m_MaxSize ]; if ( !m_QuerySet ) { return; } for( int i =0; i < m_MaxSize; i++ ) { if( i < m_index ) { m_QuerySet[ i ] = pOldSet[ i ]; } } delete [] pOldSet; }
if ( !( m_cNumOfRecordInSet > 0 && ( m_QuerySet[0] ).IsNULL() ) ) { m_QuerySet[ m_index++ ] = strArray; m_cNumOfRecordInSet = m_index; } }
void CQueryEnumerator::ArrayDelete() { delete [] m_QuerySet; m_QuerySet = NULL; m_cNumOfRecordInSet = 0; m_MaxSize = INITIAL_SIZE; m_index = 0; }
void CQueryEnumerator::And( CQueryEnumerator& instEnumerator) { int nSize = instEnumerator.m_cNumOfRecordInSet; if ( nSize > 0 ) { CQueryEnumerator qeOld = *this; ArrayDelete(); for ( int i=0; i< nSize; i++ ) { CQueryEnumerator qeNew = qeOld; if ( !qeNew.m_QuerySet ) { return; } qeNew.ArrayMerge( instEnumerator.m_QuerySet[ i ] ); for ( int j=0; j< qeNew.m_cNumOfRecordInSet; ++j ) { ArrayAdd( qeNew.m_QuerySet[ j ] ); } } } }
void CQueryEnumerator::Or( CQueryEnumerator& instEnumerator) { for(int i=0; i< instEnumerator.m_cNumOfRecordInSet; i++) {
if(instEnumerator.m_QuerySet[i].IsNULL()) { if(m_cNumOfRecordInSet > 0) ArrayDelete(); ArrayAdd(instEnumerator.m_QuerySet[i]); } else { ArrayAdd(instEnumerator.m_QuerySet[i]); } } } void CQueryEnumerator::Reset() { m_index = 0; } // CStringArray
CQueryEnumerator::CStringArray::CStringArray() :m_ppWstr(NULL), m_cNumString(0), m_bIsNull(TRUE) { }
CQueryEnumerator::CStringArray::~CStringArray() { if(m_ppWstr != NULL) { for (int i=0; i< m_cNumString; i++) { delete [] m_ppWstr[i]; } delete [] m_ppWstr; } }
CQueryEnumerator::CStringArray::CStringArray( WCHAR **ppWstrInput, int cNumString) :m_ppWstr(NULL) { m_cNumString = cNumString; m_bIsNull = !StringArrayCopy( &m_ppWstr, ppWstrInput, cNumString); } CQueryEnumerator::CStringArray::CStringArray( CQueryEnumerator::CStringArray& strArray) :m_ppWstr(NULL) { m_cNumString = strArray.m_cNumString; m_bIsNull = !StringArrayCopy( &m_ppWstr, strArray.m_ppWstr, strArray.m_cNumString); }
CQueryEnumerator::CStringArray& CQueryEnumerator::CStringArray::operator =( CQueryEnumerator::CStringArray& strArray) { if(m_ppWstr != NULL) { for (int i=0; i< m_cNumString; i++) { delete [] *m_ppWstr; *m_ppWstr = NULL; } delete [] m_ppWstr; m_ppWstr = NULL; }
m_cNumString = strArray.m_cNumString; m_bIsNull= !StringArrayCopy( &m_ppWstr, strArray.m_ppWstr, strArray.m_cNumString); return *this; }
int CQueryEnumerator::CStringArray::Size() { return m_cNumString; }
const WCHAR** CQueryEnumerator::CStringArray::Data() { return (const WCHAR**) m_ppWstr; }
// return true if any element is copied,
// false if no element is copied, and no element set to NULL
BOOL CQueryEnumerator::CStringArray::StringArrayCopy( WCHAR*** pppDest, WCHAR** ppSrc, int cArgs) { BOOL bFlag = FALSE; if(cArgs >0 && ppSrc != NULL) { *pppDest = new WCHAR*[cArgs]; if ( *pppDest ) { for(int i=0; i< cArgs; i++) { (*pppDest)[i] = NULL; if(ppSrc[i] != NULL) { int len = wcslen(ppSrc[i]); (*pppDest)[i] = new WCHAR[len+1]; if ( (*pppDest)[i] == NULL ) { //
// Free memory already allocated on allocation failure.
//
for ( int j = 0; j < i; ++j ) { delete [] (*pppDest)[ j ]; } delete [] *pppDest; *pppDest = NULL; throw WBEM_E_OUT_OF_MEMORY; } wcscpy((*pppDest)[i], ppSrc[i]); bFlag = TRUE; } } } } return bFlag; }
void CQueryEnumerator::CStringArray::Merge( CQueryEnumerator::CStringArray& instStrArray) { if(instStrArray.Size() != m_cNumString) throw WBEM_E_FAILED; const WCHAR** ppSrc = instStrArray.Data(); for(int i=0; i<m_cNumString; i++) { // if source is null, we leave target string as it was
if( ppSrc[i] != NULL) { if(m_ppWstr[i] == NULL) { m_ppWstr[i] = new WCHAR[wcslen(ppSrc[i])+1]; if ( m_ppWstr[i] == NULL ) { throw WBEM_E_OUT_OF_MEMORY; } wcscpy(m_ppWstr[i], ppSrc[i]); } else { // a key can not take two different value
if(_wcsicmp(m_ppWstr[i], ppSrc[i]) != 0) throw WBEM_E_INVALID_PARAMETER; } } } }
|