📄 objistrasnb.cpp
字号:
m_CurrentTagState = eTagParsed;#endif return fByte; } size_t i = 1; Uint1 byte; do { if ( i > 1024 ) { ThrowError(fOverflow, "tag number is too big (greater than 1024)"); } byte = PeekTagByte(i++); } while ( (byte & 0x80) != 0 ); m_CurrentTagLength = i;#if CHECK_STREAM_INTEGRITY m_CurrentTagState = eTagParsed;#endif return fByte;}void CObjectIStreamAsnBinary::UnexpectedTag(TTag tag){ ThrowError(fFormatError, "unexpected tag: " + NStr::IntToString(m_Input.PeekChar()) + ", should be: " + NStr::IntToString(tag));}void CObjectIStreamAsnBinary::UnexpectedByte(Uint1 byte){ ThrowError(fFormatError, "byte " + NStr::IntToString(byte) + " expected");}#if CHECK_STREAM_INTEGRITYUint1 CObjectIStreamAsnBinary::FlushTag(void){ if ( m_CurrentTagState != eTagParsed || m_CurrentTagLength == 0 ) ThrowError(fIllegalCall, "illegal FlushTag call"); m_Input.SkipChars(m_CurrentTagLength); m_CurrentTagState = eLengthValue; return m_Input.GetChar();}bool CObjectIStreamAsnBinary::PeekIndefiniteLength(void){ if ( m_CurrentTagState != eTagParsed ) ThrowError(fIllegalCall, "illegal PeekIndefiniteLength call"); return Uint1(m_Input.PeekChar(m_CurrentTagLength)) == 0x80;}void CObjectIStreamAsnBinary::ExpectIndefiniteLength(void){ // indefinite length allowed only for constructed tags if ( !ExtractConstructed(m_Input.PeekChar()) ) ThrowError(fFormatError, "illegal ExpectIndefiniteLength call"); if ( FlushTag() != 0x80 ) { ThrowError(fFormatError, "indefinite length is expected"); } _ASSERT(m_CurrentTagLimit == numeric_limits<size_t>::max()); // save tag limit // tag limit is not changed m_Limits.push(m_CurrentTagLimit); m_CurrentTagState = eTagStart; m_CurrentTagLength = 0;}size_t CObjectIStreamAsnBinary::StartTagData(size_t length){ size_t cur_pos = m_Input.GetStreamOffset(); size_t newLimit = cur_pos + length; _ASSERT(newLimit >= cur_pos); size_t currentLimit = m_CurrentTagLimit; _ASSERT(newLimit <= currentLimit); m_Limits.push(currentLimit); m_CurrentTagLimit = newLimit; m_CurrentTagState = eData; return length;}#endifsize_t CObjectIStreamAsnBinary::ReadShortLength(void){ Uint1 byte = FlushTag(); if ( byte >= 0x80 ) { ThrowError(fFormatError, "short length expected"); } return StartTagData(byte);}size_t CObjectIStreamAsnBinary::ReadLength(void){ Uint1 byte = FlushTag(); if ( byte < 0x80 ) { return StartTagData(byte); } size_t lengthLength = byte - 0x80; if ( lengthLength == 0 ) { ThrowError(fFormatError, "unexpected indefinite length"); } if ( lengthLength > sizeof(size_t) ) { ThrowError(fOverflow, "length overflow"); } byte = m_Input.GetChar(); if ( byte == 0 ) { ThrowError(fFormatError, "illegal length start"); } if ( size_t(-1) < size_t(0) ) { // size_t is signed // check for sign overflow if ( lengthLength == sizeof(size_t) && (byte & 0x80) != 0 ) { ThrowError(fOverflow, "length overflow"); } } lengthLength--; size_t length = byte; while ( lengthLength-- > 0 ) length = (length << 8) | Uint1(m_Input.GetChar()); return StartTagData(length);}void CObjectIStreamAsnBinary::ExpectShortLength(size_t length){ if ( ReadShortLength() != length ) { ThrowError(fFormatError, "length expected: "+NStr::UIntToString(length)); }}#if CHECK_STREAM_INTEGRITYvoid CObjectIStreamAsnBinary::EndOfTag(void){ if ( m_CurrentTagState != eData ) ThrowError(fIllegalCall, "illegal EndOfTag call"); // check for all bytes read if ( m_CurrentTagLimit != numeric_limits<size_t>::max() ) { if ( m_Input.GetStreamOffset() != m_CurrentTagLimit ) ThrowError(fIllegalCall, "illegal EndOfTag call: not all data bytes read"); } m_CurrentTagState = eTagStart; m_CurrentTagLength = 0; // restore tag limit from stack m_CurrentTagLimit = m_Limits.top(); m_Limits.pop(); _ASSERT(m_CurrentTagLimit == numeric_limits<size_t>::max());}void CObjectIStreamAsnBinary::ExpectEndOfContent(void){ if ( m_CurrentTagState != eTagStart ) ThrowError(fFormatError, "illegal ExpectEndOfContent call"); ExpectSysTag(eNone); if ( FlushTag() != 0 ) { ThrowError(fFormatError, "zero length expected"); } _ASSERT(m_CurrentTagLimit == numeric_limits<size_t>::max()); // restore tag limit from stack m_CurrentTagLimit = m_Limits.top(); m_Limits.pop(); _ASSERT(m_CurrentTagLimit == numeric_limits<size_t>::max()); m_CurrentTagState = eTagStart; m_CurrentTagLength = 0;}Uint1 CObjectIStreamAsnBinary::ReadByte(void){ if ( m_CurrentTagState != eData ) ThrowError(fIllegalCall, "illegal ReadByte call"); if ( m_Input.GetStreamOffset() >= m_CurrentTagLimit ) ThrowError(fOverflow, "tag size overflow"); return m_Input.GetChar();}#endifvoid CObjectIStreamAsnBinary::ReadBytes(char* buffer, size_t count){#if CHECK_STREAM_INTEGRITY if ( m_CurrentTagState != eData ) { ThrowError(fIllegalCall, "illegal ReadBytes call"); }#endif if ( count == 0 ) return;#if CHECK_STREAM_INTEGRITY size_t cur_pos = m_Input.GetStreamOffset(); size_t end_pos = cur_pos + count; if ( end_pos < cur_pos || end_pos > m_CurrentTagLimit ) ThrowError(fOverflow, "tag size overflow");#endif m_Input.GetChars(buffer, count);}void CObjectIStreamAsnBinary::SkipBytes(size_t count){#if CHECK_STREAM_INTEGRITY if ( m_CurrentTagState != eData ) { ThrowError(fIllegalCall, "illegal ReadBytes call"); }#endif if ( count == 0 ) return;#if CHECK_STREAM_INTEGRITY size_t cur_pos = m_Input.GetStreamOffset(); size_t end_pos = cur_pos + count; if ( end_pos < cur_pos || end_pos > m_CurrentTagLimit ) ThrowError(fOverflow, "tag size overflow");#endif m_Input.GetChars(count);}template<typename T>void ReadStdSigned(CObjectIStreamAsnBinary& in, T& data){ size_t length = in.ReadShortLength(); if ( length == 0 ) { in.ThrowError(in.fFormatError, "zero length of number"); } T n; if ( length > sizeof(data) ) { // skip --length; Int1 c = in.ReadSByte(); if ( c != 0 && c != -1 ) { in.ThrowError(in.fOverflow, "overflow error"); } while ( length > sizeof(data) ) { --length; if ( in.ReadSByte() != c ) { in.ThrowError(in.fOverflow, "overflow error"); } } --length; n = in.ReadSByte(); if ( ((n ^ c) & 0x80) != 0 ) { in.ThrowError(in.fOverflow, "overflow error"); } } else { --length; n = in.ReadSByte(); } while ( length > 0 ) { --length; n = (n << 8) | in.ReadByte(); } data = n; in.EndOfTag();}template<typename T>void ReadStdUnsigned(CObjectIStreamAsnBinary& in, T& data){ size_t length = in.ReadShortLength(); if ( length == 0 ) { in.ThrowError(in.fFormatError, "zero length of number"); } T n; if ( length > sizeof(data) ) { // skip while ( length > sizeof(data) ) { --length; if ( in.ReadSByte() != 0 ) { in.ThrowError(in.fOverflow, "overflow error"); } } --length; n = in.ReadByte(); if ( (n & 0x80) != 0 ) { in.ThrowError(in.fOverflow, "overflow error"); } } else if ( length == sizeof(data) ) { --length; n = in.ReadByte(); if ( (n & 0x80) != 0 ) { in.ThrowError(in.fOverflow, "overflow error"); } } else { n = 0; } while ( length > 0 ) { --length; n = (n << 8) | in.ReadByte(); } data = n; in.EndOfTag();}bool CObjectIStreamAsnBinary::ReadBool(void){ ExpectSysTag(eBoolean); ExpectShortLength(1); bool ret = ReadByte() != 0; EndOfTag(); return ret;}char CObjectIStreamAsnBinary::ReadChar(void){ ExpectSysTag(eGeneralString); ExpectShortLength(1); char ret = ReadByte(); EndOfTag(); return ret;}Int4 CObjectIStreamAsnBinary::ReadInt4(void){ ExpectSysTag(eInteger); Int4 data; ReadStdSigned(*this, data); return data;}Uint4 CObjectIStreamAsnBinary::ReadUint4(void){ ExpectSysTag(eInteger); Uint4 data; ReadStdUnsigned(*this, data); return data;}Int8 CObjectIStreamAsnBinary::ReadInt8(void){ ExpectSysTag(eInteger); Uint8 data; ReadStdSigned(*this, data); return data;}Uint8 CObjectIStreamAsnBinary::ReadUint8(void){ ExpectSysTag(eInteger); Uint8 data; ReadStdUnsigned(*this, data); return data;}static const size_t kMaxDoubleLength = 256;double CObjectIStreamAsnBinary::ReadDouble(void){ ExpectSysTag(eReal); size_t length = ReadLength(); if ( length < 2 ) { ThrowError(fFormatError, "too short REAL data: length < 2"); } if ( length > kMaxDoubleLength ) { ThrowError(fFormatError, "too long REAL data: length > " + NStr::UIntToString(kMaxDoubleLength)); } ExpectByte(eDecimal); length--; char buffer[kMaxDoubleLength + 2]; ReadBytes(buffer, length); EndOfTag(); buffer[length] = 0; char* endptr; double data = strtod(buffer, &endptr); if ( *endptr != 0 ) { ThrowError(fFormatError, "bad REAL data string"); } return data;}void CObjectIStreamAsnBinary::ReadString(string& s, EStringType type){ ExpectSysTag(eVisibleString); ReadStringValue(ReadLength(), s, type == eStringTypeUTF8? eFNP_Allow: m_FixMethod);}void CObjectIStreamAsnBinary::ReadString(string& s, CPackString& pack_string, EStringType type){ ExpectSysTag(eVisibleString); size_t length = ReadLength(); char buffer[1024]; if ( length > sizeof(buffer) || length > pack_string.GetLengthLimit() ) { pack_string.Skipped(); ReadStringValue(length, s, type == eStringTypeUTF8? eFNP_Allow: m_FixMethod); } else { ReadBytes(buffer, length); EndOfTag(); pair<CPackString::iterator, bool> found = pack_string.Locate(buffer, length); if ( found.second ) { pack_string.AddOld(s, found.first); } else { if ( type == eStringTypeVisible && m_FixMethod != eFNP_Allow ) { // check contents of string for ( size_t i = 0; i < length; ++i ) { if ( !GoodVisibleChar(buffer[i]) ) { for ( ; i < length; ++i ) { FixVisibleChar(buffer[i], m_FixMethod); } pack_string.Pack(s, buffer, length); return; } } } pack_string.AddNew(s, buffer, length, found.first); } }}void CObjectIStreamAsnBinary::ReadStringStore(string& s){ ExpectSysTag(eApplication, false, eStringStore); ReadStringValue(ReadLength(), s, m_FixMethod);}void CObjectIStreamAsnBinary::ReadStringValue(size_t length, string& s, EFixNonPrint fix_method){ s.reserve(length); char buffer[1024]; if ( length < sizeof(buffer) ) { // try to reuse old value ReadBytes(buffer, length); if ( fix_method != eFNP_Allow ) { for ( size_t i = 0; i < length; ++i ) { FixVisibleChar(buffer[i], fix_method); } } if ( s.size() != length || memcmp(s.data(), buffer, length) != 0 ) { s.assign(buffer, length); } } else { s.erase(); while ( length ) { size_t count = min(length, sizeof(buffer)); ReadBytes(buffer, count); if ( fix_method != eFNP_Allow ) { for ( size_t i = 0; i < count; ++i ) { FixVisibleChar(buffer[i], fix_method); } } s.append(buffer, count); length -= count; } } EndOfTag();}char* CObjectIStreamAsnBinary::ReadCString(void){ ExpectSysTag(eVisibleString); size_t length = ReadLength(); char* s = static_cast<char*>(malloc(length + 1)); ReadBytes(s, length); s[length] = 0; if ( m_FixMethod != eFNP_Allow ) { // Check the string for non-printable characters for ( char* ptr = s; length; ++ptr, --length ) { FixVisibleChar(*ptr, m_FixMethod); } } EndOfTag(); return s;}void CObjectIStreamAsnBinary::BeginContainer(const CContainerTypeInfo* containerType){ if ( containerType->RandomElementsOrder() ) ExpectSysTag(eUniversal, true, eSet); else ExpectSysTag(eUniversal, true, eSequence); ExpectIndefiniteLength();}void CObjectIStreamAsnBinary::EndContainer(void)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -