⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 asmrulep.cpp

📁 著名的 helix realplayer 基于手机 symbian 系统的 播放器全套源代码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/* ***** BEGIN LICENSE BLOCK ***** 
 * Version: RCSL 1.0/RPSL 1.0 
 *  
 * Portions Copyright (c) 1995-2002 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 
 * Version 1.0 (the "RPSL") available at 
 * http://www.helixcommunity.org/content/rpsl unless you have licensed 
 * the file under the RealNetworks Community Source License Version 1.0 
 * (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.  
 *  
 * 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);

	    UINT32 ulNumThresholdR = 0;
	    pThresholdR = pThreshold + ulNumThresholdL;
	    float Right = RPreEvaluate(pNode->m_pRight, pVars, pPreVar,
			    pThresholdR, ulNumThresholdR, bInvolveR);

	    /* Handle aggregation of Threshold arrays */
	    switch (((OperatorNode *)pNode)->m_Data)
	    {
	    case HX_RE_GREATEREQUAL:
	    case HX_RE_GREATER:

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -