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

📄 oidutils.c

📁 基于h323协议的软phone
💻 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.

*/

#ifdef __cplusplus
extern "C" {
#endif

#include "rvstdio.h"
#include "rvtypes.h"
#include "rverror.h"
#include "oidutils.h"

char* node[]={(char*)"itu-t",(char*)"iso",(char*)"joint-iso-itu-t",(char*)"ccitt", (char*)"joint-iso-ccitt",(char*)NULL};
char* node0[]={(char*)"recommendation",(char*)"question",(char*)"administration",
        (char*)"network-operator",(char*)"identified-organization",(char*)NULL};
char* node1[]={(char*)"standard",(char*)"1",(char*)"member-body",(char*)"identified-organization",(char*)NULL};
char* series[]={(char*)"",(char*)"a",(char*)"b",(char*)"c",(char*)"d",(char*)"e",(char*)"f",(char*)"g",(char*)"h",
        (char*)"i",(char*)"j",(char*)"k",(char*)"l",(char*)"m",(char*)"n",(char*)"o",(char*)"p",(char*)"q",
        (char*)"r",(char*)"s",(char*)"t",(char*)"u",(char*)"v",(char*)"w",(char*)"x",(char*)"y",(char*)"z",
        (char*)NULL};


char** nodes[]={node0,node1,NULL};

static int findName(char** names,char* name, RvSize_t nameSize)
{
    RvSize_t curNameLen;
    int i=0;
    while(names[i])
    {
        curNameLen = strlen(names[i]);
        if ((nameSize == curNameLen) && !strncmp(names[i], name, nameSize))
            return i;
    i++;
    }
    return RV_ERROR_UNKNOWN;
}

static
void eatWhiteSpaces(char**startPtr)
{
    while(isspace((int)**startPtr))
        (*startPtr)++;
}

RvBool isNonFirstNameChar(char c)
{
    return isalnum((int)c) || c=='-';
}

static
void eatName(char**startPtr)
{
    while(isNonFirstNameChar(**startPtr))
        (*startPtr)++;
}

static
int eatNumber(char**startPtr)
{
    int number=0;
    while(isdigit((int)**startPtr))
        number=number*10+(*((*startPtr)++)-'0');
    return number;
}

static
int addComp(int* buffSize,RvUint8** buff,unsigned number)
{
    int bytes=0;
    int i;
    char c;
    for (i=0;i<5;i++)
    {
        c=(RvUint8)(number>>(i?25:28));
        if (*buff)
            **buff=c;
        number<<=(i?7:4);
        if (c||bytes||i==4)
        {
            if (*buff)
            {
                if (*buffSize <= 0)
                    return -1;
                if (i!=4)
                    **buff+= (RvUint8)0x80;
                (*buff)++;
            }
            (*buffSize)--;
            bytes++;
        }
    }
    return bytes;
}

/* == oidEncodeOID ==

   oidSize  size of target oid buffer
   oid      target oid buffer, or null
   buff     buffer of string data to encode

   Returns the size of the output string or -1 if there was not enough space.
   If (oid==NULL), the function doesn't write it's output to the oid buffer,
   but the size of the output string is still returned for valid inputs.
   oidSize is ignored in this case.
*/
int oidEncodeOID(
    IN  int         oidSize,
    OUT char        *oid,
    IN  const char  *buff)
{
    char *startPtr=(char*)buff;
    int size =oidSize;
    int number;
    int compNum=1;
    int comps[2];

    if (oid == NULL)
        oidSize = 0;

    eatWhiteSpaces(&startPtr);
    while(*startPtr && *startPtr!='}')
    {
        char *nexttoken;
        if (isalpha((int)*startPtr))
        {
            char*stopPtr;
            nexttoken=startPtr+1;
            eatName(&nexttoken);
            stopPtr=nexttoken;
            eatWhiteSpaces(&nexttoken);
            if (*nexttoken=='(') /*NameAndNumberForm*/
            {
                nexttoken++;
                eatWhiteSpaces(&nexttoken);
                number=eatNumber(&nexttoken);
                eatWhiteSpaces(&nexttoken);
                if (*nexttoken==')')  nexttoken++;
            }
            else /*NameForm*/
            {
                if (compNum==3 && !comps[0] && !comps[1])
                    number=findName(series,startPtr, (RvSize_t)(stopPtr-startPtr));
                else
                    number=findName((compNum>1)?nodes[comps[0]]:node, startPtr, (RvSize_t)(stopPtr-startPtr));
                if (compNum==1) number%=3;
            }
        }
        else if (isdigit((int)*startPtr)) /*NumberForm*/
        {
            nexttoken=startPtr;
            eatWhiteSpaces(&nexttoken);
            number=eatNumber(&nexttoken);
        }
/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
        else if (*startPtr == '(')
        {
            nexttoken=++startPtr;
            eatWhiteSpaces(&nexttoken);
            number=eatNumber(&nexttoken);
            eatWhiteSpaces(&nexttoken);
            if (*nexttoken != ')')
                return -1;
            nexttoken++;
        }
        else
            return -1;

        if (compNum<3) comps[compNum-1]=number;
        if (compNum==2)
        {
            number=comps[0]*40+comps[1];
        }

        if (compNum>=2)
            if (addComp(&oidSize, (RvUint8**)&oid, (unsigned) number) < 0)
                return -1;
        compNum++;
        startPtr=nexttoken;
        eatWhiteSpaces(&startPtr);
    }
    return size-oidSize;
}

int getComp(int *oidSize, unsigned char** oid)
{
    int number=0;
    do
    {
        number<<=7;
        number+=(**oid)&0x7f;
    --(*oidSize);
    }
    while(*oidSize && *((*oid)++)>=0x80);
    return number;
}

#define IF_SPACE_OK(checklen)                   \
{                                               \
    addlen = (checklen);                        \
    if (*buff)                                  \
    {                                           \
        (*buffSize) -= addlen;                  \
        if (*buffSize > 0)

#define END_IF_SPACE                            \
    }                                           \
    len += addlen;                              \
}


int putComp(int* buffSize, char**buff, int num, int compNum, char**nodes,form f)
{
    char nBuf[10];
    int i=9, len = 0, addlen;
    int saveNum=num;
    nBuf[9]=0;
    if(compNum);

    if (nodes && nodes[saveNum] && f!=numberForm)
    {
        IF_SPACE_OK(strlen(nodes[saveNum]) + (f!=nameForm))
        {
            strcpy(*buff,nodes[saveNum]);
            *buff+=strlen(nodes[saveNum]);
            if (f!=nameForm)
                *((*buff)++)='(';
        }
        END_IF_SPACE;
    }

    do
    {
        nBuf[--i]=(char)((num%10)+'0');
        num/=10;
    }
    while(num);

    if (f != nameForm  ||  !(nodes  &&  nodes[saveNum]))
    {
        IF_SPACE_OK(9 - i);
        {
            memcpy(*buff, nBuf+i, (RvSize_t)(10-i));
            *buff+=(9-i);
        }
        END_IF_SPACE;
    }

    if (nodes && nodes[saveNum] && f==nameAndNumberForm)
    {
        IF_SPACE_OK(1)
        {
            *((*buff)++)=')';
        }
        END_IF_SPACE;
    }

    IF_SPACE_OK(1)
    {
        *((*buff)++)=' ';
    }
    END_IF_SPACE;

    return len;
}

/* == oidEncodeOID ==

   oidSize  size of source oid buffer
   oid      source oid buffer
   buffSize size of target buffer
   buff     target buffer for decoded oid
   form     the format for the decoded oid

   Returns the size of the output string or -1 if there was not enough space.
   If (buff==NULL), the function doesn't write it's output to the buffer,
   but the size of the output string is still returned for valid inputs.
   buffSize is ignored in this case.
*/

int oidDecodeOID(int oidSize, char* oid, int buffSize, char *buff,form f)
{
    int compNum=2, num, root=0, len = 0;

    if (oidSize < 0)
    {
        if (buff != NULL)
            *buff = 0;
        return RV_ERROR_UNKNOWN;
    }

    while(oidSize)
    {
        num = getComp(&oidSize,(unsigned char **)&oid);

        if (compNum>2)
        {
            len += putComp(&buffSize, &buff, num, compNum,
                (!root && (compNum==3))? series : (char**)NULL,f);
        }
        else
        {
            root = num / 40;
            if (root > 2)
            {
                /* joint-iso-itu-t may have more than 40 sub-arcs */
                root = 2;
                num -= 80;
            }
            else
            {
                num %= 40; /* the second level has up to 40 arcs */
            }
            len += putComp(&buffSize, &buff, root, 1, node, f);
            len += putComp(&buffSize, &buff, num, 2, nodes[root], f);
        }
        compNum++;
    }

    if (buff != NULL)
        *buff = 0;

    return (buffSize >= 0)? len : buffSize;
}

RVAPI int RVCALLCONV
utlDecodeOIDInt(int oidSize, char* oid, int buffSize, int *buff)
{
    int compNum=2, num, root=0, len = 0;

    if (oidSize<0) return RV_ERROR_UNKNOWN;

    while(oidSize || buffSize>len)
    {
        num = getComp(&oidSize,(unsigned char **)&oid);

        if (compNum>2)
        {
            if (buffSize!=len) buff[len++]=num;
        }
        else
        {
            root = num / 40;
            if (root > 2)
            {
                /* joint-iso-itu-t may have more than 40 sub-arcs */
                root = 2;
                num -= 80;
            }
            else
            {
                num %= 40; /* the second level has up to 40 arcs */
            }

            if (buffSize!=len) buff[len++]=root;
            if (buffSize!=len) buff[len++]=num;
        }
        compNum++;
    }
    return len;
}

#ifdef __cplusplus
}
#endif



⌨️ 快捷键说明

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