📄 pvaltree.c
字号:
{
if (value < 0)
{
isBitStr = 0; /* node is in a temporary building state */
}
else
{
/* We've got a bit string to handle. In this case, the length we get is in bits,
so we should change it to bytes and add another character in the end, telling the
amount of bits in the last character... */
bitsNotInUse = (char)((8 - (value % 8))%8);
copiedValue = (value + 7) / 8; /* Number of bytes we have in the bit string itself */
value = copiedValue + 1; /* We add the indication of how many bits are not used to the node */
}
}
/* If we have a string with the same length already we'll use that string's allocation
instead of reallocating the new one */
if ((node->string != NULL) && ((node->value != value) || (string == NULL)))
{
/* This is node holds a string and we're replacing it with an empty one or with one
with a different length - in this case, we first delete the original string */
rpoolFree(vt->sPool, node->string);
node->string = NULL;
}
if ((pstIsStringNode(hSyn, synField) || (string != NULL)) && (value > 0))
{
/* We've got some kind of a string to handle... */
if (node->string == NULL)
{
/* No string yet - allocate a brand new one and fill it in with the desired value */
node->string = rpoolAllocCopyExternal(vt->sPool, string, (int)copiedValue);
}
else
{
/* Looks like we've got the same length in the original string this node held and
the new one - just replace the original one if necessary. */
if (rpoolCopyFromExternal(vt->sPool, node->string, string, 0, (int)copiedValue) == NULL)
return RV_PVT_ERROR_UNKNOWN;
}
if (node->string == NULL)
return RV_ERROR_UNKNOWN;
if (isBitStr)
{
/* For bit strings, we already copied the string inself, we only have to put
the indication of how many bits are not used in the last character of this
bit string... */
if (rpoolCopyFromExternal(vt->sPool, node->string, &bitsNotInUse, copiedValue, 1) == NULL)
return RV_PVT_ERROR_UNKNOWN;
}
}
/* Set the value of this node */
node->value = value;
return nodePath;
}
static
RvPvtNodeId /* new node id or negative value on failure */
pvtAddSyn(
/*
Add child node under parentId.
The new node is placed in its relative position according to syntax tree
indexing of SEQUENCE fields of structure.
*/
IN HPVT hVal,
IN HPST hSyn, /* -1 ==> copy from parent node */
IN RvPvtNodeId parentId,
IN RvPstFieldId fieldEnum, /* field inside SEQUENCE or CHOICE, or -1 if not applicable */
IN RvInt32 value, /* if string exists ==> size of string ,
if Bit String - length in bit*/
IN const char *string, /* NULL if no string */
OUT RvPvtNodeId *newNodeId, /* id for the new node */
OUT int *index) /* index of new node */
{
vtStruct *vt = (vtStruct *)hVal;
int childIndex, childCount;
RvPvtNodeId path = RV_PVT_INVALID_NODEID;
RvPvtNodeId cur, pre;
RvPstFieldId curFieldId;
RvPstNodeId synParentNodeId, synNodeId;
pstNodeType type;
vtNode *parentNode;
if (!vt || !RV_PVT_NODEID_IS_VALID(parentId)) return RV_PVT_ERROR_UNKNOWN;
/* -- Check choice brothers and delete if exist */
parentNode = (vtNode *)rtGetByPath(vt->vTree, (int)parentId);
if (!parentNode)
return RV_PVT_ERROR_UNKNOWN;
synParentNodeId = VTN_SYN_NODE(parentNode);
if (hSyn == (HPST)-1)
hSyn = parentNode->hSyn;
type=pstGetNodeType(hSyn, synParentNodeId);
if (type == RV_ERROR_UNKNOWN) return RV_PVT_ERROR_UNKNOWN;
if (type == pstChoice)
{
pvtDelete(hVal, pvtChild(hVal, parentId));
}
synNodeId = pvtResolveSynNodeId(hVal, hSyn, parentId, fieldEnum, &childIndex);
if (!RV_PST_NODEID_IS_VALID(synNodeId))
{
RvLogWarning(&vt->log,
(&vt->log, "pvtAddSyn: pvtResolveSynNodeId failed for %s (%d).",
pstGetFieldNamePtr(hSyn, fieldEnum), fieldEnum));
return RV_PVT_ERROR_UNKNOWN;
}
if (childIndex < 0)
{ /* SEQUENCE OF */
if ((path = (RvPvtNodeId)rtAddTail(vt->vTree, (int)parentId, NULL)) <0)
{
RvLogError(&vt->log,
(&vt->log, "pvtAddSyn: rtAddTail failed for %s (%d).",
pstGetFieldNamePtr(hSyn, fieldEnum), fieldEnum));
return RV_PVT_ERROR_OUTOFRESOURCES;
}
}
else
{
/* Find the left brother of the new node (or none) so we know
where to insert in the child list. */
/* pre: the previous node - the left brother */
pre = RV_PVT_INVALID_NODEID; /* RV_ERROR_UNKNOWN -> add as leftmost */
childCount = pstGetNumberOfChildren(hSyn, synParentNodeId);
if (childCount > 0)
{
cur = pvtChild(hVal, parentId);
if (RV_PVT_NODEID_IS_VALID(cur))
{
pstChildExt st_child;
int stChildIndex = 1;
vtNode *node;
RvUint32* iter = pstGetChildExt(hSyn, synParentNodeId, stChildIndex, &st_child);
RvBool stop = RV_FALSE;
node = (vtNode *)rtGetByPath(vt->vTree, (int)cur);
if (node)
curFieldId = VTN_SYN_FIELD(node);
else
curFieldId = RV_ERROR_UNKNOWN;
while (!stop)
{
/* this is just a sanity check: */
if (stChildIndex > childCount)
{
/* should never reach here */
RvLogError(&vt->log, (&vt->log, "pvtAddSyn: probable integrity failiure in vt 0x%p.", hVal));
pre = RV_PVT_INVALID_NODEID; /* allow leftmost insertion */
break;
}
if (iter == NULL)
{
pre = RV_PVT_INVALID_NODEID;
break;
}
if (st_child.fieldId == fieldEnum)
break;
if (st_child.fieldId != curFieldId)
{
stChildIndex++;
iter = pstGetBrotherExt(hSyn, stChildIndex, iter, &st_child);
continue;
}
pre = cur;
cur = (RvPvtNodeId)rtBrother(vt->vTree, (int)cur);
if (cur >= 0)
{
node = (vtNode *)rtGetByPath(vt->vTree, (int)cur);
if (node)
curFieldId = VTN_SYN_FIELD(node);
else
curFieldId = RV_ERROR_UNKNOWN;
}
else
{
stop = RV_TRUE; /* Make sure we get out of this while loop */
}
}
if (cur>=0 && curFieldId==fieldEnum)
path=cur;
}
}
if (path<0)
{
if (pre < 0)
{
if ((path = (RvPvtNodeId)rtAddHead(vt->vTree, (int)parentId, NULL)) <0)
{
RvLogError(&vt->log,
(&vt->log, "pvtAddSyn: rtAddHead (left brother) failed for %s (%d).",
pstGetFieldNamePtr(hSyn, fieldEnum), fieldEnum));
return RV_PVT_ERROR_OUTOFRESOURCES;
}
}
else
{
if ((path = (RvPvtNodeId)rtAddBrother(vt->vTree, (int)pre, NULL)) <0)
{
RvLogError(&vt->log,
(&vt->log, "pvtAddSyn: rtAddBrother failed for %s (%d).",
pstGetFieldNamePtr(hSyn, fieldEnum), fieldEnum));
return RV_PVT_ERROR_OUTOFRESOURCES;
}
}
}
}
if (newNodeId) *newNodeId = path;
return pvtSetNode(hVal, hSyn, path, synNodeId, parentId, fieldEnum, value, string, index);
}
static void *
pvtAddTreeFunc(HRTREE rtH, int nodeId, void *vts)
{
vtNode *node = (vtNode *)rtGetByPath(rtH, nodeId);
vtStructs* v = (vtStructs *)vts;
HRPOOLELEM string;
if (!vts || !node) return NULL;
string = node->string;
if (string)
{
if (!(node->string = rpoolAllocCopyInternal(v->dest->sPool, v->src->sPool, string, (int)node->value)))
{
RvLogError(&v->dest->log,
(&v->dest->log, "pvtAddTreeFunc: String allocation failed for '%d' (%d).",
string, (int)node->value));
return NULL;
}
}
return vts;
}
/*________________________________________delete_________________________________*/
static void *
pvtDeleteFunc(HRTREE rtH, int nodeId, void *hVal)
{
vtNode *node = (vtNode *)rtGetByPath(rtH, nodeId);
vtStruct *vt = *(vtStruct **)hVal;
if (!hVal || !node) return NULL;
if (node->string)
{
if (rpoolFree(vt->sPool, node->string) <0)
{
RvLogError(&vt->log,
(&vt->log, "pvtDeleteFunc:%d: Failed to free string from pool [0x%p].",
nodeId, node->string));
}
}
return hVal;
}
/*________________________________________get&set node_________________________________*/
static int
pvtSetSyn(
/* Desc:Set values of existed node */
IN HPVT hVal,
IN HPST hSyn, /* -1 ==> don't change */
IN RvPvtNodeId nodeId,
IN RvPstFieldId fieldEnum, /* <0 not changing current value */
IN RvInt32 value, /* if bit string - length in bits */
IN const char *string)
{
vtStruct *vt = (vtStruct *)hVal;
vtNode *node;
char bitsNotInUse;
RvBool isBitStr;
RvPstNodeId synField;
RvInt32 copiedValue = value; /* How many bytes to copy - used for bit strings */
if (!vt) return RV_ERROR_UNKNOWN;
if (! (node = (vtNode *)rtGetByPath(vt->vTree, (int)nodeId)) ) return RV_ERROR_UNKNOWN;
if (hSyn == (HPST)-1)
{
hSyn = node->hSyn;
}
else
{
node->hSyn = hSyn;
}
if ( fieldEnum >= 0 )
{
/* See if the field Id was changed */
if (fieldEnum != (RvPstFieldId)VTN_SYN_FIELD(node))
{
RvPvtNodeId parentId = pvtParent(hVal, nodeId);
/* Make sure it's not a root node */
if (RV_PVT_NODEID_IS_VALID(parentId))
{
RvPstNodeId synNodeId = pvtResolveSynNodeId(hVal, hSyn, parentId, fieldEnum, NULL);
VTN_SET_SYN_NODE(node, synNodeId);
}
}
VTN_SET_SYN_FIELD(node, fieldEnum);
}
synField = VTN_SYN_NODE(node);
/* See if it's a bit string */
if ((isBitStr = pvtIsBitString(hSyn, synField)))
{
/* We've got a bit string to handle. In this case, we the length we get is in bits,
so we should change it to bytes and add another character in the end, telling the
amount of bits in the last character... */
bitsNotInUse = (char)((8 - (value % 8))%8);
copiedValue = (value + 7) / 8; /* Number of bytes we have in the bit string itself */
value = copiedValue + 1; /* We add the indication of how many bits are not used to the node */
}
/* If we have a string with the same length already we'll use that string's allocation
instead of reallocating the new one */
if ((node->string != NULL) && ((node->value != value) || (string == NULL)))
{
/* This is node holds a string and we're replacing it with an empty one or with one
with a different length - in this case, we first delete the original string */
rpoolFree(vt->sPool, node->string);
node->string = NULL;
}
if ((pstIsStringNode(hSyn, synField) || (string != NULL)) && (value > 0))
{
/* We've got some kind of a string to handle... */
if (node->string == NULL)
{
/* No string yet - allocate a brand new one and fill it in with the desired value */
node->string = rpoolAllocCopyExternal(vt->sPool, string, (int)copiedValue);
}
else
{
/* Looks like we've got the same length in the original string this node held and
the new one - just replace the original one if necessary. */
if (rpoolCopyFromExternal(vt->sPool, node->string, string, 0, (int)copiedValue) == NULL)
return RV_PVT_ERROR_UNKNOWN;
}
if (node->string == NULL)
return RV_ERROR_UNKNOWN;
if (isBitStr)
{
/* For bit strings, we already copied the string inself, we only have to put
the indication of how many bits are not used in the last character of this
bit string... */
if (rpoolCopyFromExternal(vt->sPool, node->string, &bitsNotInUse, copiedValue, 1) == NULL)
return RV_PVT_ERROR_UNKNOWN;
}
}
/* Set the value of this node */
node->value = value;
return RV_TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -