📄 pvaltreestackapi.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 + -