⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 asnber.cxx

📁 pwlib源码库
💻 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 + -