📄 persimpl.c
字号:
/*
clause '10.6'
*/
int
perEncodeNormallySmallInt(IN RvUint32 n, /* the number */
OUT HBB bbH)
{
RvUint8 octets[32]; /* space for tmp encoding */
RvUint32 length=0;
RvInt32 offset;
HBB tmpBB; /* for length encoding */
RvInt32 tmpBBlen;
if (n <= 63)
{
/* 10.6.1 */
perEncodeInt(0, 0, 1, RV_FALSE, RV_FALSE, RV_FALSE, bbH);
return perEncodeInt(n, 0, 63, RV_FALSE, RV_FALSE, RV_FALSE, bbH);
}
/* 10.6.2: ... | 1 | length | n | */
#ifdef RV_CODER_DEBUG
if (bbGetAllocationSize(10) > (int)sizeof(octets))
{
RvLogExcep(&rvPerErrLogSource, (&rvPerErrLogSource,
"perEncodeNormallySmallInt: Allocation space for length not enough [%d].",
bbGetAllocationSize(10)));
return RV_ERROR_UNKNOWN;
}
#endif /* RV_CODER_DEBUG */
tmpBB = bbConstructFrom(10, (RvInt8 *)octets, 32);
perEncodeInt(1, 0, 1, RV_FALSE, RV_FALSE, RV_FALSE, bbH);
offset = bbBitsInUse(bbH);
perEncodeSemiConstInt(n, 0, bbH, &length);
if (perEncodeLen(perLenTypeNORMALLY_SMALL, length, 0, 0, tmpBB) <0)
{
RvLogError(&rvPerErrLogSource, (&rvPerErrLogSource,
"perEncodeNormallySmallInt: length encoding failed for '%d'.", length));
return RV_ERROR_UNKNOWN;
}
tmpBBlen = bbBitsInUse(tmpBB);
if (bbMove(bbH, offset, length, offset + tmpBBlen) < 0)
return RV_ERROR_UNKNOWN;
if (bbSet(bbH, offset, tmpBBlen, bbOctets(tmpBB)) <0)
{
RvLogError(&rvPerErrLogSource, (&rvPerErrLogSource,
"perEncodeNormallySmallInt: set failed for '%d'.", length));
return RV_ERROR_UNKNOWN;
}
return RV_TRUE;
}
int
perDecodeNormallySmallInt(OUT RvUint32 *n, /* the number */
IN HPER hPer,
IN RvUint32 from,
OUT RvUint32 *dec)
{
RvBool boola = RV_FALSE;
RvUint32 myDec = RV_FALSE;
RvUint32 length;
int ret = RV_TRUE;
perDecodeBool(&boola, hPer, from, &myDec);
*dec = myDec;
if (boola == RV_FALSE)
{
/* 10.6.1 */
ret = perDecodeInt(n, 0, 63, RV_FALSE, RV_FALSE, RV_FALSE, hPer, from + myDec, &myDec, (char*)"normally small int");
*dec += myDec;
return ret;
}
/* 10.6.2 */
ret = perDecodeLen(perLenTypeNORMALLY_SMALL, &length, 0, 0, hPer, from, &myDec);
if (ret >= 0)
{
*dec += myDec;
ret = perDecodeSemiConstInt(n, 0, (RvInt32)length, hPer, from + (*dec), &myDec);
*dec += myDec;
}
return ret;
}
/*___________________________________________________________________________*/
/*________________________________Length_____________________________________*/
/*___________________________________________________________________________*/
/*
Desc: Encodes length and puts it in the TAIL of bit buffer.
Returns: Failure if cannnot encode n.
Note: clause 10.9
as CONSTRAINED: ub <= 64K.
as UNCONSTRAINED: n < 16K.
*/
int
perEncodeLen(IN perLenType type, /* CONSTRAINED, NORMALLY_SMALL, UNCONSTRAINED */
IN RvUint32 n, /* the length */
IN RvUint32 lb, /* only for constrained type */
IN RvUint32 ub, /* only for constrained type */
OUT HBB bbH) /* Should be initialized with sufficient size.
It has to have at least 4 bytes size. */
{
if (bbFreeBytes(bbH) <MAX_INT_SIZE)
{
RvLogExcep(&rvPerErrLogSource, (&rvPerErrLogSource,
"per:EncodeLen: Buffer allocation error."));
return RV_ERROR_UNKNOWN; /* Buffer allocation error */
}
if (type == perLenTypeCONSTRAINED && ub < K64) /* 10.9.3.3 */
return perEncodeInt(n, lb, ub, RV_FALSE, RV_FALSE, RV_FALSE, bbH);
if (type == perLenTypeNORMALLY_SMALL) /* 10.9.3.4 extension addition bitmap length of set or sequence type */
{
if (n <= 64)
{
perEncodeInt(0, 0, 1, RV_FALSE, RV_FALSE, RV_FALSE, bbH);
return perEncodeInt(n - 1, 0, 63, RV_FALSE, RV_FALSE, RV_FALSE, bbH);
}
else
perEncodeInt(1, 0, 1, RV_FALSE, RV_FALSE, RV_FALSE, bbH);
}
/* unconstrained length 10.9.3.5 */
lb = 0;
if (n <= 127) /* 10.9.3.6 */
return perEncodeInt(n, 0, 255, RV_FALSE, RV_FALSE, RV_FALSE, bbH); /* 1 octet aligned. 10.5.7.2 */
if (n < 16384) /* 10.9.3.7 */
return perEncodeInt(n + 0x8000, 0, (RvUint32)(K64 - 1), RV_FALSE, RV_FALSE, RV_FALSE, bbH); /* 2 octet aligned */
/* fragmentation procedure */
if (n >= 16384)
{
RvLogExcep(&rvPerErrLogSource, (&rvPerErrLogSource,
"perEncodeLen: fragmentation procedure not available [%d]", n));
}
/* not reached */
return RV_ERROR_UNKNOWN;
}
/*
Desc: Dencodes length from the bit buffer.(at position).
Returns: RV_ERROR_UNKNOWN or RV_TRUE.
Note: clause 10.9
*/
int
perDecodeLen(IN perLenType type, /* CONSTRAINED, NORMALLY_SMALL, UNCONSTRAINED */
OUT RvUint32 *n, /* the length */
IN RvUint32 lb,
IN RvUint32 ub,
OUT HPER hPer,
IN RvUint32 from, /* position in buffer */
OUT RvUint32 *decoded)
{
RvInt32 num;
int ret;
RvUint32 flag;
RvUint32 dec = 0;
if (!n || !decoded)
{
RvLogExcep(&rvPerErrLogSource, (&rvPerErrLogSource,
"per:DecodeLen: parameters (n,del) not allocated."));
return RV_ERROR_UNKNOWN;
}
*n = 0;
*decoded = 0;
if (type == perLenTypeCONSTRAINED && ub < K64) /* 10.9.3.3 */
{
return perDecodeInt(n, lb, ub, RV_FALSE, RV_FALSE, RV_FALSE, hPer, from, decoded, (char*)"constrained length");
}
if (type == perLenTypeNORMALLY_SMALL)
{
ret = perDecodeInt(&flag, 0, 1, RV_FALSE, RV_FALSE, RV_FALSE, hPer, from, &dec, (char*)"normally small length (1st bit)");
*decoded += dec;
from += dec;
if (ret < 0)
return ret; /* error decoding int. */
if (!flag)
{
/* 10.9.3.4: n <= 64 */
ret = perDecodeInt(n, 0, 63, RV_FALSE, RV_FALSE, RV_FALSE, hPer, from, &dec, (char*)"normally small length");
*decoded += dec;
from += dec;
(*n)++;
return ret;
}
}
/* unconstrained length 10.9.3.5 */
ret = perDecodeInt(&flag, 0, 255, RV_FALSE, RV_FALSE, RV_FALSE, hPer, from, &dec, (char*)"unconstrained length (1st byte)"); /* decode 1 aligned octet */
*decoded += dec;
from += dec;
if (ret < 0)
return ret;
if (!(flag & 1 << 7))
{
/* 1st bit =0 ==> 1 octet aligned. 10.5.7.2 */
*n = flag;
return RV_TRUE;
}
if (!(flag & 1 << 6))
{
/* bits = 10 ==> 10.9.3.7: n < 16384 */
num = flag & ~(1 << 7);
num = num << 8;
ret = perDecodeInt(&flag, 0, 255, RV_FALSE, RV_FALSE, RV_FALSE, hPer, from, &dec, (char*)"unconstrained length (2 bytes)"); /* decode 1 aligned octet */
*decoded += dec;
from += dec;
*n = num + flag;
return RV_TRUE;
}
RvLogExcep(&rvPerErrLogSource, (&rvPerErrLogSource,
"perDecodeLen: fragmentation procedure not available [%d]", *n));
return RV_ERROR_UNKNOWN;
}
/*___________________________________________________________________________*/
/*________________________________Boolean____________________________________*/
/*___________________________________________________________________________*/
/*
Desc: Encodes boolean and puts it in the TAIL of bit buffer.
Returns: Failure if cannnot encode n.
Note: clause 11
*/
int
perEncodeBool(IN RvBool n,
OUT HBB bbH) /* Should be initialized with sufficient size.
It has to have at least 1 byte size. */
{
if (bbFreeBytes(bbH) < MAX_INT_SIZE)
{
RvLogExcep(&rvPerErrLogSource, (&rvPerErrLogSource,
"per:EncodeBool: Buffer allocation error."));
return RV_ERROR_UNKNOWN; /* Buffer allocation error */
}
if (n == RV_TRUE)
return perEncodeInt(1, 0, 1, RV_FALSE, RV_FALSE, RV_FALSE, bbH);
if (n == RV_FALSE)
return perEncodeInt(0, 0, 1, RV_FALSE, RV_FALSE, RV_FALSE, bbH);
RvLogError(&rvPerErrLogSource, (&rvPerErrLogSource,
"perEncodeBool: Illegal value %d", n));
return RV_ERROR_UNKNOWN;
}
/*
Desc: Decodes boolean from buffer(at position).
Returns: RV_ERROR_UNKNOWN or positive number.
Note: clause 10.9
Note: clause 11
*/
int
perDecodeBool(OUT RvBool *n,
IN HPER hPer,
IN RvUint32 from,
OUT RvUint32 *decoded)
{
RvUint32 num;
int ret;
if (!n)
return RV_ERROR_UNKNOWN;
ret = perDecodeInt(&num, 0, 1, RV_FALSE, RV_FALSE, RV_FALSE, hPer, from, decoded, (char*)"boolean");
if (num)
*n = RV_TRUE;
else
*n = RV_FALSE;
return ret;
}
/*___________________________________________________________________________*/
/*________________________________NULL_______________________________________*/
/*___________________________________________________________________________*/
int
perEncodeNull(HBB bbH)
{
if (bbH)
;
return RV_TRUE;
}
int
perDecodeNull(HBB bbH)
{
if (bbH)
;
return RV_TRUE;
}
#ifdef __cplusplus
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -