📄 objostrasn.cpp
字号:
* Revision 1.2 1999/06/16 20:35:34 vasilche* Cleaned processing of blocks of data.* Added input from ASN.1 text format.** Revision 1.1 1999/06/15 16:19:51 vasilche* Added ASN.1 object output stream.** Revision 1.5 1999/06/10 21:06:49 vasilche* Working binary output and almost working binary input.** Revision 1.4 1999/06/07 20:10:03 vasilche* Avoid using of numeric_limits.** Revision 1.3 1999/06/07 19:30:27 vasilche* More bug fixes** Revision 1.2 1999/06/04 20:51:47 vasilche* First compilable version of serialization.** Revision 1.1 1999/05/19 19:56:55 vasilche* Commit just in case.** ===========================================================================*/#include <ncbi_pch.hpp>#include <corelib/ncbistd.hpp>#include <corelib/ncbi_limits.h>#include <serial/objostrasn.hpp>#include <serial/objistr.hpp>#include <serial/objcopy.hpp>#include <serial/memberid.hpp>#include <serial/enumvalues.hpp>#include <serial/memberlist.hpp>#include <serial/objhook.hpp>#include <serial/classinfo.hpp>#include <serial/choice.hpp>#include <serial/continfo.hpp>#include <serial/delaybuf.hpp>#include <stdio.h>#include <math.h>BEGIN_NCBI_SCOPECObjectOStream* CObjectOStream::OpenObjectOStreamAsn(CNcbiOstream& out, bool deleteOut){ return new CObjectOStreamAsn(out, deleteOut);}CObjectOStreamAsn::CObjectOStreamAsn(CNcbiOstream& out, EFixNonPrint how) : CObjectOStream(eSerial_AsnText, out), m_FixMethod(how){ m_Output.SetBackLimit(80); SetSeparator("\n"); SetAutoSeparator(true);}CObjectOStreamAsn::CObjectOStreamAsn(CNcbiOstream& out, bool deleteOut, EFixNonPrint how) : CObjectOStream(eSerial_AsnText, out, deleteOut), m_FixMethod(how){ m_Output.SetBackLimit(80); SetSeparator("\n"); SetAutoSeparator(true);}CObjectOStreamAsn::~CObjectOStreamAsn(void){}string CObjectOStreamAsn::GetPosition(void) const{ return "line "+NStr::UIntToString(m_Output.GetLine());}void CObjectOStreamAsn::WriteFileHeader(TTypeInfo type){ if ( true || m_Output.ZeroIndentLevel() ) { WriteId(type->GetName()); m_Output.PutString(" ::= "); }}inlinevoid CObjectOStreamAsn::WriteEnum(TEnumValueType value, const string& valueName){ if ( !valueName.empty() ) m_Output.PutString(valueName); else m_Output.PutInt4(value);}void CObjectOStreamAsn::WriteEnum(const CEnumeratedTypeValues& values, TEnumValueType value){ WriteEnum(value, values.FindName(value, values.IsInteger()));}void CObjectOStreamAsn::CopyEnum(const CEnumeratedTypeValues& values, CObjectIStream& in){ TEnumValueType value = in.ReadEnum(values); WriteEnum(value, values.FindName(value, values.IsInteger()));}void CObjectOStreamAsn::WriteBool(bool data){ if ( data ) m_Output.PutString("TRUE"); else m_Output.PutString("FALSE");}void CObjectOStreamAsn::WriteChar(char data){ m_Output.PutChar('\''); m_Output.PutChar(data); m_Output.PutChar('\'');}void CObjectOStreamAsn::WriteInt4(Int4 data){ m_Output.PutInt4(data);}void CObjectOStreamAsn::WriteUint4(Uint4 data){ m_Output.PutUint4(data);}void CObjectOStreamAsn::WriteInt8(Int8 data){ m_Output.PutInt8(data);}void CObjectOStreamAsn::WriteUint8(Uint8 data){ m_Output.PutUint8(data);}void CObjectOStreamAsn::WriteDouble2(double data, size_t digits){ if (isnan(data)) { ThrowError(fInvalidData, "invalid double: not a number"); } if (!finite(data)) { ThrowError(fInvalidData, "invalid double: infinite"); } if ( data == 0.0 ) { m_Output.PutString("{ 0, 10, 0 }"); return; } char buffer[128]; // ensure buffer is large enough to fit result // (additional bytes are for sign, dot and exponent) _ASSERT(sizeof(buffer) > digits + 16); int width = sprintf(buffer, "%.*e", int(digits-1), data); if ( width <= 0 || width >= int(sizeof(buffer) - 1) ) ThrowError(fOverflow, "buffer overflow"); _ASSERT(int(strlen(buffer)) == width); char* dotPos = strchr(buffer, '.'); _ASSERT(dotPos); char* ePos = strchr(dotPos, 'e'); _ASSERT(ePos); // now we have: // mantissa with dot - buffer:ePos // exponent - (ePos+1): int exp; // calculate exponent if ( sscanf(ePos + 1, "%d", &exp) != 1 ) ThrowError(fFail, "double value conversion error"); // remove trailing zeroes int fractDigits = int(ePos - dotPos - 1); while ( fractDigits > 0 && ePos[-1] == '0' ) { --ePos; --fractDigits; } // now we have: // mantissa with dot without trailing zeroes - buffer:ePos m_Output.PutString("{ "); m_Output.PutString(buffer, dotPos - buffer); m_Output.PutString(dotPos + 1, fractDigits); m_Output.PutString(", 10, "); m_Output.PutInt4(exp - fractDigits); m_Output.PutString(" }");}void CObjectOStreamAsn::WriteDouble(double data){ WriteDouble2(data, DBL_DIG);}void CObjectOStreamAsn::WriteFloat(float data){ WriteDouble2(data, FLT_DIG);}void CObjectOStreamAsn::WriteNull(void){ m_Output.PutString("NULL");}void CObjectOStreamAsn::WriteAnyContentObject(const CAnyContentObject& ){ NCBI_THROW(CSerialException,eNotImplemented, "CObjectOStreamAsn::WriteAnyContentObject: " "unable to write AnyContent object in ASN");}void CObjectOStreamAsn::CopyAnyContentObject(CObjectIStream& ){ NCBI_THROW(CSerialException,eNotImplemented, "CObjectOStreamAsn::CopyAnyContentObject: " "unable to copy AnyContent object in ASN");}void CObjectOStreamAsn::WriteString(const char* ptr, size_t length){ size_t startLine = m_Output.GetLine(); m_Output.PutChar('"'); while ( length > 0 ) { char c = *ptr++; FixVisibleChar(c, m_FixMethod, startLine); --length; m_Output.WrapAt(78, true); m_Output.PutChar(c); if ( c == '"' ) m_Output.PutChar('"'); } m_Output.PutChar('"');}void CObjectOStreamAsn::WriteCString(const char* str){ if ( str == 0 ) { WriteNull(); } else { WriteString(str, strlen(str)); }}void CObjectOStreamAsn::WriteString(const string& str, EStringType type){ EFixNonPrint fix = m_FixMethod; if (type == eStringTypeUTF8) { m_FixMethod = eFNP_Allow; } WriteString(str.data(), str.size()); m_FixMethod = fix;}void CObjectOStreamAsn::WriteStringStore(const string& str){ WriteString(str.data(), str.size());}void CObjectOStreamAsn::CopyString(CObjectIStream& in){ string s; in.ReadStd(s); WriteString(s.data(), s.size());}void CObjectOStreamAsn::CopyStringStore(CObjectIStream& in){ string s; in.ReadStringStore(s); WriteString(s.data(), s.size());}void CObjectOStreamAsn::WriteId(const string& str){ if ( str.find(' ') != NPOS || str.find('<') != NPOS || str.find(':') != NPOS ) { m_Output.PutChar('['); m_Output.PutString(str); m_Output.PutChar(']'); } else { m_Output.PutString(str); }}void CObjectOStreamAsn::WriteNullPointer(void){ m_Output.PutString("NULL");}void CObjectOStreamAsn::WriteObjectReference(TObjectIndex index){ m_Output.PutChar('@'); if ( sizeof(TObjectIndex) == sizeof(Int4) ) m_Output.PutInt4(Int4(index)); else if ( sizeof(TObjectIndex) == sizeof(Int8) ) m_Output.PutInt8(index); else ThrowError(fIllegalCall, "invalid size of TObjectIndex: " "must be either sizeof(Int4) or sizeof(Int8)");}void CObjectOStreamAsn::WriteOtherBegin(TTypeInfo typeInfo){ m_Output.PutString(": "); WriteId(typeInfo->GetName()); m_Output.PutChar(' ');}void CObjectOStreamAsn::WriteOther(TConstObjectPtr object, TTypeInfo typeInfo){ m_Output.PutString(": "); WriteId(typeInfo->GetName()); m_Output.PutChar(' '); WriteObject(object, typeInfo);}void CObjectOStreamAsn::StartBlock(void){ m_Output.PutChar('{'); m_Output.IncIndentLevel(); m_BlockStart = true;}void CObjectOStreamAsn::EndBlock(void){ m_Output.DecIndentLevel(); m_Output.PutEol(); m_Output.PutChar('}'); m_BlockStart = false;}void CObjectOStreamAsn::NextElement(void){ if ( m_BlockStart ) m_BlockStart = false; else m_Output.PutChar(','); m_Output.PutEol();}void CObjectOStreamAsn::BeginContainer(const CContainerTypeInfo* /*cType*/){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -