ci.c

来自「基于h323协议的软phone」· C语言 代码 · 共 642 行 · 第 1/2 页

C
642
字号
    if (outbits) *outbits = bits;

    return ERR_CI_NOERROR;
}

RVAPI
ci_errors RVCALLCONV ciGetString(
        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 */
        )
{
    ci_errors result;
    cfgHandle* cfg = (cfgHandle *)hCfg;

    if (hCfg == NULL)
        return ERR_CI_GENERALERROR;

    RvMutexLock(&cfg->mutex);
    result = ciGetStringInternal(hCfg, path, str, maxStrLen, NULL);
    RvMutexUnlock(&cfg->mutex);
    return result;
}

RVAPI
ci_errors RVCALLCONV ciGetBitString(
        IN  HCFG         hCfg,
        IN  const char * path,       /* full path to node, i.e. "a.b.c" */
        OUT char *       str,
        IN  RvUint32     maxStrLen,  /* length of output string buffer */
        OUT RvUint32 *   bits
        )
{
    ci_errors result;
    cfgHandle* cfg = (cfgHandle *)hCfg;

    if (hCfg == NULL)
        return ERR_CI_GENERALERROR;

    RvMutexLock(&cfg->mutex);
    result = ciGetStringInternal(hCfg, path, str, maxStrLen, bits);
    RvMutexUnlock(&cfg->mutex);
    return result;
}


RVAPI
ci_errors RVCALLCONV ciNext(
        IN   HCFG         hCfg,
        IN   const char * path,       /* full path to nodeID */
        OUT  char       * nextPath,   /* buffer for next path in cfg */
        IN   RvUint32     maxPathLen  /* length of output buffer */
        )
{
    cfgHandle* cfg = (cfgHandle *)hCfg;
    int len, firstTime = 1;
    int root;
    int nodeID;
    pcfgValue cfgVal;

    if (hCfg == NULL)
        return ERR_CI_GENERALERROR;

    RvMutexLock(&cfg->mutex);

    root = rtRoot(cfg->tree);
    nodeID = path ? ciGetNodeID(hCfg, path) : root;

    if (root < 0)
    {
        RvMutexUnlock(&cfg->mutex);
        return ERR_CI_GENERALERROR;
    }
    if (nodeID < 0)
    {
        RvMutexUnlock(&cfg->mutex);
        return ERR_CI_NOTFOUND;
    }

    do
    {
        nodeID = rtNext(cfg->tree, root, nodeID);
        if (nodeID < 0)
        {
            RvMutexUnlock(&cfg->mutex);
            return ERR_CI_NOTFOUND;
        }
    } while (rtParent(cfg->tree, nodeID) == root); /* skip first level */

    /* build full path */

    maxPathLen--;

    do
    {
        cfgVal = (pcfgValue)rtGetByPath(cfg->tree, nodeID);

        len = rpoolChunkSize(cfg->pool, cfgVal->name) + 1;
        if ((RvUint32)len > maxPathLen)
        {
            RvMutexUnlock(&cfg->mutex);
            return ERR_CI_BUFFERTOOSMALL;
        }

        if (firstTime)
        {
            rpoolCopyToExternal(cfg->pool, nextPath, cfgVal->name, 0, len);
            nextPath[len - 1] = '\0';
            firstTime = 0;
        }
        else
        {
            memmove(nextPath + len, nextPath, strlen(nextPath) + 1);
            rpoolCopyToExternal(cfg->pool, nextPath, cfgVal->name, 0, len);
            nextPath[len - 1] = '.';
        }

        maxPathLen -= len;
        nodeID = rtParent(cfg->tree, nodeID);
    } while (nodeID != root);

    RvMutexUnlock(&cfg->mutex);
    return ERR_CI_NOERROR;
}


