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

📄 pvaltreestackapi.c

📁 基于h323协议的软phone
💻 C
字号:
/***********************************************************************
        Copyright (c) 2002 RADVISION Ltd.
************************************************************************
NOTICE:
This document contains information that is confidential and proprietary
to RADVISION Ltd.. No part of this document may be reproduced in any
form whatsoever without written prior approval by RADVISION Ltd..

RADVISION Ltd. reserve the right to revise this publication and make
changes without obligation to notify any person of such revisions or
changes.
***********************************************************************/

/*
  pvaltreeStackApi

  This file contains functions which are available for the use of the stack modules,
  but are not part of the API provided to the users

  */

#include "pvaltreeDef.h"
#include "pvaltreeStackApi.h"

#ifdef __cplusplus
extern "C" {
#endif




/************************************************************************
 *
 *                          Private declarations
 *
 ************************************************************************/


/************************************************************************
 * pvtCompareContext
 * Context to use for pvtCompareFunction.
 * This contexts includes the following information:
 * hVal     - Value tree to use
 * nodeId   - Value node id to compare
 *            This node will be compare with a syntax value node
 ************************************************************************/
typedef struct
{
    HPVT        hVal;
    RvPvtNodeId nodeId;
} pvtCompareContext;




/************************************************************************
 *
 *                          Private functions
 *
 ************************************************************************/


static
RvBool
pvtCompareTwo(
         /* Compare two vt nodes */
         RTElement element1,
         RTElement element2,
         void *param /* syntax handle */
         )
{
    vtNode *node1 = (vtNode*)element1;
    vtNode *node2 = (vtNode*)element2;
    vtStruct* vt  = (vtStruct *)param; /*((vtStruct**)param)[0];*/
    HPST hSyn    = node1->hSyn; /*((HPST*)param)[1];*/
    int  synField;

    /* -- structure */
    if (/* Fix for 230 */VTN_SYN_FIELD(node1) >= 0 &&
      VTN_SYN_FIELD(node1) != VTN_SYN_FIELD(node2)) return RV_FALSE;
    if (VTN_SYN_NODE(node1) != VTN_SYN_NODE(node2)) return RV_FALSE;
    synField = VTN_SYN_NODE(node1);
    if (pstIsNodeComplex(hSyn, synField)) return RV_TRUE;

    /* -- value */
    if (node1->value != node2->value) return RV_FALSE;
    if ( (node1->string && !node2->string) ||
       (!node1->string && node2->string)) return RV_FALSE;
    if (node1->string &&
        rpoolCompareInternal(vt->sPool,node1->string, node2->string, node1->value)) return RV_FALSE;

    return RV_TRUE;
}


/************************************************************************
 * pvtCompare
 * purpose: Comparision function used when searching for a specific object
 *          in an association table.
 * input  : hSyn        - Syntax tree used
 *          sNodeId     - Syntax value node to compare
 *          context     - Context to use for comparison
 * output : none
 * return : Negative if the key is lower than elem in dictionary comparison
 *          0 if the key and the element are equal
 *          Positive if the key is higher than elem in dictionary comparison
 ************************************************************************/
static int pvtCompare(IN HPST hSyn, IN int sNodeId, IN void* context)
{
    pvtCompareContext* key = (pvtCompareContext *)context;

    int cmp,vSynNodeId=-1,vValue=0,stNodeId;
    RvPvtNodeId vtNodeId;
    RvPstFieldId vFieldId=-1;
    pstValueTreeStruct sValTreeStruct;
    pstValueNodeStruct sValNodeStruct;
    char vString[2048];

    vtNodeId = key->nodeId;

    pvtGet(key->hVal,key->nodeId,NULL,&vSynNodeId,NULL,NULL);

    pstGetValueTreeStruct(hSyn, sNodeId, &sValTreeStruct);

    if(sValTreeStruct.isString != pstValueSubTree)
    {
        if(pvtGetByIndex(key->hVal,key->nodeId,1,NULL)>=0)
        return RV_TRUE;

        pvtGet(key->hVal,key->nodeId,NULL,NULL,&vValue,NULL);
        pvtGetString(key->hVal,key->nodeId,vValue,vString);

        if(sValTreeStruct.isString == pstValueString)
        {
            return(strcmp(vString,pstGetFieldNamePtr(hSyn,sValTreeStruct.value)));
        }
        else
        {
            if(vValue>sValTreeStruct.value) return RV_TRUE;
            else if(vValue<sValTreeStruct.value) return RV_ERROR_UNKNOWN;
            else return RV_FALSE;
        }
    }

    for(stNodeId=stGetFirstValueNode(hSyn,sNodeId),vtNodeId=pvtChild(key->hVal,vtNodeId);
        (vtNodeId >= 0) && (stNodeId >= 0);
        vtNodeId=pvtBrother(key->hVal,vtNodeId),stNodeId=stGetNextValueNode(hSyn,stNodeId))
    {
        pvtGet(key->hVal,vtNodeId,&vFieldId,NULL,NULL,NULL);
        pstGetValueNodeStruct(hSyn, stNodeId, &sValNodeStruct);
        if(vFieldId>sValNodeStruct.fieldName)
            return RV_TRUE;
        else
            if(vFieldId<sValNodeStruct.fieldName)
                return RV_ERROR_UNKNOWN;
        else
        {
            pvtCompareContext newContext;
            newContext.hVal = key->hVal;
            newContext.nodeId = vtNodeId;
            if ((cmp=pvtCompare(hSyn, stNodeId, &newContext)))
                return cmp;
        }
    }

    return RV_FALSE;
}




/************************************************************************
 *
 *                          Public functions
 *
 ************************************************************************/


/************************************************************************
 * pvtCompareTree
 * purpose: Compare between two trees
 *          The trees must be structure identical, the compare function only
 *          checks that the values are identical.
 * input  : val1H       - PVT handle of the 1st tree
 *          val1RootId  - Root ID of the 1st tree
 *          val2H       - PVT handle of the 2nd tree
 *          val2RootId  - Root ID of the 2nd tree
 * output : none
 * return : Non-negative value if trees are identical
 *          Negative value on failure
 ************************************************************************/
int pvtCompareTree(
    IN  HPVT        val1H,
    IN  RvPvtNodeId val1RootId,
    IN  HPVT        val2H,
    IN  RvPvtNodeId val2RootId)
{
    vtStruct *vt1 = (vtStruct *)val1H;
    vtStruct *vt2 = (vtStruct *)val2H;
    RvMutex  *mutex1, *mutex2;
    int     result;

    if (!val1H || !val2H) return RV_ERROR_UNKNOWN;

    /* Make sure we lock an an orderly fashion to diminish dead-locking possibilities */
    if (val1H > val2H)
    {
        mutex1 = &vt2->mutex;
        mutex2 = &vt1->mutex;
    }
    else
    {
        mutex1 = &vt1->mutex;
        mutex2 = &vt2->mutex;
    }

    RvMutexLock(mutex1);
    RvMutexLock(mutex2);
    result = rtCompareTrees(vt1->vTree, (int)val1RootId, vt2->vTree, (int)val2RootId, pvtCompareTwo,
        (void *)val1H);
    RvMutexUnlock(mutex2);
    RvMutexUnlock(mutex1);

    return result;
}


RVAPI int RVCALLCONV
pvtFindObject(
         IN  HPVT           hVal,
         IN  RvPvtNodeId    nodeId,
         IN  HPST           hSyn,
         IN  int            stNodeIdOfAT,
         OUT int*           objectId)
{
    vtStruct* vt = (vtStruct *)hVal;
    pvtCompareContext   key;

    if (vt == NULL) return RV_ERROR_UNKNOWN;
    RvMutexLock(&vt->mutex);

    key.hVal = hVal;
    key.nodeId = nodeId;

    *objectId = pstFindObjectInAT(hSyn, stNodeIdOfAT, pvtCompare, &key);

    RvMutexUnlock(&vt->mutex);
    return (*objectId);
}


RVAPI int RVCALLCONV
pvtAddChildsIfDiffer(
            IN  HPVT        destH,
            IN  RvPvtNodeId destParentId,
            IN  HPVT        srcH,
            IN  RvPvtNodeId srcParentId,
            IN  RvBool      move)
{
    RvPvtNodeId destCur, srcCur, leftBrother = RV_PVT_ERROR_UNKNOWN;
    RvBool notFound;

    if (!destH || !srcH) return RV_ERROR_UNKNOWN;

    destCur = pvtChild(destH, destParentId);
    if (destCur<0)
        return pvtAddChilds(destH, destParentId, srcH, srcParentId);

    for(; destCur >=0; destCur = pvtBrother(destH, destCur))
    leftBrother = destCur;

    for(srcCur = pvtChild(srcH, srcParentId); srcCur >= 0; srcCur = pvtBrother(srcH, srcCur))
    {
        notFound = RV_TRUE;
        for(destCur = pvtChild(destH, destParentId);
            destCur >= 0;
            destCur = pvtBrother(destH, destCur))
            if (pvtCompareTree(destH, destCur, srcH, srcCur) == RV_TRUE)
            {
                notFound = RV_FALSE;
                break;
            }

        if (notFound) /* srcCur child not found in dest children */
        {
            if (move)
            {
                pvtAdoptChild(destH, srcCur, destParentId, leftBrother);
                leftBrother = pvtBrother(destH, leftBrother);
            }
            else
                pvtAddTree(destH, destParentId, srcH, srcCur);
        }
    }
    return RV_TRUE;

}




#ifdef __cplusplus
}
#endif



⌨️ 快捷键说明

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