git-svn-id: https://svn.code.sf.net/p/flaim/code/trunk@383 0109f412-320b-0410-ab79-c3e0c5ffbbe6
1833 lines
42 KiB
C++
1833 lines
42 KiB
C++
//------------------------------------------------------------------------------
|
|
// Desc: Contains the methods for doing evaluation of query expressions.
|
|
//
|
|
// Tabs: 3
|
|
//
|
|
// Copyright (c) 2003-2006 Novell, Inc. All Rights Reserved.
|
|
//
|
|
// This program is free software; you can redistribute it and/or
|
|
// modify it under the terms of version 2 of the GNU General Public
|
|
// License as published by the Free Software Foundation.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program; if not, contact Novell, Inc.
|
|
//
|
|
// To contact Novell about this file by physical or electronic mail,
|
|
// you may find current contact information at www.novell.com
|
|
//
|
|
// $Id: fqeval.cpp 3114 2006-01-19 13:22:45 -0700 (Thu, 19 Jan 2006) dsanders $
|
|
//------------------------------------------------------------------------------
|
|
|
|
#include "flaimsys.h"
|
|
#include "fquery.h"
|
|
|
|
FSTATIC RCODE fqApproxCompare(
|
|
FQVALUE * pLValue,
|
|
FQVALUE * pRValue,
|
|
FLMINT * piResult);
|
|
|
|
FSTATIC RCODE fqCompareBinary(
|
|
IF_OperandComparer * pOpComparer,
|
|
FQVALUE * pLValue,
|
|
FQVALUE * pRValue,
|
|
FLMINT * piResult);
|
|
|
|
FSTATIC RCODE fqCompareText(
|
|
IF_OperandComparer * pOpComparer,
|
|
FQVALUE * pLValue,
|
|
FQVALUE * pRValue,
|
|
FLMUINT uiCompareRules,
|
|
FLMBOOL bOpIsMatch,
|
|
FLMUINT uiLanguage,
|
|
FLMINT * piResult);
|
|
|
|
FSTATIC void fqOpUUBitAND(
|
|
FQVALUE * pLValue,
|
|
FQVALUE * pRValue,
|
|
FQVALUE * pResult);
|
|
|
|
FSTATIC void fqOpUUBitOR(
|
|
FQVALUE * pLValue,
|
|
FQVALUE * pRValue,
|
|
FQVALUE * pResult);
|
|
|
|
FSTATIC void fqOpUUBitXOR(
|
|
FQVALUE * pLValue,
|
|
FQVALUE * pRValue,
|
|
FQVALUE * pResult);
|
|
|
|
FSTATIC void fqOpUUMult(
|
|
FQVALUE * pLValue,
|
|
FQVALUE * pRValue,
|
|
FQVALUE * pResult);
|
|
|
|
FSTATIC void fqOpUSMult(
|
|
FQVALUE * pLValue,
|
|
FQVALUE * pRValue,
|
|
FQVALUE * pResult);
|
|
|
|
FSTATIC void fqOpSSMult(
|
|
FQVALUE * pLValue,
|
|
FQVALUE * pRValue,
|
|
FQVALUE * pResult);
|
|
|
|
FSTATIC void fqOpSUMult(
|
|
FQVALUE * pLValue,
|
|
FQVALUE * pRValue,
|
|
FQVALUE * pResult);
|
|
|
|
FSTATIC void fqOpUUDiv(
|
|
FQVALUE * pLValue,
|
|
FQVALUE * pRValue,
|
|
FQVALUE * pResult);
|
|
|
|
FSTATIC void fqOpUSDiv(
|
|
FQVALUE * pLValue,
|
|
FQVALUE * pRValue,
|
|
FQVALUE * pResult);
|
|
|
|
FSTATIC void fqOpSSDiv(
|
|
FQVALUE * pLValue,
|
|
FQVALUE * pRValue,
|
|
FQVALUE * pResult);
|
|
|
|
FSTATIC void fqOpSUDiv(
|
|
FQVALUE * pLValue,
|
|
FQVALUE * pRValue,
|
|
FQVALUE * pResult);
|
|
|
|
FSTATIC void fqOpUUMod(
|
|
FQVALUE * pLValue,
|
|
FQVALUE * pRValue,
|
|
FQVALUE * pResult);
|
|
|
|
FSTATIC void fqOpUSMod(
|
|
FQVALUE * pLValue,
|
|
FQVALUE * pRValue,
|
|
FQVALUE * pResult);
|
|
|
|
FSTATIC void fqOpSSMod(
|
|
FQVALUE * pLValue,
|
|
FQVALUE * pRValue,
|
|
FQVALUE * pResult);
|
|
|
|
FSTATIC void fqOpSUMod(
|
|
FQVALUE * pLValue,
|
|
FQVALUE * pRValue,
|
|
FQVALUE * pResult);
|
|
|
|
FSTATIC void fqOpUUPlus(
|
|
FQVALUE * pLValue,
|
|
FQVALUE * pRValue,
|
|
FQVALUE * pResult);
|
|
|
|
FSTATIC void fqOpUSPlus(
|
|
FQVALUE * pLValue,
|
|
FQVALUE * pRValue,
|
|
FQVALUE * pResult);
|
|
|
|
FSTATIC void fqOpSSPlus(
|
|
FQVALUE * pLValue,
|
|
FQVALUE * pRValue,
|
|
FQVALUE * pResult);
|
|
|
|
FSTATIC void fqOpSUPlus(
|
|
FQVALUE * pLValue,
|
|
FQVALUE * pRValue,
|
|
FQVALUE * pResult);
|
|
|
|
FSTATIC void fqOpUUMinus(
|
|
FQVALUE * pLValue,
|
|
FQVALUE * pRValue,
|
|
FQVALUE * pResult);
|
|
|
|
FSTATIC void fqOpUSMinus(
|
|
FQVALUE * pLValue,
|
|
FQVALUE * pRValue,
|
|
FQVALUE * pResult);
|
|
|
|
FSTATIC void fqOpSSMinus(
|
|
FQVALUE * pLValue,
|
|
FQVALUE * pRValue,
|
|
FQVALUE * pResult);
|
|
|
|
FSTATIC void fqOpSUMinus(
|
|
FQVALUE * pLValue,
|
|
FQVALUE * pRValue,
|
|
FQVALUE * pResult);
|
|
|
|
typedef void FQ_OPERATION(
|
|
FQVALUE * pLValue,
|
|
FQVALUE * pRValue,
|
|
FQVALUE * pResult);
|
|
|
|
FQ_OPERATION * FQ_ArithOpTable[
|
|
((XFLM_LAST_ARITH_OP - XFLM_FIRST_ARITH_OP) + 1) * 4 ] =
|
|
{
|
|
/* U = Unsigned S = Signed
|
|
U + U U + S
|
|
S + U S + S */
|
|
/* BITAND */ fqOpUUBitAND, fqOpUUBitAND,
|
|
fqOpUUBitAND, fqOpUUBitAND,
|
|
/* BITOR */ fqOpUUBitOR, fqOpUUBitOR,
|
|
fqOpUUBitOR, fqOpUUBitOR,
|
|
/* BITXOR */ fqOpUUBitXOR, fqOpUUBitXOR,
|
|
fqOpUUBitXOR, fqOpUUBitXOR,
|
|
/* MULT */ fqOpUUMult, fqOpUSMult,
|
|
fqOpSUMult, fqOpSSMult,
|
|
/* DIV */ fqOpUUDiv, fqOpUSDiv,
|
|
fqOpSUDiv, fqOpSSDiv,
|
|
/* MOD */ fqOpUUMod, fqOpUSMod,
|
|
fqOpSUMod, fqOpSSMod,
|
|
/* PLUS */ fqOpUUPlus, fqOpUSPlus,
|
|
fqOpSUPlus, fqOpSSPlus,
|
|
/* MINUS */ fqOpUUMinus, fqOpUSMinus,
|
|
fqOpSUMinus, fqOpSSMinus
|
|
};
|
|
|
|
/***************************************************************************
|
|
Desc: Returns a 64-bit unsigned integer
|
|
***************************************************************************/
|
|
FINLINE FLMUINT64 fqGetUInt64(
|
|
FQVALUE * pValue)
|
|
{
|
|
if (pValue->eValType == XFLM_UINT_VAL)
|
|
{
|
|
return( (FLMUINT64)pValue->val.uiVal);
|
|
}
|
|
else if( pValue->eValType == XFLM_UINT64_VAL)
|
|
{
|
|
return( pValue->val.ui64Val);
|
|
}
|
|
else if( pValue->eValType == XFLM_INT64_VAL)
|
|
{
|
|
if( pValue->val.i64Val >= 0)
|
|
{
|
|
return( (FLMUINT64)pValue->val.i64Val);
|
|
}
|
|
}
|
|
else if( pValue->eValType == XFLM_INT_VAL)
|
|
{
|
|
if( pValue->val.iVal >= 0)
|
|
{
|
|
return( (FLMUINT64)pValue->val.iVal);
|
|
}
|
|
}
|
|
|
|
flmAssert( 0);
|
|
return( 0);
|
|
}
|
|
|
|
/***************************************************************************
|
|
Desc: Returns a 64-bit signed integer
|
|
***************************************************************************/
|
|
FINLINE FLMINT64 fqGetInt64(
|
|
FQVALUE * pValue)
|
|
{
|
|
if (pValue->eValType == XFLM_INT_VAL)
|
|
{
|
|
return( (FLMINT64)pValue->val.iVal);
|
|
}
|
|
else if( pValue->eValType == XFLM_INT64_VAL)
|
|
{
|
|
return( pValue->val.i64Val);
|
|
}
|
|
else if( pValue->eValType == XFLM_UINT_VAL)
|
|
{
|
|
return( (FLMINT64)pValue->val.uiVal);
|
|
}
|
|
else if( pValue->eValType == XFLM_UINT64_VAL)
|
|
{
|
|
if( pValue->val.ui64Val <= (FLMUINT64)FLM_MAX_INT64)
|
|
{
|
|
return( (FLMINT64)pValue->val.ui64Val);
|
|
}
|
|
}
|
|
|
|
flmAssert( 0);
|
|
return( 0);
|
|
}
|
|
|
|
/***************************************************************************
|
|
Desc: Performs the bit and operation
|
|
***************************************************************************/
|
|
FSTATIC void fqOpUUBitAND(
|
|
FQVALUE * pLValue,
|
|
FQVALUE * pRValue,
|
|
FQVALUE * pResult)
|
|
{
|
|
if( isNativeNum( pLValue->eValType) &&
|
|
isNativeNum( pRValue->eValType))
|
|
{
|
|
pResult->val.uiVal = pLValue->val.uiVal & pRValue->val.uiVal;
|
|
pResult->eValType = XFLM_UINT_VAL;
|
|
}
|
|
else
|
|
{
|
|
pResult->val.ui64Val =
|
|
fqGetUInt64( pLValue) & fqGetUInt64( pRValue);
|
|
pResult->eValType = XFLM_UINT64_VAL;
|
|
}
|
|
}
|
|
|
|
/***************************************************************************
|
|
Desc: Performs the bit or operation
|
|
***************************************************************************/
|
|
FSTATIC void fqOpUUBitOR(
|
|
FQVALUE * pLValue,
|
|
FQVALUE * pRValue,
|
|
FQVALUE * pResult)
|
|
{
|
|
if( isNativeNum( pLValue->eValType) &&
|
|
isNativeNum( pRValue->eValType))
|
|
{
|
|
pResult->val.uiVal = pLValue->val.uiVal | pRValue->val.uiVal;
|
|
pResult->eValType = XFLM_UINT_VAL;
|
|
}
|
|
else
|
|
{
|
|
pResult->val.ui64Val =
|
|
fqGetUInt64( pLValue) | fqGetUInt64( pRValue);
|
|
pResult->eValType = XFLM_UINT64_VAL;
|
|
}
|
|
}
|
|
|
|
/***************************************************************************
|
|
Desc: Performs the bit xor operation
|
|
***************************************************************************/
|
|
FSTATIC void fqOpUUBitXOR(
|
|
FQVALUE * pLValue,
|
|
FQVALUE * pRValue,
|
|
FQVALUE * pResult)
|
|
{
|
|
if( isNativeNum( pLValue->eValType) &&
|
|
isNativeNum( pRValue->eValType))
|
|
{
|
|
pResult->val.uiVal = pLValue->val.uiVal ^ pRValue->val.uiVal;
|
|
pResult->eValType = XFLM_UINT_VAL;
|
|
}
|
|
else
|
|
{
|
|
pResult->val.ui64Val =
|
|
fqGetUInt64( pLValue) ^ fqGetUInt64( pRValue);
|
|
pResult->eValType = XFLM_UINT64_VAL;
|
|
}
|
|
}
|
|
|
|
/***************************************************************************
|
|
Desc: Performs the multiply operation
|
|
***************************************************************************/
|
|
FSTATIC void fqOpUUMult(
|
|
FQVALUE * pLValue,
|
|
FQVALUE * pRValue,
|
|
FQVALUE * pResult)
|
|
{
|
|
if( isNativeNum( pLValue->eValType) &&
|
|
isNativeNum( pRValue->eValType))
|
|
{
|
|
pResult->val.uiVal = pLValue->val.uiVal * pRValue->val.uiVal;
|
|
pResult->eValType = XFLM_UINT_VAL;
|
|
}
|
|
else
|
|
{
|
|
pResult->val.ui64Val =
|
|
fqGetUInt64( pLValue) * fqGetUInt64( pRValue);
|
|
pResult->eValType = XFLM_UINT64_VAL;
|
|
}
|
|
}
|
|
|
|
/***************************************************************************
|
|
Desc: Performs the multiply operation
|
|
***************************************************************************/
|
|
FSTATIC void fqOpUSMult(
|
|
FQVALUE * pLValue,
|
|
FQVALUE * pRValue,
|
|
FQVALUE * pResult)
|
|
{
|
|
if( isNativeNum( pLValue->eValType) &&
|
|
isNativeNum( pRValue->eValType))
|
|
{
|
|
pResult->val.iVal = (FLMINT)pLValue->val.uiVal * pRValue->val.iVal;
|
|
pResult->eValType = XFLM_INT_VAL;
|
|
}
|
|
else
|
|
{
|
|
pResult->val.i64Val = (FLMINT64)
|
|
fqGetUInt64( pLValue) * fqGetInt64( pRValue);
|
|
pResult->eValType = XFLM_INT64_VAL;
|
|
}
|
|
}
|
|
|
|
/***************************************************************************
|
|
Desc: Performs the multiply operation
|
|
***************************************************************************/
|
|
FSTATIC void fqOpSSMult(
|
|
FQVALUE * pLValue,
|
|
FQVALUE * pRValue,
|
|
FQVALUE * pResult)
|
|
{
|
|
if( isNativeNum( pLValue->eValType) &&
|
|
isNativeNum( pRValue->eValType))
|
|
{
|
|
pResult->val.iVal = pLValue->val.iVal * pRValue->val.iVal;
|
|
pResult->eValType = (pResult->val.iVal < 0)
|
|
? XFLM_INT_VAL
|
|
: XFLM_UINT_VAL;
|
|
}
|
|
else
|
|
{
|
|
pResult->val.i64Val = (FLMINT64)(fqGetInt64( pLValue) *
|
|
fqGetInt64( pRValue));
|
|
|
|
pResult->eValType = (pResult->val.i64Val < 0)
|
|
? XFLM_INT64_VAL
|
|
: XFLM_UINT64_VAL;
|
|
}
|
|
}
|
|
|
|
/***************************************************************************
|
|
Desc: Performs the multiply operation
|
|
***************************************************************************/
|
|
FSTATIC void fqOpSUMult(
|
|
FQVALUE * pLValue,
|
|
FQVALUE * pRValue,
|
|
FQVALUE * pResult)
|
|
{
|
|
if( isNativeNum( pLValue->eValType) &&
|
|
isNativeNum( pRValue->eValType))
|
|
{
|
|
pResult->val.iVal = pLValue->val.iVal *
|
|
(FLMINT)pRValue->val.uiVal;
|
|
pResult->eValType = XFLM_INT_VAL;
|
|
}
|
|
else
|
|
{
|
|
pResult->val.i64Val = (FLMINT64)
|
|
(fqGetInt64( pLValue) * fqGetUInt64( pRValue));
|
|
pResult->eValType = XFLM_INT64_VAL;
|
|
}
|
|
}
|
|
|
|
/***************************************************************************
|
|
Desc: Performs the divide operation
|
|
***************************************************************************/
|
|
FSTATIC void fqOpUUDiv(
|
|
FQVALUE * pLValue,
|
|
FQVALUE * pRValue,
|
|
FQVALUE * pResult)
|
|
{
|
|
if( isNativeNum( pLValue->eValType) &&
|
|
isNativeNum( pRValue->eValType))
|
|
{
|
|
if( pRValue->val.uiVal)
|
|
{
|
|
pResult->val.uiVal = pLValue->val.uiVal / pRValue->val.uiVal;
|
|
pResult->eValType = XFLM_UINT_VAL;
|
|
}
|
|
else
|
|
{
|
|
pResult->val.uiVal = 0; // Divide by ZERO case.
|
|
pResult->eValType = XFLM_MISSING_VAL;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
FLMUINT64 ui64LValue = fqGetUInt64( pLValue);
|
|
FLMUINT64 ui64RValue = fqGetUInt64( pRValue);
|
|
|
|
if( ui64RValue)
|
|
{
|
|
pResult->val.ui64Val = ui64LValue / ui64RValue;
|
|
pResult->eValType = XFLM_UINT64_VAL;
|
|
}
|
|
else
|
|
{
|
|
pResult->val.uiVal = 0; // Divide by ZERO case.
|
|
pResult->eValType = XFLM_MISSING_VAL;
|
|
}
|
|
}
|
|
}
|
|
|
|
/***************************************************************************
|
|
Desc: Performs the divide operation
|
|
***************************************************************************/
|
|
FSTATIC void fqOpUSDiv(
|
|
FQVALUE * pLValue,
|
|
FQVALUE * pRValue,
|
|
FQVALUE * pResult)
|
|
{
|
|
if( isNativeNum( pLValue->eValType) &&
|
|
isNativeNum( pRValue->eValType))
|
|
{
|
|
if( pRValue->val.iVal)
|
|
{
|
|
pResult->val.iVal = pLValue->val.uiVal / pRValue->val.iVal;
|
|
pResult->eValType = XFLM_INT_VAL;
|
|
}
|
|
else
|
|
{
|
|
pResult->val.uiVal = 0; // Divide by ZERO case.
|
|
pResult->eValType = XFLM_MISSING_VAL;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
FLMUINT64 ui64LValue = fqGetUInt64( pLValue);
|
|
FLMINT64 i64RValue = fqGetInt64( pRValue);
|
|
|
|
if( i64RValue)
|
|
{
|
|
pResult->val.i64Val = ui64LValue / i64RValue;
|
|
pResult->eValType = XFLM_INT64_VAL;
|
|
}
|
|
else
|
|
{
|
|
pResult->val.uiVal = 0; // Divide by ZERO case.
|
|
pResult->eValType = XFLM_MISSING_VAL;
|
|
}
|
|
}
|
|
}
|
|
|
|
/***************************************************************************
|
|
Desc: Performs the divide operation
|
|
***************************************************************************/
|
|
FSTATIC void fqOpSSDiv(
|
|
FQVALUE * pLValue,
|
|
FQVALUE * pRValue,
|
|
FQVALUE * pResult)
|
|
{
|
|
if( isNativeNum( pLValue->eValType) &&
|
|
isNativeNum( pRValue->eValType))
|
|
{
|
|
if( pRValue->val.iVal)
|
|
{
|
|
pResult->val.iVal = pLValue->val.iVal / pRValue->val.iVal;
|
|
pResult->eValType = (pResult->val.iVal < 0)
|
|
? XFLM_INT_VAL : XFLM_UINT_VAL;
|
|
}
|
|
else
|
|
{
|
|
pResult->val.uiVal = 0; // Divide by ZERO case.
|
|
pResult->eValType = XFLM_MISSING_VAL;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
FLMINT64 i64LValue = fqGetInt64( pLValue);
|
|
FLMINT64 i64RValue = fqGetInt64( pRValue);
|
|
|
|
if( i64RValue)
|
|
{
|
|
pResult->val.i64Val = i64LValue / i64RValue;
|
|
pResult->eValType = (pResult->val.i64Val < 0)
|
|
? XFLM_INT64_VAL : XFLM_UINT64_VAL;
|
|
}
|
|
else
|
|
{
|
|
pResult->val.uiVal = 0; // Divide by ZERO case.
|
|
pResult->eValType = XFLM_MISSING_VAL;
|
|
}
|
|
}
|
|
}
|
|
|
|
/***************************************************************************
|
|
Desc: Performs the divide operation
|
|
***************************************************************************/
|
|
FSTATIC void fqOpSUDiv(
|
|
FQVALUE * pLValue,
|
|
FQVALUE * pRValue,
|
|
FQVALUE * pResult)
|
|
{
|
|
if( isNativeNum( pLValue->eValType) &&
|
|
isNativeNum( pRValue->eValType))
|
|
{
|
|
if( pRValue->val.uiVal)
|
|
{
|
|
pResult->val.iVal = pLValue->val.iVal / pRValue->val.uiVal;
|
|
pResult->eValType = XFLM_INT_VAL;
|
|
}
|
|
else
|
|
{
|
|
pResult->val.uiVal = 0; // Divide by ZERO case.
|
|
pResult->eValType = XFLM_MISSING_VAL;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
FLMINT64 i64LValue = fqGetInt64( pLValue);
|
|
FLMUINT64 ui64RValue = fqGetUInt64( pRValue);
|
|
|
|
if( ui64RValue)
|
|
{
|
|
pResult->val.i64Val = i64LValue / ui64RValue;
|
|
pResult->eValType = XFLM_INT64_VAL;
|
|
}
|
|
else
|
|
{
|
|
pResult->val.uiVal = 0; // Divide by ZERO case.
|
|
pResult->eValType = XFLM_MISSING_VAL;
|
|
}
|
|
}
|
|
}
|
|
|
|
/***************************************************************************
|
|
Desc: Performs the modulo operation
|
|
***************************************************************************/
|
|
FSTATIC void fqOpUUMod(
|
|
FQVALUE * pLValue,
|
|
FQVALUE * pRValue,
|
|
FQVALUE * pResult)
|
|
{
|
|
if( isNativeNum( pLValue->eValType) &&
|
|
isNativeNum( pRValue->eValType))
|
|
{
|
|
if( pRValue->val.uiVal)
|
|
{
|
|
pResult->val.uiVal = pLValue->val.uiVal % pRValue->val.uiVal;
|
|
pResult->eValType = XFLM_UINT_VAL;
|
|
}
|
|
else
|
|
{
|
|
pResult->val.uiVal = 0; // MOD by ZERO case.
|
|
pResult->eValType = XFLM_MISSING_VAL;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
FLMUINT64 ui64LValue = fqGetUInt64( pLValue);
|
|
FLMUINT64 ui64RValue = fqGetUInt64( pRValue);
|
|
|
|
if( ui64RValue)
|
|
{
|
|
pResult->val.ui64Val = ui64LValue % ui64RValue;
|
|
pResult->eValType = XFLM_UINT64_VAL;
|
|
}
|
|
else
|
|
{
|
|
pResult->val.uiVal = 0; // MOD by ZERO case.
|
|
pResult->eValType = XFLM_MISSING_VAL;
|
|
}
|
|
}
|
|
}
|
|
|
|
/***************************************************************************
|
|
Desc: Performs the modulo operation
|
|
***************************************************************************/
|
|
FSTATIC void fqOpUSMod(
|
|
FQVALUE * pLValue,
|
|
FQVALUE * pRValue,
|
|
FQVALUE * pResult)
|
|
{
|
|
if( isNativeNum( pLValue->eValType) &&
|
|
isNativeNum( pRValue->eValType))
|
|
{
|
|
if( pRValue->val.iVal)
|
|
{
|
|
pResult->val.iVal = pLValue->val.uiVal % pRValue->val.iVal;
|
|
pResult->eValType = XFLM_INT_VAL;
|
|
}
|
|
else
|
|
{
|
|
pResult->val.uiVal = 0; // MOD by ZERO case.
|
|
pResult->eValType = XFLM_MISSING_VAL;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
FLMUINT64 ui64LValue = fqGetUInt64( pLValue);
|
|
FLMINT64 i64RValue = fqGetInt64( pRValue);
|
|
|
|
if( i64RValue)
|
|
{
|
|
pResult->val.i64Val = ui64LValue % i64RValue;
|
|
pResult->eValType = XFLM_INT64_VAL;
|
|
}
|
|
else
|
|
{
|
|
pResult->val.uiVal = 0; // MOD by ZERO case.
|
|
pResult->eValType = XFLM_MISSING_VAL;
|
|
}
|
|
}
|
|
}
|
|
|
|
/***************************************************************************
|
|
Desc: Performs the modulo operation
|
|
***************************************************************************/
|
|
FSTATIC void fqOpSSMod(
|
|
FQVALUE * pLValue,
|
|
FQVALUE * pRValue,
|
|
FQVALUE * pResult)
|
|
{
|
|
if( isNativeNum( pLValue->eValType) &&
|
|
isNativeNum( pRValue->eValType))
|
|
{
|
|
if( pRValue->val.iVal)
|
|
{
|
|
pResult->val.iVal = pLValue->val.iVal % pRValue->val.iVal;
|
|
pResult->eValType = (pResult->val.iVal < 0)
|
|
? XFLM_INT_VAL : XFLM_UINT_VAL;
|
|
}
|
|
else
|
|
{
|
|
pResult->val.uiVal = 0; // MOD by ZERO case.
|
|
pResult->eValType = XFLM_MISSING_VAL;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
FLMINT64 i64LValue = fqGetInt64( pLValue);
|
|
FLMINT64 i64RValue = fqGetInt64( pRValue);
|
|
|
|
if( i64RValue)
|
|
{
|
|
pResult->val.i64Val = i64LValue % i64RValue;
|
|
pResult->eValType = (pResult->val.i64Val < 0)
|
|
? XFLM_INT64_VAL : XFLM_UINT64_VAL;
|
|
}
|
|
else
|
|
{
|
|
pResult->val.uiVal = 0; // MOD by ZERO case.
|
|
pResult->eValType = XFLM_MISSING_VAL;
|
|
}
|
|
}
|
|
}
|
|
|
|
/***************************************************************************
|
|
Desc: Performs the modulo operation
|
|
***************************************************************************/
|
|
FSTATIC void fqOpSUMod(
|
|
FQVALUE * pLValue,
|
|
FQVALUE * pRValue,
|
|
FQVALUE * pResult)
|
|
{
|
|
if( isNativeNum( pLValue->eValType) &&
|
|
isNativeNum( pRValue->eValType))
|
|
{
|
|
if( pRValue->val.uiVal)
|
|
{
|
|
pResult->val.iVal = pLValue->val.iVal % pRValue->val.uiVal;
|
|
pResult->eValType = XFLM_INT_VAL;
|
|
}
|
|
else
|
|
{
|
|
pResult->val.uiVal = 0; // MOD by ZERO case.
|
|
pResult->eValType = XFLM_MISSING_VAL;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
FLMINT64 i64LValue = fqGetInt64( pLValue);
|
|
FLMUINT64 ui64RValue = fqGetUInt64( pRValue);
|
|
|
|
if( ui64RValue)
|
|
{
|
|
pResult->val.i64Val = i64LValue % ui64RValue;
|
|
pResult->eValType = XFLM_INT64_VAL;
|
|
}
|
|
else
|
|
{
|
|
pResult->val.uiVal = 0; // MOD by ZERO case.
|
|
pResult->eValType = XFLM_MISSING_VAL;
|
|
}
|
|
}
|
|
}
|
|
|
|
/***************************************************************************
|
|
Desc: Performs an addition operation
|
|
***************************************************************************/
|
|
FSTATIC void fqOpUUPlus(
|
|
FQVALUE * pLValue,
|
|
FQVALUE * pRValue,
|
|
FQVALUE * pResult)
|
|
{
|
|
if( isNativeNum( pLValue->eValType) &&
|
|
isNativeNum( pRValue->eValType))
|
|
{
|
|
pResult->val.uiVal = pLValue->val.uiVal + pRValue->val.uiVal;
|
|
pResult->eValType = XFLM_UINT_VAL;
|
|
}
|
|
else
|
|
{
|
|
pResult->val.ui64Val =
|
|
fqGetUInt64( pLValue) + fqGetUInt64( pRValue);
|
|
pResult->eValType = XFLM_UINT64_VAL;
|
|
}
|
|
}
|
|
|
|
/***************************************************************************
|
|
Desc: Performs an addition operation
|
|
***************************************************************************/
|
|
FSTATIC void fqOpUSPlus(
|
|
FQVALUE * pLValue,
|
|
FQVALUE * pRValue,
|
|
FQVALUE * pResult)
|
|
{
|
|
if( isNativeNum( pLValue->eValType) &&
|
|
isNativeNum( pRValue->eValType))
|
|
{
|
|
if( (pRValue->val.iVal >= 0) ||
|
|
(pLValue->val.uiVal > gv_uiMaxSignedIntVal))
|
|
{
|
|
pResult->val.uiVal = pLValue->val.uiVal + (FLMUINT)pRValue->val.iVal;
|
|
pResult->eValType = XFLM_UINT_VAL;
|
|
}
|
|
else
|
|
{
|
|
pResult->val.iVal = (FLMINT)pLValue->val.uiVal + pRValue->val.iVal;
|
|
pResult->eValType = (pResult->val.iVal < 0)
|
|
? XFLM_INT_VAL : XFLM_UINT_VAL;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
FLMUINT64 ui64LValue = fqGetUInt64( pLValue);
|
|
FLMINT64 i64RValue = fqGetInt64( pRValue);
|
|
|
|
if( (i64RValue >= 0) || (ui64LValue > gv_ui64MaxSignedIntVal))
|
|
{
|
|
pResult->val.ui64Val = ui64LValue + (FLMUINT64)i64RValue;
|
|
pResult->eValType = XFLM_UINT64_VAL;
|
|
}
|
|
else
|
|
{
|
|
pResult->val.i64Val = (FLMINT64)ui64LValue + i64RValue;
|
|
pResult->eValType = (pResult->val.i64Val < 0)
|
|
? XFLM_INT64_VAL : XFLM_UINT64_VAL;
|
|
}
|
|
}
|
|
}
|
|
|
|
/***************************************************************************
|
|
Desc: Performs an addition operation
|
|
***************************************************************************/
|
|
FSTATIC void fqOpSSPlus(
|
|
FQVALUE * pLValue,
|
|
FQVALUE * pRValue,
|
|
FQVALUE * pResult)
|
|
{
|
|
if( isNativeNum( pLValue->eValType) &&
|
|
isNativeNum( pRValue->eValType))
|
|
{
|
|
pResult->val.iVal = pLValue->val.iVal + pRValue->val.iVal;
|
|
pResult->eValType = (pResult->val.iVal < 0)
|
|
? XFLM_INT_VAL : XFLM_UINT_VAL;
|
|
}
|
|
else
|
|
{
|
|
pResult->val.i64Val =
|
|
fqGetInt64( pLValue) + fqGetInt64( pRValue);
|
|
pResult->eValType = (pResult->val.i64Val < 0)
|
|
? XFLM_INT64_VAL : XFLM_UINT64_VAL;
|
|
}
|
|
}
|
|
|
|
/***************************************************************************
|
|
Desc: Performs an addition operation
|
|
***************************************************************************/
|
|
FSTATIC void fqOpSUPlus(
|
|
FQVALUE * pLValue,
|
|
FQVALUE * pRValue,
|
|
FQVALUE * pResult)
|
|
{
|
|
if( isNativeNum( pLValue->eValType) &&
|
|
isNativeNum( pRValue->eValType))
|
|
{
|
|
if( (pLValue->val.iVal >= 0) ||
|
|
(pRValue->val.uiVal > gv_uiMaxSignedIntVal))
|
|
{
|
|
pResult->val.uiVal = (FLMUINT)pLValue->val.iVal + pRValue->val.uiVal;
|
|
pResult->eValType = XFLM_UINT_VAL;
|
|
}
|
|
else
|
|
{
|
|
pResult->val.iVal = pLValue->val.iVal + (FLMINT)pRValue->val.uiVal;
|
|
pResult->eValType = (pResult->val.iVal < 0)
|
|
? XFLM_INT_VAL : XFLM_UINT_VAL;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
FLMINT64 i64LValue = fqGetInt64( pLValue);
|
|
FLMUINT64 ui64RValue = fqGetUInt64( pRValue);
|
|
|
|
if( (i64LValue >= 0) || (ui64RValue > gv_ui64MaxSignedIntVal))
|
|
{
|
|
pResult->val.ui64Val = (FLMUINT64)i64LValue + ui64RValue;
|
|
pResult->eValType = XFLM_UINT64_VAL;
|
|
}
|
|
else
|
|
{
|
|
pResult->val.i64Val = i64LValue + (FLMINT64)ui64RValue;
|
|
pResult->eValType = (pResult->val.i64Val < 0)
|
|
? XFLM_INT64_VAL : XFLM_UINT64_VAL;
|
|
}
|
|
}
|
|
}
|
|
|
|
/***************************************************************************
|
|
Desc: Performs a subtraction operation
|
|
***************************************************************************/
|
|
FSTATIC void fqOpUUMinus(
|
|
FQVALUE * pLValue,
|
|
FQVALUE * pRValue,
|
|
FQVALUE * pResult)
|
|
{
|
|
if( isNativeNum( pLValue->eValType) &&
|
|
isNativeNum( pRValue->eValType))
|
|
{
|
|
if( pLValue->val.uiVal >= pRValue->val.uiVal)
|
|
{
|
|
pResult->val.uiVal = pLValue->val.uiVal - pRValue->val.uiVal;
|
|
pResult->eValType = XFLM_UINT_VAL;
|
|
}
|
|
else
|
|
{
|
|
pResult->val.iVal = (FLMINT)(pLValue->val.uiVal - pRValue->val.uiVal);
|
|
pResult->eValType = XFLM_INT_VAL;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
FLMUINT64 ui64LValue = fqGetUInt64( pLValue);
|
|
FLMUINT64 ui64RValue = fqGetUInt64( pRValue);
|
|
|
|
if( ui64LValue >= ui64RValue)
|
|
{
|
|
pResult->val.ui64Val = ui64LValue - ui64RValue;
|
|
pResult->eValType = XFLM_UINT64_VAL;
|
|
}
|
|
else
|
|
{
|
|
pResult->val.i64Val = (FLMINT64)(ui64LValue - ui64RValue);
|
|
pResult->eValType = XFLM_INT64_VAL;
|
|
}
|
|
}
|
|
}
|
|
|
|
/***************************************************************************
|
|
Desc: Performs a subtraction operation
|
|
***************************************************************************/
|
|
FSTATIC void fqOpUSMinus(
|
|
FQVALUE * pLValue,
|
|
FQVALUE * pRValue,
|
|
FQVALUE * pResult)
|
|
{
|
|
if( isNativeNum( pLValue->eValType) &&
|
|
isNativeNum( pRValue->eValType))
|
|
{
|
|
if( pRValue->val.iVal < 0)
|
|
{
|
|
pResult->val.uiVal = pLValue->val.uiVal - pRValue->val.iVal;
|
|
pResult->eValType = XFLM_UINT_VAL;
|
|
}
|
|
else
|
|
{
|
|
pResult->val.iVal = (FLMINT)pLValue->val.uiVal - pRValue->val.iVal;
|
|
pResult->eValType = (pResult->val.iVal < 0)
|
|
? XFLM_INT_VAL : XFLM_UINT_VAL;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
FLMUINT64 ui64LValue = fqGetUInt64( pLValue);
|
|
FLMINT64 i64RValue = fqGetInt64( pRValue);
|
|
|
|
if( i64RValue < 0)
|
|
{
|
|
pResult->val.ui64Val = ui64LValue - i64RValue;
|
|
pResult->eValType = XFLM_UINT64_VAL;
|
|
}
|
|
else
|
|
{
|
|
pResult->val.i64Val = (FLMINT64)ui64LValue - i64RValue;
|
|
pResult->eValType = (pResult->val.i64Val < 0)
|
|
? XFLM_INT64_VAL : XFLM_UINT64_VAL;
|
|
}
|
|
}
|
|
}
|
|
|
|
/***************************************************************************
|
|
Desc: Performs a subtraction operation
|
|
***************************************************************************/
|
|
FSTATIC void fqOpSSMinus(
|
|
FQVALUE * pLValue,
|
|
FQVALUE * pRValue,
|
|
FQVALUE * pResult)
|
|
{
|
|
if( isNativeNum( pLValue->eValType) &&
|
|
isNativeNum( pRValue->eValType))
|
|
{
|
|
if(( pLValue->val.iVal > 0) && ( pRValue->val.iVal < 0))
|
|
{
|
|
pResult->val.uiVal = (FLMUINT)(pLValue->val.iVal - pRValue->val.iVal);
|
|
pResult->eValType = XFLM_UINT_VAL;
|
|
}
|
|
else
|
|
{
|
|
pResult->val.iVal = pLValue->val.iVal - pRValue->val.iVal;
|
|
pResult->eValType = (pResult->val.iVal < 0)
|
|
? XFLM_INT_VAL : XFLM_UINT_VAL;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
FLMINT64 i64LValue = fqGetInt64( pLValue);
|
|
FLMINT64 i64RValue = fqGetInt64( pRValue);
|
|
|
|
if( (i64LValue > 0) && (i64RValue < 0))
|
|
{
|
|
pResult->val.ui64Val = (FLMUINT64)( i64LValue - i64RValue);
|
|
pResult->eValType = XFLM_UINT64_VAL;
|
|
}
|
|
else
|
|
{
|
|
pResult->val.i64Val = i64LValue - i64RValue;
|
|
pResult->eValType = (pResult->val.i64Val < 0)
|
|
? XFLM_INT64_VAL : XFLM_UINT64_VAL;
|
|
}
|
|
}
|
|
}
|
|
|
|
/***************************************************************************
|
|
Desc: Performs a subtraction operation
|
|
***************************************************************************/
|
|
FSTATIC void fqOpSUMinus(
|
|
FQVALUE * pLValue,
|
|
FQVALUE * pRValue,
|
|
FQVALUE * pResult)
|
|
{
|
|
if( isNativeNum( pLValue->eValType) &&
|
|
isNativeNum( pRValue->eValType))
|
|
{
|
|
if( pRValue->val.uiVal > gv_uiMaxSignedIntVal)
|
|
{
|
|
pResult->val.iVal = (pLValue->val.iVal - gv_uiMaxSignedIntVal) -
|
|
(FLMINT)(pRValue->val.uiVal - gv_uiMaxSignedIntVal);
|
|
pResult->eValType = XFLM_INT_VAL;
|
|
}
|
|
else
|
|
{
|
|
pResult->val.iVal = pLValue->val.iVal - (FLMINT)pRValue->val.uiVal;
|
|
pResult->eValType = (pResult->val.iVal < 0)
|
|
? XFLM_INT_VAL : XFLM_UINT_VAL;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
FLMINT64 i64LValue = fqGetInt64( pLValue);
|
|
FLMUINT64 ui64RValue = fqGetUInt64( pRValue);
|
|
|
|
if( ui64RValue > gv_ui64MaxSignedIntVal)
|
|
{
|
|
pResult->val.i64Val = (i64LValue - gv_ui64MaxSignedIntVal) -
|
|
(FLMINT64)(ui64RValue - gv_ui64MaxSignedIntVal);
|
|
pResult->eValType = XFLM_INT64_VAL;
|
|
}
|
|
else
|
|
{
|
|
pResult->val.i64Val = i64LValue - (FLMINT64)ui64RValue;
|
|
pResult->eValType = (pResult->val.i64Val < 0)
|
|
? XFLM_INT64_VAL : XFLM_UINT64_VAL;
|
|
}
|
|
}
|
|
}
|
|
|
|
/***************************************************************************
|
|
Desc: Compare two entire strings.
|
|
****************************************************************************/
|
|
FSTATIC RCODE fqCompareText(
|
|
IF_OperandComparer * pOpComparer,
|
|
FQVALUE * pLValue,
|
|
FQVALUE * pRValue,
|
|
FLMUINT uiCompareRules,
|
|
FLMBOOL bOpIsMatch,
|
|
FLMUINT uiLanguage,
|
|
FLMINT * piResult)
|
|
{
|
|
RCODE rc = NE_XFLM_OK;
|
|
IF_BufferIStream * pBufferLStream = NULL;
|
|
IF_PosIStream * pLStream;
|
|
IF_BufferIStream * pBufferRStream = NULL;
|
|
IF_PosIStream * pRStream;
|
|
|
|
// Types must be text
|
|
|
|
if (pLValue->eValType != XFLM_UTF8_VAL ||
|
|
pRValue->eValType != XFLM_UTF8_VAL)
|
|
{
|
|
rc = RC_SET_AND_ASSERT( NE_XFLM_NOT_IMPLEMENTED);
|
|
goto Exit;
|
|
}
|
|
|
|
// Open the streams
|
|
|
|
if( !(pLValue->uiFlags & VAL_IS_STREAM))
|
|
{
|
|
if( RC_BAD( rc = FlmAllocBufferIStream( &pBufferLStream)))
|
|
{
|
|
goto Exit;
|
|
}
|
|
|
|
if (RC_BAD( rc = pBufferLStream->open(
|
|
(const char *)pLValue->val.pucBuf, pLValue->uiDataLen)))
|
|
{
|
|
goto Exit;
|
|
}
|
|
|
|
pLStream = pBufferLStream;
|
|
}
|
|
else
|
|
{
|
|
pLStream = pLValue->val.pIStream;
|
|
}
|
|
|
|
if( !(pRValue->uiFlags & VAL_IS_STREAM))
|
|
{
|
|
if( RC_BAD( rc = FlmAllocBufferIStream( &pBufferRStream)))
|
|
{
|
|
goto Exit;
|
|
}
|
|
|
|
if( RC_BAD( rc = pBufferRStream->open(
|
|
(const char *)pRValue->val.pucBuf, pRValue->uiDataLen)))
|
|
{
|
|
goto Exit;
|
|
}
|
|
pRStream = pBufferRStream;
|
|
}
|
|
else
|
|
{
|
|
pRStream = pRValue->val.pIStream;
|
|
}
|
|
|
|
if (pOpComparer)
|
|
{
|
|
rc = pOpComparer->compare( pLStream, pRStream, piResult);
|
|
goto Exit;
|
|
}
|
|
|
|
if( RC_BAD( rc = f_compareUTF8Streams(
|
|
pLStream,
|
|
(bOpIsMatch && (pLValue->uiFlags & VAL_IS_CONSTANT)) ? TRUE : FALSE,
|
|
pRStream,
|
|
(bOpIsMatch && (pRValue->uiFlags & VAL_IS_CONSTANT)) ? TRUE : FALSE,
|
|
uiCompareRules, uiLanguage, piResult)))
|
|
{
|
|
goto Exit;
|
|
}
|
|
|
|
Exit:
|
|
|
|
if( pBufferLStream)
|
|
{
|
|
pBufferLStream->Release();
|
|
}
|
|
|
|
if( pBufferRStream)
|
|
{
|
|
pBufferRStream->Release();
|
|
}
|
|
|
|
return( rc);
|
|
}
|
|
|
|
/***************************************************************************
|
|
Desc: Approximate compare - only works for strings right now.
|
|
****************************************************************************/
|
|
FSTATIC RCODE fqApproxCompare(
|
|
FQVALUE * pLValue,
|
|
FQVALUE * pRValue,
|
|
FLMINT * piResult)
|
|
{
|
|
RCODE rc = NE_XFLM_OK;
|
|
FLMUINT uiLMeta;
|
|
FLMUINT uiRMeta;
|
|
FLMUINT64 ui64StartPos;
|
|
IF_BufferIStream * pBufferLStream = NULL;
|
|
IF_PosIStream * pLStream;
|
|
IF_BufferIStream * pBufferRStream = NULL;
|
|
IF_PosIStream * pRStream;
|
|
|
|
// Types must be text
|
|
|
|
if (pLValue->eValType != XFLM_UTF8_VAL ||
|
|
pRValue->eValType != XFLM_UTF8_VAL)
|
|
{
|
|
rc = RC_SET_AND_ASSERT( NE_XFLM_NOT_IMPLEMENTED);
|
|
goto Exit;
|
|
}
|
|
|
|
// Open the streams
|
|
|
|
if (!(pLValue->uiFlags & VAL_IS_STREAM))
|
|
{
|
|
if( RC_BAD( rc = FlmAllocBufferIStream( &pBufferLStream)))
|
|
{
|
|
goto Exit;
|
|
}
|
|
|
|
if (RC_BAD( rc = pBufferLStream->open(
|
|
(const char *)pLValue->val.pucBuf, pLValue->uiDataLen)))
|
|
{
|
|
goto Exit;
|
|
}
|
|
|
|
pLStream = pBufferLStream;
|
|
}
|
|
else
|
|
{
|
|
pLStream = pLValue->val.pIStream;
|
|
}
|
|
|
|
if (!(pRValue->uiFlags & VAL_IS_STREAM))
|
|
{
|
|
if( RC_BAD( rc = FlmAllocBufferIStream( &pBufferRStream)))
|
|
{
|
|
goto Exit;
|
|
}
|
|
|
|
if( RC_BAD( rc = pBufferRStream->open(
|
|
(const char *)pRValue->val.pucBuf, pRValue->uiDataLen)))
|
|
{
|
|
goto Exit;
|
|
}
|
|
|
|
pRStream = pBufferRStream;
|
|
}
|
|
else
|
|
{
|
|
pRStream = pRValue->val.pIStream;
|
|
}
|
|
|
|
if ((pLValue->uiFlags & VAL_IS_CONSTANT) ||
|
|
!(pRValue->uiFlags & VAL_IS_CONSTANT))
|
|
{
|
|
for( ;;)
|
|
{
|
|
if( RC_BAD( rc = f_getNextMetaphone( pLStream, &uiLMeta)))
|
|
{
|
|
if( rc == NE_XFLM_EOF_HIT)
|
|
{
|
|
*piResult = 0;
|
|
rc = NE_XFLM_OK;
|
|
}
|
|
goto Exit;
|
|
}
|
|
|
|
ui64StartPos = pRStream->getCurrPosition();
|
|
|
|
for( ;;)
|
|
{
|
|
if( RC_BAD( rc = f_getNextMetaphone( pRStream, &uiRMeta)))
|
|
{
|
|
if( rc == NE_XFLM_EOF_HIT)
|
|
{
|
|
rc = NE_XFLM_OK;
|
|
*piResult = -1;
|
|
}
|
|
|
|
goto Exit;
|
|
}
|
|
|
|
if( uiLMeta == uiRMeta)
|
|
{
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
if( RC_BAD( rc = pRStream->positionTo( ui64StartPos)))
|
|
{
|
|
goto Exit;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for( ;;)
|
|
{
|
|
if( RC_BAD( rc = f_getNextMetaphone( pRStream, &uiRMeta)))
|
|
{
|
|
if( rc == NE_XFLM_EOF_HIT)
|
|
{
|
|
*piResult = 0;
|
|
rc = NE_XFLM_OK;
|
|
}
|
|
goto Exit;
|
|
}
|
|
|
|
ui64StartPos = pLStream->getCurrPosition();
|
|
|
|
for( ;;)
|
|
{
|
|
if( RC_BAD( rc = f_getNextMetaphone( pLStream, &uiLMeta)))
|
|
{
|
|
if( rc == NE_XFLM_EOF_HIT)
|
|
{
|
|
rc = NE_XFLM_OK;
|
|
*piResult = 1;
|
|
}
|
|
|
|
goto Exit;
|
|
}
|
|
|
|
if( uiLMeta == uiRMeta)
|
|
{
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
if( RC_BAD( rc = pLStream->positionTo( ui64StartPos)))
|
|
{
|
|
goto Exit;
|
|
}
|
|
}
|
|
}
|
|
|
|
Exit:
|
|
|
|
if( pBufferLStream)
|
|
{
|
|
pBufferLStream->Release();
|
|
}
|
|
|
|
if( pBufferRStream)
|
|
{
|
|
pBufferRStream->Release();
|
|
}
|
|
|
|
return( rc);
|
|
}
|
|
|
|
/***************************************************************************
|
|
Desc: Performs binary comparison on two streams - may be text or binary,
|
|
it really doesn't matter. Returns XFLM_TRUE or XFLM_FALSE.
|
|
***************************************************************************/
|
|
FSTATIC RCODE fqCompareBinary(
|
|
IF_OperandComparer * pOpComparer,
|
|
FQVALUE * pLValue,
|
|
FQVALUE * pRValue,
|
|
FLMINT * piResult)
|
|
{
|
|
RCODE rc = NE_XFLM_OK;
|
|
IF_BufferIStream * pBufferLStream = NULL;
|
|
IF_PosIStream * pLStream;
|
|
IF_BufferIStream * pBufferRStream = NULL;
|
|
IF_PosIStream * pRStream;
|
|
FLMBYTE ucLByte;
|
|
FLMBYTE ucRByte;
|
|
FLMUINT uiOffset = 0;
|
|
FLMBOOL bLEmpty = FALSE;
|
|
|
|
*piResult = 0;
|
|
|
|
// Types must be binary
|
|
|
|
if ( pLValue->eValType != XFLM_BINARY_VAL ||
|
|
pRValue->eValType != XFLM_BINARY_VAL)
|
|
{
|
|
rc = RC_SET_AND_ASSERT( NE_XFLM_NOT_IMPLEMENTED);
|
|
goto Exit;
|
|
}
|
|
|
|
// Open the streams
|
|
|
|
if( !(pLValue->uiFlags & VAL_IS_STREAM))
|
|
{
|
|
if( RC_BAD( rc = FlmAllocBufferIStream( &pBufferLStream)))
|
|
{
|
|
goto Exit;
|
|
}
|
|
|
|
if (RC_BAD( rc = pBufferLStream->open(
|
|
(const char *)pLValue->val.pucBuf, pLValue->uiDataLen)))
|
|
{
|
|
goto Exit;
|
|
}
|
|
|
|
pLStream = pBufferLStream;
|
|
}
|
|
else
|
|
{
|
|
pLStream = pLValue->val.pIStream;
|
|
}
|
|
|
|
if( !(pRValue->uiFlags & VAL_IS_STREAM))
|
|
{
|
|
if( RC_BAD( rc = pBufferRStream->open(
|
|
(const char *)pRValue->val.pucBuf, pRValue->uiDataLen)))
|
|
{
|
|
goto Exit;
|
|
}
|
|
pRStream = pBufferRStream;
|
|
}
|
|
else
|
|
{
|
|
pRStream = pRValue->val.pIStream;
|
|
}
|
|
|
|
if (pOpComparer)
|
|
{
|
|
rc = pOpComparer->compare( pLStream, pRStream, piResult);
|
|
goto Exit;
|
|
}
|
|
|
|
for (;;)
|
|
{
|
|
if (RC_BAD( rc = flmReadStorageAsBinary(
|
|
pLStream, &ucLByte, 1, uiOffset, NULL)))
|
|
{
|
|
if (rc == NE_XFLM_EOF_HIT)
|
|
{
|
|
rc = NE_XFLM_OK;
|
|
bLEmpty = TRUE;
|
|
}
|
|
else
|
|
{
|
|
goto Exit;
|
|
}
|
|
}
|
|
|
|
if (RC_BAD( rc = flmReadStorageAsBinary(
|
|
pRStream, &ucRByte, 1, uiOffset, NULL)))
|
|
{
|
|
if (rc == NE_XFLM_EOF_HIT)
|
|
{
|
|
rc = NE_XFLM_OK;
|
|
if( bLEmpty)
|
|
{
|
|
*piResult = 0;
|
|
}
|
|
else
|
|
{
|
|
*piResult = 1;
|
|
}
|
|
}
|
|
goto Exit;
|
|
}
|
|
else if( bLEmpty)
|
|
{
|
|
*piResult = -1;
|
|
goto Exit;
|
|
}
|
|
|
|
if( ucLByte != ucRByte)
|
|
{
|
|
*piResult = ucLByte < ucRByte ? -1 : 1;
|
|
goto Exit;
|
|
}
|
|
|
|
uiOffset++;
|
|
}
|
|
|
|
Exit:
|
|
|
|
if( pBufferLStream)
|
|
{
|
|
pBufferLStream->Release();
|
|
}
|
|
|
|
if( pBufferRStream)
|
|
{
|
|
pBufferRStream->Release();
|
|
}
|
|
|
|
return( rc);
|
|
}
|
|
|
|
/***************************************************************************
|
|
Desc: Compare two values. This routine assumes that pValue1 and pValue2
|
|
are non-null.
|
|
***************************************************************************/
|
|
RCODE fqCompare(
|
|
FQVALUE * pValue1,
|
|
FQVALUE * pValue2,
|
|
FLMUINT uiCompareRules,
|
|
IF_OperandComparer * pOpComparer,
|
|
FLMUINT uiLanguage,
|
|
FLMINT * piCmp)
|
|
{
|
|
RCODE rc = NE_XFLM_OK;
|
|
|
|
// We have already called fqCanCompare, so no need to do it here
|
|
|
|
switch (pValue1->eValType)
|
|
{
|
|
case XFLM_BOOL_VAL:
|
|
*piCmp = pValue1->val.eBool > pValue2->val.eBool
|
|
? 1
|
|
: pValue1->val.eBool < pValue2->val.eBool
|
|
? -1
|
|
: 0;
|
|
break;
|
|
case XFLM_UINT_VAL:
|
|
switch (pValue2->eValType)
|
|
{
|
|
case XFLM_UINT_VAL:
|
|
*piCmp = pValue1->val.uiVal > pValue2->val.uiVal
|
|
? 1
|
|
: pValue1->val.uiVal < pValue2->val.uiVal
|
|
? -1
|
|
: 0;
|
|
break;
|
|
case XFLM_UINT64_VAL:
|
|
*piCmp = (FLMUINT64)pValue1->val.uiVal > pValue2->val.ui64Val
|
|
? 1
|
|
: (FLMUINT64)pValue1->val.uiVal < pValue2->val.ui64Val
|
|
? -1
|
|
: 0;
|
|
break;
|
|
case XFLM_INT_VAL:
|
|
*piCmp = pValue2->val.iVal < 0 ||
|
|
pValue1->val.uiVal > (FLMUINT)pValue2->val.iVal
|
|
? 1
|
|
: pValue1->val.uiVal < (FLMUINT)pValue2->val.iVal
|
|
? -1
|
|
: 0;
|
|
break;
|
|
case XFLM_INT64_VAL:
|
|
*piCmp = pValue2->val.i64Val < 0 ||
|
|
(FLMUINT64)pValue1->val.uiVal >
|
|
(FLMUINT64)pValue2->val.i64Val
|
|
? 1
|
|
: (FLMUINT64)pValue1->val.uiVal <
|
|
(FLMUINT64)pValue2->val.i64Val
|
|
? -1
|
|
: 0;
|
|
break;
|
|
default:
|
|
rc = RC_SET_AND_ASSERT( NE_XFLM_NOT_IMPLEMENTED);
|
|
goto Exit;
|
|
}
|
|
break;
|
|
case XFLM_UINT64_VAL:
|
|
switch (pValue2->eValType)
|
|
{
|
|
case XFLM_UINT_VAL:
|
|
*piCmp = pValue1->val.ui64Val > (FLMUINT64)pValue2->val.uiVal
|
|
? 1
|
|
: pValue1->val.ui64Val < (FLMUINT64)pValue2->val.uiVal
|
|
? -1
|
|
: 0;
|
|
break;
|
|
case XFLM_UINT64_VAL:
|
|
*piCmp = pValue1->val.ui64Val > pValue2->val.ui64Val
|
|
? 1
|
|
: pValue1->val.ui64Val < pValue2->val.ui64Val
|
|
? -1
|
|
: 0;
|
|
break;
|
|
case XFLM_INT_VAL:
|
|
*piCmp = pValue2->val.iVal < 0 ||
|
|
pValue1->val.ui64Val > (FLMUINT64)pValue2->val.iVal
|
|
? 1
|
|
: pValue1->val.ui64Val < (FLMUINT64)pValue2->val.iVal
|
|
? -1
|
|
: 0;
|
|
break;
|
|
case XFLM_INT64_VAL:
|
|
*piCmp = pValue2->val.i64Val < 0 ||
|
|
pValue1->val.ui64Val > (FLMUINT64)pValue2->val.i64Val
|
|
? 1
|
|
: pValue1->val.ui64Val < (FLMUINT64)pValue2->val.i64Val
|
|
? -1
|
|
: 0;
|
|
break;
|
|
default:
|
|
rc = RC_SET_AND_ASSERT( NE_XFLM_NOT_IMPLEMENTED);
|
|
goto Exit;
|
|
}
|
|
break;
|
|
case XFLM_INT_VAL:
|
|
switch (pValue2->eValType)
|
|
{
|
|
case XFLM_UINT_VAL:
|
|
*piCmp = pValue1->val.iVal < 0 ||
|
|
(FLMUINT)pValue1->val.iVal < pValue2->val.uiVal
|
|
? -1
|
|
: (FLMUINT)pValue1->val.iVal > pValue2->val.uiVal
|
|
? 1
|
|
: 0;
|
|
break;
|
|
case XFLM_UINT64_VAL:
|
|
*piCmp = pValue1->val.iVal < 0 ||
|
|
(FLMUINT64)pValue1->val.iVal < pValue2->val.ui64Val
|
|
? -1
|
|
: (FLMUINT64)pValue1->val.iVal > pValue2->val.ui64Val
|
|
? 1
|
|
: 0;
|
|
break;
|
|
case XFLM_INT_VAL:
|
|
*piCmp = pValue1->val.iVal < pValue2->val.iVal
|
|
? -1
|
|
: pValue1->val.iVal > pValue2->val.iVal
|
|
? 1
|
|
: 0;
|
|
break;
|
|
case XFLM_INT64_VAL:
|
|
*piCmp = (FLMINT64)pValue1->val.iVal < pValue2->val.i64Val
|
|
? -1
|
|
: (FLMINT64)pValue1->val.iVal > pValue2->val.i64Val
|
|
? 1
|
|
: 0;
|
|
break;
|
|
default:
|
|
rc = RC_SET_AND_ASSERT( NE_XFLM_NOT_IMPLEMENTED);
|
|
goto Exit;
|
|
}
|
|
break;
|
|
case XFLM_INT64_VAL:
|
|
switch (pValue2->eValType)
|
|
{
|
|
case XFLM_UINT_VAL:
|
|
*piCmp = pValue1->val.i64Val < 0 ||
|
|
(FLMUINT64)pValue1->val.i64Val <
|
|
(FLMUINT64)pValue2->val.uiVal
|
|
? -1
|
|
: (FLMUINT64)pValue1->val.i64Val >
|
|
(FLMUINT64)pValue2->val.uiVal
|
|
? 1
|
|
: 0;
|
|
break;
|
|
case XFLM_UINT64_VAL:
|
|
*piCmp = pValue1->val.i64Val < 0 ||
|
|
(FLMUINT64)pValue1->val.i64Val < pValue2->val.ui64Val
|
|
? -1
|
|
: (FLMUINT64)pValue1->val.i64Val > pValue2->val.ui64Val
|
|
? 1
|
|
: 0;
|
|
break;
|
|
case XFLM_INT_VAL:
|
|
*piCmp = pValue1->val.i64Val < (FLMINT64)pValue2->val.iVal
|
|
? -1
|
|
: pValue1->val.i64Val > (FLMINT64)pValue2->val.iVal
|
|
? 1
|
|
: 0;
|
|
break;
|
|
case XFLM_INT64_VAL:
|
|
*piCmp = pValue1->val.i64Val < pValue2->val.i64Val
|
|
? -1
|
|
: pValue1->val.i64Val > pValue2->val.i64Val
|
|
? 1
|
|
: 0;
|
|
break;
|
|
default:
|
|
rc = RC_SET_AND_ASSERT( NE_XFLM_NOT_IMPLEMENTED);
|
|
goto Exit;
|
|
}
|
|
break;
|
|
case XFLM_BINARY_VAL:
|
|
if (RC_BAD( rc = fqCompareBinary( pOpComparer, pValue1,
|
|
pValue2, piCmp)))
|
|
{
|
|
goto Exit;
|
|
}
|
|
break;
|
|
case XFLM_UTF8_VAL:
|
|
if (RC_BAD( rc = fqCompareText( pOpComparer,
|
|
pValue1, pValue2,
|
|
uiCompareRules, FALSE, uiLanguage, piCmp)))
|
|
{
|
|
goto Exit;
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
Exit:
|
|
|
|
return( rc);
|
|
}
|
|
|
|
/***************************************************************************
|
|
Desc: Do a comparison operator.
|
|
***************************************************************************/
|
|
RCODE fqCompareOperands(
|
|
FLMUINT uiLanguage,
|
|
FQVALUE * pLValue,
|
|
FQVALUE * pRValue,
|
|
eQueryOperators eOperator,
|
|
FLMUINT uiCompareRules,
|
|
IF_OperandComparer * pOpComparer,
|
|
FLMBOOL bNotted,
|
|
XFlmBoolType * peBool)
|
|
{
|
|
RCODE rc = NE_XFLM_OK;
|
|
FLMINT iCmp;
|
|
|
|
if (!pLValue || pLValue->eValType == XFLM_MISSING_VAL ||
|
|
!pRValue || pRValue->eValType == XFLM_MISSING_VAL ||
|
|
!fqCanCompare( pLValue, pRValue))
|
|
{
|
|
*peBool = (bNotted ? XFLM_TRUE : XFLM_FALSE);
|
|
}
|
|
|
|
// At this point, both operands are known to be present and are of
|
|
// types that can be compared. The comparison
|
|
// will therefore be performed according to the
|
|
// operator specified.
|
|
|
|
else
|
|
{
|
|
switch (eOperator)
|
|
{
|
|
case XFLM_EQ_OP:
|
|
case XFLM_NE_OP:
|
|
if (pLValue->eValType == XFLM_UTF8_VAL ||
|
|
pRValue->eValType == XFLM_UTF8_VAL)
|
|
{
|
|
if (RC_BAD( rc = fqCompareText( pOpComparer, pLValue, pRValue,
|
|
uiCompareRules, TRUE, uiLanguage, &iCmp)))
|
|
{
|
|
goto Exit;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (RC_BAD( rc = fqCompare( pLValue, pRValue,
|
|
uiCompareRules, pOpComparer, uiLanguage, &iCmp)))
|
|
{
|
|
goto Exit;
|
|
}
|
|
}
|
|
if (eOperator == XFLM_EQ_OP)
|
|
{
|
|
*peBool = (iCmp == 0 ? XFLM_TRUE : XFLM_FALSE);
|
|
}
|
|
else
|
|
{
|
|
*peBool = (iCmp != 0 ? XFLM_TRUE : XFLM_FALSE);
|
|
}
|
|
break;
|
|
|
|
case XFLM_APPROX_EQ_OP:
|
|
if (RC_BAD( rc = fqApproxCompare( pLValue, pRValue, &iCmp)))
|
|
{
|
|
goto Exit;
|
|
}
|
|
*peBool = (iCmp == 0 ? XFLM_TRUE : XFLM_FALSE);
|
|
break;
|
|
|
|
case XFLM_LT_OP:
|
|
if (RC_BAD( rc = fqCompare( pLValue, pRValue,
|
|
uiCompareRules, pOpComparer, uiLanguage, &iCmp)))
|
|
{
|
|
goto Exit;
|
|
}
|
|
*peBool = (iCmp < 0 ? XFLM_TRUE : XFLM_FALSE);
|
|
break;
|
|
|
|
case XFLM_LE_OP:
|
|
if (RC_BAD( rc = fqCompare( pLValue, pRValue,
|
|
uiCompareRules, pOpComparer, uiLanguage, &iCmp)))
|
|
{
|
|
goto Exit;
|
|
}
|
|
*peBool = (iCmp <= 0 ? XFLM_TRUE : XFLM_FALSE);
|
|
break;
|
|
|
|
case XFLM_GT_OP:
|
|
if (RC_BAD( rc = fqCompare( pLValue, pRValue,
|
|
uiCompareRules, pOpComparer, uiLanguage, &iCmp)))
|
|
{
|
|
goto Exit;
|
|
}
|
|
*peBool = (iCmp > 0 ? XFLM_TRUE : XFLM_FALSE);
|
|
break;
|
|
|
|
case XFLM_GE_OP:
|
|
if (RC_BAD( rc = fqCompare( pLValue, pRValue,
|
|
uiCompareRules, pOpComparer, uiLanguage, &iCmp)))
|
|
{
|
|
goto Exit;
|
|
}
|
|
*peBool = (iCmp >= 0 ? XFLM_TRUE : XFLM_FALSE);
|
|
break;
|
|
|
|
default:
|
|
*peBool = XFLM_UNKNOWN;
|
|
rc = RC_SET_AND_ASSERT( NE_XFLM_QUERY_SYNTAX);
|
|
goto Exit;
|
|
}
|
|
}
|
|
|
|
Exit:
|
|
|
|
return( rc);
|
|
}
|
|
|
|
/***************************************************************************
|
|
Desc: Do an arithmetic operator.
|
|
***************************************************************************/
|
|
RCODE fqArithmeticOperator(
|
|
FQVALUE * pLValue,
|
|
FQVALUE * pRValue,
|
|
eQueryOperators eOperator,
|
|
FQVALUE * pResult)
|
|
{
|
|
RCODE rc = NE_XFLM_OK;
|
|
FQ_OPERATION * fnOp;
|
|
FLMUINT uiOffset = 0;
|
|
|
|
if( !isArithOp( eOperator))
|
|
{
|
|
rc = RC_SET( NE_XFLM_SYNTAX);
|
|
goto Exit;
|
|
}
|
|
|
|
if (pLValue->eValType == XFLM_MISSING_VAL ||
|
|
pRValue->eValType == XFLM_MISSING_VAL)
|
|
{
|
|
pResult->eValType = XFLM_MISSING_VAL;
|
|
goto Exit;
|
|
}
|
|
|
|
if( isUnsigned( pLValue))
|
|
{
|
|
if( isUnsigned( pRValue))
|
|
{
|
|
uiOffset = 0;
|
|
}
|
|
else if( isSigned( pRValue))
|
|
{
|
|
uiOffset = 1;
|
|
}
|
|
else
|
|
{
|
|
rc = RC_SET_AND_ASSERT( NE_XFLM_NOT_IMPLEMENTED);
|
|
goto Exit;
|
|
}
|
|
}
|
|
else if( isSigned( pLValue))
|
|
{
|
|
if( isUnsigned( pRValue))
|
|
{
|
|
uiOffset = 2;
|
|
}
|
|
else if( isSigned( pRValue))
|
|
{
|
|
uiOffset = 3;
|
|
}
|
|
else
|
|
{
|
|
rc = RC_SET_AND_ASSERT( NE_XFLM_NOT_IMPLEMENTED);
|
|
goto Exit;
|
|
}
|
|
}
|
|
|
|
fnOp = FQ_ArithOpTable[ ((((FLMUINT)eOperator) -
|
|
XFLM_FIRST_ARITH_OP) * 4) + uiOffset];
|
|
fnOp( pLValue, pRValue, pResult);
|
|
|
|
Exit:
|
|
|
|
return( rc);
|
|
}
|