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

📄 persimpl.c

📁 基于h323协议的软phone
💻 C
📖 第 1 页 / 共 3 页
字号:
            "per:DecodeInt:%s: Buffer allocation error.", nprn(desc)));
        return RV_ERROR_UNKNOWN; /* Buffer allocation error */
    }

    if (isExtension)
    {
        perDecodeBool(&isExtended, hPer, from, decoded); /* decoding extension bit. Sergey M. */
        myFrom += *decoded;
    }

    /* Unconstrained or Semiconstrained INTEGER. Sergey M. */
    if (isToAbsent !=  RV_FALSE || isExtended)
    {
        perDecodeLen(perLenTypeUNCONSTRAINED, (RvUint32 *)&bytes, 0, 0, hPer, myFrom, &extract);
        bits = bytes*8; /* set # bits to extract */
        *decoded += extract;
        myFrom += extract;
        *decoded += bbAlignBits(per->hBB, (RvInt32)myFrom);
        myFrom += bbAlignBits(per->hBB, (RvInt32)myFrom); /* move to alignment */
        if (myFrom + bits > bbBitsInUse(per->hBB))
        {
            RvLogError(&rvPerErrLogSource, (&rvPerErrLogSource,
                "per:DecodeInt:%s: Integer too large to decode from buffer [len=%ld]",
                nprn(desc), bits));
            return RV_ERROR_UNKNOWN;
        }

        if (isFromAbsent !=  RV_FALSE || isExtended) /* Unconstrained INTEGER. Sergey M. */
        {
            if ((RvInt32)(extract = bbGet2Right(hPer, myFrom, bits, (RvUint8 *)(numOct + (MAX_INT_SIZE - bytes)))) <0)
            {
                RvLogError(&rvPerErrLogSource, (&rvPerErrLogSource,
                    "per:DecodeInt:%s: Extracting failed [%d]", nprn(desc), extract));
                return RV_ERROR_UNKNOWN;
            }

            num = numOct[3] +((RvUint32)numOct[2] << 8) +((RvUint32)numOct[1] << 16) +((RvUint32)numOct[0] << 24);
            /*num += lb; */

            *decoded += extract;

            *n = num;

            RvLogDebug(&rvPerLogSource, (&rvPerLogSource,
                " >> [%lu..%lu] (%lu:%lu) => %lu \t \t %s.",
                lb, ub, from, *decoded, *n, nprn(desc)));
            return RV_TRUE;
        }
        else /* Semiconstrained INTEGER. Sergey M. */
        {
            perDecodeSemiConstInt(n, (RvInt32)lb, (RvInt32)bytes, hPer, myFrom, &extract);
            *decoded += extract;
            RvLogDebug(&rvPerLogSource, (&rvPerLogSource,
                " >> [%lu....] (%lu:%lu) => %lu \t \t %s.",
                lb, from, *decoded, *n, nprn(desc)));
            return RV_TRUE;
        }
    } /* end of Unconstrainted or Semiconstrained INTEGER. Sergey M. */


    if (ub == lb) /* no encoding needed */
    {
        *n = lb;
        return RV_TRUE;
    }


    bits = perIntBits(range);
    bytes = bbSetByte(bits);
    if (bytes > MAX_INT_SIZE)
    {
        RvLogError(&rvPerErrLogSource, (&rvPerErrLogSource,
            "per:DecodeInt:%s: Number of bits in integer error [%ld]", nprn(desc), bits));
        return RV_ERROR_UNKNOWN;
    }

    if (bits > 16)
    {
        /* Extract length */
        /* 12.2.6a */
        perDecodeLen(perLenTypeCONSTRAINED, (RvUint32 *)&bytes, 1, bbSetByte(perIntBits(ub)), hPer, myFrom, &extract);
        if (bytes > MAX_INT_SIZE)
        {
            RvLogError(&rvPerErrLogSource, (&rvPerErrLogSource,
                "perDecodeInt:%s: Integer value too large to decode [%ld].", nprn(desc), bytes));
            return RV_ERROR_UNKNOWN;
        }
        bits = bytes*8; /* set # bits to extract */
        *decoded += extract;
        myFrom += extract;
    }

    if (range >= 256)
    {
        *decoded += bbAlignBits(per->hBB, (RvInt32)myFrom);
        myFrom += bbAlignBits(per->hBB, (RvInt32)myFrom); /* move to alignment */
    }

    if (myFrom + bits > bbBitsInUse(per->hBB))
    {
        RvLogError(&rvPerErrLogSource, (&rvPerErrLogSource,
            "per:DecodeInt:%s: Integer too large to decode from buffer [len=%ld]",
            nprn(desc), bits));
        return RV_ERROR_UNKNOWN;
    }

    if ((RvInt32)(extract = bbGet2Right(hPer, myFrom, bits, (RvUint8 *)(numOct + (MAX_INT_SIZE - bytes)))) <0)
    {
        RvLogError(&rvPerErrLogSource, (&rvPerErrLogSource,
            "per:DecodeInt:%s: Extracting failed [%d]", nprn(desc), extract));
        return RV_ERROR_UNKNOWN;
    }

    num = numOct[3] +((RvUint32)numOct[2] << 8) +((RvUint32)numOct[1] << 16) +((RvUint32)numOct[0] << 24);
    num += lb;

    if (num - lb > ub - lb)
    {
        RvLogError(&rvPerErrLogSource, (&rvPerErrLogSource,
            "per:DecodeInt:%s: Decoded number out of range [%ld]", nprn(desc), num));
        return RV_ERROR_UNKNOWN;
    }

    *decoded += extract;

    *n = num;

    RvLogDebug(&rvPerLogSource, (&rvPerLogSource,
        " >> [%lu..%lu] (%lu:%lu) => %lu \t \t %s.",
        lb, ub, from, *decoded, *n, nprn(desc)));
    return RV_TRUE;
}




/*___________________________________________________________________________*/
/*________________________Constraigned_non_negative_integer__________________*/
/*___________________________________________________________________________*/
/*
Desc: Encodes an integer into b bits and puts it in TAIL of bit buffer.
Returns: Failure if cannnot encode n.
Note: n <=2^32
*/
int
perEncodeNumber(IN  RvUint32 n,
                IN  RvUint32 b,  /* number of bits to hold the encoding */
                OUT HBB bbH) /* Should be initialized with sufficient size. */
{
    RvUint32 tmpNum;
    unsigned char numOct[MAX_INT_SIZE]; /*num converted to array in BIG ENDIAN*/

    if (b>MAX_INT_SIZE*8)
    {
        RvLogExcep(&rvPerErrLogSource, (&rvPerErrLogSource,
            "perDecodeNumber: Encoding not supported for %d bits.", b));
        return RV_ERROR_UNKNOWN;
    }

    if (!bbH || bbFreeBits(bbH) < (RvInt32)b)
    {
        RvLogExcep(&rvPerErrLogSource, (&rvPerErrLogSource,
            "perEncodeNumber: Buffer allocation error. [%d bits]", b));
        return RV_ERROR_UNKNOWN; /* Buffer allocation error */
    }

    /* Convert the number to 4 bytes in BIG ENDIAN order */
    tmpNum = n; /* 4 bytes integer */
    numOct[0] =(unsigned char)(tmpNum >> 24); /* n / 2^24 */
    tmpNum -= numOct[0] << 24;
    numOct[1] =(unsigned char)(tmpNum >> 16); /* n / 2^16 */
    tmpNum -= numOct[1] << 16;
    numOct[2] =(unsigned char)(tmpNum >> 8); /* n / 2^8 */
    tmpNum -= numOct[2] << 8;
    numOct[3] =(unsigned char)(tmpNum);

    return bbAddTailFrom(bbH, (RvUint8 *)numOct, MAX_INT_SIZE*8 - b, b, RV_FALSE);
}



