1396 lines
40 KiB
C
1396 lines
40 KiB
C
/**********************************************************************************
|
|
|
|
Copyright (c) Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
FilterResults.c
|
|
|
|
Abstract:
|
|
|
|
This modules has functions which are required to parse Command Line options.
|
|
|
|
Author:
|
|
|
|
G.V.N.Murali Sunil
|
|
|
|
Revision History:
|
|
|
|
None
|
|
|
|
|
|
**********************************************************************************/
|
|
|
|
#include "pch.h"
|
|
#include "cmdline.h"
|
|
|
|
//
|
|
// constants / definitions / enumerations
|
|
//
|
|
|
|
#define OPERATOR_DELIMITER _T( "|" )
|
|
#define CHAR_ASTERISK _T( '*' )
|
|
|
|
#define OPERATOR_EQ _T( "=| eq " )
|
|
#define OPERATOR_NE _T( "!=| ne " )
|
|
#define OPERATOR_GT _T( ">| gt " )
|
|
#define OPERATOR_LT _T( "<| lt " )
|
|
#define OPERATOR_GE _T( ">=| ge " )
|
|
#define OPERATOR_LE _T( "<=| le " )
|
|
|
|
|
|
//
|
|
// private user-defined types ... for internal usage only
|
|
//
|
|
typedef struct ___tagOperator
|
|
{
|
|
DWORD dwMask;
|
|
OPERATORS szOperator;
|
|
} TOPERATOR;
|
|
|
|
typedef TOPERATOR* PTOPERATOR;
|
|
|
|
//
|
|
// private functions ... used only within this file
|
|
//
|
|
|
|
/***************************************************************************
|
|
Routine Description:
|
|
|
|
Arguments:
|
|
[ in ] dwCount:
|
|
[ in ] optInfo[]:
|
|
[ in ] szOperator:
|
|
|
|
|
|
Return Value:
|
|
|
|
|
|
***************************************************************************/
|
|
DWORD __FindOperatorMask( DWORD dwCount, TOPERATOR optInfo[], LPCTSTR szOperator )
|
|
{
|
|
// local variables
|
|
DWORD dw = 0; // looping variable
|
|
|
|
// check the input value
|
|
if ( optInfo == NULL || szOperator == NULL )
|
|
{
|
|
SetLastError( ERROR_INVALID_PARAMETER );
|
|
SaveLastError();
|
|
return 0;
|
|
}
|
|
|
|
// traverse thru the list of operators list
|
|
for( dw = 0; dw < dwCount; dw++ )
|
|
{
|
|
// check whether the current operator information matches
|
|
if ( InString( szOperator, optInfo[ dw ].szOperator, TRUE ) )
|
|
return optInfo[ dw ].dwMask; // operator matched ... return its mask
|
|
}
|
|
|
|
// operator not found
|
|
return 0;
|
|
}
|
|
|
|
/***************************************************************************
|
|
Routine Description:
|
|
Compares Two Strings in two ways with and without case sensitivily,
|
|
|
|
Arguments:
|
|
[ in ] szValue1 = First String
|
|
[ in ] szValue2 = Second String
|
|
[ in ] bIgnoreCase = Case Sensitivity or not
|
|
[ in ] lCount = no. of characters to be compare
|
|
|
|
|
|
Return Value:
|
|
|
|
MASK_EQ - if both strings are equal
|
|
MASK_LT - First string is less
|
|
MASK_GT - Second String is less
|
|
***************************************************************************/
|
|
DWORD __StringCompare( LPCTSTR szValue1, LPCTSTR szValue2, BOOL bIgnoreCase, LONG lCount )
|
|
{
|
|
// local variables
|
|
LONG lResult = 0; // hold the string comparision result
|
|
|
|
// check the input value
|
|
if ( szValue1 == NULL || szValue2 == NULL )
|
|
{
|
|
SetLastError( ERROR_INVALID_PARAMETER );
|
|
SaveLastError();
|
|
return 0;
|
|
}
|
|
|
|
// if the no. of characters that needs to checked is -1, just return
|
|
if ( lCount == -1 )
|
|
return MASK_ALL; // that strings are equal
|
|
|
|
// compare the two strings and get the result of comparision
|
|
lResult = StringCompare( szValue1, szValue2, bIgnoreCase, lCount );
|
|
|
|
//
|
|
// now determine the result value
|
|
if ( lResult == 0 )
|
|
return MASK_EQ;
|
|
else if ( lResult < 0 )
|
|
return MASK_LT;
|
|
else if ( lResult > 0 )
|
|
return MASK_GT;
|
|
|
|
// never come across this situation ... still
|
|
return 0;
|
|
}
|
|
|
|
// ***************************************************************************
|
|
// Routine Description:
|
|
// compares two long data type values
|
|
//
|
|
// Arguments:
|
|
// [ in ] lvalue1: First value
|
|
// [ in ] lvalue2: Second Value
|
|
//
|
|
// Return Value:
|
|
// MASK_EQ: both are equal
|
|
// MASK_LT: First is less than second
|
|
// MASK_GT: First is geater than second
|
|
// ***************************************************************************
|
|
DWORD __LongCompare( LONG lValue1, LONG lValue2 )
|
|
{
|
|
//
|
|
// determine the result value
|
|
if ( lValue1 == lValue2 )
|
|
return MASK_EQ;
|
|
else if ( lValue1 < lValue2 )
|
|
return MASK_LT;
|
|
else if ( lValue1 > lValue2 )
|
|
return MASK_GT;
|
|
|
|
// never come across this situation ... still
|
|
return 0;
|
|
}
|
|
|
|
// ***************************************************************************
|
|
// Routine Description:
|
|
// compares two DWORD data type values
|
|
//
|
|
// Arguments:
|
|
// [ in ] dwValue1: First value
|
|
// [ in ] dwValue2: Second Value
|
|
//
|
|
// Return Value:
|
|
// MASK_EQ: both are equal
|
|
// MASK_LT: First is less than second
|
|
// MASK_GT: First is geater than second
|
|
// ***************************************************************************
|
|
DWORD __DWORDCompare( DWORD dwValue1, DWORD dwValue2 )
|
|
{
|
|
//
|
|
// determine the result value
|
|
if ( dwValue1 == dwValue2 )
|
|
return MASK_EQ;
|
|
else if ( dwValue1 < dwValue2 )
|
|
return MASK_LT;
|
|
else if ( dwValue1 > dwValue2 )
|
|
return MASK_GT;
|
|
|
|
// never come across this situation ... still
|
|
return 0;
|
|
}
|
|
|
|
// ***************************************************************************
|
|
// Routine Description:
|
|
// compares two float data type values
|
|
//
|
|
// Arguments:
|
|
// [ in ] fValue1: First value
|
|
// [ in ] fValue2: Second Value
|
|
//
|
|
// Return Value:
|
|
// MASK_EQ: both are equal
|
|
// MASK_LT: First is less than second
|
|
// MASK_GT: First is geater than second
|
|
// ***************************************************************************
|
|
DWORD __FloatCompare( float fValue1, float fValue2 )
|
|
{
|
|
//
|
|
// determine the result value
|
|
if ( fValue1 == fValue2 )
|
|
return MASK_EQ;
|
|
else if ( fValue1 < fValue2 )
|
|
return MASK_LT;
|
|
else if ( fValue1 > fValue2 )
|
|
return MASK_GT;
|
|
|
|
// never come across this situation ... still
|
|
return 0;
|
|
}
|
|
|
|
// ***************************************************************************
|
|
// Routine Description:
|
|
// compares two double data type values
|
|
//
|
|
// Arguments:
|
|
// [ in ] dblValue1: First value
|
|
// [ in ] dblValue2: Second Value
|
|
//
|
|
// Return Value:
|
|
// MASK_EQ: both are equal
|
|
// MASK_LT: First is less than second
|
|
// MASK_GT: First is geater than second
|
|
// ***************************************************************************
|
|
DWORD __DoubleCompare( double dblValue1, double dblValue2 )
|
|
{
|
|
//
|
|
// determine the result value
|
|
if ( dblValue1 == dblValue2 )
|
|
return MASK_EQ;
|
|
else if ( dblValue1 < dblValue2 )
|
|
return MASK_LT;
|
|
else if ( dblValue1 > dblValue2 )
|
|
return MASK_GT;
|
|
|
|
// never come across this situation ... still
|
|
return 0;
|
|
}
|
|
|
|
// ***************************************************************************
|
|
// Routine Description:
|
|
// compares two date data type values
|
|
//
|
|
// Arguments:
|
|
// [ in ] szValue1: First value
|
|
// [ in ] szValue2: Second Value
|
|
//
|
|
// Return Value:
|
|
// MASK_EQ: both are equal
|
|
// MASK_LT: First is less than second
|
|
// MASK_GT: First is geater than second
|
|
// ***************************************************************************
|
|
DWORD __DateCompare( LPCTSTR szValue1, LPCTSTR szValue2 )
|
|
{
|
|
// check the input value
|
|
if ( szValue1 == NULL || szValue2 == NULL )
|
|
{
|
|
SetLastError( ERROR_INVALID_PARAMETER );
|
|
SaveLastError();
|
|
return 0;
|
|
}
|
|
|
|
// never come across this situation ... still
|
|
return 0;
|
|
}
|
|
|
|
// ***************************************************************************
|
|
// Routine Description:
|
|
// compares two time data type values
|
|
// Arguments:
|
|
// szValue1: First value
|
|
// szValue2: Second Value
|
|
// Return Value:
|
|
// MASK_EQ: both are equal
|
|
// MASK_LT: First is less than second
|
|
// MASK_GT: First is geater than second
|
|
// ***************************************************************************
|
|
DWORD __TimeCompare( LPCTSTR szValue1, LPCTSTR szValue2 )
|
|
{
|
|
// check the input value
|
|
if ( szValue1 == NULL || szValue2 == NULL )
|
|
{
|
|
SetLastError( ERROR_INVALID_PARAMETER );
|
|
SaveLastError();
|
|
return 0;
|
|
}
|
|
|
|
// never come across this situation ... still
|
|
return 0;
|
|
}
|
|
|
|
// ***************************************************************************
|
|
// Routine Description:
|
|
// compares two date+time data type values
|
|
//
|
|
// Arguments:
|
|
// [ in ] szValue1: First value
|
|
// [ in ] szValue2: Second Value
|
|
//
|
|
// Return Value:
|
|
// MASK_EQ: both are equal
|
|
// MASK_LT: First is less than second
|
|
// MASK_GT: First is geater than second
|
|
// ***************************************************************************
|
|
DWORD __DateTimeCompare( LPCTSTR szValue1, LPCTSTR szValue2 )
|
|
{
|
|
// check the input value
|
|
if ( szValue1 == NULL || szValue2 == NULL )
|
|
{
|
|
SetLastError( ERROR_INVALID_PARAMETER );
|
|
SaveLastError();
|
|
return 0;
|
|
}
|
|
|
|
// never come across this situation ... still
|
|
return 0;
|
|
}
|
|
|
|
// ***************************************************************************
|
|
// Routine Description:
|
|
// compares value stored in arrRecords and arrFilter array depending on
|
|
// filterConfig structure
|
|
//
|
|
// Arguments:
|
|
// [ in ] arrRecord: First value
|
|
// [ in ] arrFilter: Second Value
|
|
// [ in ] filterConfig: Compare criteria.
|
|
// Return Value:
|
|
// MASK_EQ: both are equal
|
|
// MASK_LT: First is less than second
|
|
// MASK_GT: First is geater than second
|
|
// ***************************************************************************
|
|
DWORD __DoComparision( TARRAY arrRecord, TARRAY arrFilter, TFILTERCONFIG filter )
|
|
{
|
|
// local variables
|
|
LONG lLength = 0; // used for pattern matched strings
|
|
LPTSTR pszTemp = NULL;
|
|
DWORD dwCompareResult = 0;
|
|
__MAX_SIZE_STRING szValue = NULL_STRING;
|
|
|
|
// variables used for comparision
|
|
LPVOID pData = NULL;
|
|
LONG lValue1 = 0, lValue2 = 0;
|
|
DWORD dwValue1 = 0, dwValue2 = 0;
|
|
float fValue1 = 0.0f, fValue2 = 0.0f;
|
|
double dblValue1 = 0.0f, dblValue2 = 0.0f;
|
|
LPCTSTR pszValue1 = NULL, pszValue2 = NULL;
|
|
LPCTSTR pszProperty = NULL, pszOperator = NULL, pszValue = NULL;
|
|
|
|
// check the input value
|
|
if ( arrRecord == NULL || arrFilter == NULL )
|
|
{
|
|
SetLastError( ERROR_INVALID_PARAMETER );
|
|
SaveLastError();
|
|
return 0;
|
|
}
|
|
|
|
// do the comparision
|
|
switch( filter.dwFlags & F_TYPE_MASK )
|
|
{
|
|
case F_TYPE_TEXT:
|
|
{
|
|
//
|
|
// string comparision
|
|
|
|
// get the value at the specified column and filter value
|
|
pszValue1 = DynArrayItemAsString( arrRecord, filter.dwColumn );
|
|
pszValue2 = DynArrayItemAsString( arrFilter, F_PARSED_INDEX_VALUE );
|
|
|
|
// check the values we got from the dynamic array
|
|
if ( pszValue1 == NULL || pszValue2 == NULL )
|
|
return F_RESULT_REMOVE;
|
|
|
|
// determine the length of the string that has to be compared
|
|
lLength = 0;
|
|
if ( filter.dwFlags & F_MODE_PATTERN )
|
|
{
|
|
// needs to do the pattern matching
|
|
// identify till which part string should be compared
|
|
lstrcpy( szValue, pszValue2 );
|
|
pszTemp = _tcschr( szValue, CHAR_ASTERISK );
|
|
if ( pszTemp != NULL )
|
|
{
|
|
lLength = lstrlen( szValue ) - lstrlen( pszTemp );
|
|
|
|
// special case:
|
|
// if the pattern is just asterisk, which means that all the
|
|
// information needs to passed thru the filter
|
|
if ( lLength == 0 )
|
|
lLength = -1; // match all values
|
|
}
|
|
}
|
|
|
|
// do the comparision and get the result
|
|
dwCompareResult = __StringCompare( pszValue1, pszValue2, TRUE, lLength );
|
|
|
|
// break from the switch case
|
|
break;
|
|
}
|
|
|
|
case F_TYPE_NUMERIC:
|
|
{
|
|
//
|
|
// numeric comparision
|
|
|
|
// get the value into buffer - PREFIX PURPOSE
|
|
pszValue = DynArrayItemAsString( arrFilter, F_PARSED_INDEX_VALUE );
|
|
if ( pszValue == NULL )
|
|
return 0;
|
|
|
|
// get the value at the specified column and filter value
|
|
lValue1 = DynArrayItemAsLong( arrRecord, filter.dwColumn );
|
|
lValue2 = AsLong( pszValue, 10 );
|
|
|
|
// do the comparision and get the result
|
|
dwCompareResult = __LongCompare( lValue1, lValue2 );
|
|
|
|
// break from the switch case
|
|
break;
|
|
}
|
|
|
|
case F_TYPE_UNUMERIC:
|
|
{
|
|
//
|
|
// unsigned numeric comparision
|
|
|
|
// get the value into buffer - PREFIX PURPOSE
|
|
pszValue = DynArrayItemAsString( arrFilter, F_PARSED_INDEX_VALUE );
|
|
if ( pszValue == NULL )
|
|
return 0;
|
|
|
|
// get the value at the specified column and filter value
|
|
dwValue1 = DynArrayItemAsLong( arrRecord, filter.dwColumn );
|
|
dwValue2 = (DWORD) AsLong( pszValue, 10 );
|
|
|
|
// do the comparision and get the result
|
|
dwCompareResult = __DWORDCompare( dwValue1, dwValue2 );
|
|
|
|
// break from the switch case
|
|
break;
|
|
}
|
|
|
|
case F_TYPE_DATE:
|
|
case F_TYPE_TIME:
|
|
case F_TYPE_DATETIME:
|
|
{
|
|
// not yet implemented
|
|
dwCompareResult = F_RESULT_KEEP;
|
|
|
|
// break from the switch case
|
|
break;
|
|
}
|
|
|
|
case F_TYPE_FLOAT:
|
|
{
|
|
//
|
|
// float comparision
|
|
|
|
// get the value into buffer - PREFIX PURPOSE
|
|
pszValue = DynArrayItemAsString( arrFilter, F_PARSED_INDEX_VALUE );
|
|
if ( pszValue == NULL )
|
|
return 0;
|
|
|
|
// get the value at the specified column and filter value
|
|
fValue1 = DynArrayItemAsFloat( arrRecord, filter.dwColumn );
|
|
fValue2 = (float) AsFloat( pszValue );
|
|
|
|
// do the comparision and get the result
|
|
dwCompareResult = __FloatCompare( fValue1, fValue2 );
|
|
|
|
// break from the switch case
|
|
break;
|
|
}
|
|
|
|
case F_TYPE_DOUBLE:
|
|
{
|
|
//
|
|
// double comparision
|
|
|
|
// get the value into buffer - PREFIX PURPOSE
|
|
pszValue = DynArrayItemAsString( arrFilter, F_PARSED_INDEX_VALUE );
|
|
if ( pszValue == NULL )
|
|
return 0;
|
|
|
|
// get the value at the specified column and filter value
|
|
dblValue1 = DynArrayItemAsDouble( arrRecord, filter.dwColumn );
|
|
dblValue2 = AsFloat( pszValue );
|
|
|
|
// do the comparision and get the result
|
|
dwCompareResult = __DoubleCompare( dblValue1, dblValue2 );
|
|
|
|
// break from the switch case
|
|
break;
|
|
}
|
|
|
|
case F_TYPE_CUSTOM:
|
|
{
|
|
//
|
|
// custom comparision
|
|
|
|
// get the filter values
|
|
pszProperty = DynArrayItemAsString( arrFilter, F_PARSED_INDEX_PROPERTY );
|
|
pszOperator = DynArrayItemAsString( arrFilter, F_PARSED_INDEX_OPERATOR );
|
|
pszValue = DynArrayItemAsString( arrFilter, F_PARSED_INDEX_VALUE );
|
|
|
|
// check ...
|
|
if ( pszProperty == NULL || pszOperator == NULL || pszValue == NULL )
|
|
return 0;
|
|
|
|
// call the custom function
|
|
dwCompareResult = (filter.pFunction)( pszProperty, pszOperator, pszValue,
|
|
filter.pFunctionData == NULL ? &filter : filter.pFunctionData, arrRecord );
|
|
|
|
// break from the switch case
|
|
break;
|
|
}
|
|
|
|
default:
|
|
{
|
|
// not yet implemented
|
|
dwCompareResult = F_RESULT_KEEP;
|
|
|
|
// break from the switch case
|
|
break;
|
|
}
|
|
}
|
|
|
|
// return the result
|
|
return dwCompareResult;
|
|
}
|
|
|
|
// ***************************************************************************
|
|
// Routine Description:
|
|
// compares two arrays
|
|
//
|
|
// Arguments:
|
|
// [ in ] arrRecord: First Value
|
|
// [ in ] arrFilter: Second Value
|
|
// [ in ] filterConfig: Comperison Criteria
|
|
//
|
|
// Return Value:
|
|
// MASK_EQ: both are equal
|
|
// MASK_LT: First is less than second
|
|
// MASK_GT: First is geater than second
|
|
// ***************************************************************************
|
|
DWORD __DoArrayComparision( TARRAY arrRecord, TARRAY arrFilter, TFILTERCONFIG filterConfig )
|
|
{
|
|
// local variables
|
|
LONG lIndex = 0;
|
|
LONG lLength = 0; // used for pattern matched strings
|
|
DWORD dwCompareResult = 0;
|
|
LPCTSTR pszTemp = NULL;
|
|
__MAX_SIZE_STRING szValue = NULL_STRING;
|
|
|
|
// variables used for comparision
|
|
TARRAY arrValues = NULL;
|
|
LPCTSTR pszFilterValue = NULL;
|
|
|
|
// check the input value
|
|
if ( arrRecord == NULL || arrFilter == NULL )
|
|
{
|
|
SetLastError( ERROR_INVALID_PARAMETER );
|
|
SaveLastError();
|
|
return F_RESULT_REMOVE;
|
|
}
|
|
|
|
// array data in the record
|
|
arrValues = DynArrayItem( arrRecord, filterConfig.dwColumn );
|
|
if ( arrValues == NULL )
|
|
return F_RESULT_REMOVE;
|
|
|
|
switch( filterConfig.dwFlags & F_TYPE_MASK )
|
|
{
|
|
case F_TYPE_TEXT:
|
|
{
|
|
//
|
|
// string comparision
|
|
|
|
// get the value at the specified column and filter value
|
|
pszFilterValue = DynArrayItemAsString( arrFilter, F_PARSED_INDEX_VALUE );
|
|
if ( pszFilterValue == NULL )
|
|
return F_RESULT_REMOVE;
|
|
|
|
// determine the length of the string that has to be compared
|
|
lLength = 0;
|
|
if ( filterConfig.dwFlags & F_MODE_PATTERN )
|
|
{
|
|
// needs to do the pattern matching
|
|
// identify till which part string should be compared
|
|
lstrcpy( szValue, pszFilterValue );
|
|
pszTemp = _tcschr( szValue, CHAR_ASTERISK );
|
|
if ( pszTemp != NULL )
|
|
{
|
|
lLength = lstrlen( szValue ) - lstrlen( pszTemp );
|
|
|
|
// special case:
|
|
// if the pattern is just asterisk, which means that all the
|
|
// information needs to passed thru the filter
|
|
if ( lLength == 0 )
|
|
lLength = -1; // match all values
|
|
}
|
|
}
|
|
|
|
// do the comparision and get the result
|
|
if ( lLength == -1 )
|
|
{
|
|
// filter has to be passed
|
|
dwCompareResult = MASK_ALL;
|
|
}
|
|
else
|
|
{
|
|
// find the string in the array and check the result
|
|
lIndex = DynArrayFindString( arrValues, pszFilterValue, TRUE, lLength );
|
|
if ( lIndex == -1 )
|
|
{
|
|
// value not found
|
|
dwCompareResult = MASK_NE;
|
|
}
|
|
else
|
|
{
|
|
pszTemp = DynArrayItemAsString( arrValues, lIndex );
|
|
if ( pszTemp == NULL )
|
|
return F_RESULT_REMOVE;
|
|
|
|
// comparision ...
|
|
dwCompareResult = __StringCompare(pszTemp, pszFilterValue, TRUE, lLength);
|
|
}
|
|
}
|
|
|
|
// break from the switch case
|
|
break;
|
|
}
|
|
}
|
|
|
|
// return the result
|
|
return dwCompareResult;
|
|
}
|
|
|
|
// ***************************************************************************
|
|
// Routine Description:
|
|
// Prepares a two dimensional array(arrOperators)based on Operator information
|
|
// supplied with pfilterConfigs variable
|
|
//
|
|
//
|
|
// Arguments:
|
|
// [ in] dwCount = No. of operatores
|
|
// [ in] pfilterConfigs = Pointer to TFILTERCONFIG structure
|
|
// [out] arrOperators = Array of operators.
|
|
//
|
|
// Return Value:
|
|
// NONE
|
|
//
|
|
// ***************************************************************************
|
|
VOID __PrepareOperators( DWORD dwCount, PTFILTERCONFIG pfilterConfigs, TARRAY arrOperators )
|
|
{
|
|
// local variables
|
|
DWORD i = 0; // looping varible
|
|
LONG lIndex = 0; // holds the result of find operation
|
|
LPTSTR pszOperator = NULL; // operator specified in filter
|
|
PTFILTERCONFIG pFilter = NULL; // temporary filter configuration
|
|
__MAX_SIZE_STRING szTemp = NULL_STRING; // temporary string buffer
|
|
|
|
// check the input value
|
|
if ( pfilterConfigs == NULL || arrOperators == NULL )
|
|
{
|
|
SetLastError( ERROR_INVALID_PARAMETER );
|
|
SaveLastError();
|
|
return;
|
|
}
|
|
|
|
// NOTE:- Here in this logic, we are compromising on the memory Vs time
|
|
// At the cost of using more memory, the time taken by the validating
|
|
// functionality is improved.
|
|
//
|
|
|
|
// collect all the operators that are supported and save them in the local array
|
|
// Idea:-
|
|
// => This is a two-dimensional array
|
|
// => In all rows, the first column will have the operator
|
|
// => operator column is followed by the index of the filter property supporting
|
|
// this operator, and this column is followed by filter property name
|
|
// => This filter property index and its name's can be any number
|
|
// => The operator is being treated as key field in the array
|
|
//
|
|
// SAMPLE:
|
|
// 0 1 2 3 4 5 6
|
|
// -------------------------------------------------------------------
|
|
// = 1 property1 2 property2
|
|
// != 0 property0 2 property2
|
|
// <= 0 property0 3 property3
|
|
// >= 1 property1 3 property3 4 property4
|
|
//
|
|
for( i = 0; i < dwCount; i++ )
|
|
{
|
|
// get the filter info at the specified index into local memory
|
|
pFilter = pfilterConfigs + i;
|
|
|
|
// collect operators and prepare with all the available operators
|
|
lstrcpy( szTemp, pFilter->szOperators ); // IMP. get the local copy.
|
|
pszOperator = _tcstok( szTemp, OPERATOR_DELIMITER ); // get the first token
|
|
while ( pszOperator != NULL )
|
|
{
|
|
// check whether this operator exists in the operators array
|
|
lIndex = DynArrayFindStringEx( arrOperators, 0, pszOperator, TRUE, 0 );
|
|
if ( lIndex == -1 )
|
|
{
|
|
//
|
|
// operator is not in the list
|
|
|
|
// add the new operator to the list and set the index to the row added
|
|
// for this operator
|
|
lIndex = DynArrayAppendRow( arrOperators, 0 );
|
|
if ( lIndex == -1 )
|
|
return;
|
|
|
|
// now add the operator as the first column to the newly added row
|
|
DynArrayAppendString2( arrOperators, lIndex, pszOperator, 0 );
|
|
}
|
|
|
|
// add the filter property info and its index to the operator row
|
|
DynArrayAppendLong2( arrOperators, lIndex, i );
|
|
DynArrayAppendString2( arrOperators, lIndex, pFilter->szProperty, 0 );
|
|
|
|
// fetch the next token
|
|
pszOperator = _tcstok( NULL, OPERATOR_DELIMITER );
|
|
}
|
|
}
|
|
}
|
|
|
|
// ***************************************************************************
|
|
// Routine Description:
|
|
// Checks the type of pszValue string for the criteria given by fcInfo
|
|
// filters.
|
|
|
|
// Arguments:
|
|
// [ in ] fcInfo = filter stucture.
|
|
// [ in ] pszProperty = property string
|
|
// [ in ] pszOperator = operator
|
|
// [ in ] pszValue = string to be checked
|
|
//
|
|
// Return Value:
|
|
// TRUE = valid line
|
|
// FALSE = not a valid line
|
|
// ***************************************************************************
|
|
BOOL __CheckValue( TFILTERCONFIG fcInfo,
|
|
LPCTSTR pszProperty, LPCTSTR pszOperator, LPCTSTR pszValue )
|
|
{
|
|
// local variables
|
|
DWORD dwResult = 0;
|
|
LPTSTR pszTemp = NULL;
|
|
__MAX_SIZE_STRING szValue = NULL_STRING;
|
|
|
|
// check the input value
|
|
if ( pszProperty == NULL || pszOperator == NULL || pszValue == NULL )
|
|
{
|
|
SetLastError( ERROR_INVALID_PARAMETER );
|
|
SaveLastError();
|
|
return FALSE;
|
|
}
|
|
|
|
// check the length of the value string ... it should not be empty
|
|
if ( lstrlen( pszValue ) == 0 )
|
|
return FALSE; // value string is empty
|
|
|
|
// start validating the data
|
|
switch( fcInfo.dwFlags & F_TYPE_MASK )
|
|
{
|
|
case F_TYPE_TEXT:
|
|
{
|
|
// check if the pattern is supported
|
|
// if supported, see the '*' is appearing only at the end. if not error
|
|
if ( fcInfo.dwFlags & F_MODE_PATTERN )
|
|
{
|
|
// copy the current value to the local buffer
|
|
lstrcpy( szValue, pszValue );
|
|
|
|
// search for the wild card character
|
|
pszTemp = _tcschr( szValue, CHAR_ASTERISK );
|
|
|
|
// if the wild card character was found and if it is not the last character
|
|
// (or) wild card is the only character specified, then invalid filter
|
|
if ( pszTemp != NULL && ( lstrlen( pszTemp ) != 1 || pszTemp == szValue ) )
|
|
return FALSE; // error ... invalid pattern string
|
|
}
|
|
|
|
// for all these types, no need to do any special checking
|
|
// provided, they need not be checked with the list of values
|
|
if ( ! ( fcInfo.dwFlags & F_MODE_VALUES ) )
|
|
return TRUE; // no special validation
|
|
|
|
// check for the value in the list and return the result
|
|
return ( InString( pszValue, fcInfo.szValues, TRUE ) );
|
|
|
|
// break from the switch
|
|
break;
|
|
}
|
|
|
|
case F_TYPE_NUMERIC:
|
|
{
|
|
// if the value is not of numeric type, invalid value
|
|
if ( ! IsNumeric( pszValue, 10, TRUE ) )
|
|
return FALSE;
|
|
|
|
// check for the value in the list and return the result
|
|
// if values are pre-defined
|
|
if ( fcInfo.dwFlags & F_MODE_VALUES )
|
|
return ( InString( fcInfo.szValues, pszValue, TRUE ) );
|
|
|
|
// value is valid
|
|
return TRUE;
|
|
|
|
// break from the switch
|
|
break;
|
|
}
|
|
|
|
case F_TYPE_UNUMERIC:
|
|
{
|
|
// if the value is not of unsigned numeric type, invalid value
|
|
if ( ! IsNumeric( pszValue, 10, FALSE ) )
|
|
return FALSE;
|
|
|
|
// check for the value in the list and return the result
|
|
// if values are pre-defined
|
|
if ( fcInfo.dwFlags & F_MODE_VALUES )
|
|
return ( InString( fcInfo.szValues, pszValue, TRUE ) );
|
|
|
|
// value is valid
|
|
return TRUE;
|
|
|
|
// break from the switch
|
|
break;
|
|
}
|
|
|
|
case F_TYPE_FLOAT:
|
|
case F_TYPE_DOUBLE:
|
|
{
|
|
// NOTE: Values attribute is ignored for this data type
|
|
|
|
// return the result of the type validation function itself
|
|
return ( IsFloatingPoint( pszValue ) );
|
|
|
|
// break from the switch
|
|
break;
|
|
}
|
|
|
|
case F_TYPE_DATE:
|
|
case F_TYPE_TIME:
|
|
case F_TYPE_DATETIME:
|
|
{
|
|
// break from the switch
|
|
break;
|
|
}
|
|
|
|
case F_TYPE_CUSTOM:
|
|
{
|
|
// check whether function pointer is specified or not
|
|
// if not specified, error
|
|
if ( fcInfo.pFunction == NULL )
|
|
return FALSE; // function ptr not specified ... error
|
|
|
|
// call the custom function
|
|
dwResult = (*fcInfo.pFunction)( pszProperty, pszOperator, pszValue,
|
|
fcInfo.pFunctionData == NULL ? &fcInfo : fcInfo.pFunctionData, NULL );
|
|
|
|
// check the result and return appropriately
|
|
if ( dwResult == F_FILTER_INVALID )
|
|
return FALSE;
|
|
else
|
|
return TRUE;
|
|
|
|
// break from the switch
|
|
break;
|
|
}
|
|
|
|
default:
|
|
{
|
|
// invalid configuration information
|
|
return FALSE;
|
|
|
|
// break from the switch
|
|
break;
|
|
}
|
|
}
|
|
|
|
// not a valid value
|
|
return FALSE;
|
|
}
|
|
|
|
// ***************************************************************************
|
|
// Routine Description:
|
|
//
|
|
// Arguments:
|
|
// [ in] szFilter = filter
|
|
// [ in ] arrOperators = Array of Operators
|
|
// [ in ] pfilterConfigs = filter configurations
|
|
// [ in ] pszProperty =property
|
|
// [ in ] pszOperator = operator
|
|
// [ in ] pszValue - value
|
|
//
|
|
// Return Value: Returns a long value
|
|
//
|
|
// ***************************************************************************
|
|
LONG __IdentifyFilterConfig( LPCTSTR szFilter,
|
|
TARRAY arrOperators,
|
|
PTFILTERCONFIG pfilterConfigs,
|
|
LPTSTR pszProperty, LPTSTR pszOperator, LPTSTR pszValue )
|
|
{
|
|
// local variables
|
|
DWORD dw = 0; // looping variable
|
|
LONG lPosition = 0; // used to result of 'find' function
|
|
LONG lIndex = 0;
|
|
DWORD dwOperators = 0; // holds the count of operators supported
|
|
LPTSTR pszBuffer = NULL;
|
|
__MAX_SIZE_STRING szTemp = NULL_STRING; // temporary string buffer
|
|
__MAX_SIZE_STRING szFmtFilter = NULL_STRING;
|
|
__MAX_SIZE_STRING szFmtOperator = NULL_STRING;
|
|
|
|
// check the input value
|
|
if ( szFilter == NULL || arrOperators == NULL || pfilterConfigs == NULL ||
|
|
pszProperty == NULL || pszOperator == NULL || pszValue == NULL )
|
|
{
|
|
SetLastError( ERROR_INVALID_PARAMETER );
|
|
SaveLastError();
|
|
return -1;
|
|
}
|
|
|
|
// get the filter info into local format buffer and change the case
|
|
lstrcpy( szFmtFilter, szFilter );
|
|
CharUpper( szFmtFilter );
|
|
|
|
// initially assume the filter is unknown and set the message
|
|
SetLastError( ERROR_DS_FILTER_UNKNOWN );
|
|
SaveLastError();
|
|
|
|
// traverse thru the list of operators available and check
|
|
// whether the filter is having any of the supported operator
|
|
dwOperators = DynArrayGetCount( arrOperators ); // no. of operators supported
|
|
for( dw = 0; dw < dwOperators; dw++ )
|
|
{
|
|
// get the operator
|
|
pszBuffer = ( LPTSTR ) DynArrayItemAsString2( arrOperators, dw, 0 );
|
|
if ( pszBuffer == NULL )
|
|
{
|
|
SetLastError( EVENT_E_INTERNALERROR );
|
|
SaveLastError();
|
|
return -1;
|
|
}
|
|
|
|
// ...
|
|
lstrcpy( pszOperator, pszBuffer );
|
|
lstrcpy( szFmtOperator, pszOperator ); // also get the operator
|
|
CharUpper( szFmtOperator ); // into format buffer and chane the case
|
|
|
|
// search for the current operator in the filter
|
|
// check whether the operator was found or not
|
|
// before processing, copy to the temp buffer and do manipulations on that
|
|
lstrcpy( szTemp, szFmtFilter );
|
|
if ( ( pszBuffer = _tcsstr( szTemp, szFmtOperator ) ) != NULL )
|
|
{
|
|
//
|
|
// operator was found
|
|
|
|
// extract the property, and value information
|
|
// => property name
|
|
// ( total length of the string - position where the operator starts )
|
|
// => value
|
|
// ( start position of operator + length of operator )
|
|
szTemp[ lstrlen( szTemp ) - lstrlen( pszBuffer ) ] = NULL_CHAR;
|
|
lstrcpy( pszProperty, szTemp );
|
|
|
|
// value might not have specified at all ... so be careful
|
|
if ( (pszBuffer + lstrlen(pszOperator)) != NULL )
|
|
{
|
|
// copy the value part
|
|
lstrcpy( pszValue, (pszBuffer + lstrlen(pszOperator)) );
|
|
|
|
//
|
|
// now cross-check whether the property name exists or not for the current
|
|
// operator.
|
|
|
|
// remove the leading and trailing spaces ( if any )
|
|
// in the property name and value
|
|
lstrcpy( pszValue, TrimString( pszValue, TRIM_ALL ) );
|
|
lstrcpy( pszProperty, TrimString( pszProperty, TRIM_ALL ) );
|
|
|
|
// check whether this property exists or not
|
|
// if found, return to the caller, else continue furthur
|
|
// this might match with some with some other operator
|
|
lPosition = DynArrayFindString2( arrOperators, dw, pszProperty, TRUE, 0 );
|
|
if ( lPosition > 1 )
|
|
{
|
|
// NOTE:
|
|
// we know that the property name if exist, starts from index number
|
|
// 2 only that is the reason why, the condition is > 1 is only valid
|
|
|
|
// get the corresponding filter config. info
|
|
lIndex = DynArrayItemAsLong2( arrOperators, dw, lPosition - 1 );
|
|
|
|
// now check whether the filter is having appropriate value
|
|
if ( __CheckValue( pfilterConfigs[ lIndex ], pszProperty, pszOperator, pszValue) )
|
|
{
|
|
//
|
|
// filter is having valid value
|
|
SetLastError( NOERROR );
|
|
SetReason( NULL_STRING );
|
|
|
|
// return the filter configuration index
|
|
return lIndex;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// filter is not valid
|
|
return -1;
|
|
}
|
|
|
|
//
|
|
// public functions ... exposed to external world
|
|
//
|
|
|
|
// ***************************************************************************
|
|
// Routine Description:
|
|
//
|
|
// Arguments:
|
|
// [ in ] dwCount = Count
|
|
// [ in ] pfilterConfigs = filter configurations
|
|
// [ in ] arrFilterArgs = filter arguments
|
|
// [ in ] parrParsedFilters = array of parsed filters
|
|
//
|
|
// Return Value:return a boolean value
|
|
//
|
|
// ***************************************************************************
|
|
BOOL ParseAndValidateFilter( DWORD dwCount,
|
|
PTFILTERCONFIG pfilterConfigs,
|
|
TARRAY arrFilterArgs, PTARRAY parrParsedFilters )
|
|
{
|
|
// local variables
|
|
DWORD dw = 0; // looping variables
|
|
DWORD dwFilters = 0; // holds the count of filters
|
|
LONG lIndex = 0; // index variable
|
|
LONG lNewIndex = 0; // index variable
|
|
BOOL bResult = FALSE; // holds the result of the filter validation
|
|
__MAX_SIZE_STRING szValue = NULL_STRING; // value specified in filter
|
|
__MAX_SIZE_STRING szOperator = NULL_STRING; // operator specified in filter
|
|
__MAX_SIZE_STRING szProperty = NULL_STRING; // property specified in filter
|
|
LPCTSTR pszFilter = NULL;
|
|
TARRAY arrOperators = NULL; // operator-wise filter configuration
|
|
|
|
// check the input value
|
|
if ( pfilterConfigs == NULL || arrFilterArgs == NULL )
|
|
{
|
|
SetLastError( ERROR_INVALID_PARAMETER );
|
|
SaveLastError();
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// parse the filter configuration information and customize the information
|
|
// to fasten the performance of the validating functionality
|
|
//
|
|
// create the dynamic array and prepare
|
|
arrOperators = CreateDynamicArray();
|
|
if ( arrOperators == NULL )
|
|
{
|
|
SetLastError( E_OUTOFMEMORY );
|
|
SaveLastError();
|
|
return FALSE;
|
|
}
|
|
|
|
// ...
|
|
__PrepareOperators( dwCount, pfilterConfigs, arrOperators );
|
|
|
|
// check whether filters ( parsed ) needs to initialized
|
|
if ( parrParsedFilters != NULL && *parrParsedFilters == NULL )
|
|
{
|
|
*parrParsedFilters = CreateDynamicArray(); // create a dynamic array
|
|
if ( *parrParsedFilters == NULL )
|
|
{
|
|
SetLastError( E_OUTOFMEMORY );
|
|
SaveLastError();
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
//
|
|
// now start validating the filter
|
|
//
|
|
|
|
// traverse through the filters information and validate them
|
|
bResult = TRUE; // assume that filter validation is passed
|
|
dwFilters = DynArrayGetCount( arrFilterArgs ); // count of filter specified
|
|
for( dw = 0; dw < dwFilters; dw++ )
|
|
{
|
|
// reset all the needed variables
|
|
lstrcpy( szValue, NULL_STRING );
|
|
lstrcpy( szOperator, NULL_STRING );
|
|
lstrcpy( szProperty, NULL_STRING );
|
|
|
|
// get the filter
|
|
pszFilter = DynArrayItemAsString( arrFilterArgs, dw );
|
|
if ( pszFilter == NULL )
|
|
{
|
|
// error occured
|
|
bResult = FALSE;
|
|
break; // break from the loop ... no need of furthur processing
|
|
}
|
|
|
|
// identify the filter config for the current filter
|
|
lIndex = __IdentifyFilterConfig( pszFilter,
|
|
arrOperators, pfilterConfigs, szProperty, szOperator, szValue );
|
|
|
|
// check whether the filter is found or not
|
|
if ( lIndex == -1 )
|
|
{
|
|
// filter found to be invalid
|
|
bResult = FALSE;
|
|
break; // break from the loop ... no need of furthur processing
|
|
}
|
|
|
|
// now that we found, current filter is having
|
|
// valid property name, operator and valid value
|
|
// save the parsed filter info and its corresponding filter configuration index
|
|
// in global dynamic array if it is available
|
|
if ( parrParsedFilters != NULL )
|
|
{
|
|
// append the filter info at the end of the array
|
|
lNewIndex = DynArrayAppendRow( *parrParsedFilters, F_PARSED_INFO_COUNT );
|
|
if ( lNewIndex == -1 )
|
|
{
|
|
SetLastError( E_OUTOFMEMORY );
|
|
SaveLastError();
|
|
return FALSE;
|
|
}
|
|
|
|
// ...
|
|
DynArraySetDWORD2( *parrParsedFilters, lNewIndex, F_PARSED_INDEX_FILTER, lIndex );
|
|
DynArraySetString2( *parrParsedFilters, lNewIndex, F_PARSED_INDEX_PROPERTY, szProperty, 0 );
|
|
DynArraySetString2( *parrParsedFilters, lNewIndex, F_PARSED_INDEX_OPERATOR, szOperator, 0 );
|
|
DynArraySetString2( *parrParsedFilters, lNewIndex, F_PARSED_INDEX_VALUE, szValue, 0 );
|
|
}
|
|
}
|
|
|
|
// destroy the operators array
|
|
DestroyDynamicArray( &arrOperators );
|
|
|
|
// return the filter validation result
|
|
return bResult;
|
|
}
|
|
|
|
// ***************************************************************************
|
|
// Routine Description:
|
|
//
|
|
// Arguments:
|
|
// [ in ] dwCount = count
|
|
// [ in ] filterConfigs[] = filter configurations
|
|
// [ in ] arrRecord = array of records
|
|
//
|
|
// [ ]arrParsedFilters = array of parsed filters
|
|
// Return Value:return a boolean value
|
|
//
|
|
// ***************************************************************************
|
|
BOOL CanFilterRecord( DWORD dwCount,
|
|
TFILTERCONFIG filterConfigs[],
|
|
TARRAY arrRecord, TARRAY arrParsedFilters )
|
|
{
|
|
// local variables
|
|
DWORD dw = 0; // looping variables
|
|
DWORD dwFilters = 0; // holds the total no. of filter available
|
|
DWORD dwOperator = 0; // holds the mask of the current filter
|
|
DWORD dwFilterIndex = 0;
|
|
DWORD dwCompareResult = 0; // holds the result of comparision
|
|
LPCTSTR pszTemp = NULL;
|
|
TARRAY arrTemp = NULL;
|
|
|
|
// prepare the operators mappings
|
|
DWORD dwOperatorsCount = 0;
|
|
TOPERATOR operators[] = {
|
|
{ MASK_EQ, OPERATOR_EQ },
|
|
{ MASK_NE, OPERATOR_NE },
|
|
{ MASK_GT, OPERATOR_GT },
|
|
{ MASK_LT, OPERATOR_LT },
|
|
{ MASK_GE, OPERATOR_GE },
|
|
{ MASK_LE, OPERATOR_LE }
|
|
};
|
|
|
|
// check the input value
|
|
if ( filterConfigs == NULL || arrRecord == NULL || arrParsedFilters == NULL )
|
|
{
|
|
SetLastError( ERROR_INVALID_PARAMETER );
|
|
SaveLastError();
|
|
return FALSE;
|
|
}
|
|
|
|
// traverse thru all the filters
|
|
dwFilters = DynArrayGetCount( arrParsedFilters );
|
|
dwOperatorsCount = sizeof( operators ) / sizeof( operators[ 0 ] );
|
|
for( dw = 0; dw < dwFilters; dw++ )
|
|
{
|
|
// get the current filter configuration index
|
|
dwFilterIndex = DynArrayItemAsDWORD2( arrParsedFilters, dw, F_PARSED_INDEX_FILTER );
|
|
|
|
// get the appropriate operator mask
|
|
pszTemp = DynArrayItemAsString2( arrParsedFilters, dw, F_PARSED_INDEX_OPERATOR );
|
|
if ( pszTemp == NULL )
|
|
continue;
|
|
|
|
// ...
|
|
dwOperator = __FindOperatorMask( dwOperatorsCount, operators, pszTemp );
|
|
|
|
// if the operator is undefined, the filter should have
|
|
// custom validation mask
|
|
if ( dwOperator == 0 &&
|
|
( filterConfigs[ dwFilterIndex ].dwFlags & F_TYPE_MASK ) != F_TYPE_CUSTOM )
|
|
return FALSE; // invalid filter configuration
|
|
|
|
// get the parsed filter info into local buffer
|
|
arrTemp = DynArrayItem( arrParsedFilters, dw );
|
|
if ( arrTemp == NULL )
|
|
return FALSE;
|
|
|
|
// do the comparision and get the result
|
|
if ( filterConfigs[ dwFilterIndex ].dwFlags & F_MODE_ARRAY )
|
|
{
|
|
dwCompareResult = __DoArrayComparision(
|
|
arrRecord, arrTemp, filterConfigs[ dwFilterIndex ] );
|
|
}
|
|
else
|
|
{
|
|
dwCompareResult = __DoComparision( arrRecord, arrTemp, filterConfigs[ dwFilterIndex ] );
|
|
}
|
|
|
|
// now check whether the current can be kept or not
|
|
// if the filter is failed, break from the loop so that this row can be deleted
|
|
if ( ( dwCompareResult & dwOperator ) == 0 )
|
|
break; // filter failed
|
|
}
|
|
|
|
// return the result of filter operation
|
|
return ( dw != dwFilters ); // TRUE : delete record, FALSE : keep record
|
|
}
|
|
|
|
// ***************************************************************************
|
|
// Routine Description:
|
|
//
|
|
// Arguments:
|
|
// [ in ] dwCount = count
|
|
// [ in ] filterConfigs[] = filter configurations
|
|
// [ in ] arrData = array of data
|
|
// [ in ] arrParsedFilters = array of parsed filters
|
|
//
|
|
// Return Value: Return a DWord
|
|
//
|
|
// ***************************************************************************
|
|
DWORD FilterResults( DWORD dwCount,
|
|
TFILTERCONFIG filterConfigs[],
|
|
TARRAY arrData, TARRAY arrParsedFilters )
|
|
{
|
|
// local variables
|
|
DWORD dw = 0; // looping variables
|
|
DWORD dwDeleted = 0;
|
|
DWORD dwRecords = 0; // holds the total no. of records
|
|
LPCTSTR szTemp = NULL;
|
|
TARRAY arrRecord = NULL;
|
|
|
|
// check the input value
|
|
if ( filterConfigs == NULL || arrData == NULL || arrParsedFilters == NULL )
|
|
{
|
|
SetLastError( ERROR_INVALID_PARAMETER );
|
|
SaveLastError();
|
|
return 0;
|
|
}
|
|
|
|
//
|
|
// start filtering the data
|
|
|
|
// get the count of filters and records
|
|
dwRecords = DynArrayGetCount( arrData );
|
|
|
|
// traverse thru all thru the data
|
|
for( dw = 0; dw < dwRecords; dw++ )
|
|
{
|
|
// get the current row ... this is just to increase fastness
|
|
arrRecord = DynArrayItem( arrData, dw );
|
|
if ( arrRecord == NULL )
|
|
{
|
|
SetLastError( ERROR_INVALID_PARAMETER );
|
|
SaveLastError();
|
|
return 0;
|
|
}
|
|
|
|
// check whether this record needs to be deleted or not
|
|
if ( CanFilterRecord( dwCount, filterConfigs, arrRecord, arrParsedFilters ) )
|
|
{
|
|
DynArrayRemove( arrData, dw ); // delete record
|
|
dw--; // adjust the next record position
|
|
dwRecords--; // also adjust the total no. of records information
|
|
dwDeleted++;
|
|
}
|
|
}
|
|
|
|
// return no. of records deleted
|
|
return dwDeleted;
|
|
}
|
|
|
|
// ***************************************************************************
|
|
// Routine Description:
|
|
// retuns the mathematical operator from english operator
|
|
//
|
|
// Arguments:
|
|
// [ in ] szOperator = mathematical (or) english operator
|
|
//
|
|
// Return Value:
|
|
// Return a mathematical operator
|
|
//
|
|
// ***************************************************************************
|
|
LPCTSTR FindOperator( LPCTSTR szOperator )
|
|
{
|
|
// local variables
|
|
DWORD dwMask = 0;
|
|
DWORD dwOperatorsCount = 0;
|
|
TOPERATOR operators[] = {
|
|
{ MASK_EQ, OPERATOR_EQ },
|
|
{ MASK_NE, OPERATOR_NE },
|
|
{ MASK_GT, OPERATOR_GT },
|
|
{ MASK_LT, OPERATOR_LT },
|
|
{ MASK_GE, OPERATOR_GE },
|
|
{ MASK_LE, OPERATOR_LE }
|
|
};
|
|
|
|
// check the input value
|
|
if ( szOperator == NULL )
|
|
{
|
|
SetLastError( ERROR_INVALID_PARAMETER );
|
|
SaveLastError();
|
|
return MATH_EQ;
|
|
}
|
|
|
|
// find the operator mask
|
|
dwOperatorsCount = sizeof( operators ) / sizeof( operators[ 0 ] );
|
|
dwMask = __FindOperatorMask( dwOperatorsCount, operators, szOperator );
|
|
switch ( dwMask )
|
|
{
|
|
case MASK_EQ:
|
|
return MATH_EQ;
|
|
break;
|
|
|
|
case MASK_NE:
|
|
return MATH_NE;
|
|
break;
|
|
|
|
case MASK_LT:
|
|
return MATH_LT;
|
|
break;
|
|
|
|
case MASK_GT:
|
|
return MATH_GT;
|
|
break;
|
|
|
|
case MASK_LE:
|
|
return MATH_LE;
|
|
break;
|
|
|
|
case MASK_GE:
|
|
return MATH_GE;
|
|
break;
|
|
|
|
default:
|
|
// default to be on safe side ... return '=' operator
|
|
return MATH_EQ;
|
|
break;
|
|
|
|
}
|
|
|
|
// defaul
|
|
return MATH_EQ;
|
|
}
|