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

📄 ci.c

📁 基于h323协议的软phone
💻 C
📖 第 1 页 / 共 2 页
字号:
/*

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 + -