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

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: stdtypes.cpp,v $
  4.  * PRODUCTION Revision 1000.3  2004/06/01 19:41:52  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.44
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /*  $Id: stdtypes.cpp,v 1000.3 2004/06/01 19:41:52 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. *   CTypeInfo classes for primitive leaf types.
  38. */
  39. #include <ncbi_pch.hpp>
  40. #include <serial/serialdef.hpp>
  41. #include <serial/stdtypesimpl.hpp>
  42. #include <serial/typeinfoimpl.hpp>
  43. #include <serial/objistr.hpp>
  44. #include <serial/objostr.hpp>
  45. #include <serial/objcopy.hpp>
  46. #include <limits.h>
  47. #if HAVE_WINDOWS_H
  48. // In MSVC limits.h doesn't define FLT_MIN & FLT_MAX
  49. # include <float.h>
  50. #endif
  51. #include <math.h>
  52. BEGIN_NCBI_SCOPE
  53. class CPrimitiveTypeFunctionsBase
  54. {
  55. public:
  56.     static bool IsNegative(Int4 value)
  57.         {
  58.             return value < 0;
  59.         }
  60.     static bool IsNegative(Uint4 /*value*/)
  61.         {
  62.             return false;
  63.         }
  64. #if SIZEOF_LONG == 4
  65.     // add variants with long to avoid ambiguity
  66.     static bool IsNegative(long value)
  67.         {
  68.             return value < 0;
  69.         }
  70.     static bool IsNegative(unsigned long /*value*/)
  71.         {
  72.             return false;
  73.         }
  74. #endif
  75.     static bool IsNegative(Int8 value)
  76.         {
  77.             return value < 0;
  78.         }
  79.     static bool IsNegative(Uint8 /*value*/)
  80.         {
  81.             return false;
  82.         }
  83. };
  84. template<typename T>
  85. class CPrimitiveTypeFunctions : public CPrimitiveTypeFunctionsBase
  86. {
  87. public:
  88.     typedef T TObjectType;
  89.     static TObjectType& Get(TObjectPtr object)
  90.         {
  91.             return CTypeConverter<TObjectType>::Get(object);
  92.         }
  93.     static const TObjectType& Get(TConstObjectPtr object)
  94.         {
  95.             return CTypeConverter<TObjectType>::Get(object);
  96.         }
  97.     static void SetIOFunctions(CPrimitiveTypeInfo* info)
  98.         {
  99.             info->SetIOFunctions(&Read, &Write, &Copy, &Skip);
  100.         }
  101.     static void SetMemFunctions(CPrimitiveTypeInfo* info)
  102.         {
  103.             info->SetMemFunctions(&Create,
  104.                                   &IsDefault, &SetDefault,
  105.                                   &Equals, &Assign);
  106.         }
  107.     static TObjectPtr Create(TTypeInfo )
  108.         {
  109.             return new TObjectType(0);
  110.         }
  111.     static bool IsDefault(TConstObjectPtr objectPtr)
  112.         {
  113.             return Get(objectPtr) == TObjectType(0);
  114.         }
  115.     static void SetDefault(TObjectPtr objectPtr)
  116.         {
  117.             Get(objectPtr) = TObjectType(0);
  118.         }
  119.     static bool Equals(TConstObjectPtr obj1, TConstObjectPtr obj2,
  120.                        ESerialRecursionMode)
  121.         {
  122.             return Get(obj1) == Get(obj2);
  123.         }
  124.     static void Assign(TObjectPtr dst, TConstObjectPtr src,
  125.                        ESerialRecursionMode)
  126.         {
  127.             Get(dst) = Get(src);
  128.         }
  129.     static void Read(CObjectIStream& in,
  130.                      TTypeInfo , TObjectPtr objectPtr)
  131.         {
  132.             in.ReadStd(Get(objectPtr));
  133.         }
  134.     static void Write(CObjectOStream& out,
  135.                       TTypeInfo , TConstObjectPtr objectPtr)
  136.         {
  137.             out.WriteStd(Get(objectPtr));
  138.         }
  139.     static void Skip(CObjectIStream& in, TTypeInfo )
  140.         {
  141.             TObjectType data;
  142.             in.ReadStd(data);
  143.         }
  144.     static void Copy(CObjectStreamCopier& copier, TTypeInfo )
  145.         {
  146.             TObjectType data;
  147.             copier.In().ReadStd(data);
  148.             copier.Out().WriteStd(data);
  149.         }
  150. };
  151. #define EPSILON_(n) 1e-##n
  152. #define EPSILON(n) EPSILON_(n)
  153. #ifndef DBL_EPSILON
  154. #  define DBL_EPSILON EPSILON(DBL_DIG)
  155. #endif
  156. EMPTY_TEMPLATE
  157. bool CPrimitiveTypeFunctions<double>::Equals(TConstObjectPtr obj1,
  158.                                              TConstObjectPtr obj2,
  159.                                              ESerialRecursionMode)
  160. {
  161.     const double& x = Get(obj1);
  162.     const double& y = Get(obj2);
  163.     return (x == y  ||  fabs(x - y) < fabs(x + y) * DBL_EPSILON);
  164. }
  165. #ifndef FLT_EPSILON
  166. #  define FLT_EPSILON EPSILON(FLT_DIG)
  167. #endif
  168. EMPTY_TEMPLATE
  169. bool CPrimitiveTypeFunctions<float>::Equals(TConstObjectPtr obj1,
  170.                                             TConstObjectPtr obj2,
  171.                                             ESerialRecursionMode)
  172. {
  173.     const float& x = Get(obj1);
  174.     const float& y = Get(obj2);
  175.     return (x == y  ||  fabs(x - y) < fabs(x + y) * FLT_EPSILON);
  176. }
  177. #if SIZEOF_LONG_DOUBLE != 0
  178. EMPTY_TEMPLATE
  179. bool CPrimitiveTypeFunctions<long double>::Equals(TConstObjectPtr obj1,
  180.                                                   TConstObjectPtr obj2,
  181.                                                   ESerialRecursionMode)
  182. {
  183.     const long double& x = Get(obj1);
  184.     const long double& y = Get(obj2);
  185.     // We use DBL_EPSILON because I/O is double-based anyway.
  186.     return (x == y  ||  fabs(x - y) < fabs(x + y) * DBL_EPSILON);
  187. }
  188. #endif
  189. void CVoidTypeFunctions::ThrowException(const char* operation,
  190.                                         TTypeInfo objectType)
  191. {
  192.     string message("cannot ");
  193.     message += operation;
  194.     message += " object of type: ";
  195.     message += objectType->GetName();
  196.     NCBI_THROW(CSerialException,eIllegalCall, message);
  197. }
  198. bool CVoidTypeFunctions::IsDefault(TConstObjectPtr )
  199. {
  200.     return true;
  201. }
  202. bool CVoidTypeFunctions::Equals(TConstObjectPtr , TConstObjectPtr,
  203.                                 ESerialRecursionMode )
  204. {
  205.     ThrowIllegalCall();
  206.     return false;
  207. }
  208. void CVoidTypeFunctions::SetDefault(TObjectPtr )
  209. {
  210. }
  211. void CVoidTypeFunctions::Assign(TObjectPtr , TConstObjectPtr, ESerialRecursionMode )
  212. {
  213.     ThrowIllegalCall();
  214. }
  215. void CVoidTypeFunctions::Read(CObjectIStream& in, TTypeInfo ,
  216.                               TObjectPtr )
  217. {
  218.     in.ThrowError(in.fIllegalCall,
  219.                   "CVoidTypeFunctions::Read cannot read");
  220. }
  221. void CVoidTypeFunctions::Write(CObjectOStream& out, TTypeInfo ,
  222.                                TConstObjectPtr )
  223. {
  224.     out.ThrowError(out.fIllegalCall,
  225.                    "CVoidTypeFunctions::Write cannot write");
  226. }
  227. void CVoidTypeFunctions::Copy(CObjectStreamCopier& copier, TTypeInfo )
  228. {
  229.     copier.ThrowError(CObjectIStream::fIllegalCall,
  230.                       "CVoidTypeFunctions::Copy cannot copy");
  231. }
  232. void CVoidTypeFunctions::Skip(CObjectIStream& in, TTypeInfo )
  233. {
  234.     in.ThrowError(in.fIllegalCall,
  235.                   "CVoidTypeFunctions::Skip cannot skip");
  236. }
  237. TObjectPtr CVoidTypeFunctions::Create(TTypeInfo objectType)
  238. {
  239.     ThrowException("CVoidTypeFunctions::Create cannot create", objectType);
  240.     return 0;
  241. }
  242. CVoidTypeInfo::CVoidTypeInfo(void)
  243.     : CParent(0, ePrimitiveValueSpecial)
  244. {
  245. }
  246. CPrimitiveTypeInfo::CPrimitiveTypeInfo(size_t size,
  247.                                        EPrimitiveValueType valueType,
  248.                                        bool isSigned)
  249.     : CParent(eTypeFamilyPrimitive, size),
  250.       m_ValueType(valueType), m_Signed(isSigned)
  251. {
  252.     typedef CVoidTypeFunctions TFunctions;
  253.     SetMemFunctions(&TFunctions::Create,
  254.                     &TFunctions::IsDefault, &TFunctions::SetDefault,
  255.                     &TFunctions::Equals, &TFunctions::Assign);
  256. }
  257. CPrimitiveTypeInfo::CPrimitiveTypeInfo(size_t size, const char* name,
  258.                                        EPrimitiveValueType valueType,
  259.                                        bool isSigned)
  260.     : CParent(eTypeFamilyPrimitive, size, name),
  261.       m_ValueType(valueType), m_Signed(isSigned)
  262. {
  263.     typedef CVoidTypeFunctions TFunctions;
  264.     SetMemFunctions(&TFunctions::Create,
  265.                     &TFunctions::IsDefault, &TFunctions::SetDefault,
  266.                     &TFunctions::Equals, &TFunctions::Assign);
  267. }
  268. CPrimitiveTypeInfo::CPrimitiveTypeInfo(size_t size, const string& name,
  269.                                        EPrimitiveValueType valueType,
  270.                                        bool isSigned)
  271.     : CParent(eTypeFamilyPrimitive, size, name),
  272.       m_ValueType(valueType), m_Signed(isSigned)
  273. {
  274.     typedef CVoidTypeFunctions TFunctions;
  275.     SetMemFunctions(&TFunctions::Create,
  276.                     &TFunctions::IsDefault, &TFunctions::SetDefault,
  277.                     &TFunctions::Equals, &TFunctions::Assign);
  278. }
  279. void CPrimitiveTypeInfo::SetMemFunctions(TTypeCreate create,
  280.                                          TIsDefaultFunction isDefault,
  281.                                          TSetDefaultFunction setDefault,
  282.                                          TEqualsFunction equals,
  283.                                          TAssignFunction assign)
  284. {
  285.     SetCreateFunction(create);
  286.     m_IsDefault = isDefault;
  287.     m_SetDefault = setDefault;
  288.     m_Equals = equals;
  289.     m_Assign = assign;
  290. }
  291. void CPrimitiveTypeInfo::SetIOFunctions(TTypeReadFunction read,
  292.                                         TTypeWriteFunction write,
  293.                                         TTypeCopyFunction copy,
  294.                                         TTypeSkipFunction skip)
  295. {
  296.     SetReadFunction(read);
  297.     SetWriteFunction(write);
  298.     SetCopyFunction(copy);
  299.     SetSkipFunction(skip);
  300. }
  301. bool CPrimitiveTypeInfo::GetValueBool(TConstObjectPtr /*objectPtr*/) const
  302. {
  303.     ThrowIncompatibleValue();
  304.     return false;
  305. }
  306. bool CPrimitiveTypeInfo::IsDefault(TConstObjectPtr objectPtr) const
  307. {
  308.     return m_IsDefault(objectPtr);
  309. }
  310. void CPrimitiveTypeInfo::SetDefault(TObjectPtr objectPtr) const
  311. {
  312.     m_SetDefault(objectPtr);
  313. }
  314. bool CPrimitiveTypeInfo::Equals(TConstObjectPtr obj1, TConstObjectPtr obj2,
  315.                                 ESerialRecursionMode how) const
  316. {
  317.     return m_Equals(obj1, obj2, how);
  318. }
  319. void CPrimitiveTypeInfo::Assign(TObjectPtr dst, TConstObjectPtr src,
  320.                                 ESerialRecursionMode how) const
  321. {
  322.     m_Assign(dst, src, how);
  323. }
  324. void CPrimitiveTypeInfo::SetValueBool(TObjectPtr /*objectPtr*/, bool /*value*/) const
  325. {
  326.     ThrowIncompatibleValue();
  327. }
  328. char CPrimitiveTypeInfo::GetValueChar(TConstObjectPtr /*objectPtr*/) const
  329. {
  330.     ThrowIncompatibleValue();
  331.     return 0;
  332. }
  333. void CPrimitiveTypeInfo::SetValueChar(TObjectPtr /*objectPtr*/, char /*value*/) const
  334. {
  335.     ThrowIncompatibleValue();
  336. }
  337. Int4 CPrimitiveTypeInfo::GetValueInt4(TConstObjectPtr /*objectPtr*/) const
  338. {
  339.     ThrowIncompatibleValue();
  340.     return 0;
  341. }
  342. void CPrimitiveTypeInfo::SetValueInt4(TObjectPtr /*objectPtr*/,
  343.                                       Int4 /*value*/) const
  344. {
  345.     ThrowIncompatibleValue();
  346. }
  347. Uint4 CPrimitiveTypeInfo::GetValueUint4(TConstObjectPtr /*objectPtr*/) const
  348. {
  349.     ThrowIncompatibleValue();
  350.     return 0;
  351. }
  352. void CPrimitiveTypeInfo::SetValueUint4(TObjectPtr /*objectPtr*/,
  353.                                        Uint4 /*value*/) const
  354. {
  355.     ThrowIncompatibleValue();
  356. }
  357. Int8 CPrimitiveTypeInfo::GetValueInt8(TConstObjectPtr /*objectPtr*/) const
  358. {
  359.     ThrowIncompatibleValue();
  360.     return 0;
  361. }
  362. void CPrimitiveTypeInfo::SetValueInt8(TObjectPtr /*objectPtr*/,
  363.                                       Int8 /*value*/) const
  364. {
  365.     ThrowIncompatibleValue();
  366. }
  367. Uint8 CPrimitiveTypeInfo::GetValueUint8(TConstObjectPtr /*objectPtr*/) const
  368. {
  369.     ThrowIncompatibleValue();
  370.     return 0;
  371. }
  372. void CPrimitiveTypeInfo::SetValueUint8(TObjectPtr /*objectPtr*/,
  373.                                        Uint8 /*value*/) const
  374. {
  375.     ThrowIncompatibleValue();
  376. }
  377. double CPrimitiveTypeInfo::GetValueDouble(TConstObjectPtr /*objectPtr*/) const
  378. {
  379.     ThrowIncompatibleValue();
  380.     return 0;
  381. }
  382. void CPrimitiveTypeInfo::SetValueDouble(TObjectPtr /*objectPtr*/,
  383.                                         double /*value*/) const
  384. {
  385.     ThrowIncompatibleValue();
  386. }
  387. #if SIZEOF_LONG_DOUBLE != 0
  388. long double CPrimitiveTypeInfo::GetValueLDouble(TConstObjectPtr objectPtr) const
  389. {
  390.     return GetValueDouble(objectPtr);
  391. }
  392. void CPrimitiveTypeInfo::SetValueLDouble(TObjectPtr objectPtr,
  393.                                          long double value) const
  394. {
  395.     SetValueDouble(objectPtr, value);
  396. }
  397. #endif
  398. void CPrimitiveTypeInfo::GetValueString(TConstObjectPtr /*objectPtr*/,
  399.                                         string& /*value*/) const
  400. {
  401.     ThrowIncompatibleValue();
  402. }
  403. void CPrimitiveTypeInfo::SetValueString(TObjectPtr /*objectPtr*/,
  404.                                         const string& /*value*/) const
  405. {
  406.     ThrowIncompatibleValue();
  407. }
  408. void CPrimitiveTypeInfo::GetValueOctetString(TConstObjectPtr /*objectPtr*/,
  409.                                              vector<char>& /*value*/) const
  410. {
  411.     ThrowIncompatibleValue();
  412. }
  413. void CPrimitiveTypeInfo::SetValueOctetString(TObjectPtr /*objectPtr*/,
  414.                                              const vector<char>& /*value*/) const
  415. {
  416.     ThrowIncompatibleValue();
  417. }
  418. CPrimitiveTypeInfoBool::CPrimitiveTypeInfoBool(void)
  419.     : CParent(sizeof(TObjectType), ePrimitiveValueBool)
  420. {
  421.     CPrimitiveTypeFunctions<TObjectType>::SetMemFunctions(this);
  422.     CPrimitiveTypeFunctions<TObjectType>::SetIOFunctions(this);
  423. }
  424. bool CPrimitiveTypeInfoBool::GetValueBool(TConstObjectPtr object) const
  425. {
  426.     return CPrimitiveTypeFunctions<TObjectType>::Get(object);
  427. }
  428. void CPrimitiveTypeInfoBool::SetValueBool(TObjectPtr object, bool value) const
  429. {
  430.     CPrimitiveTypeFunctions<TObjectType>::Get(object) = value;
  431. }
  432. TTypeInfo CStdTypeInfo<bool>::GetTypeInfo(void)
  433. {
  434.     static TTypeInfo info = CreateTypeInfo();
  435.     return info;
  436. }
  437. CTypeInfo* CStdTypeInfo<bool>::CreateTypeInfo(void)
  438. {
  439.     return new CPrimitiveTypeInfoBool();
  440. }
  441. class CNullBoolFunctions : public CPrimitiveTypeFunctions<bool>
  442. {
  443. public:
  444.     static TObjectPtr Create(TTypeInfo type)
  445.         {
  446.             NCBI_THROW(CSerialException,eIllegalCall, "Cannot create NULL object");
  447.             return 0;
  448.         }
  449.     static bool IsDefault(TConstObjectPtr)
  450.         {
  451.             return false;
  452.         }
  453.     static void SetDefault(TObjectPtr)
  454.         {
  455.         }
  456.     static bool Equals(TConstObjectPtr, TConstObjectPtr,
  457.                        ESerialRecursionMode)
  458.         {
  459.             return true;
  460.         }
  461.     static void Assign(TObjectPtr, TConstObjectPtr,
  462.                        ESerialRecursionMode)
  463.         {
  464.         }
  465.     static void Read(CObjectIStream& in, TTypeInfo ,
  466.                      TObjectPtr object)
  467.         {
  468.             in.ReadNull();
  469.         }
  470.     static void Write(CObjectOStream& out, TTypeInfo ,
  471.                       TConstObjectPtr /*object*/)
  472.         {
  473.             out.WriteNull();
  474.         }
  475.     static void Copy(CObjectStreamCopier& copier, TTypeInfo )
  476.         {
  477.             copier.In().ReadNull();
  478.             copier.Out().WriteNull();
  479.         }
  480.     static void Skip(CObjectIStream& in, TTypeInfo )
  481.         {
  482.             in.SkipNull();
  483.         }
  484. };
  485. TTypeInfo CStdTypeInfo<bool>::GetTypeInfoNullBool(void)
  486. {
  487.     static TTypeInfo info = CreateTypeInfoNullBool();
  488.     return info;
  489. }
  490. CTypeInfo* CStdTypeInfo<bool>::CreateTypeInfoNullBool(void)
  491. {
  492.     CPrimitiveTypeInfo* info = new CPrimitiveTypeInfoBool;
  493.     typedef CNullBoolFunctions TFunctions;
  494.     info->SetMemFunctions(&TFunctions::Create, &TFunctions::IsDefault,
  495.                           &TFunctions::SetDefault,&TFunctions::Equals,
  496.                           &TFunctions::Assign);
  497.     info->SetIOFunctions(&TFunctions::Read, &TFunctions::Write,
  498.                          &TFunctions::Copy, &TFunctions::Skip);
  499.     return info;
  500. }
  501. CPrimitiveTypeInfoChar::CPrimitiveTypeInfoChar(void)
  502.     : CParent(sizeof(TObjectType), ePrimitiveValueChar)
  503. {
  504.     CPrimitiveTypeFunctions<TObjectType>::SetMemFunctions(this);
  505.     CPrimitiveTypeFunctions<TObjectType>::SetIOFunctions(this);
  506. }
  507. char CPrimitiveTypeInfoChar::GetValueChar(TConstObjectPtr object) const
  508. {
  509.     return CPrimitiveTypeFunctions<TObjectType>::Get(object);
  510. }
  511. void CPrimitiveTypeInfoChar::SetValueChar(TObjectPtr object, char value) const
  512. {
  513.     CPrimitiveTypeFunctions<TObjectType>::Get(object) = value;
  514. }
  515. void CPrimitiveTypeInfoChar::GetValueString(TConstObjectPtr object,
  516.                                             string& value) const
  517. {
  518.     value.assign(1, CPrimitiveTypeFunctions<TObjectType>::Get(object));
  519. }
  520. void CPrimitiveTypeInfoChar::SetValueString(TObjectPtr object,
  521.                                             const string& value) const
  522. {
  523.     if ( value.size() != 1 )
  524.         ThrowIncompatibleValue();
  525.     CPrimitiveTypeFunctions<TObjectType>::Get(object) = value[0];
  526. }
  527. TTypeInfo CStdTypeInfo<char>::GetTypeInfo(void)
  528. {
  529.     static TTypeInfo info = CreateTypeInfo();
  530.     return info;
  531. }
  532. CTypeInfo* CStdTypeInfo<char>::CreateTypeInfo(void)
  533. {
  534.     return new CPrimitiveTypeInfoChar();
  535. }
  536. template<typename T>
  537. class CPrimitiveTypeInfoIntFunctions : public CPrimitiveTypeFunctions<T>
  538. {
  539.     typedef CPrimitiveTypeFunctions<T> CParent;
  540. public:
  541.     typedef T TObjectType;
  542.     
  543.     static CPrimitiveTypeInfoInt* CreateTypeInfo(void)
  544.         {
  545.             CPrimitiveTypeInfoInt* info =
  546.                 new CPrimitiveTypeInfoInt(sizeof(TObjectType), IsSigned());
  547.             info->SetMemFunctions(&CParent::Create,
  548.                                   &IsDefault, &SetDefault, &Equals, &Assign);
  549.             info->SetIOFunctions(&CParent::Read, &CParent::Write,
  550.                                  &CParent::Copy, &CParent::Skip);
  551.             SetInt4Functions(info);
  552.             SetInt8Functions(info);
  553.             return info;
  554.         }
  555.     static void SetInt4Functions(CPrimitiveTypeInfoInt* info)
  556.         {
  557.             info->SetInt4Functions(&GetValueInt4, &SetValueInt4,
  558.                                   &GetValueUint4, &SetValueUint4);
  559.         }
  560.     static void SetInt8Functions(CPrimitiveTypeInfoInt* info)
  561.         {
  562.             info->SetInt8Functions(&GetValueInt8, &SetValueInt8,
  563.                                   &GetValueUint8, &SetValueUint8);
  564.         }
  565.     static bool IsDefault(TConstObjectPtr objectPtr)
  566.         {
  567.             return CParent::Get(objectPtr) == 0;
  568.         }
  569.     static void SetDefault(TObjectPtr objectPtr)
  570.         {
  571.             CParent::Get(objectPtr) = 0;
  572.         }
  573.     static bool Equals(TConstObjectPtr obj1, TConstObjectPtr obj2,
  574.                        ESerialRecursionMode)
  575.         {
  576.             return CParent::Get(obj1) == CParent::Get(obj2);
  577.         }
  578.     static void Assign(TObjectPtr dst, TConstObjectPtr src,
  579.                        ESerialRecursionMode)
  580.         {
  581.             CParent::Get(dst) = CParent::Get(src);
  582.         }
  583.     static bool IsSigned(void)
  584.         {
  585.             return TObjectType(-1) < 0;
  586.         }
  587.     static bool IsUnsigned(void)
  588.         {
  589.             return TObjectType(-1) > 0;
  590.         }
  591.     static Int4 GetValueInt4(TConstObjectPtr objectPtr)
  592.         {
  593.             TObjectType value = CParent::Get(objectPtr);
  594.             Int4 result = Int4(value);
  595.             if ( IsUnsigned() ) {
  596.                 // unsigned -> signed
  597.                 if ( sizeof(value) == sizeof(result) ) {
  598.                     // same size - check for sign change only
  599.                     if ( CParent::IsNegative(result) )
  600.                         ThrowIntegerOverflow();
  601.                 }
  602.             }
  603.             if ( sizeof(value) > sizeof(result) ) {
  604.                 if ( value != TObjectType(result) )
  605.                     ThrowIntegerOverflow();
  606.             }
  607.             return result;
  608.         }
  609.     static Uint4 GetValueUint4(TConstObjectPtr objectPtr)
  610.         {
  611.             TObjectType value = CParent::Get(objectPtr);
  612.             Uint4 result = Uint4(value);
  613.             if ( IsSigned() ) {
  614.                 // signed -> unsigned
  615.                 // check for negative value
  616.                 if ( IsNegative(value) )
  617.                     ThrowIntegerOverflow();
  618.             }
  619.             if ( sizeof(value) > sizeof(result) ) {
  620.                 if ( value != TObjectType(result) )
  621.                     ThrowIntegerOverflow();
  622.             }
  623.             return result;
  624.         }
  625.     static void SetValueInt4(TObjectPtr objectPtr, Int4 value)
  626.         {
  627.             TObjectType result = TObjectType(value);
  628.             if ( IsUnsigned() ) {
  629.                 // signed -> unsigned
  630.                 // check for negative value
  631.                 if ( CParent::IsNegative(value) )
  632.                     ThrowIntegerOverflow();
  633.             }
  634.             if ( sizeof(value) > sizeof(result) ) {
  635.                 if ( value != Int4(result) )
  636.                     ThrowIntegerOverflow();
  637.             }
  638.             CParent::Get(objectPtr) = result;
  639.         }
  640.     static void SetValueUint4(TObjectPtr objectPtr, Uint4 value)
  641.         {
  642.             TObjectType result = TObjectType(value);
  643.             if ( IsSigned() ) {
  644.                 // unsigned -> signed
  645.                 if ( sizeof(value) == sizeof(result) ) {
  646.                     // same size - check for sign change only
  647.                     if ( IsNegative(result) )
  648.                         ThrowIntegerOverflow();
  649.                 }
  650.             }
  651.             if ( sizeof(value) > sizeof(result) ) {
  652.                 if ( value != Uint4(result) )
  653.                     ThrowIntegerOverflow();
  654.             }
  655.             CParent::Get(objectPtr) = result;
  656.         }
  657.     static Int8 GetValueInt8(TConstObjectPtr objectPtr)
  658.         {
  659.             TObjectType value = CParent::Get(objectPtr);
  660.             Int8 result = Int8(value);
  661.             if ( IsUnsigned() ) {
  662.                 // unsigned -> signed
  663.                 if ( sizeof(value) == sizeof(result) ) {
  664.                     // same size - check for sign change only
  665.                     if ( CParent::IsNegative(result) )
  666.                         ThrowIntegerOverflow();
  667.                 }
  668.             }
  669.             if ( sizeof(value) > sizeof(result) ) {
  670.                 if ( value != TObjectType(result) )
  671.                     ThrowIntegerOverflow();
  672.             }
  673.             return result;
  674.         }
  675.     static Uint8 GetValueUint8(TConstObjectPtr objectPtr)
  676.         {
  677.             TObjectType value = CParent::Get(objectPtr);
  678.             Uint8 result = Uint8(value);
  679.             if ( IsSigned() ) {
  680.                 // signed -> unsigned
  681.                 // check for negative value
  682.                 if ( IsNegative(value) )
  683.                     ThrowIntegerOverflow();
  684.             }
  685.             if ( sizeof(value) > sizeof(result) ) {
  686.                 if ( value != TObjectType(result) )
  687.                     ThrowIntegerOverflow();
  688.             }
  689.             return result;
  690.         }
  691.     static void SetValueInt8(TObjectPtr objectPtr, Int8 value)
  692.         {
  693.             TObjectType result = TObjectType(value);
  694.             if ( IsUnsigned() ) {
  695.                 // signed -> unsigned
  696.                 // check for negative value
  697.                 if ( CParent::IsNegative(value) )
  698.                     ThrowIntegerOverflow();
  699.             }
  700.             if ( sizeof(value) > sizeof(result) ) {
  701.                 if ( value != Int8(result) )
  702.                     ThrowIntegerOverflow();
  703.             }
  704.             CParent::Get(objectPtr) = result;
  705.         }
  706.     static void SetValueUint8(TObjectPtr objectPtr, Uint8 value)
  707.         {
  708.             TObjectType result = TObjectType(value);
  709.             if ( IsSigned() ) {
  710.                 // unsigned -> signed
  711.                 if ( sizeof(value) == sizeof(result) ) {
  712.                     // same size - check for sign change only
  713.                     if ( IsNegative(result) )
  714.                         ThrowIntegerOverflow();
  715.                 }
  716.             }
  717.             if ( sizeof(value) > sizeof(result) ) {
  718.                 if ( value != Uint8(result) )
  719.                     ThrowIntegerOverflow();
  720.             }
  721.             CParent::Get(objectPtr) = result;
  722.         }
  723. };
  724. CPrimitiveTypeInfoInt::CPrimitiveTypeInfoInt(size_t size, bool isSigned)
  725.     : CParent(size, ePrimitiveValueInteger, isSigned)
  726. {
  727. }
  728. void CPrimitiveTypeInfoInt::SetInt4Functions(TGetInt4Function getInt4,
  729.                                              TSetInt4Function setInt4,
  730.                                              TGetUint4Function getUint4,
  731.                                              TSetUint4Function setUint4)
  732. {
  733.     m_GetInt4 = getInt4;
  734.     m_SetInt4 = setInt4;
  735.     m_GetUint4 = getUint4;
  736.     m_SetUint4 = setUint4;
  737. }
  738. void CPrimitiveTypeInfoInt::SetInt8Functions(TGetInt8Function getInt8,
  739.                                              TSetInt8Function setInt8,
  740.                                              TGetUint8Function getUint8,
  741.                                              TSetUint8Function setUint8)
  742. {
  743.     m_GetInt8 = getInt8;
  744.     m_SetInt8 = setInt8;
  745.     m_GetUint8 = getUint8;
  746.     m_SetUint8 = setUint8;
  747. }
  748. Int4 CPrimitiveTypeInfoInt::GetValueInt4(TConstObjectPtr objectPtr) const
  749. {
  750.     return m_GetInt4(objectPtr);
  751. }
  752. Uint4 CPrimitiveTypeInfoInt::GetValueUint4(TConstObjectPtr objectPtr) const
  753. {
  754.     return m_GetUint4(objectPtr);
  755. }
  756. void CPrimitiveTypeInfoInt::SetValueInt4(TObjectPtr objectPtr,
  757.                                          Int4 value) const
  758. {
  759.     m_SetInt4(objectPtr, value);
  760. }
  761. void CPrimitiveTypeInfoInt::SetValueUint4(TObjectPtr objectPtr,
  762.                                           Uint4 value) const
  763. {
  764.     m_SetUint4(objectPtr, value);
  765. }
  766. Int8 CPrimitiveTypeInfoInt::GetValueInt8(TConstObjectPtr objectPtr) const
  767. {
  768.     return m_GetInt8(objectPtr);
  769. }
  770. Uint8 CPrimitiveTypeInfoInt::GetValueUint8(TConstObjectPtr objectPtr) const
  771. {
  772.     return m_GetUint8(objectPtr);
  773. }
  774. void CPrimitiveTypeInfoInt::SetValueInt8(TObjectPtr objectPtr,
  775.                                          Int8 value) const
  776. {
  777.     m_SetInt8(objectPtr, value);
  778. }
  779. void CPrimitiveTypeInfoInt::SetValueUint8(TObjectPtr objectPtr,
  780.                                           Uint8 value) const
  781. {
  782.     m_SetUint8(objectPtr, value);
  783. }
  784. #define DECLARE_STD_INT_TYPE(Type) 
  785. TTypeInfo CStdTypeInfo<Type>::GetTypeInfo(void) 
  786.     static TTypeInfo info = CreateTypeInfo(); 
  787.     return info; 
  788. CTypeInfo* CStdTypeInfo<Type>::CreateTypeInfo(void) 
  789.     return CPrimitiveTypeInfoIntFunctions<Type>::CreateTypeInfo(); 
  790. }
  791. DECLARE_STD_INT_TYPE(signed char)
  792. DECLARE_STD_INT_TYPE(unsigned char)
  793. DECLARE_STD_INT_TYPE(short)
  794. DECLARE_STD_INT_TYPE(unsigned short)
  795. DECLARE_STD_INT_TYPE(int)
  796. DECLARE_STD_INT_TYPE(unsigned)
  797. #if SIZEOF_LONG == 4
  798. DECLARE_STD_INT_TYPE(long)
  799. DECLARE_STD_INT_TYPE(unsigned long)
  800. #endif
  801. DECLARE_STD_INT_TYPE(Int8)
  802. DECLARE_STD_INT_TYPE(Uint8)
  803. const CPrimitiveTypeInfo* CPrimitiveTypeInfo::GetIntegerTypeInfo(size_t size,
  804.                                                                  bool sign)
  805. {
  806.     TTypeInfo info;
  807.     if ( size == sizeof(int) ) {
  808.         if ( sign )
  809.             info = CStdTypeInfo<int>::GetTypeInfo();
  810.         else
  811.             info = CStdTypeInfo<unsigned>::GetTypeInfo();
  812.     }
  813.     else if ( size == sizeof(short) ) {
  814.         if ( sign )
  815.             info = CStdTypeInfo<short>::GetTypeInfo();
  816.         else
  817.             info = CStdTypeInfo<unsigned short>::GetTypeInfo();
  818.     }
  819.     else if ( size == sizeof(signed char) ) {
  820.         if ( sign )
  821.             info = CStdTypeInfo<signed char>::GetTypeInfo();
  822.         else
  823.             info = CStdTypeInfo<unsigned char>::GetTypeInfo();
  824.     }
  825.     else if ( size == sizeof(Int8) ) {
  826.         if ( sign )
  827.             info = CStdTypeInfo<Int8>::GetTypeInfo();
  828.         else
  829.             info = CStdTypeInfo<Uint8>::GetTypeInfo();
  830.     }
  831.     else {
  832.         string message("Illegal enum size: ");
  833.         message += NStr::UIntToString(size);
  834.         NCBI_THROW(CSerialException,eInvalidData, message);
  835.     }
  836.     _ASSERT(info->GetSize() == size);
  837.     _ASSERT(info->GetTypeFamily() == eTypeFamilyPrimitive);
  838.     _ASSERT(CTypeConverter<CPrimitiveTypeInfo>::SafeCast(info)->GetPrimitiveValueType() == ePrimitiveValueInteger);
  839.     return CTypeConverter<CPrimitiveTypeInfo>::SafeCast(info);
  840. }
  841. CPrimitiveTypeInfoDouble::CPrimitiveTypeInfoDouble(void)
  842.     : CParent(sizeof(TObjectType), ePrimitiveValueReal, true)
  843. {
  844.     CPrimitiveTypeFunctions<TObjectType>::SetMemFunctions(this);
  845.     CPrimitiveTypeFunctions<TObjectType>::SetIOFunctions(this);
  846. }
  847. double CPrimitiveTypeInfoDouble::GetValueDouble(TConstObjectPtr objectPtr) const
  848. {
  849.     return CPrimitiveTypeFunctions<TObjectType>::Get(objectPtr);
  850. }
  851. void CPrimitiveTypeInfoDouble::SetValueDouble(TObjectPtr objectPtr,
  852.                                               double value) const
  853. {
  854.     CPrimitiveTypeFunctions<TObjectType>::Get(objectPtr) = value;
  855. }
  856. TTypeInfo CStdTypeInfo<double>::GetTypeInfo(void)
  857. {
  858.     static TTypeInfo info = CreateTypeInfo();
  859.     return info;
  860. }
  861. CTypeInfo* CStdTypeInfo<double>::CreateTypeInfo(void)
  862. {
  863.     return new CPrimitiveTypeInfoDouble();
  864. }
  865. CPrimitiveTypeInfoFloat::CPrimitiveTypeInfoFloat(void)
  866.     : CParent(sizeof(TObjectType), ePrimitiveValueReal, true)
  867. {
  868.     CPrimitiveTypeFunctions<TObjectType>::SetMemFunctions(this);
  869.     CPrimitiveTypeFunctions<TObjectType>::SetIOFunctions(this);
  870. }
  871. double CPrimitiveTypeInfoFloat::GetValueDouble(TConstObjectPtr objectPtr) const
  872. {
  873.     return CPrimitiveTypeFunctions<TObjectType>::Get(objectPtr);
  874. }
  875. void CPrimitiveTypeInfoFloat::SetValueDouble(TObjectPtr objectPtr,
  876.                                              double value) const
  877. {
  878. #if defined(FLT_MIN) && defined(FLT_MAX)
  879.     if ( value < FLT_MIN || value > FLT_MAX )
  880.         ThrowIncompatibleValue();
  881. #endif
  882.     CPrimitiveTypeFunctions<TObjectType>::Get(objectPtr) = TObjectType(value);
  883. }
  884. TTypeInfo CStdTypeInfo<float>::GetTypeInfo(void)
  885. {
  886.     static TTypeInfo info = CreateTypeInfo();
  887.     return info;
  888. }
  889. CTypeInfo* CStdTypeInfo<float>::CreateTypeInfo(void)
  890. {
  891.     return new CPrimitiveTypeInfoFloat();
  892. }
  893. #if SIZEOF_LONG_DOUBLE != 0
  894. CPrimitiveTypeInfoLongDouble::CPrimitiveTypeInfoLongDouble(void)
  895.     : CParent(sizeof(TObjectType), ePrimitiveValueReal, true)
  896. {
  897.     CPrimitiveTypeFunctions<TObjectType>::SetMemFunctions(this);
  898.     CPrimitiveTypeFunctions<TObjectType>::SetIOFunctions(this);
  899. }
  900. double CPrimitiveTypeInfoLongDouble::GetValueDouble(TConstObjectPtr objectPtr) const
  901. {
  902.     return CPrimitiveTypeFunctions<TObjectType>::Get(objectPtr);
  903. }
  904. void CPrimitiveTypeInfoLongDouble::SetValueDouble(TObjectPtr objectPtr,
  905.                                                double value) const
  906. {
  907.     CPrimitiveTypeFunctions<TObjectType>::Get(objectPtr) = TObjectType(value);
  908. }
  909. long double CPrimitiveTypeInfoLongDouble::GetValueLDouble(TConstObjectPtr objectPtr) const
  910. {
  911.     return CPrimitiveTypeFunctions<TObjectType>::Get(objectPtr);
  912. }
  913. void CPrimitiveTypeInfoLongDouble::SetValueLDouble(TObjectPtr objectPtr,
  914.                                                    long double value) const
  915. {
  916.     CPrimitiveTypeFunctions<TObjectType>::Get(objectPtr) = TObjectType(value);
  917. }
  918. TTypeInfo CStdTypeInfo<long double>::GetTypeInfo(void)
  919. {
  920.     static TTypeInfo info = CreateTypeInfo();
  921.     return info;
  922. }
  923. CTypeInfo* CStdTypeInfo<long double>::CreateTypeInfo(void)
  924. {
  925.     return new CPrimitiveTypeInfoLongDouble();
  926. }
  927. #endif
  928. template<typename T>
  929. class CStringFunctions : public CPrimitiveTypeFunctions<T>
  930. {
  931.     typedef CPrimitiveTypeFunctions<T> CParent;
  932. public:
  933.     static TObjectPtr Create(TTypeInfo )
  934.         {
  935.             return new T();
  936.         }
  937.     static bool IsDefault(TConstObjectPtr objectPtr)
  938.         {
  939.             return CParent::Get(objectPtr).empty();
  940.         }
  941.     static void SetDefault(TObjectPtr objectPtr)
  942.         {
  943.             CParent::Get(objectPtr).erase();
  944.         }
  945.     static void Copy(CObjectStreamCopier& copier, TTypeInfo )
  946.         {
  947.             copier.CopyString();
  948.         }
  949.     static void Skip(CObjectIStream& in, TTypeInfo )
  950.         {
  951.             in.SkipString();
  952.         }
  953. };
  954. CPrimitiveTypeInfoString::CPrimitiveTypeInfoString(EType type)
  955.     : CParent(sizeof(string), ePrimitiveValueString), m_Type(type)
  956. {
  957.     if (type == eStringTypeUTF8) {
  958.         SetMemFunctions(&CStringFunctions<CStringUTF8>::Create,
  959.                         &CStringFunctions<CStringUTF8>::IsDefault,
  960.                         &CStringFunctions<CStringUTF8>::SetDefault,
  961.                         &CStringFunctions<CStringUTF8>::Equals,
  962.                         &CStringFunctions<CStringUTF8>::Assign);
  963.         SetIOFunctions(&CStringFunctions<CStringUTF8>::Read,
  964.                        &CStringFunctions<CStringUTF8>::Write,
  965.                        &CStringFunctions<CStringUTF8>::Copy,
  966.                        &CStringFunctions<CStringUTF8>::Skip);
  967.     } else {
  968.         SetMemFunctions(&CStringFunctions<string>::Create,
  969.                         &CStringFunctions<string>::IsDefault,
  970.                         &CStringFunctions<string>::SetDefault,
  971.                         &CStringFunctions<string>::Equals,
  972.                         &CStringFunctions<string>::Assign);
  973.         SetIOFunctions(&CStringFunctions<string>::Read,
  974.                        &CStringFunctions<string>::Write,
  975.                        &CStringFunctions<string>::Copy,
  976.                        &CStringFunctions<string>::Skip);
  977.     }
  978. }
  979. void CPrimitiveTypeInfoString::GetValueString(TConstObjectPtr object,
  980.                                               string& value) const
  981. {
  982.     value = CPrimitiveTypeFunctions<TObjectType>::Get(object);
  983. }
  984. void CPrimitiveTypeInfoString::SetValueString(TObjectPtr object,
  985.                                               const string& value) const
  986. {
  987.     CPrimitiveTypeFunctions<TObjectType>::Get(object) = value;
  988. }
  989. char CPrimitiveTypeInfoString::GetValueChar(TConstObjectPtr object) const
  990. {
  991.     if ( CPrimitiveTypeFunctions<TObjectType>::Get(object).size() != 1 )
  992.         ThrowIncompatibleValue();
  993.     return CPrimitiveTypeFunctions<TObjectType>::Get(object)[0];
  994. }
  995. void CPrimitiveTypeInfoString::SetValueChar(TObjectPtr object,
  996.                                             char value) const
  997. {
  998.     CPrimitiveTypeFunctions<TObjectType>::Get(object).assign(1, value);
  999. }
  1000. TTypeInfo CStdTypeInfo<string>::GetTypeInfo(void)
  1001. {
  1002.     static TTypeInfo info = CreateTypeInfo();
  1003.     return info;
  1004. }
  1005. CTypeInfo* CStdTypeInfo<string>::CreateTypeInfo(void)
  1006. {
  1007.     return new CPrimitiveTypeInfoString();
  1008. }
  1009. TTypeInfo CStdTypeInfo<ncbi::CStringUTF8>::GetTypeInfo(void)
  1010. {
  1011.     static TTypeInfo info = CreateTypeInfo();
  1012.     return info;
  1013. }
  1014. CTypeInfo* CStdTypeInfo<ncbi::CStringUTF8>::CreateTypeInfo(void)
  1015. {
  1016.     return new CPrimitiveTypeInfoString(CPrimitiveTypeInfoString::eStringTypeUTF8);
  1017. }
  1018. class CStringStoreFunctions : public CStringFunctions<string>
  1019. {
  1020. public:
  1021.     static void Read(CObjectIStream& in, TTypeInfo , TObjectPtr objectPtr)
  1022.         {
  1023.             in.ReadStringStore(Get(objectPtr));
  1024.         }
  1025.     static void Write(CObjectOStream& out, TTypeInfo ,
  1026.                       TConstObjectPtr objectPtr)
  1027.         {
  1028.             out.WriteStringStore(Get(objectPtr));
  1029.         }
  1030.     static void Copy(CObjectStreamCopier& copier, TTypeInfo )
  1031.         {
  1032.             copier.CopyStringStore();
  1033.         }
  1034.     static void Skip(CObjectIStream& in, TTypeInfo )
  1035.         {
  1036.             in.SkipStringStore();
  1037.         }
  1038. };
  1039. TTypeInfo CStdTypeInfo<string>::GetTypeInfoStringStore(void)
  1040. {
  1041.     static TTypeInfo info = CreateTypeInfoStringStore();
  1042.     return info;
  1043. }
  1044. CTypeInfo* CStdTypeInfo<string>::CreateTypeInfoStringStore(void)
  1045. {
  1046.     CPrimitiveTypeInfo* info = new CPrimitiveTypeInfoString;
  1047.     typedef CStringStoreFunctions TFunctions;
  1048.     info->SetIOFunctions(&TFunctions::Read, &TFunctions::Write,
  1049.                          &TFunctions::Copy, &TFunctions::Skip);
  1050.     return info;
  1051. }
  1052. template<typename T>
  1053. class CCharPtrFunctions : public CPrimitiveTypeFunctions<T>
  1054. {
  1055.     typedef CPrimitiveTypeFunctions<T> CParent;
  1056. public:
  1057.     static bool IsDefault(TConstObjectPtr objectPtr)
  1058.         {
  1059.             return CParent::Get(objectPtr) == 0;
  1060.         }
  1061.     static void SetDefault(TObjectPtr dst)
  1062.         {
  1063.             free(const_cast<char*>(CParent::Get(dst)));
  1064.             CParent::Get(dst) = 0;
  1065.         }
  1066.     static bool Equals(TConstObjectPtr object1, TConstObjectPtr object2,
  1067.                        ESerialRecursionMode)
  1068.         {
  1069.             return strcmp(CParent::Get(object1), CParent::Get(object2)) == 0;
  1070.         }
  1071.     static void Assign(TObjectPtr dst, TConstObjectPtr src,
  1072.                        ESerialRecursionMode)
  1073.         {
  1074.             typename CPrimitiveTypeFunctions<T>::TObjectType value
  1075.                 = CParent::Get(src);
  1076.             _ASSERT(CParent::Get(dst) != value);
  1077.             free(const_cast<char*>(CParent::Get(dst)));
  1078.             if ( value )
  1079.                 CParent::Get(dst) = NotNull(strdup(value));
  1080.             else
  1081.                 CParent::Get(dst) = 0;
  1082.         }
  1083. };
  1084. template<typename T>
  1085. CPrimitiveTypeInfoCharPtr<T>::CPrimitiveTypeInfoCharPtr(void)
  1086.     : CParent(sizeof(TObjectType), ePrimitiveValueString)
  1087. {
  1088.     typedef CCharPtrFunctions<TObjectType> TFunctions;
  1089.     SetMemFunctions(&CVoidTypeFunctions::Create,
  1090.                     &TFunctions::IsDefault, &TFunctions::SetDefault,
  1091.                     &TFunctions::Equals, &TFunctions::Assign);
  1092.     SetIOFunctions(&TFunctions::Read, &TFunctions::Write,
  1093.                    &TFunctions::Copy, &TFunctions::Skip);
  1094. }
  1095. template<typename T>
  1096. char CPrimitiveTypeInfoCharPtr<T>::GetValueChar(TConstObjectPtr objectPtr) const
  1097. {
  1098.     TObjectType obj = CCharPtrFunctions<TObjectType>::Get(objectPtr);
  1099.     if ( !obj || obj[0] == '' || obj[1] != '' )
  1100.         ThrowIncompatibleValue();
  1101.     return obj[0];
  1102. }
  1103. template<typename T>
  1104. void CPrimitiveTypeInfoCharPtr<T>::SetValueChar(TObjectPtr objectPtr,
  1105.                                                 char value) const
  1106. {
  1107.     char* obj = static_cast<char*>(NotNull(malloc(2)));
  1108.     obj[0] =  value;
  1109.     obj[1] = '';
  1110.     CCharPtrFunctions<TObjectPtr>::Get(objectPtr) = obj;
  1111. }
  1112. template<typename T>
  1113. void CPrimitiveTypeInfoCharPtr<T>::GetValueString(TConstObjectPtr objectPtr,
  1114.                                                   string& value) const
  1115. {
  1116.     value = CCharPtrFunctions<TObjectType>::Get(objectPtr);
  1117. }
  1118. template<typename T>
  1119. void CPrimitiveTypeInfoCharPtr<T>::SetValueString(TObjectPtr objectPtr,
  1120.                                                   const string& value) const
  1121. {
  1122.     CCharPtrFunctions<TObjectPtr>::Get(objectPtr) =
  1123.         NotNull(strdup(value.c_str()));
  1124. }
  1125. TTypeInfo CStdTypeInfo<char*>::GetTypeInfo(void)
  1126. {
  1127.     static TTypeInfo info = CreateTypeInfo();
  1128.     return info;
  1129. }
  1130. CTypeInfo* CStdTypeInfo<char*>::CreateTypeInfo(void)
  1131. {
  1132.     return new CPrimitiveTypeInfoCharPtr<char*>();
  1133. }
  1134. TTypeInfo CStdTypeInfo<const char*>::GetTypeInfo(void)
  1135. {
  1136.     static TTypeInfo info = CreateTypeInfo();
  1137.     return info;
  1138. }
  1139. CTypeInfo* CStdTypeInfo<const char*>::CreateTypeInfo(void)
  1140. {
  1141.     return new CPrimitiveTypeInfoCharPtr<const char*>();
  1142. }
  1143. void ThrowIncompatibleValue(void)
  1144. {
  1145.     NCBI_THROW(CSerialException,eInvalidData, "incompatible value");
  1146. }
  1147. void ThrowIllegalCall(void)
  1148. {
  1149.     NCBI_THROW(CSerialException,eIllegalCall, "illegal call");
  1150. }
  1151. void ThrowIntegerOverflow(void)
  1152. {
  1153.     NCBI_THROW(CSerialException,eOverflow, "integer overflow");
  1154. }
  1155. class CCharVectorFunctionsBase
  1156. {
  1157. public:
  1158.     static void Copy(CObjectStreamCopier& copier,
  1159.                      TTypeInfo )
  1160.         {
  1161.             copier.CopyByteBlock();
  1162.         }
  1163.     static void Skip(CObjectIStream& in, TTypeInfo )
  1164.         {
  1165.             in.SkipByteBlock();
  1166.         }
  1167. };
  1168. template<typename Char>
  1169. class CCharVectorFunctions : public CCharVectorFunctionsBase
  1170. {
  1171. public:
  1172.     typedef vector<Char> TObjectType;
  1173.     typedef Char TChar;
  1174.     static TObjectType& Get(TObjectPtr object)
  1175.         {
  1176.             return CTypeConverter<TObjectType>::Get(object);
  1177.         }
  1178.     static const TObjectType& Get(TConstObjectPtr object)
  1179.         {
  1180.             return CTypeConverter<TObjectType>::Get(object);
  1181.         }
  1182.     static char* ToChar(TChar* p)
  1183.         { return reinterpret_cast<char*>(p); }
  1184.     static const char* ToChar(const TChar* p)
  1185.         { return reinterpret_cast<const char*>(p); }
  1186.     static const TChar* ToTChar(const char* p)
  1187.         { return reinterpret_cast<const TChar*>(p); }
  1188.     static TObjectPtr Create(TTypeInfo )
  1189.         {
  1190.             return new TObjectType();
  1191.         }
  1192.     static bool IsDefault(TConstObjectPtr object)
  1193.         {
  1194.             return Get(object).empty();
  1195.         }
  1196.     static bool Equals(TConstObjectPtr object1, TConstObjectPtr object2,
  1197.                        ESerialRecursionMode)
  1198.         {
  1199.             return Get(object1) == Get(object2);
  1200.         }
  1201.     static void SetDefault(TObjectPtr dst)
  1202.         {
  1203.             Get(dst).clear();
  1204.         }
  1205.     static void Assign(TObjectPtr dst, TConstObjectPtr src,
  1206.                        ESerialRecursionMode)
  1207.         {
  1208.             Get(dst) = Get(src);
  1209.         }
  1210.     static void Read(CObjectIStream& in,
  1211.                      TTypeInfo , TObjectPtr objectPtr)
  1212.         {
  1213.             TObjectType& o = Get(objectPtr);
  1214.             CObjectIStream::ByteBlock block(in);
  1215.             if ( block.KnownLength() ) {
  1216.                 size_t length = block.GetExpectedLength();
  1217. #if 1
  1218.                 o.clear();
  1219.                 o.reserve(length);
  1220.                 Char buf[2048];
  1221.                 size_t count;
  1222.                 while ( (count = block.Read(ToChar(buf), sizeof(buf))) != 0 ) {
  1223.                     o.insert(o.end(), buf, buf + count);
  1224.                 }
  1225. #else
  1226.                 o.resize(length);
  1227.                 block.Read(ToChar(&o.front()), length, true);
  1228. #endif
  1229.             }
  1230.             else {
  1231.                 // length is unknown -> copy via buffer
  1232.                 o.clear();
  1233.                 Char buf[4096];
  1234.                 size_t count;
  1235.                 while ( (count = block.Read(ToChar(buf), sizeof(buf))) != 0 ) {
  1236. #ifdef RESERVE_VECTOR_SIZE
  1237.                     size_t new_size = o.size() + count;
  1238.                     if ( new_size > o.capacity() ) {
  1239.                         o.reserve(RESERVE_VECTOR_SIZE(new_size));
  1240.                     }
  1241. #endif
  1242.                     o.insert(o.end(), buf, buf + count);
  1243.                 }
  1244.             }
  1245.             block.End();
  1246.         }
  1247.     static void Write(CObjectOStream& out,
  1248.                       TTypeInfo , TConstObjectPtr objectPtr)
  1249.         {
  1250.             const TObjectType& o = Get(objectPtr);
  1251.             size_t length = o.size();
  1252.             CObjectOStream::ByteBlock block(out, length);
  1253.             if ( length > 0 )
  1254.                 block.Write(ToChar(&o.front()), length);
  1255.             block.End();
  1256.         }
  1257. };
  1258. template<typename Char>
  1259. CCharVectorTypeInfo<Char>::CCharVectorTypeInfo(void)
  1260.     : CParent(sizeof(TObjectType), ePrimitiveValueOctetString)
  1261. {
  1262.     typedef CCharVectorFunctions<Char> TFunctions;
  1263.     SetMemFunctions(&TFunctions::Create,
  1264.                     &TFunctions::IsDefault, &TFunctions::SetDefault,
  1265.                     &TFunctions::Equals, &TFunctions::Assign);
  1266.     SetIOFunctions(&TFunctions::Read, &TFunctions::Write,
  1267.                    &TFunctions::Copy, &TFunctions::Skip);
  1268. }
  1269. template<typename Char>
  1270. void CCharVectorTypeInfo<Char>::GetValueString(TConstObjectPtr objectPtr,
  1271.                                                string& value) const
  1272. {
  1273.     const TObjectType& obj = CCharVectorFunctions<TChar>::Get(objectPtr);
  1274.     const char* buffer = CCharVectorFunctions<TChar>::ToChar(&obj.front());
  1275.     value.assign(buffer, buffer + obj.size());
  1276. }
  1277. template<typename Char>
  1278. void CCharVectorTypeInfo<Char>::SetValueString(TObjectPtr objectPtr,
  1279.                                                const string& value) const
  1280. {
  1281.     TObjectType& obj = CCharVectorFunctions<TChar>::Get(objectPtr);
  1282.     obj.clear();
  1283.     const TChar* buffer = CCharVectorFunctions<TChar>::ToTChar(value.data());
  1284.     obj.insert(obj.end(), buffer, buffer + value.size());
  1285. }
  1286. template<typename Char>
  1287. void CCharVectorTypeInfo<Char>::GetValueOctetString(TConstObjectPtr objectPtr,
  1288.                                                     vector<char>& value) const
  1289. {
  1290.     const TObjectType& obj = CCharVectorFunctions<TChar>::Get(objectPtr);
  1291.     value.clear();
  1292.     const char* buffer = CCharVectorFunctions<TChar>::ToChar(&obj.front());
  1293.     value.insert(value.end(), buffer, buffer + obj.size());
  1294. }
  1295. template<typename Char>
  1296. void CCharVectorTypeInfo<Char>::SetValueOctetString(TObjectPtr objectPtr,
  1297.                                                     const vector<char>& value) const
  1298. {
  1299.     TObjectType& obj = CCharVectorFunctions<TChar>::Get(objectPtr);
  1300.     obj.clear();
  1301.     const TChar* buffer = CCharVectorFunctions<TChar>::ToTChar(&value.front());
  1302.     obj.insert(obj.end(), buffer, buffer + value.size());
  1303. }
  1304. TTypeInfo CStdTypeInfo< vector<char> >::GetTypeInfo(void)
  1305. {
  1306.     static TTypeInfo typeInfo = CreateTypeInfo();
  1307.     return typeInfo;
  1308. }
  1309. TTypeInfo CStdTypeInfo< vector<signed char> >::GetTypeInfo(void)
  1310. {
  1311.     static TTypeInfo typeInfo = CreateTypeInfo();
  1312.     return typeInfo;
  1313. }
  1314. TTypeInfo CStdTypeInfo< vector<unsigned char> >::GetTypeInfo(void)
  1315. {
  1316.     static TTypeInfo typeInfo = CreateTypeInfo();
  1317.     return typeInfo;
  1318. }
  1319. CTypeInfo* CStdTypeInfo< vector<char> >::CreateTypeInfo(void)
  1320. {
  1321.     return new CCharVectorTypeInfo<char>;
  1322. }
  1323. CTypeInfo* CStdTypeInfo< vector<signed char> >::CreateTypeInfo(void)
  1324. {
  1325.     return new CCharVectorTypeInfo<signed char>;
  1326. }
  1327. CTypeInfo* CStdTypeInfo< vector<unsigned char> >::CreateTypeInfo(void)
  1328. {
  1329.     return new CCharVectorTypeInfo<unsigned char>;
  1330. }
  1331. class CAnyContentFunctions : public CPrimitiveTypeFunctions<ncbi::CAnyContentObject>
  1332. {
  1333. public:
  1334.     static TObjectPtr Create(TTypeInfo )
  1335.         {
  1336.             return new TObjectType();
  1337.         }
  1338.     static bool IsDefault(TConstObjectPtr objectPtr)
  1339.         {
  1340.             return Get(objectPtr) == TObjectType();
  1341.         }
  1342.     static void SetDefault(TObjectPtr objectPtr)
  1343.         {
  1344.             Get(objectPtr) = TObjectType();
  1345.         }
  1346.     static void Read(CObjectIStream& in, TTypeInfo , TObjectPtr objectPtr)
  1347.         {
  1348.             in.ReadAnyContentObject(Get(objectPtr));
  1349.         }
  1350.     static void Write(CObjectOStream& out, TTypeInfo ,
  1351.                       TConstObjectPtr objectPtr)
  1352.         {
  1353.             out.WriteAnyContentObject(Get(objectPtr));
  1354.         }
  1355.     static void Copy(CObjectStreamCopier& copier, TTypeInfo )
  1356.         {
  1357.             copier.CopyAnyContentObject();
  1358.         }
  1359.     static void Skip(CObjectIStream& in, TTypeInfo )
  1360.         {
  1361.             in.SkipAnyContentObject();
  1362.         }
  1363. };
  1364. CPrimitiveTypeInfoAnyContent::CPrimitiveTypeInfoAnyContent(void)
  1365.     : CParent(sizeof(CAnyContentObject), ePrimitiveValueOther)
  1366. {
  1367.     m_IsCObject = true;
  1368.     typedef CPrimitiveTypeFunctions<ncbi::CAnyContentObject> TFunctions;
  1369.     SetMemFunctions(&CAnyContentFunctions::Create,
  1370.                     &CAnyContentFunctions::IsDefault,
  1371.                     &CAnyContentFunctions::SetDefault,
  1372.                     &TFunctions::Equals, &TFunctions::Assign);
  1373.     SetIOFunctions(&CAnyContentFunctions::Read,
  1374.                    &CAnyContentFunctions::Write,
  1375.                    &CAnyContentFunctions::Copy,
  1376.                    &CAnyContentFunctions::Skip);
  1377. }
  1378. TTypeInfo CStdTypeInfo<CAnyContentObject>::GetTypeInfo(void)
  1379. {
  1380.     static TTypeInfo info = CreateTypeInfo();
  1381.     return info;
  1382. }
  1383. CTypeInfo* CStdTypeInfo<ncbi::CAnyContentObject>::CreateTypeInfo(void)
  1384. {
  1385.     return new CPrimitiveTypeInfoAnyContent();
  1386. }
  1387. END_NCBI_SCOPE
  1388. /*
  1389. * ===========================================================================
  1390. *
  1391. * $Log: stdtypes.cpp,v $
  1392. * Revision 1000.3  2004/06/01 19:41:52  gouriano
  1393. * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.44
  1394. *
  1395. * Revision 1.44  2004/05/17 21:03:03  gorelenk
  1396. * Added include of PCH ncbi_pch.hpp
  1397. *
  1398. * Revision 1.43  2004/04/26 16:40:59  ucko
  1399. * Tweak for GCC 3.4 compatibility.
  1400. *
  1401. * Revision 1.42  2004/03/25 15:57:08  gouriano
  1402. * Added possibility to copy and compare serial object non-recursively
  1403. *
  1404. * Revision 1.41  2004/02/04 19:03:00  ucko
  1405. * Make floating-point comparison slightly looser, as I/O may introduce
  1406. * insignificant discrepancies.
  1407. *
  1408. * Revision 1.40  2004/02/02 14:42:48  vasilche
  1409. * Try to avoid filling vector<char> by zeroes.
  1410. *
  1411. * Revision 1.39  2004/01/27 17:09:12  ucko
  1412. * CStringFunctions::Create: tweak to compile with default IBM VisualAge
  1413. * settings.
  1414. * Move CVS log to end.
  1415. *
  1416. * Revision 1.38  2003/11/20 14:33:19  gouriano
  1417. * changed generated C++ code so NULL data types have no value
  1418. *
  1419. * Revision 1.37  2003/09/22 20:56:31  gouriano
  1420. * Changed base type of AnyContent object to CSerialObject
  1421. *
  1422. * Revision 1.36  2003/08/13 15:47:45  gouriano
  1423. * implemented serialization of AnyContent objects
  1424. *
  1425. * Revision 1.35  2003/05/22 20:10:02  gouriano
  1426. * added UTF8 strings
  1427. *
  1428. * Revision 1.34  2003/05/16 18:02:18  gouriano
  1429. * revised exception error messages
  1430. *
  1431. * Revision 1.33  2003/03/10 18:54:26  gouriano
  1432. * use new structured exceptions (based on CException)
  1433. *
  1434. * Revision 1.32  2002/10/25 14:49:27  vasilche
  1435. * NCBI C Toolkit compatibility code extracted to libxcser library.
  1436. * Serial streams flags names were renamed to fXxx.
  1437. *
  1438. * Names of flags
  1439. *
  1440. * Revision 1.31  2002/07/01 15:42:07  grichenk
  1441. * Fixed 'unused variable' warnings, removed commented code.
  1442. *
  1443. * Revision 1.30  2002/02/13 22:39:17  ucko
  1444. * Support AIX.
  1445. *
  1446. * Revision 1.29  2002/01/15 21:38:26  grichenk
  1447. * Fixed NULL type initialization/reading/writing
  1448. *
  1449. * Revision 1.28  2001/05/17 15:07:09  lavr
  1450. * Typos corrected
  1451. *
  1452. * Revision 1.27  2001/01/30 21:41:05  vasilche
  1453. * Fixed dealing with unsigned enums.
  1454. *
  1455. * Revision 1.26  2000/12/15 15:38:46  vasilche
  1456. * Added support of Int8 and long double.
  1457. * Enum values now have type Int4 instead of long.
  1458. *
  1459. * Revision 1.25  2000/11/07 17:25:41  vasilche
  1460. * Fixed encoding of XML:
  1461. *     removed unnecessary apostrophes in OCTET STRING
  1462. *     removed unnecessary content in NULL
  1463. * Added module names to CTypeInfo and CEnumeratedTypeValues
  1464. *
  1465. * Revision 1.24  2000/10/20 15:51:43  vasilche
  1466. * Fixed data error processing.
  1467. * Added interface for constructing container objects directly into output stream.
  1468. * object.hpp, object.inl and object.cpp were split to
  1469. * objectinfo.*, objecttype.*, objectiter.* and objectio.*.
  1470. *
  1471. * Revision 1.23  2000/10/17 18:45:36  vasilche
  1472. * Added possibility to turn off object cross reference detection in
  1473. * CObjectIStream and CObjectOStream.
  1474. *
  1475. * Revision 1.22  2000/10/13 20:22:56  vasilche
  1476. * Fixed warnings on 64 bit compilers.
  1477. * Fixed missing typename in templates.
  1478. *
  1479. * Revision 1.21  2000/10/13 16:28:40  vasilche
  1480. * Reduced header dependency.
  1481. * Avoid use of templates with virtual methods.
  1482. * Reduced amount of different maps used.
  1483. * All this lead to smaller compiled code size (libraries and programs).
  1484. *
  1485. * Revision 1.20  2000/09/18 20:00:25  vasilche
  1486. * Separated CVariantInfo and CMemberInfo.
  1487. * Implemented copy hooks.
  1488. * All hooks now are stored in CTypeInfo/CMemberInfo/CVariantInfo.
  1489. * Most type specific functions now are implemented via function pointers instead of virtual functions.
  1490. *
  1491. * Revision 1.19  2000/09/01 13:16:21  vasilche
  1492. * Implemented class/container/choice iterators.
  1493. * Implemented CObjectStreamCopier for copying data without loading into memory.
  1494. *
  1495. * Revision 1.18  2000/07/03 18:42:47  vasilche
  1496. * Added interface to typeinfo via CObjectInfo and CConstObjectInfo.
  1497. * Reduced header dependency.
  1498. *
  1499. * Revision 1.17  2000/05/24 20:08:49  vasilche
  1500. * Implemented XML dump.
  1501. *
  1502. * Revision 1.16  2000/04/06 16:11:01  vasilche
  1503. * Fixed bug with iterators in choices.
  1504. * Removed unneeded calls to ReadExternalObject/WriteExternalObject.
  1505. * Added output buffering to text ASN.1 data.
  1506. *
  1507. * Revision 1.15  2000/03/14 14:42:32  vasilche
  1508. * Fixed error reporting.
  1509. *
  1510. * Revision 1.14  2000/03/07 14:06:24  vasilche
  1511. * Added stream buffering to ASN.1 binary input.
  1512. * Optimized class loading/storing.
  1513. * Fixed bugs in processing OPTIONAL fields.
  1514. * Added generation of reference counted objects.
  1515. *
  1516. * Revision 1.13  2000/01/10 19:46:42  vasilche
  1517. * Fixed encoding/decoding of REAL type.
  1518. * Fixed encoding/decoding of StringStore.
  1519. * Fixed encoding/decoding of NULL type.
  1520. * Fixed error reporting.
  1521. * Reduced object map (only classes).
  1522. *
  1523. * Revision 1.12  2000/01/05 19:43:57  vasilche
  1524. * Fixed error messages when reading from ASN.1 binary file.
  1525. * Fixed storing of integers with enumerated values in ASN.1 binary file.
  1526. * Added TAG support to key/value of map.
  1527. * Added support of NULL variant in CHOICE.
  1528. *
  1529. * Revision 1.11  1999/12/28 18:55:52  vasilche
  1530. * Reduced size of compiled object files:
  1531. * 1. avoid inline or implicit virtual methods (especially destructors).
  1532. * 2. avoid std::string's methods usage in inline methods.
  1533. * 3. avoid string literals ("xxx") in inline methods.
  1534. *
  1535. * Revision 1.10  1999/12/17 19:05:04  vasilche
  1536. * Simplified generation of GetTypeInfo methods.
  1537. *
  1538. * Revision 1.9  1999/09/23 18:57:02  vasilche
  1539. * Fixed bugs with overloaded methods in objistr*.hpp & objostr*.hpp
  1540. *
  1541. * Revision 1.8  1999/09/14 18:54:20  vasilche
  1542. * Fixed bugs detected by gcc & egcs.
  1543. * Removed unneeded includes.
  1544. *
  1545. * Revision 1.7  1999/07/07 21:56:35  vasilche
  1546. * Fixed problem with static variables in templates on SunPro
  1547. *
  1548. * Revision 1.6  1999/07/07 21:15:03  vasilche
  1549. * Cleaned processing of string types (string, char*, const char*).
  1550. *
  1551. * Revision 1.5  1999/07/07 19:59:08  vasilche
  1552. * Reduced amount of data allocated on heap
  1553. * Cleaned ASN.1 structures info
  1554. *
  1555. * Revision 1.4  1999/06/30 16:05:05  vasilche
  1556. * Added support for old ASN.1 structures.
  1557. *
  1558. * Revision 1.3  1999/06/24 14:45:01  vasilche
  1559. * Added binary ASN.1 output.
  1560. *
  1561. * Revision 1.2  1999/06/04 20:51:49  vasilche
  1562. * First compilable version of serialization.
  1563. *
  1564. * Revision 1.1  1999/05/19 19:56:57  vasilche
  1565. * Commit just in case.
  1566. *
  1567. * ===========================================================================
  1568. */