📄 asnber.cxx
字号:
/* * asnber.cxx * * Abstract Syntax Notation 1 Encoding Rules * * Portable Windows Library * *////////////////////////////////////////////////////////////////////////BOOL PBER_Stream::NullDecode(PASN_Null & value){ unsigned len; if (!HeaderDecode(value, len)) return FALSE; byteOffset += len; return TRUE;}void PBER_Stream::NullEncode(const PASN_Null & value){ HeaderEncode(value);}///////////////////////////////////////////////////////////////////////BOOL PBER_Stream::BooleanDecode(PASN_Boolean & value){ unsigned len; if (!HeaderDecode(value, len)) return FALSE; while (len-- > 0) { if (IsAtEnd()) return FALSE; value = (BOOL)ByteDecode(); } return TRUE;}void PBER_Stream::BooleanEncode(const PASN_Boolean & value){ HeaderEncode(value); ByteEncode((BOOL)value);}///////////////////////////////////////////////////////////////////////BOOL PBER_Stream::IntegerDecode(PASN_Integer & value){ unsigned len; if (!HeaderDecode(value, len) || len == 0 || IsAtEnd()) return FALSE; int accumulator = (char)ByteDecode(); // sign extended first byte while (--len > 0) { if (IsAtEnd()) return FALSE; accumulator = (accumulator << 8) | ByteDecode(); } value = accumulator; return TRUE;}void PBER_Stream::IntegerEncode(const PASN_Integer & value){ HeaderEncode(value); // output the integer bits for (int count = GetIntegerDataLength(value)-1; count >= 0; count--) ByteEncode(value >> (count*8));}///////////////////////////////////////////////////////////////////////BOOL PBER_Stream::EnumerationDecode(PASN_Enumeration & value){ unsigned len; if (!HeaderDecode(value, len) || len == 0 || IsAtEnd()) return FALSE; unsigned val = 0; while (len-- > 0) { if (IsAtEnd()) return FALSE; val = (val << 8) | ByteDecode(); } value = val; return TRUE;}void PBER_Stream::EnumerationEncode(const PASN_Enumeration & value){ HeaderEncode(value); // output the integer bits for (int count = GetIntegerDataLength(value)-1; count >= 0; count--) ByteEncode(value >> (count*8));}///////////////////////////////////////////////////////////////////////BOOL PBER_Stream::RealDecode(PASN_Real & value){ unsigned len; if (!HeaderDecode(value, len) || len == 0 || IsAtEnd()) return FALSE; PAssertAlways(PUnimplementedFunction); byteOffset += len; return TRUE;}void PBER_Stream::RealEncode(const PASN_Real &){ PAssertAlways(PUnimplementedFunction);}///////////////////////////////////////////////////////////////////////BOOL PBER_Stream::ObjectIdDecode(PASN_ObjectId & value){ unsigned len; if (!HeaderDecode(value, len)) return FALSE; return value.CommonDecode(*this, len);}void PBER_Stream::ObjectIdEncode(const PASN_ObjectId & value){ HeaderEncode(value); PBYTEArray data; value.CommonEncode(data); BlockEncode(data, data.GetSize());}///////////////////////////////////////////////////////////////////////BOOL PASN_BitString::DecodeBER(PBER_Stream & strm, unsigned len){ totalBits = len*8 - strm.ByteDecode(); unsigned nBytes = (totalBits+7)/8; return strm.BlockDecode(bitData.GetPointer(nBytes), nBytes) == nBytes;}void PASN_BitString::EncodeBER(PBER_Stream & strm) const{ if (totalBits == 0) strm.ByteEncode(0); else { strm.ByteEncode(8-totalBits%8); strm.BlockEncode(bitData, (totalBits+7)/8); }}///////////////////////////////////////////////////////////////////////BOOL PBER_Stream::BitStringDecode(PASN_BitString & value){ unsigned len; if (!HeaderDecode(value, len) || len == 0 || IsAtEnd()) return FALSE; return value.DecodeBER(*this, len);}void PBER_Stream::BitStringEncode(const PASN_BitString & value){ HeaderEncode(value); value.EncodeBER(*this);}///////////////////////////////////////////////////////////////////////BOOL PBER_Stream::OctetStringDecode(PASN_OctetString & value){ unsigned len; if (!HeaderDecode(value, len)) return FALSE; return BlockDecode(value.GetPointer(len), len) == len;}void PBER_Stream::OctetStringEncode(const PASN_OctetString & value){ HeaderEncode(value); BlockEncode(value, value.GetSize());}///////////////////////////////////////////////////////////////////////BOOL PASN_ConstrainedString::DecodeBER(PBER_Stream & strm, unsigned len){ return strm.BlockDecode((BYTE *)value.GetPointer(len+1), len) == len;}void PASN_ConstrainedString::EncodeBER(PBER_Stream & strm) const{ strm.BlockEncode(value, value.GetSize()-1);}///////////////////////////////////////////////////////////////////////BOOL PBER_Stream::ConstrainedStringDecode(PASN_ConstrainedString & value){ unsigned len; if (!HeaderDecode(value, len)) return FALSE; return value.DecodeBER(*this, len);}void PBER_Stream::ConstrainedStringEncode(const PASN_ConstrainedString & value){ HeaderEncode(value); value.EncodeBER(*this);}///////////////////////////////////////////////////////////////////////BOOL PASN_BMPString::DecodeBER(PBER_Stream & strm, unsigned len){ value.SetSize(len/2); return strm.BlockDecode((BYTE *)value.GetPointer(len), len) == len;}void PASN_BMPString::EncodeBER(PBER_Stream & strm) const{ strm.BlockEncode((const BYTE *)(const WORD *)value, value.GetSize()*2);}///////////////////////////////////////////////////////////////////////BOOL PBER_Stream::BMPStringDecode(PASN_BMPString & value){ unsigned len; if (!HeaderDecode(value, len)) return FALSE; return value.DecodeBER(*this, len);}void PBER_Stream::BMPStringEncode(const PASN_BMPString & value){ HeaderEncode(value); value.EncodeBER(*this);}///////////////////////////////////////////////////////////////////////BOOL PBER_Stream::ChoiceDecode(PASN_Choice & value){ PINDEX savedPosition = GetPosition(); unsigned tag; PASN_Object::TagClass tagClass; BOOL primitive; unsigned entryLen; if (!HeaderDecode(tag, tagClass, primitive, entryLen)) return FALSE; SetPosition(savedPosition); value.SetTag(tag, tagClass); if (value.IsValid()) return value.GetObject().Decode(*this); return TRUE;}void PBER_Stream::ChoiceEncode(const PASN_Choice & value){ if (value.IsValid()) value.GetObject().Encode(*this);}///////////////////////////////////////////////////////////////////////BOOL PASN_Sequence::PreambleDecodeBER(PBER_Stream & strm){ fields.RemoveAll(); unsigned len; if (!strm.HeaderDecode(*this, len)) return FALSE; endBasicEncoding = strm.GetPosition() + len; return !strm.IsAtEnd();}void PASN_Sequence::PreambleEncodeBER(PBER_Stream & strm) const{ strm.HeaderEncode(*this);}BOOL PASN_Sequence::KnownExtensionDecodeBER(PBER_Stream & strm, PINDEX, PASN_Object & field){ if (strm.GetPosition() >= endBasicEncoding) return FALSE; return field.Decode(strm);}void PASN_Sequence::KnownExtensionEncodeBER(PBER_Stream & strm, PINDEX, const PASN_Object & field) const{ field.Encode(strm);}BOOL PASN_Sequence::UnknownExtensionsDecodeBER(PBER_Stream & strm){ while (strm.GetPosition() < endBasicEncoding) { PINDEX savedPosition = strm.GetPosition(); unsigned tag; PASN_Object::TagClass tagClass; BOOL primitive; unsigned entryLen; if (!strm.HeaderDecode(tag, tagClass, primitive, entryLen)) return FALSE; PINDEX nextEntryPosition = strm.GetPosition() + entryLen; strm.SetPosition(savedPosition); PASN_Object * obj = strm.CreateObject(tag, tagClass, primitive); if (obj == NULL) strm.SetPosition(nextEntryPosition); else { if (!obj->Decode(strm)) return FALSE; fields.Append(obj); } } return TRUE;}void PASN_Sequence::UnknownExtensionsEncodeBER(PBER_Stream & strm) const{ for (PINDEX i = 0; i < fields.GetSize(); i++) fields[i].Encode(strm);}///////////////////////////////////////////////////////////////////////BOOL PBER_Stream::SequencePreambleDecode(PASN_Sequence & seq){ return seq.PreambleDecodeBER(*this);}void PBER_Stream::SequencePreambleEncode(const PASN_Sequence & seq){ seq.PreambleEncodeBER(*this);}BOOL PBER_Stream::SequenceKnownDecode(PASN_Sequence & seq, PINDEX fld, PASN_Object & field){ return seq.KnownExtensionDecodeBER(*this, fld, field);}void PBER_Stream::SequenceKnownEncode(const PASN_Sequence & seq, PINDEX fld, const PASN_Object & field){ seq.KnownExtensionEncodeBER(*this, fld, field);}BOOL PBER_Stream::SequenceUnknownDecode(PASN_Sequence & seq){ return seq.UnknownExtensionsDecodeBER(*this);}void PBER_Stream::SequenceUnknownEncode(const PASN_Sequence & seq){ seq.UnknownExtensionsEncodeBER(*this);}///////////////////////////////////////////////////////////////////////BOOL PBER_Stream::ArrayDecode(PASN_Array & array){ array.RemoveAll(); unsigned len; if (!HeaderDecode(array, len)) return FALSE; PINDEX endOffset = byteOffset + len; PINDEX count = 0; while (byteOffset < endOffset) { if (!array.SetSize(count+1)) return FALSE; if (!array[count].Decode(*this)) return FALSE; count++; } byteOffset = endOffset; return TRUE;}void PBER_Stream::ArrayEncode(const PASN_Array & array){ HeaderEncode(array); for (PINDEX i = 0; i < array.GetSize(); i++) array[i].Encode(*this);}///////////////////////////////////////////////////////////////////////PBER_Stream::PBER_Stream(){}PBER_Stream::PBER_Stream(const PBYTEArray & bytes) : PASN_Stream(bytes){}PBER_Stream::PBER_Stream(const BYTE * buf, PINDEX size) : PASN_Stream(buf, size){}PBER_Stream & PBER_Stream::operator=(const PBYTEArray & bytes){ PBYTEArray::operator=(bytes); ResetDecoder(); return *this;}BOOL PBER_Stream::Read(PChannel & chan){ SetSize(0); PINDEX offset = 0; // read the sequence header int b; if ((b = chan.ReadChar()) < 0) return FALSE; SetAt(offset++, (char)b); // only support direct read of simple sequences if ((b&0x1f) == 0x1f) { do { if ((b = chan.ReadChar()) < 0) return FALSE; SetAt(offset++, (char)b); } while ((b & 0x80) != 0); } // read the first byte of the ASN length if ((b = chan.ReadChar()) < 0) return FALSE; SetAt(offset++, (char)b); // determine how many bytes in the length PINDEX dataLen = 0; if ((b & 0x80) == 0) dataLen = b; else { PINDEX lenLen = b&0x7f; SetSize(lenLen+2); while (lenLen-- > 0) { // read the length if ((b = chan.ReadChar()) < 0) return FALSE; dataLen = (dataLen << 8) | b; SetAt(offset++, (char)b); } } // read the data, all of it BYTE * bufptr = GetPointer(dataLen+offset) + offset; while (dataLen > 0) { if (!chan.Read(bufptr, dataLen)) return FALSE; PINDEX readbytes = chan.GetLastReadCount(); bufptr += readbytes; dataLen -= readbytes; } return TRUE;}BOOL PBER_Stream::Write(PChannel & chan){ CompleteEncoding(); return chan.Write(theArray, GetSize());}PASN_Object * PBER_Stream::CreateObject(unsigned tag, PASN_Object::TagClass tagClass, BOOL primitive) const{ if (tagClass == PASN_Object::UniversalTagClass) { switch (tag) { case PASN_Object::UniversalBoolean : return new PASN_Boolean(); case PASN_Object::UniversalInteger : return new PASN_Integer(); case PASN_Object::UniversalBitString : return new PASN_BitString(); case PASN_Object::UniversalOctetString : return new PASN_OctetString(); case PASN_Object::UniversalNull : return new PASN_Null(); case PASN_Object::UniversalObjectId : return new PASN_ObjectId(); case PASN_Object::UniversalReal : return new PASN_Real(); case PASN_Object::UniversalEnumeration : return new PASN_Enumeration(); case PASN_Object::UniversalSequence : return new PASN_Sequence(); case PASN_Object::UniversalSet : return new PASN_Set(); case PASN_Object::UniversalNumericString : return new PASN_NumericString(); case PASN_Object::UniversalPrintableString : return new PASN_PrintableString(); case PASN_Object::UniversalIA5String : return new PASN_IA5String(); case PASN_Object::UniversalVisibleString : return new PASN_VisibleString(); case PASN_Object::UniversalGeneralString : return new PASN_GeneralString(); case PASN_Object::UniversalBMPString : return new PASN_BMPString(); } } if (primitive) return new PASN_OctetString(tag, tagClass); else return new PASN_Sequence(tag, tagClass, 0, FALSE, 0);}BOOL PBER_Stream::HeaderDecode(unsigned & tagVal, PASN_Object::TagClass & tagClass, BOOL & primitive, unsigned & len){ BYTE ident = ByteDecode(); tagClass = (PASN_Object::TagClass)(ident>>6); primitive = (ident&0x20) == 0; tagVal = ident&31; if (tagVal == 31) { BYTE b; tagVal = 0; do { if (IsAtEnd()) return FALSE; b = ByteDecode(); tagVal = (tagVal << 7) | (b&0x7f); } while ((b&0x80) != 0); } if (IsAtEnd()) return FALSE; BYTE len_len = ByteDecode(); if ((len_len & 0x80) == 0) { len = len_len; return TRUE; } len_len &= 0x7f; len = 0; while (len_len-- > 0) { if (IsAtEnd()) return FALSE; len = (len << 8) | ByteDecode(); } return TRUE;}BOOL PBER_Stream::HeaderDecode(PASN_Object & obj, unsigned & len){ PINDEX pos = byteOffset; unsigned tagVal; PASN_Object::TagClass tagClass; BOOL primitive; if (HeaderDecode(tagVal, tagClass, primitive, len) && tagVal == obj.GetTag() && tagClass == obj.GetTagClass()) return TRUE; byteOffset = pos; return FALSE;}void PBER_Stream::HeaderEncode(const PASN_Object & obj){ BYTE ident = (BYTE)(obj.GetTagClass() << 6); if (!obj.IsPrimitive()) ident |= 0x20; unsigned tag = obj.GetTag(); if (tag < 31) ByteEncode(ident|tag); else { ByteEncode(ident|31); unsigned count = (CountBits(tag)+6)/7; while (count-- > 1) ByteEncode((tag >> (count*7))&0x7f); ByteEncode(tag&0x7f); } PINDEX len = obj.GetDataLength(); if (len < 128) ByteEncode(len); else { PINDEX count = (CountBits(len+1)+7)/8; ByteEncode(count|0x80); while (count-- > 0) ByteEncode(len >> (count*8)); }}///////////////////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -