📄 asnper.cxx
字号:
}
void PPER_Stream::SequencePreambleEncode(const PASN_Sequence & seq)
{
seq.PreambleEncodePER(*this);
}
BOOL PPER_Stream::SequenceKnownDecode(PASN_Sequence & seq, PINDEX fld, PASN_Object & field)
{
return seq.KnownExtensionDecodePER(*this, fld, field);
}
void PPER_Stream::SequenceKnownEncode(const PASN_Sequence & seq, PINDEX fld, const PASN_Object & field)
{
seq.KnownExtensionEncodePER(*this, fld, field);
}
BOOL PPER_Stream::SequenceUnknownDecode(PASN_Sequence & seq)
{
return seq.UnknownExtensionsDecodePER(*this);
}
void PPER_Stream::SequenceUnknownEncode(const PASN_Sequence & seq)
{
seq.UnknownExtensionsEncodePER(*this);
}
///////////////////////////////////////////////////////////////////////
BOOL PPER_Stream::ArrayDecode(PASN_Array & array)
{
array.RemoveAll();
unsigned size;
if (!array.ConstrainedLengthDecode(*this, size))
return FALSE;
if (!array.SetSize(size))
return FALSE;
for (PINDEX i = 0; i < (PINDEX)size; i++) {
if (!array[i].Decode(*this))
return FALSE;
}
return TRUE;
}
void PPER_Stream::ArrayEncode(const PASN_Array & array)
{
PINDEX size = array.GetSize();
array.ConstrainedLengthEncode(*this, size);
for (PINDEX i = 0; i < size; i++)
array[i].Encode(*this);
}
///////////////////////////////////////////////////////////////////////
PPER_Stream::PPER_Stream(BOOL alignment)
{
aligned = alignment;
}
PPER_Stream::PPER_Stream(const PBYTEArray & bytes, BOOL alignment)
: PASN_Stream(bytes)
{
aligned = alignment;
}
PPER_Stream::PPER_Stream(const BYTE * buf, PINDEX size, BOOL alignment)
: PASN_Stream(buf, size)
{
aligned = alignment;
}
PPER_Stream & PPER_Stream::operator=(const PBYTEArray & bytes)
{
PBYTEArray::operator=(bytes);
ResetDecoder();
aligned = TRUE;
return *this;
}
unsigned PPER_Stream::GetBitsLeft() const
{
return (GetSize() - byteOffset)*8 - (8 - bitOffset);
}
BOOL PPER_Stream::Read(PChannel & chan)
{
ResetDecoder();
SetSize(0);
// Get RFC1006 TPKT length
BYTE tpkt[4];
if (!chan.ReadBlock(tpkt, sizeof(tpkt)))
return FALSE;
if (tpkt[0] != 3) // Only support version 3
return TRUE;
PINDEX data_len = ((tpkt[2] << 8)|tpkt[3]) - 4;
return chan.ReadBlock(GetPointer(data_len), data_len);
}
BOOL PPER_Stream::Write(PChannel & chan)
{
CompleteEncoding();
PINDEX size = GetSize();
// Put RFC1006 TPKT length
BYTE tpkt[4];
tpkt[0] = 3; // Version 3
tpkt[1] = 0;
PINDEX len = size + sizeof(tpkt);
tpkt[2] = (BYTE)(len >> 8);
tpkt[3] = (BYTE)len;
return chan.Write(tpkt, sizeof(tpkt)) && chan.Write(theArray, size);
}
BOOL PPER_Stream::SingleBitDecode()
{
if (!CheckByteOffset(byteOffset) || ((GetSize() - byteOffset)*8 - (8 - bitOffset) == 0))
return FALSE;
bitOffset--;
BOOL value = (theArray[byteOffset] & (1 << bitOffset)) != 0;
if (bitOffset == 0) {
bitOffset = 8;
byteOffset++;
}
return value;
}
void PPER_Stream::SingleBitEncode(BOOL value)
{
if (!CheckByteOffset(byteOffset))
return;
if (byteOffset >= GetSize())
SetSize(byteOffset+10);
bitOffset--;
if (value)
theArray[byteOffset] |= 1 << bitOffset;
if (bitOffset == 0)
ByteAlign();
}
BOOL PPER_Stream::MultiBitDecode(unsigned nBits, unsigned & value)
{
if (nBits > sizeof(value)*8)
return FALSE;
unsigned bitsLeft = (GetSize() - byteOffset)*8 - (8 - bitOffset);
if (nBits > bitsLeft)
return FALSE;
if (nBits == 0) {
value = 0;
return TRUE;
}
if (!CheckByteOffset(byteOffset))
return FALSE;
if (nBits < bitOffset) {
bitOffset -= nBits;
value = (theArray[byteOffset] >> bitOffset) & ((1 << nBits) - 1);
return TRUE;
}
value = theArray[byteOffset] & ((1 << bitOffset) - 1);
nBits -= bitOffset;
bitOffset = 8;
byteOffset++;
while (nBits >= 8) {
value = (value << 8) | (BYTE)theArray[byteOffset];
byteOffset++;
nBits -= 8;
}
if (nBits > 0) {
bitOffset = 8 - nBits;
value = (value << nBits) | ((BYTE)theArray[byteOffset] >> bitOffset);
}
return TRUE;
}
void PPER_Stream::MultiBitEncode(unsigned value, unsigned nBits)
{
PAssert(byteOffset != P_MAX_INDEX, PLogicError);
if (nBits == 0)
return;
if (byteOffset+nBits/8+1 >= (unsigned)GetSize())
SetSize(byteOffset+10);
// Make sure value is in bounds of bit available.
if (nBits < sizeof(int)*8)
value &= ((1 << nBits) - 1);
if (!CheckByteOffset(byteOffset))
return;
if (nBits < bitOffset) {
bitOffset -= nBits;
theArray[byteOffset] |= value << bitOffset;
return;
}
nBits -= bitOffset;
theArray[byteOffset] |= (BYTE)(value >> nBits);
bitOffset = 8;
byteOffset++;
while (nBits >= 8) {
nBits -= 8;
theArray[byteOffset] = (BYTE)(value >> nBits);
byteOffset++;
}
if (nBits > 0) {
bitOffset = 8 - nBits;
theArray[byteOffset] |= (BYTE)((value & ((1 << nBits)-1)) << bitOffset);
}
}
BOOL PPER_Stream::SmallUnsignedDecode(unsigned & value)
{
// X.691 Section 10.6
if (!SingleBitDecode())
return MultiBitDecode(6, value); // 10.6.1
unsigned len;
if (!LengthDecode(0, INT_MAX, len)) // 10.6.2
return FALSE;
ByteAlign();
return MultiBitDecode(len*8, value);
}
void PPER_Stream::SmallUnsignedEncode(unsigned value)
{
if (value < 64) {
MultiBitEncode(value, 7);
return;
}
SingleBitEncode(1); // 10.6.2
PINDEX len = 4;
if (value < 256)
len = 1;
else if (value < 65536)
len = 2;
else if (value < 0x1000000)
len = 3;
LengthEncode(len, 0, INT_MAX); // 10.9
ByteAlign();
MultiBitEncode(value, len*8);
}
BOOL PPER_Stream::UnsignedDecode(unsigned lower, unsigned upper, unsigned & value)
{
// X.691 section 10.5
if (lower == upper) { // 10.5.4
value = lower;
return TRUE;
}
if (IsAtEnd())
return FALSE;
unsigned range = (upper - lower) + 1;
unsigned nBits = CountBits(range);
if (aligned && (range == 0 || range > 255)) { // not 10.5.6 and not 10.5.7.1
if (nBits > 16) { // not 10.5.7.4
if (!LengthDecode(1, (nBits+7)/8, nBits)) // 12.2.6
return FALSE;
nBits *= 8;
}
else if (nBits > 8) // not 10.5.7.2
nBits = 16; // 10.5.7.3
ByteAlign(); // 10.7.5.2 - 10.7.5.4
}
if (!MultiBitDecode(nBits, value))
return FALSE;
value += lower;
// clamp value to upper limit
if (value > upper)
value = upper;
return TRUE;
}
void PPER_Stream::UnsignedEncode(int value, unsigned lower, unsigned upper)
{
// X.691 section 10.5
if (lower == upper) // 10.5.4
return;
unsigned range = (upper - lower) + 1;
PINDEX nBits = CountBits(range);
if ((unsigned)value < lower)
value = 0;
else
value -= lower;
if (aligned && (range == 0 || range > 255)) { // not 10.5.6 and not 10.5.7.1
if (nBits > 16) { // not 10.5.7.4
int numBytes = value == 0 ? 1 : (((CountBits(value + 1))+7)/8);
LengthEncode(numBytes, 1, (nBits+7)/8); // 12.2.6
nBits = numBytes*8;
}
else if (nBits > 8) // not 10.5.7.2
nBits = 16; // 10.5.7.3
ByteAlign(); // 10.7.5.2 - 10.7.5.4
}
MultiBitEncode(value, nBits);
}
BOOL PPER_Stream::LengthDecode(unsigned lower, unsigned upper, unsigned & len)
{
// X.691 section 10.9
if (upper != INT_MAX && !aligned) {
if (upper - lower > 0xffff)
return FALSE; // 10.9.4.2 unsupported
unsigned base;
if (!MultiBitDecode(CountBits(upper - lower + 1), base))
return FALSE;
len = lower + base; // 10.9.4.1
// clamp value to upper limit
if (len > upper)
len = upper;
return TRUE;
}
if (upper < 65536) // 10.9.3.3
return UnsignedDecode(lower, upper, len);
// 10.9.3.5
ByteAlign();
if (IsAtEnd())
return FALSE;
if (SingleBitDecode() == 0) {
if (!MultiBitDecode(7, len)) // 10.9.3.6
return FALSE; // 10.9.3.8 unsupported
}
else if (SingleBitDecode() == 0) {
if (!MultiBitDecode(14, len)) // 10.9.3.7
return FALSE; // 10.9.3.8 unsupported
}
// clamp value to upper limit
if (len > upper)
len = upper;
return TRUE;
}
void PPER_Stream::LengthEncode(unsigned len, unsigned lower, unsigned upper)
{
// X.691 section 10.9
if (upper != INT_MAX && !aligned) {
PAssert(upper - lower < 0x10000, PUnimplementedFunction); // 10.9.4.2 unsupperted
MultiBitEncode(len - lower, CountBits(upper - lower + 1)); // 10.9.4.1
return;
}
if (upper < 65536) { // 10.9.3.3
UnsignedEncode(len, lower, upper);
return;
}
ByteAlign();
if (len < 128) {
MultiBitEncode(len, 8); // 10.9.3.6
return;
}
SingleBitEncode(TRUE);
if (len < 0x4000) {
MultiBitEncode(len, 15); // 10.9.3.7
return;
}
SingleBitEncode(TRUE);
PAssertAlways(PUnimplementedFunction); // 10.9.3.8 unsupported
}
void PPER_Stream::AnyTypeEncode(const PASN_Object * value)
{
PPER_Stream substream;
if (value != NULL)
value->Encode(substream);
substream.CompleteEncoding();
PINDEX nBytes = substream.GetSize();
if (nBytes == 0) {
const BYTE null[1] = { 0 };
nBytes = sizeof(null);
substream = PBYTEArray(null, nBytes, FALSE);
}
LengthEncode(nBytes, 0, INT_MAX);
BlockEncode(substream.GetPointer(), nBytes);
}
///////////////////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -