📄 ci.c
字号:
/*
NOTICE:
This document contains information that is proprietary to RADVISION LTD.
No part of this publication may be reproduced in any form whatsoever without
written prior approval by RADVISION LTD.
RADVISION LTD reserves the right to revise this publication and make changes
without obligation to notify any person of such revisions or changes.
*/
/***************************************************************************
ci.c -- Configuration Interface
Module Author: Oz Solomonovich
This Comment: 26-Dec-1996
Abstract: Low level configuration interface for the H323 Stack.
Configuration information can reside in a number of
different sources. CI converts the data from the
configuration source into an internal R-Tree, with the
aid of the helper functions found in cisupp.c.
Platforms: All.
Known Bugs: None.
***************************************************************************/
#include "rvmemory.h"
#include "rvcbase.h"
#include "rtree.h"
#include "rpool.h"
#include "ci.h"
#include "cisupp.h"
#ifdef __cplusplus
extern "C" {
#endif
/* local functions */
static int ciGetNodeID(IN HCFG hCfg, IN const char *path);
#define CONFIG_POOL_OVERHEAD 4
RVAPI
HCFG RVCALLCONV ciConstruct(IN const char *source)
{
return ciConstructEx(source, 0, 0);
}
RVAPI
HCFG RVCALLCONV ciConstructEx(
IN const char * source, /* configuration source identifier */
IN int extraData, /* maximum amount of data growth */
IN int extraNodes /* maximum number of nodes growth */
)
{
int nodes, data, size;
cfgHandle *hCfg = NULL;
RvStatus res;
/* Initialize the common core - this might be the first API function an application
calls in H.323 */
res = RvCBaseInit();
if (res != RV_OK)
return NULL;
if(RvMemoryAlloc(NULL, (void**)&hCfg, sizeof(cfgHandle)) != RV_OK)
{
RvCBaseEnd();
return NULL;
}
hCfg->pool = 0;
hCfg->tree = 0;
hCfg->isMutexConstructed = RV_FALSE;
if (RvMutexConstruct(&hCfg->mutex) != RV_OK)
{
ciDestruct((HCFG)hCfg);
return NULL;
}
hCfg->isMutexConstructed = RV_TRUE;
if (source != NULL)
{
ciEstimateCfgSize(source, &nodes, &data);
if (nodes < 0 || data < 0)
{
ciDestruct((HCFG)hCfg);
return NULL;
}
}
else
{
data = 0;
nodes = 0;
}
data += extraData;
nodes += extraNodes;
size = (nodes + 1) * 2 * CONFIG_POOL_OVERHEAD + data + 100;
size = (size + CONFIG_RPOOL_BLOCK_SIZE) / CONFIG_RPOOL_BLOCK_SIZE; /* set to chuncks of 8 bytes */
hCfg->pool = rpoolConstruct(CONFIG_RPOOL_BLOCK_SIZE, size, RV_FALSE, "CONFIG");
if ((hCfg->tree = ciBuildRTree(source, nodes, hCfg->pool)) == NULL)
{
ciDestruct((HCFG)hCfg);
return NULL;
}
return (HCFG)hCfg;
}
RVAPI
ci_errors RVCALLCONV ciDestruct(IN HCFG hCfg)
{
int nodeID,rootID;
cfgHandle* cfg = (cfgHandle *)hCfg;
if (!hCfg)
return ERR_CI_GENERALERROR;
rootID=nodeID=rtRoot(cfg->tree);
if (cfg->tree) rtDestruct (cfg->tree);
if (cfg->pool) rpoolDestruct(cfg->pool);
if (cfg->isMutexConstructed)
RvMutexDestruct(&cfg->mutex);
RvMemoryFree((void *)hCfg);
RvCBaseEnd();
return ERR_CI_NOERROR;
}
RVAPI
ci_errors RVCALLCONV ciSave(
IN HCFG hCfg,
IN char *target)
{
cfgHandle* cfg = (cfgHandle *)hCfg;
ci_errors result;
if (hCfg == NULL)
return ERR_CI_GENERALERROR;
RvMutexLock(&cfg->mutex);
result = (ci_errors)ciOutputRTree(target, cfg->tree, cfg->pool);
RvMutexUnlock(&cfg->mutex);
return result;
}
static int ciGetNodeID(IN HCFG hCfg, IN const char *path)
{
int nodeID;
int len;
RvChar* dot;
pcfgValue cfgVal;
if (!path || !*path)
return ERR_CI_GENERALERROR;
if ((nodeID = rtHead(__hCfg->tree, rtRoot(__hCfg->tree))) < 0)
return ERR_CI_GENERALERROR;
while (*path)
{
dot = (RvChar*) strchr(path, '.');
len = dot? dot - path : strlen(path);
cfgVal = (pcfgValue)rtGetByPath(__hCfg->tree, nodeID);
while (rpoolChunkSize(__hCfg->pool, cfgVal->name) != len ||
rpoolCompareExternal(__hCfg->pool, cfgVal->name, (void*)path, len))
{
nodeID = rtBrother(__hCfg->tree, nodeID);
if (nodeID < 0)
return ERR_CI_NOTFOUND;
cfgVal = (pcfgValue)rtGetByPath(__hCfg->tree, nodeID);
}
if (!dot)
break;
nodeID = rtHead(__hCfg->tree, nodeID);
if (nodeID < 0)
return ERR_CI_NOTFOUND;
path = dot + 1;
}
return nodeID;
}
RVAPI
ci_errors RVCALLCONV ciGetValue(
IN HCFG hCfg,
IN const char * path, /* full path to nodeID, i.e. "a.b.c" */
OUT RvBool* isString,
OUT RvInt32 * value /* data for ints, length for strings */
)
{
ci_str_type strtype = ci_str_not;
ci_errors err;
/* No need to lock this function... */
err = ciGetValueExt(hCfg, path, &strtype, value);
if (isString) *isString = (strtype != ci_str_not);
return err;
}
RVAPI
ci_errors RVCALLCONV ciGetValueExt(
IN HCFG hCfg,
IN const char *path, /* full path to nodeID, i.e. "a.b.c" */
OUT ci_str_type *strType,
OUT RvInt32 * value /* data for ints, length for strings */
)
{
cfgHandle* cfg = (cfgHandle *)hCfg;
int bits, nodeID;
pcfgValue cfgVal;
ci_str_type dummy;
if (hCfg == NULL)
return ERR_CI_GENERALERROR;
RvMutexLock(&cfg->mutex);
nodeID = ciGetNodeID(hCfg, (char *)path);
if (nodeID < 0)
{
RvMutexUnlock(&cfg->mutex);
return (ci_errors)nodeID;
}
cfgVal = (pcfgValue)rtGetByPath(cfg->tree, nodeID);
if (value) *value = cfgVal->value;
if (!strType) strType = &dummy;
if (cfgVal->isString)
{
char buff[MAX_CONFIG_TEMP_BUFFER_SIZE];
rpoolCopyToExternal(cfg->pool, (void *)buff, cfgVal->str, 0, MAX_CONFIG_TEMP_BUFFER_SIZE);
if ((bits = ciIsBitString(buff, cfgVal->value)) >= 0)
{
*strType = ci_str_bit;
if (value) *value = (bits + 7) / 8;
}
else
{
*strType = ci_str_regular;
}
}
else
*strType = ci_str_not;
RvMutexUnlock(&cfg->mutex);
return ERR_CI_NOERROR;
}
static
ci_errors RVCALLCONV ciGetStringInternal(
IN HCFG hCfg,
IN const char * path, /* full path to nodeID, i.e. "a.b.c" */
OUT char * str,
IN RvUint32 maxStrLen, /* length of output string buffer */
OUT RvUint32 * outbits
)
{
int bits, nodeID = ciGetNodeID(hCfg, (char *)path);
RvSize_t length;
pcfgValue cfgVal;
const char *srcstr;
char buff[MAX_CONFIG_TEMP_BUFFER_SIZE];
if (nodeID < 0)
return (ci_errors)nodeID;
cfgVal = (pcfgValue)rtGetByPath(__hCfg->tree, nodeID);
if (!cfgVal->isString)
return ERR_CI_GENERALERROR;
rpoolCopyToExternal(__hCfg->pool, (void *)buff, cfgVal->str, 0, MAX_CONFIG_TEMP_BUFFER_SIZE);
if ((bits = ciIsBitString(buff, cfgVal->value)) >= 0)
{
length = (bits + 7) / 8;
srcstr = ciGetBitStringData(buff);
}
else
{
length = cfgVal->value;
srcstr = buff;
}
if (maxStrLen < ((RvUint32)length))
return ERR_CI_BUFFERTOOSMALL;
memcpy(str, srcstr, length);
if (maxStrLen > ((RvUint32)length))
str[(int)length] = '\0';
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -