📄 persimpl.c
字号:
"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 + -