/*
Desc: Decodes an integer from a bit buffer.
Returns: RV_ERROR_UNKNOWN ot RV_TRUE.
*/
int
perDecodeNumber(OUT RvUint32 *n, /* decoded number */
                IN  RvUint32 b,  /* number of bits to hold the encoding */
                IN  HPER hPer,
                IN  RvUint32 from, /* position in buffer */
                OUT RvUint32 *decoded)
{
    perStruct *per =(perStruct *)hPer;

    RvUint8 numOct[MAX_INT_SIZE]; /*num converted to array in BIG ENDIAN*/
    unsigned int bytes;

    memset((char *)numOct, 0, MAX_INT_SIZE);

    if (!n || !decoded)
    {
        RvLogExcep(&rvPerErrLogSource, (&rvPerErrLogSource,
            "perDecodeNumber: parameters (n,dec) not allocated."));
        return RV_ERROR_UNKNOWN;
    }
    *n = 0;
    *decoded = 0;

    if (b>MAX_INT_SIZE*8)
    {
        RvLogExcep(&rvPerErrLogSource, (&rvPerErrLogSource,
            "perDecodeNumber: Encoding not supported for %d bits.", b));
        return RV_ERROR_UNKNOWN;
    }

    if (!(per->hBB))
    {
        RvLogExcep(&rvPerErrLogSource, (&rvPerErrLogSource,
            "perDecodeNumber: Buffer allocation error."));
        return RV_ERROR_UNKNOWN; /* Buffer allocation error */
    }

    if (from + b > bbBitsInUse(per->hBB))
    {
        RvLogExcep(&rvPerErrLogSource, (&rvPerErrLogSource,
            "perDecodeNumber: Number too large to decode from buffer [len=%d]", b));
        return RV_ERROR_UNKNOWN;
    }

    bytes = bbSetByte(b);
    if ((RvUint32)bbGet2Right(hPer, from, b, (RvUint8 *)(numOct + (MAX_INT_SIZE - bytes))) !=b)
    {
        RvLogExcep(&rvPerErrLogSource, (&rvPerErrLogSource,
            "per:DecodeInt: Extracting failed [%d]", b));
        return RV_ERROR_UNKNOWN;
    }

    *n = numOct[3] +(numOct[2] << 8) +(numOct[1] << 16) +(numOct[0] << 24);
    *decoded = b;

    RvLogDebug(&rvPerLogSource, (&rvPerLogSource,
        " >> [%d] (%ld:%ld) => %d. \t \t number", b, from, *decoded, *n));
    return RV_TRUE;
}





/*___________________________________________________________________________*/
/*________________________________normally small_____________________________*/
/*___________________________________________________________________________*/


/*
clause '10.7'
*/
int
perEncodeSemiConstInt(IN  RvUint32 n, /* the number */
                      IN  RvInt32 lb,
                      OUT HBB bbH,
                      OUT RvUint32 *length)  /* in octets */
{
    RvUint32 num, tmpNum, len;
    unsigned char numOct[MAX_INT_SIZE]; /*num converted to array in BIG ENDIAN*/

    if ((RvUint32)lb >n)
        return RV_ERROR_UNKNOWN;
    num = n - lb; /* to be encoded */

    /* 10.3: octet - aligned - bit - field as non - negative - binary - integer. */

    /* Convert the number to 4 bytes in BIG ENDIAN order */
    tmpNum = num; /* 4 bytes integer */
    numOct[0] =(unsigned char)(tmpNum >> 24); /* n / 2^24 */
    tmpNum -= numOct[0] << 24;
    numOct[1] =(unsigned char)(tmpNum >> 16); /* n / 2^16 */
    tmpNum -= numOct[1] << 16;
    numOct[2] =(unsigned char)(tmpNum >> 8); /* n / 2^8 */
    tmpNum -= numOct[2] << 8;
    numOct[3] =(unsigned char)tmpNum;

    len = bbSetByte(num);
    if (len == 0)
        len = 1; /* at least 1 octet */
    if (length)
        *length = len;
    return bbAddTail(bbH, (RvUint8 *)(numOct + (MAX_INT_SIZE - len)), len*8, RV_TRUE);
}


int
perDecodeSemiConstInt(IN  RvUint32 *n,
                      IN  RvInt32 lb,
                      IN  RvInt32 length, /* in octets */
                      IN  HPER hPer,
                      IN  RvUint32 from,
                      OUT RvUint32 *dec)
{
    RvUint8 numOct[MAX_INT_SIZE]; /*num converted to array in BIG ENDIAN*/
    RvUint32 num;
    RvInt32 extract;

    if (length>MAX_INT_SIZE)
    {
        return RV_ERROR_UNKNOWN;
    }

    memset((char *)numOct, 0, MAX_INT_SIZE);

    if ((extract = bbGet2Right(hPer, from, length*8, (RvUint8 *)(numOct + (MAX_INT_SIZE - length)))) <0)
    {
        RvLogExcep(&rvPerErrLogSource, (&rvPerErrLogSource,
            "perDecodeSemiConstInt: Extracting failed [%d]", extract));
        return RV_ERROR_UNKNOWN;
    }

    num = numOct[3] +(numOct[2] << 8) +(numOct[1] << 16) +(numOct[0] << 24);
    num += lb;
    *n = num;
    *dec = extract;
    return RV_TRUE;
}




/*___________________________________________________________________________*/
/*________________________________normally small_____________________________*/
/*___________________________________________________________________________*/

⌨️ 快捷键说明

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