asmrulep.cpp
来自「symbian 下的helix player源代码」· C++ 代码 · 共 1,524 行 · 第 1/3 页
CPP
1,524 行
/* ***** BEGIN LICENSE BLOCK *****
* Source last modified: $Id: asmrulep.cpp,v 1.14.2.3 2004/07/09 01:48:15 hubbe Exp $
*
* Portions Copyright (c) 1995-2004 RealNetworks, Inc. All Rights Reserved.
*
* The contents of this file, and the files included with this file,
* are subject to the current version of the RealNetworks Public
* Source License (the "RPSL") available at
* http://www.helixcommunity.org/content/rpsl unless you have licensed
* the file under the current version of the RealNetworks Community
* Source License (the "RCSL") available at
* http://www.helixcommunity.org/content/rcsl, in which case the RCSL
* will apply. You may also obtain the license terms directly from
* RealNetworks. You may not use this file except in compliance with
* the RPSL or, if you have a valid RCSL with RealNetworks applicable
* to this file, the RCSL. Please see the applicable RPSL or RCSL for
* the rights, obligations and limitations governing use of the
* contents of the file.
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License Version 2 or later (the
* "GPL") in which case the provisions of the GPL are applicable
* instead of those above. If you wish to allow use of your version of
* this file only under the terms of the GPL, and not to allow others
* to use your version of this file under the terms of either the RPSL
* or RCSL, indicate your decision by deleting the provisions above
* and replace them with the notice and other provisions required by
* the GPL. If you do not delete the provisions above, a recipient may
* use your version of this file under the terms of any one of the
* RPSL, the RCSL or the GPL.
*
* This file is part of the Helix DNA Technology. RealNetworks is the
* developer of the Original Code and owns the copyrights in the
* portions it created.
*
* This file, and the files included with this file, is distributed
* and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY
* KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET
* ENJOYMENT OR NON-INFRINGEMENT.
*
* Technology Compatibility Kit Test Suite(s) Location:
* http://www.helixcommunity.org/content/tck
*
* Contributor(s):
*
* ***** END LICENSE BLOCK ***** */
// #include "hlxclib/stdio.h" /* printf */
#include "hxtypes.h" /* Basic Types */
#include "hlxclib/stdlib.h"
#include "hxstrutl.h"
#include "hxcom.h" /* IUnknown */
#include "ihxpckts.h"
#include "asmrulep.h" /* ASM Public Include File */
#include "asmrulpp.h" /* ASM Private Include File */
#include "chxpckts.h"
#define RULE_VAL_INFINITY -1
#include "hxheap.h"
/*
#ifdef _DEBUG
#undef HX_THIS_FILE
static const char HX_THIS_FILE[] = __FILE__;
#endif
*/
static const char* const zpOpName[] =
{
">",
"<",
">=",
"<=",
"==",
"!=",
"AND",
"OR"
};
ASMRuleExpression::ASMRuleExpression(const char* pExpression)
{
int temp;
char* pTemp = new char[temp = (strlen(pExpression) + 1)];
memcpy(pTemp, pExpression, temp); /* Flawfinder: ignore */
m_ulNumThresholds = 1; // always have one zero rule
m_pHead = Parse(pTemp, m_ulNumThresholds);
delete[] pTemp;
}
ASMRuleExpression::~ASMRuleExpression()
{
RDelete(m_pHead);
}
/* Note: This parse is destructive to pExpression */
Node*
ASMRuleExpression::Parse(char* pExpression, UINT32& ulNumThreshold)
{
char* pTemp = pExpression;
int PLevel = 0;
BOOL bStripAgain = 1;
int OperSize;
//printf ("Parse Expression: %s\n", pExpression);
// Strip outside unneccesary parens
while ((*pExpression == '(') && (bStripAgain))
{
for (pTemp = pExpression, PLevel = 0; *pTemp; pTemp++)
{
if (*pTemp == '(')
PLevel++;
if (*pTemp == ')')
{
PLevel--;
if ((!(*(pTemp + 1))) && (!PLevel))
{
pExpression++;
pExpression[strlen(pExpression) - 1] = 0;
bStripAgain = 1;
break;
}
if (!PLevel)
{
bStripAgain = 0;
break;
}
}
}
}
for (pTemp = pExpression, PLevel = 0; *pTemp; pTemp++)
{
if (*pTemp == '(')
PLevel++;
if (*pTemp == ')')
PLevel--;
if (!PLevel)
{
OperSize = 1;
if (((*pTemp == '>') || (*pTemp == '<')) ||
((*pTemp == '=') || (*pTemp == '!')) ||
((*pTemp == '&') || (*pTemp == '|')))
{
OperatorNode* pNode = new OperatorNode;
pNode->m_Type = HX_RE_OPERATOR;
switch (*pTemp)
{
case '>':
if ((*(pTemp + 1)) == '=')
{
pNode->m_Data = HX_RE_GREATEREQUAL;
OperSize = 2;
}
else
pNode->m_Data = HX_RE_GREATER;
break;
case '<':
if ((*(pTemp + 1)) == '=')
{
pNode->m_Data = HX_RE_LESSEQUAL;
OperSize = 2;
}
else
pNode->m_Data = HX_RE_LESS;
break;
case '=':
if ((*(pTemp + 1)) == '=')
{
pNode->m_Data = HX_RE_EQUAL;
OperSize = 2;
}
break;
case '!':
if ((*(pTemp + 1)) == '=')
{
pNode->m_Data = HX_RE_NOTEQUAL;
OperSize = 2;
}
break;
case '&':
if ((*(pTemp + 1)) == '&')
{
pNode->m_Data = HX_RE_AND;
OperSize = 2;
}
break;
case '|':
if ((*(pTemp + 1)) == '|')
{
pNode->m_Data = HX_RE_OR;
OperSize = 2;
}
break;
default:
break;
};
*pTemp = 0;
pNode->m_pLeft = Parse(pExpression, ulNumThreshold);
pNode->m_pRight = Parse(pTemp + OperSize, ulNumThreshold);
return pNode;
}
}
}
for (pTemp = pExpression, PLevel = 0; *pTemp; pTemp++)
{
if (*pTemp == '(')
PLevel++;
if (*pTemp == ')')
PLevel--;
if (!PLevel)
{
if (*pTemp == '$')
{
VariableNode* pNode = new VariableNode;
pNode->m_Type = HX_RE_VARIABLE;
pNode->m_Data = new char[strlen(pTemp)];
memcpy(pNode->m_Data, pTemp + 1, strlen(pTemp)); /* Flawfinder: ignore */
pNode->m_pLeft = 0;
pNode->m_pRight = 0;
ulNumThreshold++; // each open variable means one more threshold.
return pNode;
}
}
}
for (pTemp = pExpression, PLevel = 0; *pTemp; pTemp++)
{
if (*pTemp == '(')
PLevel++;
if (*pTemp == ')')
PLevel--;
if (!PLevel)
{
if ((*pTemp == '0') || (*pTemp == '1') || (*pTemp == '2') ||
(*pTemp == '3') || (*pTemp == '4') || (*pTemp == '5') ||
(*pTemp == '6') || (*pTemp == '7') || (*pTemp == '8') ||
(*pTemp == '9'))
{
if (strchr(pTemp, '.'))
{
FloatNode* pNode = new FloatNode;
pNode->m_Type = HX_RE_FLOAT;
pNode->m_Data = (float)atof(pTemp);
pNode->m_pLeft = 0;
pNode->m_pRight = 0;
return pNode;
}
else
{
IntegerNode* pNode = new IntegerNode;
pNode->m_Type = HX_RE_INTEGER;
pNode->m_Data = atoi(pTemp);
pNode->m_pLeft = 0;
pNode->m_pRight = 0;
return pNode;
}
}
}
}
//printf ("Panic: Bad rule\n");
return 0;
}
void
ASMRuleExpression::Dump()
{
//printf ("Dumping ASMRuleExpression:\n");
RDump(m_pHead);
//printf ("\n");
}
void
ASMRuleExpression::RDump(Node* pNode)
{
if (!pNode)
return;
#if 0
switch(pNode->m_Type)
{
case HX_RE_VARIABLE:
printf (" Variable: %s\n", ((VariableNode *)pNode)->m_Data);
break;
case HX_RE_INTEGER:
printf (" Integer: %d\n", ((IntegerNode *)pNode)->m_Data);
break;
case HX_RE_FLOAT:
printf (" Float: %f\n", ((FloatNode *)pNode)->m_Data);
break;
case HX_RE_OPERATOR:
printf (" Operator: %s\n",
zpOpName[((OperatorNode *)pNode)->m_Data]);
break;
}
#endif
RDump(pNode->m_pLeft);
RDump(pNode->m_pRight);
}
void
ASMRuleExpression::RDelete(Node* pNode)
{
if (!pNode)
return;
if (pNode->m_Type == HX_RE_VARIABLE)
{
HX_VECTOR_DELETE(((VariableNode *)pNode)->m_Data);
};
RDelete(pNode->m_pLeft);
RDelete(pNode->m_pRight);
delete pNode;
}
/*
* This is a recursive expression evaluator that will determine whether
* or not we are subscribed to a particular rule, given the current conditions
*/
float
ASMRuleExpression::REvaluate(Node* pNode, IHXValues* pVars)
{
if (!pNode)
return (float)0;
switch(pNode->m_Type)
{
case HX_RE_VARIABLE:
{
IHXBuffer* pValue=NULL;
float nValue = (float)0;
pVars->GetPropertyCString(((VariableNode *)pNode)->m_Data, pValue);
if (pValue)
{
nValue = (float)atof((const char *)pValue->GetBuffer());
pValue->Release();
}
return nValue;
}
case HX_RE_INTEGER:
return (float)((IntegerNode *)pNode)->m_Data;
break;
case HX_RE_FLOAT:
return ((FloatNode *)pNode)->m_Data;
break;
case HX_RE_OPERATOR:
{
float Left = REvaluate(pNode->m_pLeft, pVars);
float Right = REvaluate(pNode->m_pRight, pVars);
switch (((OperatorNode *)pNode)->m_Data)
{
case HX_RE_GREATEREQUAL:
return (float)(Left >= Right);
break;
case HX_RE_GREATER:
return (float)(Left > Right);
break;
case HX_RE_LESSEQUAL:
if( Right == RULE_VAL_INFINITY )
{
return (float)TRUE;
}
return (float)(Left <= Right);
break;
case HX_RE_LESS:
if( Right == RULE_VAL_INFINITY )
{
return (float)TRUE;
}
return (float)(Left < Right);
break;
case HX_RE_EQUAL:
return (float)(Left == Right);
break;
case HX_RE_NOTEQUAL:
return (float)(Left != Right);
break;
case HX_RE_AND:
return (float)(Left && Right);
break;
case HX_RE_OR:
return (float)(Left || Right);
break;
default:
HX_ASSERT(0);
return (float)0;
break;
}
}
break;
default:
HX_ASSERT(0);
return (float)0;
break;
}
}
BOOL
ASMRuleExpression::Evaluate(IHXValues* pVars)
{
BOOL res;
//printf ("Evaluate ASMRuleExpression:\n");
res = (BOOL)REvaluate(m_pHead, pVars);
//printf ("%d\n", res);
return res;
}
/*
* This is a recursive function which will evaluate a tree with one free
* variable (pPrevar). The returned array will contain all possible values
* that are border cases.
*/
float
ASMRuleExpression::RPreEvaluate(Node* pNode, IHXValues* pVars,
const char* pPreVar, float*& pThreshold,
UINT32& ulNumThreshold,
BOOL& bInvolvesTheOpenVariable)
{
bInvolvesTheOpenVariable = FALSE;
float retval = 0;
float* pThresholdL = NULL;
float* pThresholdR = NULL;
#define RETURN(x) retval = x; goto exitpoint;
if (!pNode)
return (float)0;
switch(pNode->m_Type)
{
case HX_RE_VARIABLE:
{
IHXBuffer* pValue=NULL;
float nValue = (float)0;
pVars->GetPropertyCString(((VariableNode *)pNode)->m_Data, pValue);
if (pValue)
{
nValue = (float)atof((const char *)pValue->GetBuffer());
pValue->Release();
}
if (strcasecmp(((VariableNode *)pNode)->m_Data, pPreVar) == 0)
{
bInvolvesTheOpenVariable = TRUE;
}
return nValue;
}
case HX_RE_INTEGER:
return (float)((IntegerNode *)pNode)->m_Data;
break;
case HX_RE_FLOAT:
return ((FloatNode *)pNode)->m_Data;
break;
case HX_RE_OPERATOR:
{
BOOL bInvolveL, bInvolveR;
UINT32 ulNumThresholdL = 0;
pThresholdL = pThreshold;
float Left = RPreEvaluate(pNode->m_pLeft, pVars, pPreVar,
pThresholdL, ulNumThresholdL, bInvolveL);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?