objcopy.cpp
上传用户:yhdzpy8989
上传日期:2007-06-13
资源大小:13604k
文件大小:11k
源码类别:

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: objcopy.cpp,v $
  4.  * PRODUCTION Revision 1000.2  2004/06/01 19:40:36  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.13
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /*  $Id: objcopy.cpp,v 1000.2 2004/06/01 19:40:36 gouriano Exp $
  10. * ===========================================================================
  11. *
  12. *                            PUBLIC DOMAIN NOTICE
  13. *               National Center for Biotechnology Information
  14. *
  15. *  This software/database is a "United States Government Work" under the
  16. *  terms of the United States Copyright Act.  It was written as part of
  17. *  the author's official duties as a United States Government employee and
  18. *  thus cannot be copyrighted.  This software/database is freely available
  19. *  to the public for use. The National Library of Medicine and the U.S.
  20. *  Government have not placed any restriction on its use or reproduction.
  21. *
  22. *  Although all reasonable efforts have been taken to ensure the accuracy
  23. *  and reliability of the software and data, the NLM and the U.S.
  24. *  Government do not and cannot warrant the performance or results that
  25. *  may be obtained by using this software or data. The NLM and the U.S.
  26. *  Government disclaim all warranties, express or implied, including
  27. *  warranties of performance, merchantability or fitness for any particular
  28. *  purpose.
  29. *
  30. *  Please cite the author in any work or product based on this material.
  31. *
  32. * ===========================================================================
  33. *
  34. * Author: Eugene Vasilchenko
  35. *
  36. * File Description:
  37. *   !!! PUT YOUR DESCRIPTION HERE !!!
  38. *
  39. * ===========================================================================
  40. */
  41. #include <ncbi_pch.hpp>
  42. #include <corelib/ncbistd.hpp>
  43. #include <corelib/ncbimtx.hpp>
  44. #include <serial/objcopy.hpp>
  45. #include <serial/typeinfo.hpp>
  46. #include <serial/objectinfo.hpp>
  47. #include <serial/classinfo.hpp>
  48. #include <serial/continfo.hpp>
  49. #include <serial/choice.hpp>
  50. #include <serial/objistr.hpp>
  51. #include <serial/objostr.hpp>
  52. #include <serial/objistrimpl.hpp>
  53. #include <serial/objlist.hpp>
  54. #include <serial/serialimpl.hpp>
  55. #undef _TRACE
  56. #define _TRACE(arg) ((void)0)
  57. BEGIN_NCBI_SCOPE
  58. CObjectStreamCopier::CObjectStreamCopier(CObjectIStream& in,
  59.                                          CObjectOStream& out)
  60.     : m_In(in), m_Out(out)
  61. {
  62. }
  63. CObjectStreamCopier::~CObjectStreamCopier(void)
  64. {
  65.     ResetLocalHooks();
  66. }
  67. void CObjectStreamCopier::ResetLocalHooks(void)
  68. {
  69.     CMutexGuard guard(GetTypeInfoMutex());
  70.     m_ObjectHookKey.Clear();
  71.     m_ClassMemberHookKey.Clear();
  72.     m_ChoiceVariantHookKey.Clear();
  73. }
  74. void CObjectStreamCopier::Copy(const CObjectTypeInfo& objectType)
  75. {
  76.     TTypeInfo type = objectType.GetTypeInfo();
  77.     // root object
  78.     BEGIN_OBJECT_2FRAMES2(eFrameNamed, type);
  79.     In().SkipFileHeader(type);
  80.     Out().WriteFileHeader(type);
  81.     CopyObject(type);
  82.     Separator(Out());
  83.     Out().EndOfWrite();
  84.     In().EndOfRead();
  85.     END_OBJECT_2FRAMES();
  86. }
  87. void CObjectStreamCopier::Copy(TTypeInfo type, ENoFileHeader)
  88. {
  89.     // root object
  90.     BEGIN_OBJECT_2FRAMES2(eFrameNamed, type);
  91.     Out().WriteFileHeader(type);
  92.     CopyObject(type);
  93.     
  94.     Separator(Out());
  95.     Out().EndOfWrite();
  96.     In().EndOfRead();
  97.     END_OBJECT_2FRAMES();
  98. }
  99. void CObjectStreamCopier::CopyPointer(TTypeInfo declaredType)
  100. {
  101.     _TRACE("CObjectIStream::CopyPointer("<<declaredType->GetName()<<")");
  102.     if ( !In().DetectLoops() ) {
  103.         CopyObject(declaredType);
  104.         return;
  105.     }
  106.     TTypeInfo typeInfo;
  107.     switch ( In().ReadPointerType() ) {
  108.     case CObjectIStream::eNullPointer:
  109.         _TRACE("CObjectIStream::CopyPointer: null");
  110.         Out().WriteNullPointer();
  111.         return;
  112.     case CObjectIStream::eObjectPointer:
  113.         {
  114.             _TRACE("CObjectIStream::CopyPointer: @...");
  115.             CObjectIStream::TObjectIndex index = In().ReadObjectPointer();
  116.             _TRACE("CObjectIStream::CopyPointer: @" << index);
  117.             typeInfo = In().GetRegisteredObject(index).GetTypeInfo();
  118.             Out().WriteObjectReference(index);
  119.             break;
  120.         }
  121.     case CObjectIStream::eThisPointer:
  122.         {
  123.             _TRACE("CObjectIStream::CopyPointer: new");
  124.             In().RegisterObject(declaredType);
  125.             Out().RegisterObject(declaredType);
  126.             CopyObject(declaredType);
  127.             return;
  128.         }
  129.     case CObjectIStream::eOtherPointer:
  130.         {
  131.             _TRACE("CObjectIStream::CopyPointer: new...");
  132.             string className = In().ReadOtherPointer();
  133.             _TRACE("CObjectIStream::CopyPointer: new " << className);
  134.             typeInfo = CClassTypeInfoBase::GetClassInfoByName(className);
  135.             BEGIN_OBJECT_2FRAMES2(eFrameNamed, typeInfo);
  136.             In().RegisterObject(typeInfo);
  137.             Out().RegisterObject(typeInfo);
  138.             Out().WriteOtherBegin(typeInfo);
  139.             CopyObject(typeInfo);
  140.             Out().WriteOtherEnd(typeInfo);
  141.                 
  142.             END_OBJECT_2FRAMES();
  143.             In().ReadOtherPointerEnd();
  144.             break;
  145.         }
  146.     default:
  147.         ThrowError(CObjectIStream::fFormatError,"illegal pointer type");
  148.         return;
  149.     }
  150.     while ( typeInfo != declaredType ) {
  151.         // try to check parent class pointer
  152.         if ( typeInfo->GetTypeFamily() != eTypeFamilyClass ) {
  153.             ThrowError(CObjectIStream::fFormatError,"incompatible member type");
  154.         }
  155.         const CClassTypeInfo* parentClass =
  156.             CTypeConverter<CClassTypeInfo>::SafeCast(typeInfo)->GetParentClassInfo();
  157.         if ( parentClass ) {
  158.             typeInfo = parentClass;
  159.         }
  160.         else {
  161.             ThrowError(CObjectIStream::fFormatError,"incompatible member type");
  162.         }
  163.     }
  164.     return;
  165. }
  166. void CObjectStreamCopier::CopyByteBlock(void)
  167. {
  168.     CObjectIStream::ByteBlock ib(In());
  169.     if ( ib.KnownLength() ) {
  170.         size_t length = ib.GetExpectedLength();
  171.         CObjectOStream::ByteBlock ob(Out(), length);
  172.         char buffer[4096];
  173.         size_t count;
  174.         while ( (count = ib.Read(buffer, sizeof(buffer))) != 0 ) {
  175.             ob.Write(buffer, count);
  176.         }
  177.         ob.End();
  178.     }
  179.     else {
  180.         // length is unknown -> copy via buffer
  181.         vector<char> o;
  182.         {
  183.             // load data
  184.             char buffer[4096];
  185.             size_t count;
  186.             while ( (count = ib.Read(buffer, sizeof(buffer))) != 0 ) {
  187.                 o.insert(o.end(), buffer, buffer + count);
  188.             }
  189.         }
  190.         {
  191.             // store data
  192.             size_t length = o.size();
  193.             CObjectOStream::ByteBlock ob(Out(), length);
  194.             if ( length > 0 )
  195.                 ob.Write(&o.front(), length);
  196.             ob.End();
  197.         }
  198.     }
  199.     ib.End();
  200. }
  201. void CObjectStreamCopier::SetPathCopyObjectHook(const string& path,
  202.                                                CCopyObjectHook*   hook)
  203. {
  204.     m_PathCopyObjectHooks.SetHook(path,hook);
  205.     In().WatchPathHooks();
  206.     Out().WatchPathHooks();
  207. }
  208. void CObjectStreamCopier::SetPathCopyMemberHook(const string& path,
  209.                                                  CCopyClassMemberHook*   hook)
  210. {
  211.     m_PathCopyMemberHooks.SetHook(path,hook);
  212.     In().WatchPathHooks();
  213.     Out().WatchPathHooks();
  214. }
  215. void CObjectStreamCopier::SetPathCopyVariantHook(const string& path,
  216.                                                  CCopyChoiceVariantHook* hook)
  217. {
  218.     m_PathCopyVariantHooks.SetHook(path,hook);
  219.     In().WatchPathHooks();
  220.     Out().WatchPathHooks();
  221. }
  222. void CObjectStreamCopier::SetPathHooks(CObjectStack& stk, bool set)
  223. {
  224.     if (!m_PathCopyObjectHooks.IsEmpty()) {
  225.         CCopyObjectHook* hook = m_PathCopyObjectHooks.GetHook(stk);
  226.         if (hook) {
  227.             CTypeInfo* item = m_PathCopyObjectHooks.FindType(stk);
  228.             if (item) {
  229.                 if (set) {
  230.                     item->SetLocalCopyHook(*this, hook);
  231.                 } else {
  232.                     item->ResetLocalCopyHook(*this);
  233.                 }
  234.             }
  235.         }
  236.     }
  237.     if (!m_PathCopyMemberHooks.IsEmpty()) {
  238.         CCopyClassMemberHook* hook = m_PathCopyMemberHooks.GetHook(stk);
  239.         if (hook) {
  240.             CMemberInfo* item = m_PathCopyMemberHooks.FindItem(stk);
  241.             if (item) {
  242.                 if (set) {
  243.                     item->SetLocalCopyHook(*this, hook);
  244.                 } else {
  245.                     item->ResetLocalCopyHook(*this);
  246.                 }
  247.             }
  248.         }
  249.     }
  250.     if (!m_PathCopyVariantHooks.IsEmpty()) {
  251.         CCopyChoiceVariantHook* hook = m_PathCopyVariantHooks.GetHook(stk);
  252.         if (hook) {
  253.             CVariantInfo* item = m_PathCopyVariantHooks.FindItem(stk);
  254.             if (item) {
  255.                 if (set) {
  256.                     item->SetLocalCopyHook(*this, hook);
  257.                 } else {
  258.                     item->ResetLocalCopyHook(*this);
  259.                 }
  260.             }
  261.         }
  262.     }
  263. }
  264. END_NCBI_SCOPE
  265. /*
  266. * $Log: objcopy.cpp,v $
  267. * Revision 1000.2  2004/06/01 19:40:36  gouriano
  268. * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.13
  269. *
  270. * Revision 1.13  2004/05/17 21:03:02  gorelenk
  271. * Added include of PCH ncbi_pch.hpp
  272. *
  273. * Revision 1.12  2004/01/05 14:25:20  gouriano
  274. * Added possibility to set serialization hooks by stack path
  275. *
  276. * Revision 1.11  2003/07/29 18:47:47  vasilche
  277. * Fixed thread safeness of object stream hooks.
  278. *
  279. * Revision 1.10  2003/05/16 18:02:18  gouriano
  280. * revised exception error messages
  281. *
  282. * Revision 1.9  2002/10/25 14:49:27  vasilche
  283. * NCBI C Toolkit compatibility code extracted to libxcser library.
  284. * Serial streams flags names were renamed to fXxx.
  285. *
  286. * Names of flags
  287. *
  288. * Revision 1.8  2002/08/30 16:22:21  vasilche
  289. * Removed excessive _TRACEs
  290. *
  291. * Revision 1.7  2002/08/27 17:44:14  grichenk
  292. * Added separator output to object copier
  293. *
  294. * Revision 1.6  2001/05/17 15:07:06  lavr
  295. * Typos corrected
  296. *
  297. * Revision 1.5  2000/10/20 15:51:39  vasilche
  298. * Fixed data error processing.
  299. * Added interface for constructing container objects directly into output stream.
  300. * object.hpp, object.inl and object.cpp were split to
  301. * objectinfo.*, objecttype.*, objectiter.* and objectio.*.
  302. *
  303. * Revision 1.4  2000/10/17 18:45:33  vasilche
  304. * Added possibility to turn off object cross reference detection in
  305. * CObjectIStream and CObjectOStream.
  306. *
  307. * Revision 1.3  2000/09/29 16:18:22  vasilche
  308. * Fixed binary format encoding/decoding on 64 bit compulers.
  309. * Implemented CWeakMap<> for automatic cleaning map entries.
  310. * Added cleaning local hooks via CWeakMap<>.
  311. * Renamed ReadTypeName -> ReadFileHeader, ENoTypeName -> ENoFileHeader.
  312. * Added some user interface methods to CObjectIStream, CObjectOStream and
  313. * CObjectStreamCopier.
  314. *
  315. * Revision 1.2  2000/09/18 20:00:22  vasilche
  316. * Separated CVariantInfo and CMemberInfo.
  317. * Implemented copy hooks.
  318. * All hooks now are stored in CTypeInfo/CMemberInfo/CVariantInfo.
  319. * Most type specific functions now are implemented via function pointers instead of virtual functions.
  320. *
  321. * Revision 1.1  2000/09/01 13:16:15  vasilche
  322. * Implemented class/container/choice iterators.
  323. * Implemented CObjectStreamCopier for copying data without loading into memory.
  324. *
  325. * ===========================================================================
  326. */