RVAPI
ci_errors RVCALLCONV ciSetValue(
        IN  HCFG         hCfg,
        IN  const char * path,      /* full path to nodeID */
        IN  RvBool       isString,
        IN  RvInt32      value,     /* data for ints, length for strings */
        IN  const char * str        /* null for ints, data for strings */
        )
{
    cfgHandle* cfg = (cfgHandle *)hCfg;
    int nodeID, newNodeID;
    int len;
    RvChar* dot;
    cfgValue cfgVal;
    pcfgValue pCfgVal;

    if (hCfg == NULL)
        return ERR_CI_GENERALERROR;

    RvMutexLock(&cfg->mutex);

    nodeID = ciGetNodeID(hCfg, path);

    if (!path  ||  !path[0])
    {
        RvMutexUnlock(&cfg->mutex);
        return ERR_CI_GENERALERROR;
    }

    if (nodeID < 0)  /* no previous value, make a new node */
    {
        /* values for dummy nodes */
        cfgVal.isString  = RV_FALSE;
        cfgVal.value     = 0;
        cfgVal.str       = NULL;

        if ((nodeID = rtHead(cfg->tree, rtRoot(cfg->tree))) < 0)
        {
            /* a special case - an empty configuration */
            dot = (RvChar*) strchr(path, '.');
            len = dot? dot - path : strlen(path);

            cfgVal.name = rpoolAllocCopyExternal(cfg->pool, path, len);

            newNodeID = rtAddTail(cfg->tree, rtRoot(cfg->tree), &cfgVal);
            nodeID = newNodeID;
        }

        while (*path)
        {
            dot = (RvChar*) strchr(path, '.');
            len = dot? dot - path : strlen(path);
            pCfgVal = (pcfgValue)rtGetByPath(cfg->tree, nodeID);

            while (rpoolChunkSize(cfg->pool, pCfgVal->name) != len  ||
                   rpoolCompareExternal(cfg->pool, pCfgVal->name, (void*)path, len))
            {
                newNodeID = rtBrother(cfg->tree, nodeID);
                if (newNodeID < 0)
                {
                    cfgVal.name = rpoolAllocCopyExternal(cfg->pool, path, len);

                    newNodeID = rtAddBrother(cfg->tree, nodeID, &cfgVal);
                    nodeID = newNodeID;
                    break;
                }
                nodeID = newNodeID;
                pCfgVal = (pcfgValue)rtGetByPath(cfg->tree, nodeID);
            }

            newNodeID = rtHead(cfg->tree, nodeID);
            path = dot + 1;

            /* if not found, insert a dummy value */
            if (newNodeID < 0)
            {
                if (!dot)
                    break;

                dot = (RvChar*) strchr(path, '.');
                len = dot? dot - path : strlen(path);

                cfgVal.name = rpoolAllocCopyExternal(cfg->pool, path, len);

                newNodeID = rtAddTail(cfg->tree, nodeID, &cfgVal);
            }

            nodeID = newNodeID;

            if (!dot)
                break;
        }
    }

    pCfgVal = (pcfgValue)rtGetByPath(cfg->tree, nodeID);
    if (pCfgVal == NULL)
    {
        RvMutexUnlock(&cfg->mutex);
        return ERR_CI_GENERALERROR;
    }

    /* free, resize, or leave alone the old string buffer */
    if (pCfgVal->isString)
    {
        if (!isString)
        {
            rpoolFree(cfg->pool, pCfgVal->str);
            pCfgVal->str = NULL;
        }
        else
        {
            if (pCfgVal->value != value)
            {
                rpoolFree(cfg->pool, pCfgVal->str);
                pCfgVal->str = rpoolAlloc(cfg->pool, value);
            }
        }
    }
    else
    {
        if (isString)
        {
            pCfgVal->str = rpoolAlloc(cfg->pool, value);
        }
    }

    pCfgVal->isString  = isString;
    pCfgVal->value     = value;

    if (isString)
        rpoolCopyFromExternal(cfg->pool, pCfgVal->str, (void *)str, 0, value);

    RvMutexUnlock(&cfg->mutex);
    return ERR_CI_NOERROR;
}


RVAPI
ci_errors RVCALLCONV ciSetBitString(
        IN  HCFG         hCfg,
        IN  const char * path,       /* full path to node */
        IN  RvInt32      bits,       /* number of bits in the string */
        IN  const char * str         /* null for ints, data for strings */
        )
{
    char buf[1024];
    return
        ciSetValue(hCfg, path, RV_TRUE, ciBuildBitString(str, bits, buf), buf);
}


RVAPI
ci_errors RVCALLCONV ciDeleteValue(
        IN  HCFG         hCfg,
        IN  const char * path
        )
{
    cfgHandle* cfg = (cfgHandle *)hCfg;
    ci_errors result = ERR_CI_NOERROR;
    int nodeID;
    pcfgValue pCfgVal;

    if (hCfg == NULL)
        return ERR_CI_GENERALERROR;

    RvMutexLock(&cfg->mutex);

    nodeID = ciGetNodeID(hCfg, path);

    if (nodeID < 0)
          return ERR_CI_NOTFOUND;

    pCfgVal = (pcfgValue)rtGetByPath(cfg->tree, nodeID);
    if (pCfgVal && pCfgVal->str)
        rpoolFree(cfg->pool, pCfgVal->str);
    if (pCfgVal&& pCfgVal->name)
        rpoolFree(cfg->pool, pCfgVal->name);

    if (rtDelete(__hCfg->tree, nodeID, 0, 0) < 0)
        result = ERR_CI_GENERALERROR;

    RvMutexUnlock(&cfg->mutex);
    return result;
}


#ifdef __cplusplus
}
#endif




⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?