📄 pvaltree.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.
***********************************************************************/
/*
pvaltree.c
Holds message values to be used by coding systems and message compilers.
Parameters:
- parentId: Id of parent node. Unique node identifier.
- fieldEnum: enumeration of field as in the message.
- value: integer value of node.
- index: of child under parent. >=1
Version 1: Ron S. 18 July 1996. Add syntax tree association.
Now any value tree construction should be associated with a syntax tree. Each value node
holds reference to the correlated syntax tree node. So you may get syntax node directly
from the vtGet() function.
*/
#ifdef __cplusplus
extern "C" {
#endif
#include "rvtypes.h"
#include <stdlib.h>
#include "rvstdio.h"
#include "rvmemory.h"
#include "rvmutex.h"
#include "rvlog.h"
#include "rtree.h"
#include "rpool.h"
#include "intutils.h"
#include "oidutils.h"
#include "strutils.h"
#include "psyntreeDb.h"
#include "psyntreeStackApi.h"
#include "pvaltreeDef.h"
#include "pvaltreeStackApi.h"
#include "pvaltree.h"
/* used for RV_ERROR_UNKNOWN reporting */
#define getSafeFieldName(_pNode) pstGetFieldNamePtr((_pNode)->hSyn, (RvInt32)VTN_SYN_FIELD(_pNode))
#define nprn(s) ((s)?(s):"(null)")
/* Definition of functions we'll need later */
static int pvtSetSyn(IN HPVT hVal, IN HPST hSyn, IN RvPvtNodeId nodeId, IN RvPstFieldId fieldEnum, IN RvInt32 value, IN const char *string);
typedef struct
{
vtStruct* dest;
vtStruct* src;
} vtStructs;
/* We check here that the values of the following macros is the same.
Don't remove this check and don't change the value of RV_PVT_LOGDEBUG
to something other than a constant value. The reason for that is the
fact that we don't want to include rvlog.h in the header file pvaltree.h */
#if (RV_PVT_LOGDEBUG != RV_LOGLEVEL_DEBUG)
#error RV_PVT_LOGDEBUG must have the same value as RV_LOGLEVEL_DEBUG!
#endif
/************************************************************************
*
* Private functions
*
************************************************************************/
/************************************************************************
* vtPrintToLog
* purpose: Callback function called when a node has been parsed into
* a string and should be sent to the log.
* input : type - Type of log handle to use
* line - Line information
* The additional parameters are discarded
* output : none
* return : none
************************************************************************/
#if (RV_LOGMASK_COMPILEMASK & RV_LOGLEVEL_DEBUG)
void vtPrintToLog(void * type, const char* line, ...)
{
RvLogTextDebug((RvLogSource*)type, "%s", line);
}
#endif
/************************************************************************
* vtPrintFunc
* purpose: Print a tree from a given node.
* This function is the function used by all of the public
* print functions.
* input : hVal - Value Tree handle
* parentId - node ID to start printing from
* pFunc - The function called for the printing itself
* pFuncParam - The context to pass to the print function
* on each printed line
* degree - Detail degree to use when printing the message
* tree
* output : none
* return : Non-negative value on success
* Negative value on failure
************************************************************************/
static int vtPrintFunc(
IN HPVT hVal,
IN RvPvtNodeId parentId,
IN pvtPrintFuncP pFunc,
IN void * pFuncParam,
IN pvtPrintDegree degree)
{
vtStruct *vt = (vtStruct *)hVal;
int result;
RvMutexLock(&vt->mutex);
/* Set printing parameters before we start printing */
vt->pFunc = pFunc;
vt->pFuncParam = pFuncParam;
vt->degree = degree;
/* Print the message */
result = rtPrint(vt->vTree, (int)parentId, 0, -1, (void *)hVal, pFuncParam);
RvMutexUnlock(&vt->mutex);
return result;
}
/************************************************************************
* vtNodePrint
* purpose: Callback function used to print a single node using vt's
* print parameters
* input : rtH - RTree handle used
* nodeId - Node to print
* layer - Level of node in tree
* param - vtStruct of the node
* output : none
* return : vtStruct of the node (i.e. - param)
************************************************************************/
void *vtNodePrint(HRTREE rtH, int nodeId, int layer, void *param)
{
const char* hexCh = (char*)"0123456789abcdef";
const char* levels = (char*)". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ";
vtNode* n1 = (vtNode *)rtGetByPath(rtH, (int)nodeId);
vtStruct* vt = (vtStruct *)param;
char* name = NULL;
char string[1024];
char* ptr;
HPST hSyn;
char buff[128];
RvPstNodeId synNodeId = RV_PST_INVALID_NODEID;
int tmpLen, value;
pstNodeType type;
/* Make sure we've got something to print */
if ((n1 == NULL) || (param == NULL)) return param;
ptr = string;
hSyn = pvtGetSynTree((HPVT)vt, (RvPvtNodeId)nodeId);
/* 0. Layer */
ptr += RvSprintf(ptr, "%2d> ", layer);
if (layer > 32)
{
strcpy(ptr, levels);
ptr += 64;
}
else
{
memcpy(ptr, levels, (RvSize_t)(layer * 2));
ptr += (layer * 2);
}
/* 1. NODE ID */
if ((vt->degree & pvtPrintDegreeNodeId) != 0)
{
ptr += RvSprintf(ptr, "<%d> ", nodeId);
}
/* 2. FIELD NAME */
if (hSyn != NULL)
{
RvPstNodeId sNodeId = RV_PST_INVALID_NODEID;
pstNodeType parentType;
/* Get the parent's node type */
if (pvtGet((HPVT)vt, pvtParent((HPVT)vt, (RvPvtNodeId)nodeId), NULL, &sNodeId, NULL, NULL) >= 0)
parentType = pstGetNodeType(hSyn, sNodeId);
else
parentType = pstNull;
if (parentType == pstSequenceOf || parentType == pstSetOf)
{
/* SEQUENCE OF - no actual field name */
name = (char*)"*";
}
else
{
if (layer == 0)
{
/* First node - get its type */
RvPstNodeId synNodeId;
pvtGet((HPVT)vt, (RvPvtNodeId)nodeId, NULL, &synNodeId, NULL, NULL);
name = stGetNameByNodeId(hSyn, (int)synNodeId);
}
else
{
/* Not first node - get the field's name */
int synField = VTN_SYN_FIELD(n1);
name = pstGetFieldNamePtr(hSyn, synField);
}
}
}
if (name != NULL)
{
/* Add the name of field */
strcpy(ptr, name);
ptr += (int)strlen(ptr);
*ptr = ' '; ptr++;
}
else
{
/* Didn't find the name - print the value of the node */
ptr += RvSprintf(ptr, "$fid=%ld$ ", (long int)VTN_SYN_FIELD(n1));
name = buff;
}
/* 3. VALUE */
/* Check the type of the node we're about to print */
pvtGet((HPVT)vt, (RvPvtNodeId)nodeId, NULL, &synNodeId, NULL, NULL);
type = pstGetNodeType(hSyn, synNodeId);
if (type != pstBitString)
{
value = n1->value;
tmpLen = RvMin(n1->value, (int)sizeof(buff));
}
else
{
RvUint8 bitsNotInUse;
/* Calculate the length of the bitstring in bits */
rpoolCopyToExternal(vt->sPool, &bitsNotInUse, n1->string, n1->value - 1, 1);
value = (n1->value - 1) * 8 - bitsNotInUse;
tmpLen = RvMin(n1->value - 1, (int)sizeof(buff));
}
if ((vt->degree & pvtPrintDegreeValue) != 0)
{
/* We always print the value */
ptr += RvSprintf(ptr, "= (%u) ", value);
}
else
{
/* Remove values from non leaf nodes */
if ((pvtChild((HPVT)vt, (RvPvtNodeId)nodeId) < 0) || (n1->string != NULL))
{
/* leaf */
ptr += RvSprintf(ptr, "= %d ", value);
}
}
/* Get the string's value if we have a string */
if (n1->string != NULL)
{
/* -- show strings */
if (type == pstObjectIdentifier)
{
int resLen;
/* We have to decode the object identifier and only then add it in */
rpoolCopyToExternal(vt->sPool, buff, n1->string, 0, tmpLen);
ptr[0] = '{';
ptr[1] = ' ';
resLen = oidDecodeOID((int)tmpLen, buff, sizeof(buff), ptr + 2, nameForm);
if (resLen < 0) resLen = 0;
ptr[resLen + 2] = '}';
ptr += (resLen + 3);
}
else
{
/* Other string types - just print them */
int i;
char* hexPtr;
char ip[4];
/* Put the string in place */
rpoolCopyToExternal(vt->sPool, ptr + 1, n1->string, 0, tmpLen);
if (tmpLen == 4)
{
/* We might need the original string later on for IP address */
memcpy(ip, ptr + 1, (RvSize_t)tmpLen);
}
/* Fix unprintable characters and print the hex string */
*ptr = '\''; ptr++;
strcpy(ptr + tmpLen, "' =0x");
hexPtr = ptr + tmpLen + 5;
for (i = 0; i < tmpLen; i++)
{
*hexPtr = hexCh[((RvUint8)*ptr) >> 4]; hexPtr++;
*hexPtr = hexCh[((RvUint8)*ptr) & 0xf]; hexPtr++;
if ((RvUint8)*ptr < ' ') *ptr = '.';
ptr++;
}
ptr = hexPtr;
/* Deal with IP address */
if ((type == pstOctetString) && (n1->value == 4))
{
/* might be an IP address */
ptr += RvSprintf(ptr, " <%u.%u.%u.%u> ", (RvUint8)ip[0], (RvUint8)ip[1], (RvUint8)ip[2], (RvUint8)ip[3]);
}
else
{
*ptr = ' ';
ptr++;
}
}
}
/* 4. DEPENDENCY */
ptr[0] = '.';
ptr[1] = ' ';
ptr[2] = ' ';
ptr += 3;
if (type != pstNull)
{
pstChildExt child;
vtNode* n2 = (vtNode *)rtGetByPath(rtH, rtParent(rtH, (int)nodeId));
/* Check if we've got a child... */
if (hSyn && n2 != NULL)
{
RvPstNodeId synField2 = VTN_SYN_NODE(n2);
int synField1 = VTN_SYN_FIELD(n1);
if (pstGetFieldExt(hSyn, synField2, synField1, &child) >= 0)
if (child.speciality == pstDepending)
{
int objectId;
if (pvtFindObject((HPVT)vt, (RvPvtNodeId)nodeId, hSyn, child.enumerationValue, &objectId) >= 0)
ptr += RvSprintf(ptr, "[%s] ", stGetNameByNodeId(hSyn, objectId));
}
}
}
/* 5. GENERAL TYPE */
if (((vt->degree & pvtPrintDegreeSyntax) != 0) && (hSyn != NULL))
{
RvPstNodeId synField = VTN_SYN_NODE(n1);
if ((vt->degree & pvtPrintDegreeSyntaxId) != 0)
ptr += RvSprintf(ptr, "<%d> ", synField);
ptr += pstPrintNode(hSyn, synField, ptr, sizeof(string) - (ptr-string));
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -