objectio.cpp
上传用户:yhdzpy8989
上传日期:2007-06-13
资源大小:13604k
文件大小:15k
- /*
- * ===========================================================================
- * PRODUCTION $Log: objectio.cpp,v $
- * PRODUCTION Revision 1000.2 2004/06/01 19:40:45 gouriano
- * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.11
- * PRODUCTION
- * ===========================================================================
- */
- /* $Id: objectio.cpp,v 1000.2 2004/06/01 19:40:45 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:
- * !!! PUT YOUR DESCRIPTION HERE !!!
- *
- * ---------------------------------------------------------------------------
- * $Log: objectio.cpp,v $
- * Revision 1000.2 2004/06/01 19:40:45 gouriano
- * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.11
- *
- * Revision 1.11 2004/05/17 21:03:03 gorelenk
- * Added include of PCH ncbi_pch.hpp
- *
- * Revision 1.10 2004/03/30 20:28:15 gouriano
- * Corrected stream iterators to handle implicit containers
- *
- * Revision 1.9 2004/02/02 15:46:30 gouriano
- * corrected CIstreamContainerIterator constructor to handle empty containers
- *
- * Revision 1.8 2003/10/24 17:50:37 vasilche
- * CIStreamContainerIterator::operator++() moved to *.cpp file.
- *
- * Revision 1.7 2003/10/24 15:54:28 grichenk
- * Removed or blocked exceptions in destructors
- *
- * Revision 1.6 2002/10/25 14:49:27 vasilche
- * NCBI C Toolkit compatibility code extracted to libxcser library.
- * Serial streams flags names were renamed to fXxx.
- *
- * Names of flags
- *
- * Revision 1.5 2001/08/31 20:05:45 ucko
- * Fix ICC build.
- *
- * Revision 1.4 2001/05/17 15:07:07 lavr
- * Typos corrected
- *
- * Revision 1.3 2001/01/22 23:23:58 vakatov
- * Added CIStreamClassMemberIterator
- * Renamed CIStreamContainer --> CIStreamContainerIterator
- *
- * Revision 1.2 2000/10/20 19:29:36 vasilche
- * Adapted for MSVC which doesn't like explicit operator templates.
- *
- * Revision 1.1 2000/10/20 15:51:40 vasilche
- * Fixed data error processing.
- * Added interface for constructing container objects directly into output stream.
- * object.hpp, object.inl and object.cpp were split to
- * objectinfo.*, objecttype.*, objectiter.* and objectio.*.
- *
- * ===========================================================================
- */
- #include <ncbi_pch.hpp>
- #include <corelib/ncbistd.hpp>
- #include <serial/objectio.hpp>
- #include <serial/objistr.hpp>
- #include <serial/objostr.hpp>
- #include <serial/objcopy.hpp>
- #include <serial/objhook.hpp>
- BEGIN_NCBI_SCOPE
- // readers
- void CObjectInfo::ReadContainer(CObjectIStream& in,
- CReadContainerElementHook& hook)
- {
- const CContainerTypeInfo* containerType = GetContainerTypeInfo();
- BEGIN_OBJECT_FRAME_OF2(in, eFrameArray, containerType);
- in.BeginContainer(containerType);
- TTypeInfo elementType = containerType->GetElementType();
- BEGIN_OBJECT_FRAME_OF2(in, eFrameArrayElement, elementType);
- while ( in.BeginContainerElement(elementType) ) {
- hook.ReadContainerElement(in, *this);
- in.EndContainerElement();
- }
- END_OBJECT_FRAME_OF(in);
- in.EndContainer();
- END_OBJECT_FRAME_OF(in);
- }
- inline
- CIStreamFrame::CIStreamFrame(CObjectIStream& stream)
- : m_Stream(stream), m_Depth(stream.GetStackDepth())
- {
- }
- CIStreamFrame::~CIStreamFrame(void)
- {
- if ( GetStream().GetStackDepth() != m_Depth ) {
- try {
- GetStream().PopErrorFrame();
- }
- catch (...) {
- GetStream().SetFailFlags(CObjectIStream::fIllegalCall,
- "object stack frame error");
- }
- }
- }
- inline
- bool CIStreamFrame::Good(void) const
- {
- return GetStream().InGoodState();
- }
- inline
- COStreamFrame::COStreamFrame(CObjectOStream& stream)
- : m_Stream(stream), m_Depth(stream.GetStackDepth())
- {
- }
- inline
- bool COStreamFrame::Good(void) const
- {
- return GetStream().InGoodState();
- }
- COStreamFrame::~COStreamFrame(void)
- {
- if ( GetStream().GetStackDepth() != m_Depth ) {
- try {
- GetStream().PopErrorFrame();
- }
- catch (...) {
- GetStream().SetFailFlags(CObjectOStream::fIllegalCall,
- "object stack frame error");
- }
- }
- }
- #ifdef NCBI_COMPILER_ICC
- void* COStreamFrame::operator new(size_t size)
- {
- return ::operator new(size);
- }
- void* COStreamFrame::operator new[](size_t size)
- {
- return ::operator new[](size);
- }
- void* CIStreamFrame::operator new(size_t size)
- {
- return ::operator new(size);
- }
- void* CIStreamFrame::operator new[](size_t size)
- {
- return ::operator new[](size);
- }
- #endif
- /////////////////////////////////////////////////////////////////////////////
- // read/write classMember
- inline
- const CMemberInfo* CIStreamClassMemberIterator::GetMemberInfo(void) const
- {
- return m_ClassType.GetClassTypeInfo()->GetMemberInfo(m_MemberIndex);
- }
- inline
- void CIStreamClassMemberIterator::BeginClassMember(void)
- {
- if ( m_ClassType.GetClassTypeInfo()->RandomOrder() ) {
- m_MemberIndex =
- GetStream().BeginClassMember(m_ClassType.GetClassTypeInfo());
- } else {
- m_MemberIndex =
- GetStream().BeginClassMember(m_ClassType.GetClassTypeInfo(),
- m_MemberIndex + 1);
- }
- if ( *this )
- GetStream().SetTopMemberId(GetMemberInfo()->GetId());
- }
- inline
- void CIStreamClassMemberIterator::IllegalCall(const char* message) const
- {
- GetStream().ThrowError(CObjectIStream::fIllegalCall, message);
- }
- inline
- void CIStreamClassMemberIterator::BadState(void) const
- {
- IllegalCall("bad CIStreamClassMemberIterator state");
- }
- CIStreamClassMemberIterator::CIStreamClassMemberIterator(CObjectIStream& in,
- const CObjectTypeInfo& classType)
- : CParent(in), m_ClassType(classType)
- {
- const CClassTypeInfo* classTypeInfo = classType.GetClassTypeInfo();
- in.PushFrame(CObjectStackFrame::eFrameClass, classTypeInfo);
- in.BeginClass(classTypeInfo);
-
- in.PushFrame(CObjectStackFrame::eFrameClassMember);
- m_MemberIndex = kFirstMemberIndex - 1;
- BeginClassMember();
- }
- CIStreamClassMemberIterator::~CIStreamClassMemberIterator(void)
- {
- if ( Good() ) {
- try {
- if ( *this )
- GetStream().EndClassMember();
- GetStream().PopFrame();
- GetStream().EndClass();
- GetStream().PopFrame();
- }
- catch (...) {
- GetStream().SetFailFlags(CObjectIStream::fIllegalCall,
- "class member iterator error");
- }
- }
- }
- inline
- void CIStreamClassMemberIterator::CheckState(void)
- {
- if ( m_MemberIndex == kInvalidMember )
- BadState();
- }
- void CIStreamClassMemberIterator::NextClassMember(void)
- {
- CheckState();
- GetStream().EndClassMember();
- BeginClassMember();
- }
- void CIStreamClassMemberIterator::ReadClassMember(const CObjectInfo& member)
- {
- CheckState();
- GetStream().ReadSeparateObject(member);
- }
- void CIStreamClassMemberIterator::SkipClassMember(const CObjectTypeInfo& member)
- {
- CheckState();
- GetStream().SkipObject(member.GetTypeInfo());
- }
- void CIStreamClassMemberIterator::SkipClassMember(void)
- {
- CheckState();
- GetStream().SkipObject(GetMemberInfo()->GetTypeInfo());
- }
- /////////////////////////////////////////////////////////////////////////////
- // read/write class member
- COStreamClassMember::COStreamClassMember(CObjectOStream& out,
- const CObjectTypeInfoMI& member)
- : CParent(out)
- {
- const CMemberInfo* memberInfo = member.GetMemberInfo();
- out.PushFrame(CObjectStackFrame::eFrameClassMember, memberInfo->GetId());
- out.BeginClassMember(memberInfo->GetId());
- }
- COStreamClassMember::~COStreamClassMember(void)
- {
- if ( Good() ) {
- try {
- GetStream().EndClassMember();
- GetStream().PopFrame();
- }
- catch (...) {
- GetStream().SetFailFlags(CObjectIStream::fIllegalCall,
- "class member write error");
- }
- }
- }
- // read/write container
- inline
- void CIStreamContainerIterator::BeginElement(void)
- {
- _ASSERT(m_State == eElementEnd);
- if ( GetStream().BeginContainerElement(m_ElementTypeInfo) )
- m_State = eElementBegin;
- else
- m_State = eNoMoreElements;
- }
- inline
- void CIStreamContainerIterator::IllegalCall(const char* message) const
- {
- GetStream().ThrowError(CObjectIStream::fIllegalCall, message);
- // GetStream().SetFailFlags(CObjectIStream::fIllegalCall, message);
- }
- inline
- void CIStreamContainerIterator::BadState(void) const
- {
- IllegalCall("bad CIStreamContainerIterator state");
- }
- CIStreamContainerIterator::CIStreamContainerIterator(CObjectIStream& in,
- const CObjectTypeInfo& containerType)
- : CParent(in), m_ContainerType(containerType), m_State(eElementEnd)
- {
- const CContainerTypeInfo* containerTypeInfo;
- if (m_ContainerType.GetTypeFamily() == eTypeFamilyClass) {
- const CClassTypeInfo* classType =
- CTypeConverter<CClassTypeInfo>::SafeCast(m_ContainerType.GetTypeInfo());
- const CItemInfo* itemInfo =
- classType->GetItems().GetItemInfo(classType->GetItems().FirstIndex());
- _ASSERT(itemInfo->GetTypeInfo()->GetTypeFamily() == eTypeFamilyContainer);
- containerTypeInfo =
- CTypeConverter<CContainerTypeInfo>::SafeCast(itemInfo->GetTypeInfo());
- in.PushFrame(CObjectStackFrame::eFrameNamed, m_ContainerType.GetTypeInfo());
- in.BeginNamedType(m_ContainerType.GetTypeInfo());
- } else {
- containerTypeInfo = GetContainerType().GetContainerTypeInfo();
- }
- in.PushFrame(CObjectStackFrame::eFrameArray, containerTypeInfo);
- in.BeginContainer(containerTypeInfo);
-
- TTypeInfo elementTypeInfo = m_ElementTypeInfo =
- containerTypeInfo->GetElementType();
- in.PushFrame(CObjectStackFrame::eFrameArrayElement, elementTypeInfo);
- BeginElement();
- if ( m_State == eNoMoreElements ) {
- in.PopFrame();
- in.EndContainer();
- in.PopFrame();
- if (m_ContainerType.GetTypeFamily() == eTypeFamilyClass) {
- in.EndNamedType();
- in.PopFrame();
- }
- }
- }
- CIStreamContainerIterator::~CIStreamContainerIterator(void)
- {
- if ( Good() ) {
- switch ( m_State ) {
- case eNoMoreElements:
- // normal state
- return;
- case eElementBegin:
- case eElementEnd:
- // not read element(s)
- m_State = eError;
- GetStream().SetFailFlags(CObjectIStream::fIllegalCall,
- "not all elements read");
- break;
- default:
- // error -> do nothing
- return;
- }
- }
- }
- inline
- void CIStreamContainerIterator::CheckState(EState state)
- {
- bool ok = (m_State == state);
- if ( !ok ) {
- m_State = eError;
- BadState();
- }
- }
- void CIStreamContainerIterator::NextElement(void)
- {
- CheckState(eElementBegin);
- GetStream().EndContainerElement();
- m_State = eElementEnd;
- BeginElement();
- if ( m_State == eNoMoreElements ) {
- GetStream().PopFrame();
- GetStream().EndContainer();
- GetStream().PopFrame();
- if (m_ContainerType.GetTypeFamily() == eTypeFamilyClass) {
- GetStream().EndNamedType();
- GetStream().PopFrame();
- }
- }
- }
- inline
- void CIStreamContainerIterator::BeginElementData(void)
- {
- CheckState(eElementBegin);
- }
- inline
- void CIStreamContainerIterator::BeginElementData(const CObjectTypeInfo& )
- {
- //if ( elementType.GetTypeInfo() != GetElementTypeInfo() )
- // IllegalCall("wrong element type");
- BeginElementData();
- }
- void CIStreamContainerIterator::ReadElement(const CObjectInfo& element)
- {
- BeginElementData(element);
- GetStream().ReadSeparateObject(element);
- NextElement();
- if (m_State != eNoMoreElements) {
- m_State = eElementEnd;
- }
- }
- void CIStreamContainerIterator::SkipElement(const CObjectTypeInfo& elementType)
- {
- BeginElementData(elementType);
- GetStream().SkipObject(elementType.GetTypeInfo());
- NextElement();
- if (m_State != eNoMoreElements) {
- m_State = eElementEnd;
- }
- }
- void CIStreamContainerIterator::SkipElement(void)
- {
- BeginElementData();
- GetStream().SkipObject(m_ElementTypeInfo);
- NextElement();
- if (m_State != eNoMoreElements) {
- m_State = eElementEnd;
- }
- }
- CIStreamContainerIterator& CIStreamContainerIterator::operator++(void)
- {
- if (m_State == eElementBegin) {
- SkipElement();
- }
- if (m_State != eNoMoreElements) {
- CheckState(eElementEnd);
- m_State = eElementBegin;
- }
- else {
- m_State = eFinished;
- }
- return *this;
- }
- COStreamContainer::COStreamContainer(CObjectOStream& out,
- const CObjectTypeInfo& containerType)
- : CParent(out), m_ContainerType(containerType)
- {
- const CContainerTypeInfo* containerTypeInfo;
- if (m_ContainerType.GetTypeFamily() == eTypeFamilyClass) {
- const CClassTypeInfo* classType =
- CTypeConverter<CClassTypeInfo>::SafeCast(m_ContainerType.GetTypeInfo());
- const CItemInfo* itemInfo =
- classType->GetItems().GetItemInfo(classType->GetItems().FirstIndex());
- _ASSERT(itemInfo->GetTypeInfo()->GetTypeFamily() == eTypeFamilyContainer);
- containerTypeInfo =
- CTypeConverter<CContainerTypeInfo>::SafeCast(itemInfo->GetTypeInfo());
- out.PushFrame(CObjectStackFrame::eFrameNamed, m_ContainerType.GetTypeInfo());
- out.BeginNamedType(m_ContainerType.GetTypeInfo());
- } else {
- containerTypeInfo = GetContainerType().GetContainerTypeInfo();
- }
- out.PushFrame(CObjectStackFrame::eFrameArray, containerTypeInfo);
- out.BeginContainer(containerTypeInfo);
- TTypeInfo elementTypeInfo = m_ElementTypeInfo =
- containerTypeInfo->GetElementType();
- out.PushFrame(CObjectStackFrame::eFrameArrayElement, elementTypeInfo);
- }
- COStreamContainer::~COStreamContainer(void)
- {
- if ( Good() ) {
- try {
- GetStream().PopFrame();
- GetStream().EndContainer();
- GetStream().PopFrame();
- if (m_ContainerType.GetTypeFamily() == eTypeFamilyClass) {
- GetStream().EndNamedType();
- GetStream().PopFrame();
- }
- }
- catch (...) {
- GetStream().SetFailFlags(CObjectOStream::fIllegalCall,
- "container write error");
- }
- }
- }
- void COStreamContainer::WriteElement(const CConstObjectInfo& element)
- {
- GetStream().BeginContainerElement(m_ElementTypeInfo);
- GetStream().WriteSeparateObject(element);
- GetStream().EndContainerElement();
- }
- END_NCBI_SCOPE