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

📄 objostrasnb.cpp

📁 ncbi源码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/* * =========================================================================== * PRODUCTION $Log: objostrasnb.cpp,v $ * PRODUCTION Revision 1000.3  2004/06/01 19:41:15  gouriano * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.88 * PRODUCTION * =========================================================================== *//*  $Id: objostrasnb.cpp,v 1000.3 2004/06/01 19:41:15 gouriano Exp $* ===========================================================================**                            PUBLIC DOMAIN NOTICE*               National Center for Biotechnology Information**  This software/database is a "United States Government Work" under the*  terms of the United States Copyright Act.  It was written as part of*  the author's official duties as a United States Government employee and*  thus cannot be copyrighted.  This software/database is freely available*  to the public for use. The National Library of Medicine and the U.S.*  Government have not placed any restriction on its use or reproduction.**  Although all reasonable efforts have been taken to ensure the accuracy*  and reliability of the software and data, the NLM and the U.S.*  Government do not and cannot warrant the performance or results that*  may be obtained by using this software or data. The NLM and the U.S.*  Government disclaim all warranties, express or implied, including*  warranties of performance, merchantability or fitness for any particular*  purpose.**  Please cite the author in any work or product based on this material.** ===========================================================================** Author: Eugene Vasilchenko** File Description:*   ASN.1 binary object output stream.*/#include <ncbi_pch.hpp>#include <corelib/ncbistd.hpp>#include <corelib/ncbi_limits.hpp>#include <serial/objostrasnb.hpp>#include <serial/objistr.hpp>#include <serial/objcopy.hpp>#include <serial/objistrasnb.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>using namespace NCBI_NS_NCBI::CObjectStreamAsnBinaryDefs;#undef _TRACE#define _TRACE(arg) ((void)0)BEGIN_NCBI_SCOPECObjectOStream* CObjectOStream::OpenObjectOStreamAsnBinary(CNcbiOstream& out,                                                           bool deleteOut){    return new CObjectOStreamAsnBinary(out, deleteOut);}CObjectOStreamAsnBinary::CObjectOStreamAsnBinary(CNcbiOstream& out,                                                 EFixNonPrint how)    : CObjectOStream(eSerial_AsnBinary, out), m_FixMethod(how){#if CHECK_STREAM_INTEGRITY    m_CurrentPosition = 0;    m_CurrentTagState = eTagStart;    m_CurrentTagLimit = numeric_limits<size_t>::max();#endif}CObjectOStreamAsnBinary::CObjectOStreamAsnBinary(CNcbiOstream& out,                                                 bool deleteOut,                                                 EFixNonPrint how)    : CObjectOStream(eSerial_AsnBinary, out, deleteOut), m_FixMethod(how){#if CHECK_STREAM_INTEGRITY    m_CurrentPosition = 0;    m_CurrentTagState = eTagStart;    m_CurrentTagLimit = numeric_limits<size_t>::max();#endif}CObjectOStreamAsnBinary::~CObjectOStreamAsnBinary(void){#if CHECK_STREAM_INTEGRITY    if ( !m_Limits.empty() || m_CurrentTagState != eTagStart )        ERR_POST("CObjectOStreamAsnBinary not finished");#endif}#if CHECK_STREAM_INTEGRITYinlinevoid CObjectOStreamAsnBinary::StartTag(Uint1 code){    m_Limits.push(m_CurrentTagLimit);    m_CurrentTagCode = code;    m_CurrentTagPosition = m_CurrentPosition;    m_CurrentTagState = (code & 0x1f) == eLongTag? eTagValue: eLengthStart;}inlinevoid CObjectOStreamAsnBinary::EndTag(void){    if ( m_Limits.empty() )        ThrowError(fIllegalCall, "too many tag ends");    m_CurrentTagState = eTagStart;    m_CurrentTagLimit = m_Limits.top();    m_Limits.pop();}inlinevoid CObjectOStreamAsnBinary::SetTagLength(size_t length){    size_t limit = m_CurrentPosition + 1 + length;    if ( limit <= m_CurrentPosition || limit > m_CurrentTagLimit )        ThrowError(fIllegalCall, "tag will overflow enclosing tag");    else        m_CurrentTagLimit = limit;    if ( m_CurrentTagCode & 0x20 ) // constructed        m_CurrentTagState = eTagStart;    else        m_CurrentTagState = eData;    if ( length == 0 )        EndTag();}#endif#if !CHECK_STREAM_INTEGRITYinline#endifvoid CObjectOStreamAsnBinary::WriteByte(Uint1 byte){#if CHECK_STREAM_INTEGRITY    //_TRACE("WriteByte: " << NStr::PtrToString(byte));    if ( m_CurrentPosition >= m_CurrentTagLimit )        ThrowError(fOverflow, "tag size overflow");    switch ( m_CurrentTagState ) {    case eTagStart:        StartTag(byte);        break;    case eTagValue:        if ( (byte & 0x80) == 0)            m_CurrentTagState = eLengthStart;        break;    case eLengthStart:        if ( byte == 0 ) {            SetTagLength(0);            if ( m_CurrentTagCode == 0 )                EndTag();        }        else if ( byte == 0x80 ) {            if ( !(m_CurrentTagCode & 0x20) ) {                ThrowError(fIllegalCall,                           "cannot use indefinite form for primitive tag");            }            m_CurrentTagState = eTagStart;        }        else if ( byte < 0x80 ) {            SetTagLength(byte);        }        else {            m_CurrentTagLengthSize = byte - 0x80;            if ( m_CurrentTagLengthSize > sizeof(size_t) )                ThrowError(fOverflow, "tag length is too big");            m_CurrentTagState = eLengthValueFirst;        }        break;    case eLengthValueFirst:        if ( byte == 0 )            ThrowError(fFormatError, "first byte of length is zero");        if ( --m_CurrentTagLengthSize == 0 ) {            SetTagLength(byte);        }        else {            m_CurrentTagLength = byte;            m_CurrentTagState = eLengthValue;        }        break;        // fall down to next case (no break needed)    case eLengthValue:        m_CurrentTagLength = (m_CurrentTagLength << 8) | byte;        if ( --m_CurrentTagLengthSize == 0 )            SetTagLength(m_CurrentTagLength);        break;    case eData:        if ( m_CurrentPosition + 1 == m_CurrentTagLimit )            EndTag();        break;    }    m_CurrentPosition++;#endif    m_Output.PutChar(byte);}#if !CHECK_STREAM_INTEGRITYinline#endifvoid CObjectOStreamAsnBinary::WriteBytes(const char* bytes, size_t size){    if ( size == 0 )        return;#if CHECK_STREAM_INTEGRITY    //_TRACE("WriteBytes: " << size);    if ( m_CurrentTagState != eData )        ThrowError(fFormatError, "WriteBytes only allowed in DATA");    size_t new_pos = m_CurrentPosition + size;    if ( new_pos < m_CurrentPosition || new_pos > m_CurrentTagLimit )        ThrowError(fFormatError, "tag DATA overflow");    m_CurrentPosition = new_pos;    if ( new_pos == m_CurrentTagLimit )        EndTag();#endif    m_Output.PutString(bytes, size);}template<typename T>void WriteBytesOf(CObjectOStreamAsnBinary& out, const T& value, size_t count){    for ( size_t shift = (count - 1) * 8; shift > 0; shift -= 8 ) {        out.WriteByte(Uint1(value >> shift));    }    out.WriteByte(Uint1(value));}inlinevoid CObjectOStreamAsnBinary::WriteShortTag(EClass c, bool constructed,                                            TTag tag){    WriteByte((c << 6) | (constructed ? (1<<5) : 0) | tag);}inlinevoid CObjectOStreamAsnBinary::WriteSysTag(ETag tag){    WriteShortTag(eUniversal, false, tag);}void CObjectOStreamAsnBinary::WriteLongTag(EClass c, bool constructed,                                           TTag tag){    if ( tag <= 0 )        ThrowError(fFormatError, "negative tag number");        // long form    WriteShortTag(c, constructed, eLongTag);    // calculate largest shift enough for TTag to fit    size_t shift = (sizeof(TTag) * 8 - 1) / 7 * 7;    Uint1 bits;    // find first non zero 7bits    while ( (bits = (tag >> shift) & 0x7f) == 0 ) {        shift -= 7;    }        // beginning of tag    while ( shift != 0 ) {        shift -= 7;        WriteByte((tag >> shift) | 0x80);    }    // write remaining bits    WriteByte(tag & 0x7f);}inlinevoid CObjectOStreamAsnBinary::WriteTag(EClass c, bool constructed, TTag tag){    if ( tag >= 0 && tag < eLongTag )        WriteShortTag(c, constructed, tag);    else        WriteLongTag(c, constructed, tag);}void CObjectOStreamAsnBinary::WriteClassTag(TTypeInfo typeInfo){    const string& tag = typeInfo->GetName();    if ( tag.empty() )        ThrowError(fFormatError, "empty tag string");    _ASSERT( tag[0] > eLongTag );    // long form    WriteShortTag(eApplication, true, eLongTag);    SIZE_TYPE last = tag.size() - 1;    for ( SIZE_TYPE i = 0; i <= last; ++i ) {        char c = tag[i];        _ASSERT( (c & 0x80) == 0 );        if ( i != last )            c |= 0x80;        WriteByte(c);    }}inlinevoid CObjectOStreamAsnBinary::WriteIndefiniteLength(void){    WriteByte(0x80);}inlinevoid CObjectOStreamAsnBinary::WriteShortLength(size_t length){    WriteByte(Uint1(length));}void CObjectOStreamAsnBinary::WriteLongLength(size_t length){    // long form    size_t count;    if ( length <= 0xffU )        count = 1;    else if ( length <= 0xffffU )        count = 2;    else if ( length <= 0xffffffU )        count = 3;    else {        count = sizeof(length);        if ( sizeof(length) > 4 ) {            for ( size_t shift = (count-1)*8;                  count > 0; --count, shift -= 8 ) {                if ( Uint1(length >> shift) != 0 )                    break;            }        }    }    WriteByte(Uint1(0x80 + count));    WriteBytesOf(*this, length, count);}inlinevoid CObjectOStreamAsnBinary::WriteLength(size_t length){    if ( length <= 127 )        WriteShortLength(length);    else        WriteLongLength(length);}inlinevoid CObjectOStreamAsnBinary::WriteEndOfContent(void){    WriteSysTag(eNone);    WriteShortLength(0);}void CObjectOStreamAsnBinary::WriteNull(void){    WriteSysTag(eNull);    WriteShortLength(0);}void CObjectOStreamAsnBinary::WriteAnyContentObject(const CAnyContentObject& ){    NCBI_THROW(CSerialException,eNotImplemented,        "CObjectOStreamAsnBinary::WriteAnyContentObject: "        "unable to write AnyContent object in ASN");}void CObjectOStreamAsnBinary::CopyAnyContentObject(CObjectIStream& ){    NCBI_THROW(CSerialException,eNotImplemented,        "CObjectOStreamAsnBinary::CopyAnyContentObject: "        "unable to copy AnyContent object in ASN");}staticvoid WriteNumberValue(CObjectOStreamAsnBinary& out, Int4 data){    size_t length;    if ( data >= Int4(-0x80) && data <= Int4(0x7f) ) {        // one byte        length = 1;    }    else if ( data >= Int4(-0x8000) && data <= Int4(0x7fff) ) {        // two bytes        length = 2;    }    else if ( data >= Int4(-0x800000) && data <= Int4(0x7fffff) ) {        // three bytes        length = 3;    }    else {        // full length signed        length = sizeof(data);    }    out.WriteShortLength(length);    WriteBytesOf(out, data, length);}staticvoid WriteNumberValue(CObjectOStreamAsnBinary& out, Int8 data){    size_t length;    if ( data >= -Int8(0x80) && data <= Int8(0x7f) ) {        // one byte        length = 1;    }    else if ( data >= Int8(-0x8000) && data <= Int8(0x7fff) ) {        // two bytes        length = 2;    }    else if ( data >= Int8(-0x800000) && data <= Int8(0x7fffff) ) {        // three bytes        length = 3;    }    else if ( data >= Int8(-0x80000000L) && data <= Int8(0x7fffffffL) ) {        // four bytes        length = 4;    }    else {        // full length signed        length = sizeof(data);    }    out.WriteShortLength(length);    WriteBytesOf(out, data, length);}staticvoid WriteNumberValue(CObjectOStreamAsnBinary& out, Uint4 data){    size_t length;    if ( data <= 0x7fU ) {        length = 1;    }    else if ( data <= 0x7fffU ) {        // two bytes        length = 2;    }    else if ( data <= 0x7fffffU ) {        // three bytes        length = 3;    }    else if ( data <= 0x7fffffffU ) {        // four bytes        length = 4;    }    else {        // check for high bit to avoid storing unsigned data as negative        if ( (data & (Uint4(1) << (sizeof(data) * 8 - 1))) != 0 ) {            // full length unsigned - and doesn't fit in signed place            out.WriteShortLength(sizeof(data) + 1);            out.WriteByte(0);            WriteBytesOf(out, data, sizeof(data));            return;        }        else {            // full length            length = sizeof(data);        }    }    out.WriteShortLength(length);    WriteBytesOf(out, data, length);}staticvoid WriteNumberValue(CObjectOStreamAsnBinary& out, Uint8 data){    size_t length;    if ( data <= 0x7fUL ) {        length = 1;    }    else if ( data <= 0x7fffUL ) {        // two bytes        length = 2;    }    else if ( data <= 0x7fffffUL ) {        // three bytes        length = 3;    }    else if ( data <= 0x7fffffffUL ) {        // four bytes        length = 4;    }    else {        // check for high bit to avoid storing unsigned data as negative        if ( (data & (Uint8(1) << (sizeof(data) * 8 - 1))) != 0 ) {            // full length unsigned - and doesn't fit in signed place            out.WriteShortLength(sizeof(data) + 1);            out.WriteByte(0);            WriteBytesOf(out, data, sizeof(data));            return;        }        else {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -