📄 asnper.cxx
字号:
// X.691 Section 22 delete choice; choice = NULL; if (strm.IsAtEnd()) return FALSE; if (extendable) { if (strm.SingleBitDecode()) { if (!strm.SmallUnsignedDecode(tag)) return FALSE; tag += numChoices; unsigned len; if (!strm.LengthDecode(0, INT_MAX, len)) return FALSE; BOOL ok; if (CreateObject()) { PINDEX nextPos = strm.GetPosition() + len; ok = choice->Decode(strm); strm.SetPosition(nextPos); } else { PASN_OctetString * open_type = new PASN_OctetString; open_type->SetConstraints(PASN_ConstrainedObject::FixedConstraint, len); ok = open_type->Decode(strm); if (open_type->GetSize() > 0) choice = open_type; else { delete open_type; ok = FALSE; } } return ok; } } if (numChoices < 2) tag = 0; else { if (!strm.UnsignedDecode(0, numChoices-1, tag)) return FALSE; } return CreateObject() && choice->Decode(strm);}void PASN_Choice::EncodePER(PPER_Stream & strm) const{ PAssert(CheckCreate(), PLogicError); if (extendable) { BOOL extended = tag >= numChoices; strm.SingleBitEncode(extended); if (extended) { strm.SmallUnsignedEncode(tag - numChoices); strm.AnyTypeEncode(choice); return; } } if (numChoices > 1) strm.UnsignedEncode(tag, 0, numChoices-1); choice->Encode(strm);}BOOL PPER_Stream::ChoiceDecode(PASN_Choice & value){ return value.DecodePER(*this);}void PPER_Stream::ChoiceEncode(const PASN_Choice & value){ value.EncodePER(*this);}///////////////////////////////////////////////////////////////////////BOOL PASN_Sequence::PreambleDecodePER(PPER_Stream & strm){ // X.691 Section 18 if (extendable) { if (strm.IsAtEnd()) return FALSE; totalExtensions = strm.SingleBitDecode() ? -1 : 0; // 18.1 } else totalExtensions = 0; return optionMap.Decode(strm); // 18.2}void PASN_Sequence::PreambleEncodePER(PPER_Stream & strm) const{ // X.691 Section 18 if (extendable) { BOOL hasExtensions = FALSE; for (unsigned i = 0; i < extensionMap.GetSize(); i++) { if (extensionMap[i]) { hasExtensions = TRUE; break; } } strm.SingleBitEncode(hasExtensions); // 18.1 ((PASN_Sequence*)this)->totalExtensions = hasExtensions ? -1 : 0; } optionMap.Encode(strm); // 18.2}BOOL PASN_Sequence::NoExtensionsToDecode(PPER_Stream & strm){ if (totalExtensions == 0) return TRUE; if (totalExtensions < 0) { if (!extensionMap.DecodeSequenceExtensionBitmap(strm)) return FALSE; totalExtensions = extensionMap.GetSize(); } return FALSE;}BOOL PASN_Sequence::NoExtensionsToEncode(PPER_Stream & strm){ if (totalExtensions == 0) return TRUE; if (totalExtensions < 0) { totalExtensions = extensionMap.GetSize(); extensionMap.EncodeSequenceExtensionBitmap(strm); } return FALSE;}BOOL PASN_Sequence::KnownExtensionDecodePER(PPER_Stream & strm, PINDEX fld, PASN_Object & field){ if (NoExtensionsToDecode(strm)) return TRUE; if (!extensionMap[fld-optionMap.GetSize()]) return TRUE; unsigned len; if (!strm.LengthDecode(0, INT_MAX, len)) return FALSE; PINDEX nextExtensionPosition = strm.GetPosition() + len; BOOL ok = field.Decode(strm); strm.SetPosition(nextExtensionPosition); return ok;}void PASN_Sequence::KnownExtensionEncodePER(PPER_Stream & strm, PINDEX fld, const PASN_Object & field) const{ if (((PASN_Sequence*)this)->NoExtensionsToEncode(strm)) return; if (!extensionMap[fld-optionMap.GetSize()]) return; strm.AnyTypeEncode(&field);}BOOL PASN_Sequence::UnknownExtensionsDecodePER(PPER_Stream & strm){ if (NoExtensionsToDecode(strm)) return TRUE; if (totalExtensions <= knownExtensions) return TRUE; // Already read them PINDEX unknownCount = totalExtensions - knownExtensions; if (fields.GetSize() >= unknownCount) return TRUE; // Already read them if (unknownCount > MaximumArraySize) return FALSE; if (!fields.SetSize(unknownCount)) return FALSE; PINDEX i; for (i = 0; i < fields.GetSize(); i++) fields.SetAt(i, new PASN_OctetString); for (i = knownExtensions; i < (PINDEX)extensionMap.GetSize(); i++) { if (extensionMap[i]) if (!fields[i-knownExtensions].Decode(strm)) return FALSE; } return TRUE;}void PASN_Sequence::UnknownExtensionsEncodePER(PPER_Stream & strm) const{ if (((PASN_Sequence*)this)->NoExtensionsToEncode(strm)) return; int i; for (i = knownExtensions; i < totalExtensions; i++) { if (extensionMap[i]) { PINDEX f = i - knownExtensions; if (f < fields.GetSize()) fields[f].Encode(strm); else { PASN_OctetString dummy; dummy.Encode(strm); } } }}BOOL PPER_Stream::SequencePreambleDecode(PASN_Sequence & seq){ return seq.PreambleDecodePER(*this);}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 + -