src/serial/stdtypes.cpp

Go to the documentation of this file.
00001 /*  $Id: stdtypes.cpp 103491 2007-05-04 17:18:18Z kazimird $
00002 * ===========================================================================
00003 *
00004 *                            PUBLIC DOMAIN NOTICE
00005 *               National Center for Biotechnology Information
00006 *
00007 *  This software/database is a "United States Government Work" under the
00008 *  terms of the United States Copyright Act.  It was written as part of
00009 *  the author's official duties as a United States Government employee and
00010 *  thus cannot be copyrighted.  This software/database is freely available
00011 *  to the public for use. The National Library of Medicine and the U.S.
00012 *  Government have not placed any restriction on its use or reproduction.
00013 *
00014 *  Although all reasonable efforts have been taken to ensure the accuracy
00015 *  and reliability of the software and data, the NLM and the U.S.
00016 *  Government do not and cannot warrant the performance or results that
00017 *  may be obtained by using this software or data. The NLM and the U.S.
00018 *  Government disclaim all warranties, express or implied, including
00019 *  warranties of performance, merchantability or fitness for any particular
00020 *  purpose.
00021 *
00022 *  Please cite the author in any work or product based on this material.
00023 *
00024 * ===========================================================================
00025 *
00026 * Author: Eugene Vasilchenko
00027 *
00028 * File Description:
00029 *   CTypeInfo classes for primitive leaf types.
00030 */
00031 
00032 #include <ncbi_pch.hpp>
00033 #include <serial/serialdef.hpp>
00034 #include <serial/impl/stdtypesimpl.hpp>
00035 #include <serial/impl/typeinfoimpl.hpp>
00036 #include <serial/objistr.hpp>
00037 #include <serial/objostr.hpp>
00038 #include <serial/objcopy.hpp>
00039 
00040 #include <limits.h>
00041 #if HAVE_WINDOWS_H
00042 // In MSVC limits.h doesn't define FLT_MIN & FLT_MAX
00043 # include <float.h>
00044 #endif
00045 #include <math.h>
00046 
00047 BEGIN_NCBI_SCOPE
00048 
00049 
00050 class CPrimitiveTypeFunctionsBase
00051 {
00052 public:
00053     static bool IsNegative(Int4 value)
00054         {
00055             return value < 0;
00056         }
00057     static bool IsNegative(Uint4 /*value*/)
00058         {
00059             return false;
00060         }
00061 #if SIZEOF_LONG == 4
00062     // add variants with long to avoid ambiguity
00063     static bool IsNegative(long value)
00064         {
00065             return value < 0;
00066         }
00067     static bool IsNegative(unsigned long /*value*/)
00068         {
00069             return false;
00070         }
00071 #endif
00072     static bool IsNegative(Int8 value)
00073         {
00074             return value < 0;
00075         }
00076     static bool IsNegative(Uint8 /*value*/)
00077         {
00078             return false;
00079         }
00080 };
00081 
00082 template<typename T>
00083 class CPrimitiveTypeFunctions : public CPrimitiveTypeFunctionsBase
00084 {
00085 public:
00086     typedef T TObjectType;
00087 
00088     static TObjectType& Get(TObjectPtr object)
00089         {
00090             return CTypeConverter<TObjectType>::Get(object);
00091         }
00092     static const TObjectType& Get(TConstObjectPtr object)
00093         {
00094             return CTypeConverter<TObjectType>::Get(object);
00095         }
00096 
00097     static void SetIOFunctions(CPrimitiveTypeInfo* info)
00098         {
00099             info->SetIOFunctions(&Read, &Write, &Copy, &Skip);
00100         }
00101 
00102     static void SetMemFunctions(CPrimitiveTypeInfo* info)
00103         {
00104             info->SetMemFunctions(&Create,
00105                                   &IsDefault, &SetDefault,
00106                                   &Equals, &Assign);
00107         }
00108 
00109     static TObjectPtr Create(TTypeInfo /*typeInfo*/,
00110                              CObjectMemoryPool* /*memoryPool*/)
00111         {
00112             return new TObjectType(0);
00113         }
00114     static bool IsDefault(TConstObjectPtr objectPtr)
00115         {
00116             return Get(objectPtr) == TObjectType(0);
00117         }
00118     static void SetDefault(TObjectPtr objectPtr)
00119         {
00120             Get(objectPtr) = TObjectType(0);
00121         }
00122 
00123     static bool Equals(TConstObjectPtr obj1, TConstObjectPtr obj2,
00124                        ESerialRecursionMode)
00125         {
00126             return Get(obj1) == Get(obj2);
00127         }
00128     static void Assign(TObjectPtr dst, TConstObjectPtr src,
00129                        ESerialRecursionMode)
00130         {
00131             Get(dst) = Get(src);
00132         }
00133 
00134     static void Read(CObjectIStream& in,
00135                      TTypeInfo , TObjectPtr objectPtr)
00136         {
00137             in.ReadStd(Get(objectPtr));
00138         }
00139     static void Write(CObjectOStream& out,
00140                       TTypeInfo , TConstObjectPtr objectPtr)
00141         {
00142             out.WriteStd(Get(objectPtr));
00143         }
00144     static void Skip(CObjectIStream& in, TTypeInfo )
00145         {
00146             TObjectType data;
00147             in.ReadStd(data);
00148         }
00149     static void Copy(CObjectStreamCopier& copier, TTypeInfo )
00150         {
00151             TObjectType data;
00152             copier.In().ReadStd(data);
00153             copier.Out().WriteStd(data);
00154         }
00155 };
00156 
00157 #define EPSILON_(n) 1e-##n
00158 #define EPSILON(n) EPSILON_(n)
00159 
00160 #ifndef DBL_EPSILON
00161 #  define DBL_EPSILON EPSILON(DBL_DIG)
00162 #endif
00163 
00164 EMPTY_TEMPLATE
00165 bool CPrimitiveTypeFunctions<double>::Equals(TConstObjectPtr obj1,
00166                                              TConstObjectPtr obj2,
00167                                              ESerialRecursionMode)
00168 {
00169     const double& x = Get(obj1);
00170     const double& y = Get(obj2);
00171     return (x == y  ||  fabs(x - y) < fabs(x + y) * DBL_EPSILON);
00172 }
00173 
00174 #ifndef FLT_EPSILON
00175 #  define FLT_EPSILON EPSILON(FLT_DIG)
00176 #endif
00177 
00178 EMPTY_TEMPLATE
00179 bool CPrimitiveTypeFunctions<float>::Equals(TConstObjectPtr obj1,
00180                                             TConstObjectPtr obj2,
00181                                             ESerialRecursionMode)
00182 {
00183     const float& x = Get(obj1);
00184     const float& y = Get(obj2);
00185     return (x == y  ||  fabs(x - y) < fabs(x + y) * FLT_EPSILON);
00186 }
00187 
00188 #if SIZEOF_LONG_DOUBLE != 0
00189 
00190 EMPTY_TEMPLATE
00191 bool CPrimitiveTypeFunctions<long double>::Equals(TConstObjectPtr obj1,
00192                                                   TConstObjectPtr obj2,
00193                                                   ESerialRecursionMode)
00194 {
00195     const long double& x = Get(obj1);
00196     const long double& y = Get(obj2);
00197     // We use DBL_EPSILON because I/O is double-based anyway.
00198     return (x == y  ||  fabs(x - y) < fabs(x + y) * DBL_EPSILON);
00199 }
00200 #endif
00201 
00202 void CVoidTypeFunctions::ThrowException(const char* operation,
00203                                         TTypeInfo objectType)
00204 {
00205     string message("cannot ");
00206     message += operation;
00207     message += " object of type: ";
00208     message += objectType->GetName();
00209     NCBI_THROW(CSerialException,eIllegalCall, message);
00210 }
00211 
00212 bool CVoidTypeFunctions::IsDefault(TConstObjectPtr )
00213 {
00214     return true;
00215 }
00216 
00217 bool CVoidTypeFunctions::Equals(TConstObjectPtr , TConstObjectPtr,
00218                                 ESerialRecursionMode )
00219 {
00220     ThrowIllegalCall();
00221     return false;
00222 }
00223 
00224 void CVoidTypeFunctions::SetDefault(TObjectPtr )
00225 {
00226 }
00227 
00228 void CVoidTypeFunctions::Assign(TObjectPtr , TConstObjectPtr, ESerialRecursionMode )
00229 {
00230     ThrowIllegalCall();
00231 }
00232 
00233 void CVoidTypeFunctions::Read(CObjectIStream& in, TTypeInfo ,
00234                               TObjectPtr )
00235 {
00236     in.ThrowError(in.fIllegalCall,
00237                   "CVoidTypeFunctions::Read cannot read");
00238 }
00239 
00240 void CVoidTypeFunctions::Write(CObjectOStream& out, TTypeInfo ,
00241                                TConstObjectPtr )
00242 {
00243     out.ThrowError(out.fIllegalCall,
00244                    "CVoidTypeFunctions::Write cannot write");
00245 }
00246 
00247 void CVoidTypeFunctions::Copy(CObjectStreamCopier& copier, TTypeInfo )
00248 {
00249     copier.ThrowError(CObjectIStream::fIllegalCall,
00250                       "CVoidTypeFunctions::Copy cannot copy");
00251 }
00252 
00253 void CVoidTypeFunctions::Skip(CObjectIStream& in, TTypeInfo )
00254 {
00255     in.ThrowError(in.fIllegalCall,
00256                   "CVoidTypeFunctions::Skip cannot skip");
00257 }
00258 
00259 TObjectPtr CVoidTypeFunctions::Create(TTypeInfo objectType,
00260                                       CObjectMemoryPool* /*memoryPool*/)
00261 {
00262     ThrowException("CVoidTypeFunctions::Create cannot create", objectType);
00263     return 0;
00264 }
00265 
00266 CVoidTypeInfo::CVoidTypeInfo(void)
00267     : CParent(0, ePrimitiveValueSpecial)
00268 {
00269 }
00270 
00271 CPrimitiveTypeInfo::CPrimitiveTypeInfo(size_t size,
00272                                        EPrimitiveValueType valueType,
00273                                        bool isSigned)
00274     : CParent(eTypeFamilyPrimitive, size),
00275       m_ValueType(valueType), m_Signed(isSigned)
00276 {
00277     typedef CVoidTypeFunctions TFunctions;
00278     SetMemFunctions(&TFunctions::Create,
00279                     &TFunctions::IsDefault, &TFunctions::SetDefault,
00280                     &TFunctions::Equals, &TFunctions::Assign);
00281 }
00282 
00283 CPrimitiveTypeInfo::CPrimitiveTypeInfo(size_t size, const char* name,
00284                                        EPrimitiveValueType valueType,
00285                                        bool isSigned)
00286     : CParent(eTypeFamilyPrimitive, size, name),
00287       m_ValueType(valueType), m_Signed(isSigned)
00288 {
00289     typedef CVoidTypeFunctions TFunctions;
00290     SetMemFunctions(&TFunctions::Create,
00291                     &TFunctions::IsDefault, &TFunctions::SetDefault,
00292                     &TFunctions::Equals, &TFunctions::Assign);
00293 }
00294 
00295 CPrimitiveTypeInfo::CPrimitiveTypeInfo(size_t size, const string& name,
00296                                        EPrimitiveValueType valueType,
00297                                        bool isSigned)
00298     : CParent(eTypeFamilyPrimitive, size, name),
00299       m_ValueType(valueType), m_Signed(isSigned)
00300 {
00301     typedef CVoidTypeFunctions TFunctions;
00302     SetMemFunctions(&TFunctions::Create,
00303                     &TFunctions::IsDefault, &TFunctions::SetDefault,
00304                     &TFunctions::Equals, &TFunctions::Assign);
00305 }
00306 
00307 void CPrimitiveTypeInfo::SetMemFunctions(TTypeCreate create,
00308                                          TIsDefaultFunction isDefault,
00309                                          TSetDefaultFunction setDefault,
00310                                          TEqualsFunction equals,
00311                                          TAssignFunction assign)
00312 {
00313     SetCreateFunction(create);
00314     m_IsDefault = isDefault;
00315     m_SetDefault = setDefault;
00316     m_Equals = equals;
00317     m_Assign = assign;
00318 }
00319 
00320 void CPrimitiveTypeInfo::SetIOFunctions(TTypeReadFunction read,
00321                                         TTypeWriteFunction write,
00322                                         TTypeCopyFunction copy,
00323                                         TTypeSkipFunction skip)
00324 {
00325     SetReadFunction(read);
00326     SetWriteFunction(write);
00327     SetCopyFunction(copy);
00328     SetSkipFunction(skip);
00329 }
00330 
00331 bool CPrimitiveTypeInfo::GetValueBool(TConstObjectPtr /*objectPtr*/) const
00332 {
00333     ThrowIncompatibleValue();
00334     return false;
00335 }
00336 
00337 bool CPrimitiveTypeInfo::IsDefault(TConstObjectPtr objectPtr) const
00338 {
00339     return m_IsDefault(objectPtr);
00340 }
00341 
00342 void CPrimitiveTypeInfo::SetDefault(TObjectPtr objectPtr) const
00343 {
00344     m_SetDefault(objectPtr);
00345 }
00346 
00347 bool CPrimitiveTypeInfo::Equals(TConstObjectPtr obj1, TConstObjectPtr obj2,
00348                                 ESerialRecursionMode how) const
00349 {
00350     return m_Equals(obj1, obj2, how);
00351 }
00352 
00353 void CPrimitiveTypeInfo::Assign(TObjectPtr dst, TConstObjectPtr src,
00354                                 ESerialRecursionMode how) const
00355 {
00356     m_Assign(dst, src, how);
00357 }
00358 
00359 void CPrimitiveTypeInfo::SetValueBool(TObjectPtr /*objectPtr*/, bool /*value*/) const
00360 {
00361     ThrowIncompatibleValue();
00362 }
00363 
00364 char CPrimitiveTypeInfo::GetValueChar(TConstObjectPtr /*objectPtr*/) const
00365 {
00366     ThrowIncompatibleValue();
00367     return 0;
00368 }
00369 
00370 void CPrimitiveTypeInfo::SetValueChar(TObjectPtr /*objectPtr*/, char /*value*/) const
00371 {
00372     ThrowIncompatibleValue();
00373 }
00374 
00375 Int4 CPrimitiveTypeInfo::GetValueInt4(TConstObjectPtr /*objectPtr*/) const
00376 {
00377     ThrowIncompatibleValue();
00378     return 0;
00379 }
00380 
00381 void CPrimitiveTypeInfo::SetValueInt4(TObjectPtr /*objectPtr*/,
00382                                       Int4 /*value*/) const
00383 {
00384     ThrowIncompatibleValue();
00385 }
00386 
00387 Uint4 CPrimitiveTypeInfo::GetValueUint4(TConstObjectPtr /*objectPtr*/) const
00388 {
00389     ThrowIncompatibleValue();
00390     return 0;
00391 }
00392 
00393 void CPrimitiveTypeInfo::SetValueUint4(TObjectPtr /*objectPtr*/,
00394                                        Uint4 /*value*/) const
00395 {
00396     ThrowIncompatibleValue();
00397 }
00398 
00399 Int8 CPrimitiveTypeInfo::GetValueInt8(TConstObjectPtr /*objectPtr*/) const
00400 {
00401     ThrowIncompatibleValue();
00402     return 0;
00403 }
00404 
00405 void CPrimitiveTypeInfo::SetValueInt8(TObjectPtr /*objectPtr*/,
00406                                       Int8 /*value*/) const
00407 {
00408     ThrowIncompatibleValue();
00409 }
00410 
00411 Uint8 CPrimitiveTypeInfo::GetValueUint8(TConstObjectPtr /*objectPtr*/) const
00412 {
00413     ThrowIncompatibleValue();
00414     return 0;
00415 }
00416 
00417 void CPrimitiveTypeInfo::SetValueUint8(TObjectPtr /*objectPtr*/,
00418                                        Uint8 /*value*/) const
00419 {
00420     ThrowIncompatibleValue();
00421 }
00422 
00423 double CPrimitiveTypeInfo::GetValueDouble(TConstObjectPtr /*objectPtr*/) const
00424 {
00425     ThrowIncompatibleValue();
00426     return 0;
00427 }
00428 
00429 void CPrimitiveTypeInfo::SetValueDouble(TObjectPtr /*objectPtr*/,
00430                                         double /*value*/) const
00431 {
00432     ThrowIncompatibleValue();
00433 }
00434 
00435 #if SIZEOF_LONG_DOUBLE != 0
00436 long double CPrimitiveTypeInfo::GetValueLDouble(TConstObjectPtr objectPtr) const
00437 {
00438     return GetValueDouble(objectPtr);
00439 }
00440 
00441 void CPrimitiveTypeInfo::SetValueLDouble(TObjectPtr objectPtr,
00442                                          long double value) const
00443 {
00444     SetValueDouble(objectPtr, value);
00445 }
00446 #endif
00447 
00448 void CPrimitiveTypeInfo::GetValueString(TConstObjectPtr /*objectPtr*/,
00449                                         string& /*value*/) const
00450 {
00451     ThrowIncompatibleValue();
00452 }
00453 
00454 void CPrimitiveTypeInfo::SetValueString(TObjectPtr /*objectPtr*/,
00455                                         const string& /*value*/) const
00456 {
00457     ThrowIncompatibleValue();
00458 }
00459 
00460 void CPrimitiveTypeInfo::GetValueOctetString(TConstObjectPtr /*objectPtr*/,
00461                                              vector<char>& /*value*/) const
00462 {
00463     ThrowIncompatibleValue();
00464 }
00465 
00466 void CPrimitiveTypeInfo::SetValueOctetString(TObjectPtr /*objectPtr*/,
00467                                              const vector<char>& /*value*/)
00468     const
00469 {
00470     ThrowIncompatibleValue();
00471 }
00472 
00473 void CPrimitiveTypeInfo::GetValueBitString(TConstObjectPtr /*objectPtr*/,
00474                                            CBitString& /*value*/) const
00475 {
00476     ThrowIncompatibleValue();
00477 }
00478 void CPrimitiveTypeInfo::SetValueBitString(TObjectPtr /*objectPtr*/,
00479                                            const CBitString& /*value*/) const
00480 {
00481     ThrowIncompatibleValue();
00482 }
00483 
00484 void CPrimitiveTypeInfo::GetValueAnyContent(TConstObjectPtr /*objectPtr*/,
00485                                             CAnyContentObject& /*value*/) const
00486 {
00487     ThrowIncompatibleValue();
00488 }
00489 
00490 void CPrimitiveTypeInfo::SetValueAnyContent(TObjectPtr /*objectPtr*/,
00491                                             const CAnyContentObject& /*value*/)
00492     const
00493 {
00494     ThrowIncompatibleValue();
00495 }
00496 
00497 
00498 CPrimitiveTypeInfoBool::CPrimitiveTypeInfoBool(void)
00499     : CParent(sizeof(TObjectType), ePrimitiveValueBool)
00500 {
00501     CPrimitiveTypeFunctions<TObjectType>::SetMemFunctions(this);
00502     CPrimitiveTypeFunctions<TObjectType>::SetIOFunctions(this);
00503 }
00504 
00505 bool CPrimitiveTypeInfoBool::GetValueBool(TConstObjectPtr object) const
00506 {
00507     return CPrimitiveTypeFunctions<TObjectType>::Get(object);
00508 }
00509 
00510 void CPrimitiveTypeInfoBool::SetValueBool(TObjectPtr object, bool value) const
00511 {
00512     CPrimitiveTypeFunctions<TObjectType>::Get(object) = value;
00513 }
00514 
00515 TTypeInfo CStdTypeInfo<bool>::GetTypeInfo(void)
00516 {
00517     static TTypeInfo info = CreateTypeInfo();
00518     return info;
00519 }
00520 
00521 CTypeInfo* CStdTypeInfo<bool>::CreateTypeInfo(void)
00522 {
00523     return new CPrimitiveTypeInfoBool();
00524 }
00525 
00526 class CNullBoolFunctions : public CPrimitiveTypeFunctions<bool>
00527 {
00528 public:
00529     static TObjectPtr Create(TTypeInfo /* type */,
00530                              CObjectMemoryPool* /*memoryPool*/)
00531         {
00532             NCBI_THROW(CSerialException,eIllegalCall,
00533                        "Cannot create NULL object");
00534             return 0;
00535         }
00536     static bool IsDefault(TConstObjectPtr)
00537         {
00538             return false;
00539         }
00540     static void SetDefault(TObjectPtr)
00541         {
00542         }
00543 
00544     static bool Equals(TConstObjectPtr, TConstObjectPtr,
00545                        ESerialRecursionMode)
00546         {
00547             return true;
00548         }
00549     static void Assign(TObjectPtr, TConstObjectPtr,
00550                        ESerialRecursionMode)
00551         {
00552         }
00553 
00554     static void Read(CObjectIStream& in, TTypeInfo ,
00555                      TObjectPtr /* object */)
00556         {
00557             in.ReadNull();
00558         }
00559     static void Write(CObjectOStream& out, TTypeInfo ,
00560                       TConstObjectPtr /* object */)
00561         {
00562             out.WriteNull();
00563         }
00564     static void Copy(CObjectStreamCopier& copier, TTypeInfo )
00565         {
00566             copier.In().ReadNull();
00567             copier.Out().WriteNull();
00568         }
00569     static void Skip(CObjectIStream& in, TTypeInfo )
00570         {
00571             in.SkipNull();
00572         }
00573 };
00574 
00575 TTypeInfo CStdTypeInfo<bool>::GetTypeInfoNullBool(void)
00576 {
00577     static TTypeInfo info = CreateTypeInfoNullBool();
00578     return info;
00579 }
00580 
00581 CTypeInfo* CStdTypeInfo<bool>::CreateTypeInfoNullBool(void)
00582 {
00583     CPrimitiveTypeInfo* info = new CPrimitiveTypeInfoBool;
00584     typedef CNullBoolFunctions TFunctions;
00585     info->SetMemFunctions(&TFunctions::Create, &TFunctions::IsDefault,
00586                           &TFunctions::SetDefault,&TFunctions::Equals,
00587                           &TFunctions::Assign);
00588     info->SetIOFunctions(&TFunctions::Read, &TFunctions::Write,
00589                          &TFunctions::Copy, &TFunctions::Skip);
00590     return info;
00591 }
00592 
00593 CPrimitiveTypeInfoChar::CPrimitiveTypeInfoChar(void)
00594     : CParent(sizeof(TObjectType), ePrimitiveValueChar)
00595 {
00596     CPrimitiveTypeFunctions<TObjectType>::SetMemFunctions(this);
00597     CPrimitiveTypeFunctions<TObjectType>::SetIOFunctions(this);
00598 }
00599 
00600 char CPrimitiveTypeInfoChar::GetValueChar(TConstObjectPtr object) const
00601 {
00602     return CPrimitiveTypeFunctions<TObjectType>::Get(object);
00603 }
00604 
00605 void CPrimitiveTypeInfoChar::SetValueChar(TObjectPtr object, char value) const
00606 {
00607     CPrimitiveTypeFunctions<TObjectType>::Get(object) = value;
00608 }
00609 
00610 void CPrimitiveTypeInfoChar::GetValueString(TConstObjectPtr object,
00611                                             string& value) const
00612 {
00613     value.assign(1, CPrimitiveTypeFunctions<TObjectType>::Get(object));
00614 }
00615 
00616 void CPrimitiveTypeInfoChar::SetValueString(TObjectPtr object,
00617                                             const string& value) const
00618 {
00619     if ( value.size() != 1 )
00620         ThrowIncompatibleValue();
00621     CPrimitiveTypeFunctions<TObjectType>::Get(object) = value[0];
00622 }
00623 
00624 TTypeInfo CStdTypeInfo<char>::GetTypeInfo(void)
00625 {
00626     static TTypeInfo info = CreateTypeInfo();
00627     return info;
00628 }
00629 
00630 CTypeInfo* CStdTypeInfo<char>::CreateTypeInfo(void)
00631 {
00632     return new CPrimitiveTypeInfoChar();
00633 }
00634 
00635 template<typename T>
00636 class CPrimitiveTypeInfoIntFunctions : public CPrimitiveTypeFunctions<T>
00637 {
00638     typedef CPrimitiveTypeFunctions<T> CParent;
00639 public:
00640     typedef T TObjectType;
00641     
00642     static CPrimitiveTypeInfoInt* CreateTypeInfo(void)
00643         {
00644             CPrimitiveTypeInfoInt* info =
00645                 new CPrimitiveTypeInfoInt(sizeof(TObjectType), IsSigned());
00646 
00647             info->SetMemFunctions(&CParent::Create,
00648                                   &IsDefault, &SetDefault, &Equals, &Assign);
00649 
00650             info->SetIOFunctions(&CParent::Read, &CParent::Write,
00651                                  &CParent::Copy, &CParent::Skip);
00652 
00653             SetInt4Functions(info);
00654             SetInt8Functions(info);
00655             return info;
00656         }
00657 
00658     static void SetInt4Functions(CPrimitiveTypeInfoInt* info)
00659         {
00660             info->SetInt4Functions(&GetValueInt4, &SetValueInt4,
00661                                   &GetValueUint4, &SetValueUint4);
00662         }
00663 
00664     static void SetInt8Functions(CPrimitiveTypeInfoInt* info)
00665         {
00666             info->SetInt8Functions(&GetValueInt8, &SetValueInt8,
00667                                   &GetValueUint8, &SetValueUint8);
00668         }
00669 
00670     static bool IsDefault(TConstObjectPtr objectPtr)
00671         {
00672             return CParent::Get(objectPtr) == 0;
00673         }
00674     static void SetDefault(TObjectPtr objectPtr)
00675         {
00676             CParent::Get(objectPtr) = 0;
00677         }
00678     static bool Equals(TConstObjectPtr obj1, TConstObjectPtr obj2,
00679                        ESerialRecursionMode)
00680         {
00681             return CParent::Get(obj1) == CParent::Get(obj2);
00682         }
00683     static void Assign(TObjectPtr dst, TConstObjectPtr src,
00684                        ESerialRecursionMode)
00685         {
00686             CParent::Get(dst) = CParent::Get(src);
00687         }
00688 
00689     static bool IsSigned(void)
00690         {
00691             return TObjectType(-1) < 0;
00692         }
00693     static bool IsUnsigned(void)
00694         {
00695             return TObjectType(-1) > 0;
00696         }
00697 
00698     static Int4 GetValueInt4(TConstObjectPtr objectPtr)
00699         {
00700             TObjectType value = CParent::Get(objectPtr);
00701             Int4 result = Int4(value);
00702             if ( IsUnsigned() ) {
00703                 // unsigned -> signed
00704                 if ( sizeof(value) == sizeof(result) ) {
00705                     // same size - check for sign change only
00706                     if ( CParent::IsNegative(result) )
00707                         ThrowIntegerOverflow();
00708                 }
00709             }
00710             if ( sizeof(value) > sizeof(result) ) {
00711                 if ( value != TObjectType(result) )
00712                     ThrowIntegerOverflow();
00713             }
00714             return result;
00715         }
00716     static Uint4 GetValueUint4(TConstObjectPtr objectPtr)
00717         {
00718             TObjectType value = CParent::Get(objectPtr);
00719             Uint4 result = Uint4(value);
00720             if ( IsSigned() ) {
00721                 // signed -> unsigned
00722                 // check for negative value
00723                 if ( IsNegative(value) )
00724                     ThrowIntegerOverflow();
00725             }
00726             if ( sizeof(value) > sizeof(result) ) {
00727                 if ( value != TObjectType(result) )
00728                     ThrowIntegerOverflow();
00729             }
00730             return result;
00731         }
00732     static void SetValueInt4(TObjectPtr objectPtr, Int4 value)
00733         {
00734             TObjectType result = TObjectType(value);
00735             if ( IsUnsigned() ) {
00736                 // signed -> unsigned
00737                 // check for negative value
00738                 if ( CParent::IsNegative(value) )
00739                     ThrowIntegerOverflow();
00740             }
00741             if ( sizeof(value) > sizeof(result) ) {
00742                 if ( value != Int4(result) )
00743                     ThrowIntegerOverflow();
00744             }
00745             CParent::Get(objectPtr) = result;
00746         }
00747     static void SetValueUint4(TObjectPtr objectPtr, Uint4 value)
00748         {
00749             TObjectType result = TObjectType(value);
00750             if ( IsSigned() ) {
00751                 // unsigned -> signed
00752                 if ( sizeof(value) == sizeof(result) ) {
00753                     // same size - check for sign change only
00754                     if ( IsNegative(result) )
00755                         ThrowIntegerOverflow();
00756                 }
00757             }
00758             if ( sizeof(value) > sizeof(result) ) {
00759                 if ( value != Uint4(result) )
00760                     ThrowIntegerOverflow();
00761             }
00762             CParent::Get(objectPtr) = result;
00763         }
00764     static Int8 GetValueInt8(TConstObjectPtr objectPtr)
00765         {
00766             TObjectType value = CParent::Get(objectPtr);
00767             Int8 result = Int8(value);
00768             if ( IsUnsigned() ) {
00769                 // unsigned -> signed
00770                 if ( sizeof(value) == sizeof(result) ) {
00771                     // same size - check for sign change only
00772                     if ( CParent::IsNegative(result) )
00773                         ThrowIntegerOverflow();
00774                 }
00775             }
00776             if ( sizeof(value) > sizeof(result) ) {
00777                 if ( value != TObjectType(result) )
00778                     ThrowIntegerOverflow();
00779             }
00780             return result;
00781         }
00782     static Uint8 GetValueUint8(TConstObjectPtr objectPtr)
00783         {
00784             TObjectType value = CParent::Get(objectPtr);
00785             Uint8 result = Uint8(value);
00786             if ( IsSigned() ) {
00787                 // signed -> unsigned
00788                 // check for negative value
00789                 if ( IsNegative(value) )
00790                     ThrowIntegerOverflow();
00791             }
00792             if ( sizeof(value) > sizeof(result) ) {
00793                 if ( value != TObjectType(result) )
00794                     ThrowIntegerOverflow();
00795             }
00796             return result;
00797         }
00798     static void SetValueInt8(TObjectPtr objectPtr, Int8 value)
00799         {
00800             TObjectType result = TObjectType(value);
00801             if ( IsUnsigned() ) {
00802                 // signed -> unsigned
00803                 // check for negative value
00804                 if ( CParent::IsNegative(value) )
00805                     ThrowIntegerOverflow();
00806             }
00807             if ( sizeof(value) > sizeof(result) ) {
00808                 if ( value != Int8(result) )
00809                     ThrowIntegerOverflow();
00810             }
00811             CParent::Get(objectPtr) = result;
00812         }
00813     static void SetValueUint8(TObjectPtr objectPtr, Uint8 value)
00814         {
00815             TObjectType result = TObjectType(value);
00816             if ( IsSigned() ) {
00817                 // unsigned -> signed
00818                 if ( sizeof(value) == sizeof(result) ) {
00819                     // same size - check for sign change only
00820                     if ( IsNegative(result) )
00821                         ThrowIntegerOverflow();
00822                 }
00823             }
00824             if ( sizeof(value) > sizeof(result) ) {
00825                 if ( value != Uint8(result) )
00826                     ThrowIntegerOverflow();
00827             }
00828             CParent::Get(objectPtr) = result;
00829         }
00830 };
00831 
00832 CPrimitiveTypeInfoInt::CPrimitiveTypeInfoInt(size_t size, bool isSigned)
00833     : CParent(size, ePrimitiveValueInteger, isSigned)
00834 {
00835 }
00836 
00837 void CPrimitiveTypeInfoInt::SetInt4Functions(TGetInt4Function getInt4,
00838                                              TSetInt4Function setInt4,
00839                                              TGetUint4Function getUint4,
00840                                              TSetUint4Function setUint4)
00841 {
00842     m_GetInt4 = getInt4;
00843     m_SetInt4 = setInt4;
00844     m_GetUint4 = getUint4;
00845     m_SetUint4 = setUint4;
00846 }
00847 
00848 void CPrimitiveTypeInfoInt::SetInt8Functions(TGetInt8Function getInt8,
00849                                              TSetInt8Function setInt8,
00850                                              TGetUint8Function getUint8,
00851                                              TSetUint8Function setUint8)
00852 {
00853     m_GetInt8 = getInt8;
00854     m_SetInt8 = setInt8;
00855     m_GetUint8 = getUint8;
00856     m_SetUint8 = setUint8;
00857 }
00858 
00859 Int4 CPrimitiveTypeInfoInt::GetValueInt4(TConstObjectPtr objectPtr) const
00860 {
00861     return m_GetInt4(objectPtr);
00862 }
00863 
00864 Uint4 CPrimitiveTypeInfoInt::GetValueUint4(TConstObjectPtr objectPtr) const
00865 {
00866     return m_GetUint4(objectPtr);
00867 }
00868 
00869 void CPrimitiveTypeInfoInt::SetValueInt4(TObjectPtr objectPtr,
00870                                          Int4 value) const
00871 {
00872     m_SetInt4(objectPtr, value);
00873 }
00874 
00875 void CPrimitiveTypeInfoInt::SetValueUint4(TObjectPtr objectPtr,
00876                                           Uint4 value) const
00877 {
00878     m_SetUint4(objectPtr, value);
00879 }
00880 
00881 Int8 CPrimitiveTypeInfoInt::GetValueInt8(TConstObjectPtr objectPtr) const
00882 {
00883     return m_GetInt8(objectPtr);
00884 }
00885 
00886 Uint8 CPrimitiveTypeInfoInt::GetValueUint8(TConstObjectPtr objectPtr) const
00887 {
00888     return m_GetUint8(objectPtr);
00889 }
00890 
00891 void CPrimitiveTypeInfoInt::SetValueInt8(TObjectPtr objectPtr,
00892                                          Int8 value) const
00893 {
00894     m_SetInt8(objectPtr, value);
00895 }
00896 
00897 void CPrimitiveTypeInfoInt::SetValueUint8(TObjectPtr objectPtr,
00898                                           Uint8 value) const
00899 {
00900     m_SetUint8(objectPtr, value);
00901 }
00902 
00903 #define DECLARE_STD_INT_TYPE(Type) \
00904 TTypeInfo CStdTypeInfo<Type>::GetTypeInfo(void) \
00905 { \
00906     static TTypeInfo info = CreateTypeInfo(); \
00907     return info; \
00908 } \
00909 CTypeInfo* CStdTypeInfo<Type>::CreateTypeInfo(void) \
00910 { \
00911     return CPrimitiveTypeInfoIntFunctions<Type>::CreateTypeInfo(); \
00912 }
00913 
00914 DECLARE_STD_INT_TYPE(signed char)
00915 DECLARE_STD_INT_TYPE(unsigned char)
00916 DECLARE_STD_INT_TYPE(short)
00917 DECLARE_STD_INT_TYPE(unsigned short)
00918 DECLARE_STD_INT_TYPE(int)
00919 DECLARE_STD_INT_TYPE(unsigned)
00920 #if SIZEOF_LONG == 4
00921 DECLARE_STD_INT_TYPE(long)
00922 DECLARE_STD_INT_TYPE(unsigned long)
00923 #endif
00924 DECLARE_STD_INT_TYPE(Int8)
00925 DECLARE_STD_INT_TYPE(Uint8)
00926 
00927 const CPrimitiveTypeInfo* CPrimitiveTypeInfo::GetIntegerTypeInfo(size_t size,
00928                                                                  bool sign)
00929 {
00930     TTypeInfo info;
00931     if ( size == sizeof(int) ) {
00932         if ( sign )
00933             info = CStdTypeInfo<int>::GetTypeInfo();
00934         else
00935             info = CStdTypeInfo<unsigned>::GetTypeInfo();
00936     }
00937     else if ( size == sizeof(short) ) {
00938         if ( sign )
00939             info = CStdTypeInfo<short>::GetTypeInfo();
00940         else
00941             info = CStdTypeInfo<unsigned short>::GetTypeInfo();
00942     }
00943     else if ( size == sizeof(signed char) ) {
00944         if ( sign )
00945             info = CStdTypeInfo<signed char>::GetTypeInfo();
00946         else
00947             info = CStdTypeInfo<unsigned char>::GetTypeInfo();
00948     }
00949     else if ( size == sizeof(Int8) ) {
00950         if ( sign )
00951             info = CStdTypeInfo<Int8>::GetTypeInfo();
00952         else
00953             info = CStdTypeInfo<Uint8>::GetTypeInfo();
00954     }
00955     else {
00956         string message("Illegal enum size: ");
00957         message += NStr::UIntToString(size);
00958         NCBI_THROW(CSerialException,eInvalidData, message);
00959     }
00960     _ASSERT(info->GetSize() == size);
00961     _ASSERT(info->GetTypeFamily() == eTypeFamilyPrimitive);
00962     _ASSERT(CTypeConverter<CPrimitiveTypeInfo>::SafeCast(info)->GetPrimitiveValueType() == ePrimitiveValueInteger);
00963     return CTypeConverter<CPrimitiveTypeInfo>::SafeCast(info);
00964 }
00965 
00966 CPrimitiveTypeInfoDouble::CPrimitiveTypeInfoDouble(void)
00967     : CParent(sizeof(TObjectType), ePrimitiveValueReal, true)
00968 {
00969     CPrimitiveTypeFunctions<TObjectType>::SetMemFunctions(this);
00970     CPrimitiveTypeFunctions<TObjectType>::SetIOFunctions(this);
00971 }
00972 
00973 double CPrimitiveTypeInfoDouble::GetValueDouble(TConstObjectPtr objectPtr) const
00974 {
00975     return CPrimitiveTypeFunctions<TObjectType>::Get(objectPtr);
00976 }
00977 
00978 void CPrimitiveTypeInfoDouble::SetValueDouble(TObjectPtr objectPtr,
00979                                               double value) const
00980 {
00981     CPrimitiveTypeFunctions<TObjectType>::Get(objectPtr) = value;
00982 }
00983 
00984 TTypeInfo CStdTypeInfo<double>::GetTypeInfo(void)
00985 {
00986     static TTypeInfo info = CreateTypeInfo();
00987     return info;
00988 }
00989 
00990 CTypeInfo* CStdTypeInfo<double>::CreateTypeInfo(void)
00991 {
00992     return new CPrimitiveTypeInfoDouble();
00993 }
00994 
00995 CPrimitiveTypeInfoFloat::CPrimitiveTypeInfoFloat(void)
00996     : CParent(sizeof(TObjectType), ePrimitiveValueReal, true)
00997 {
00998     CPrimitiveTypeFunctions<TObjectType>::SetMemFunctions(this);
00999     CPrimitiveTypeFunctions<TObjectType>::SetIOFunctions(this);
01000 }
01001 
01002 double CPrimitiveTypeInfoFloat::GetValueDouble(TConstObjectPtr objectPtr) const
01003 {
01004     return CPrimitiveTypeFunctions<TObjectType>::Get(objectPtr);
01005 }
01006 
01007 void CPrimitiveTypeInfoFloat::SetValueDouble(TObjectPtr objectPtr,
01008                                              double value) const
01009 {
01010 #if defined(FLT_MIN) && defined(FLT_MAX)
01011     if ( value < FLT_MIN || value > FLT_MAX )
01012         ThrowIncompatibleValue();
01013 #endif
01014     CPrimitiveTypeFunctions<TObjectType>::Get(objectPtr) = TObjectType(value);
01015 }
01016 
01017 TTypeInfo CStdTypeInfo<float>::GetTypeInfo(void)
01018 {
01019     static TTypeInfo info = CreateTypeInfo();
01020     return info;
01021 }
01022 
01023 CTypeInfo* CStdTypeInfo<float>::CreateTypeInfo(void)
01024 {
01025     return new CPrimitiveTypeInfoFloat();
01026 }
01027 
01028 #if SIZEOF_LONG_DOUBLE != 0
01029 CPrimitiveTypeInfoLongDouble::CPrimitiveTypeInfoLongDouble(void)
01030     : CParent(sizeof(TObjectType), ePrimitiveValueReal, true)
01031 {
01032     CPrimitiveTypeFunctions<TObjectType>::SetMemFunctions(this);
01033     CPrimitiveTypeFunctions<TObjectType>::SetIOFunctions(this);
01034 }
01035 
01036 double CPrimitiveTypeInfoLongDouble::GetValueDouble(TConstObjectPtr objectPtr) const
01037 {
01038     return CPrimitiveTypeFunctions<TObjectType>::Get(objectPtr);
01039 }
01040 
01041 void CPrimitiveTypeInfoLongDouble::SetValueDouble(TObjectPtr objectPtr,
01042                                                double value) const
01043 {
01044     CPrimitiveTypeFunctions<TObjectType>::Get(objectPtr) = TObjectType(value);
01045 }
01046 
01047 long double CPrimitiveTypeInfoLongDouble::GetValueLDouble(TConstObjectPtr objectPtr) const
01048 {
01049     return CPrimitiveTypeFunctions<TObjectType>::Get(objectPtr);
01050 }
01051 
01052 void CPrimitiveTypeInfoLongDouble::SetValueLDouble(TObjectPtr objectPtr,
01053                                                    long double value) const
01054 {
01055     CPrimitiveTypeFunctions<TObjectType>::Get(objectPtr) = TObjectType(value);
01056 }
01057 
01058 TTypeInfo CStdTypeInfo<long double>::GetTypeInfo(void)
01059 {
01060     static TTypeInfo info = CreateTypeInfo();
01061     return info;
01062 }
01063 
01064 CTypeInfo* CStdTypeInfo<long double>::CreateTypeInfo(void)
01065 {
01066     return new CPrimitiveTypeInfoLongDouble();
01067 }
01068 #endif
01069 
01070 template<typename T>
01071 class CStringFunctions : public CPrimitiveTypeFunctions<T>
01072 {
01073     typedef CPrimitiveTypeFunctions<T> CParent;
01074 public:
01075     static TObjectPtr Create(TTypeInfo /*typeInfo*/,
01076                              CObjectMemoryPool* /*memoryPool*/)
01077         {
01078             return new T();
01079         }
01080     static bool IsDefault(TConstObjectPtr objectPtr)
01081         {
01082             return CParent::Get(objectPtr).empty();
01083         }
01084     static void SetDefault(TObjectPtr objectPtr)
01085         {
01086             CParent::Get(objectPtr).erase();
01087         }
01088     static void Copy(CObjectStreamCopier& copier, TTypeInfo )
01089         {
01090             copier.CopyString();
01091         }
01092     static void Skip(CObjectIStream& in, TTypeInfo )
01093         {
01094             in.SkipString();
01095         }
01096 };
01097 
01098 CPrimitiveTypeInfoString::CPrimitiveTypeInfoString(EType type)
01099     : CParent(sizeof(string), ePrimitiveValueString), m_Type(type)
01100 {
01101     if (type == eStringTypeUTF8) {
01102         SetMemFunctions(&CStringFunctions<CStringUTF8>::Create,
01103                         &CStringFunctions<CStringUTF8>::IsDefault,
01104                         &CStringFunctions<CStringUTF8>::SetDefault,
01105                         &CStringFunctions<CStringUTF8>::Equals,
01106                         &CStringFunctions<CStringUTF8>::Assign);
01107         SetIOFunctions(&CStringFunctions<CStringUTF8>::Read,
01108                        &CStringFunctions<CStringUTF8>::Write,
01109                        &CStringFunctions<CStringUTF8>::Copy,
01110                        &CStringFunctions<CStringUTF8>::Skip);
01111     } else {
01112         SetMemFunctions(&CStringFunctions<string>::Create,
01113                         &CStringFunctions<string>::IsDefault,
01114                         &CStringFunctions<string>::SetDefault,
01115                         &CStringFunctions<string>::Equals,
01116                         &CStringFunctions<string>::Assign);
01117         SetIOFunctions(&CStringFunctions<string>::Read,
01118                        &CStringFunctions<string>::Write,
01119                        &CStringFunctions<string>::Copy,
01120                        &CStringFunctions<string>::Skip);
01121     }
01122 }
01123 
01124 void CPrimitiveTypeInfoString::GetValueString(TConstObjectPtr object,
01125                                               string& value) const
01126 {
01127     value = CPrimitiveTypeFunctions<TObjectType>::Get(object);
01128 }
01129 
01130 void CPrimitiveTypeInfoString::SetValueString(TObjectPtr object,
01131                                               const string& value) const
01132 {
01133     CPrimitiveTypeFunctions<TObjectType>::Get(object) = value;
01134 }
01135 
01136 char CPrimitiveTypeInfoString::GetValueChar(TConstObjectPtr object) const
01137 {
01138     if ( CPrimitiveTypeFunctions<TObjectType>::Get(object).size() != 1 )
01139         ThrowIncompatibleValue();
01140     return CPrimitiveTypeFunctions<TObjectType>::Get(object)[0];
01141 }
01142 
01143 void CPrimitiveTypeInfoString::SetValueChar(TObjectPtr object,
01144                                             char value) const
01145 {
01146     CPrimitiveTypeFunctions<TObjectType>::Get(object).assign(1, value);
01147 }
01148 
01149 TTypeInfo CStdTypeInfo<string>::GetTypeInfo(void)
01150 {
01151     static TTypeInfo info = CreateTypeInfo();
01152     return info;
01153 }
01154 
01155 CTypeInfo* CStdTypeInfo<string>::CreateTypeInfo(void)
01156 {
01157     return new CPrimitiveTypeInfoString();
01158 }
01159 
01160 TTypeInfo CStdTypeInfo<ncbi::CStringUTF8>::GetTypeInfo(void)
01161 {
01162     static TTypeInfo info = CreateTypeInfo();
01163     return info;
01164 }
01165 
01166 CTypeInfo* CStdTypeInfo<ncbi::CStringUTF8>::CreateTypeInfo(void)
01167 {
01168     return new CPrimitiveTypeInfoString(CPrimitiveTypeInfoString::eStringTypeUTF8);
01169 }
01170 
01171 class CStringStoreFunctions : public CStringFunctions<string>
01172 {
01173 public:
01174     static void Read(CObjectIStream& in, TTypeInfo , TObjectPtr objectPtr)
01175         {
01176             in.ReadStringStore(Get(objectPtr));
01177         }
01178     static void Write(CObjectOStream& out, TTypeInfo ,
01179                       TConstObjectPtr objectPtr)
01180         {
01181             out.WriteStringStore(Get(objectPtr));
01182         }
01183     static void Copy(CObjectStreamCopier& copier, TTypeInfo )
01184         {
01185             copier.CopyStringStore();
01186         }
01187     static void Skip(CObjectIStream& in, TTypeInfo )
01188         {
01189             in.SkipStringStore();
01190         }
01191 };
01192 
01193 TTypeInfo CStdTypeInfo<string>::GetTypeInfoStringStore(void)
01194 {
01195     static TTypeInfo info = CreateTypeInfoStringStore();
01196     return info;
01197 }
01198 
01199 CTypeInfo* CStdTypeInfo<string>::CreateTypeInfoStringStore(void)
01200 {
01201     CPrimitiveTypeInfo* info = new CPrimitiveTypeInfoString;
01202     typedef CStringStoreFunctions TFunctions;
01203     info->SetIOFunctions(&TFunctions::Read, &TFunctions::Write,
01204                          &TFunctions::Copy, &TFunctions::Skip);
01205     return info;
01206 }
01207 
01208 template<typename T>
01209 class CCharPtrFunctions : public CPrimitiveTypeFunctions<T>
01210 {
01211     typedef CPrimitiveTypeFunctions<T> CParent;
01212 public:
01213     static bool IsDefault(TConstObjectPtr objectPtr)
01214         {
01215             return CParent::Get(objectPtr) == 0;
01216         }
01217     static void SetDefault(TObjectPtr dst)
01218         {
01219             free(const_cast<char*>(CParent::Get(dst)));
01220             CParent::Get(dst) = 0;
01221         }
01222     static bool Equals(TConstObjectPtr object1, TConstObjectPtr object2,
01223                        ESerialRecursionMode)
01224         {
01225             return strcmp(CParent::Get(object1), CParent::Get(object2)) == 0;
01226         }
01227     static void Assign(TObjectPtr dst, TConstObjectPtr src,
01228                        ESerialRecursionMode)
01229         {
01230             typename CPrimitiveTypeFunctions<T>::TObjectType value
01231                 = CParent::Get(src);
01232             _ASSERT(CParent::Get(dst) != value);
01233             free(const_cast<char*>(CParent::Get(dst)));
01234             if ( value )
01235                 CParent::Get(dst) = NotNull(strdup(value));
01236             else
01237                 CParent::Get(dst) = 0;
01238         }
01239 };
01240 
01241 template<typename T>
01242 CPrimitiveTypeInfoCharPtr<T>::CPrimitiveTypeInfoCharPtr(void)
01243     : CParent(sizeof(TObjectType), ePrimitiveValueString)
01244 {
01245     typedef CCharPtrFunctions<TObjectType> TFunctions;
01246     SetMemFunctions(&CVoidTypeFunctions::Create,
01247                     &TFunctions::IsDefault, &TFunctions::SetDefault,
01248                     &TFunctions::Equals, &TFunctions::Assign);
01249     SetIOFunctions(&TFunctions::Read, &TFunctions::Write,
01250                    &TFunctions::Copy, &TFunctions::Skip);
01251 }
01252 
01253 template<typename T>
01254 char CPrimitiveTypeInfoCharPtr<T>::GetValueChar(TConstObjectPtr objectPtr) const
01255 {
01256     TObjectType obj = CCharPtrFunctions<TObjectType>::Get(objectPtr);
01257     if ( !obj || obj[0] == '\0' || obj[1] != '\0' )
01258         ThrowIncompatibleValue();
01259     return obj[0];
01260 }
01261 
01262 template<typename T>
01263 void CPrimitiveTypeInfoCharPtr<T>::SetValueChar(TObjectPtr objectPtr,
01264                                                 char value) const
01265 {
01266     char* obj = static_cast<char*>(NotNull(malloc(2)));
01267     obj[0] =  value;
01268     obj[1] = '\0';
01269     CCharPtrFunctions<TObjectPtr>::Get(objectPtr) = obj;
01270 }
01271 
01272 template<typename T>
01273 void CPrimitiveTypeInfoCharPtr<T>::GetValueString(TConstObjectPtr objectPtr,
01274                                                   string& value) const
01275 {
01276     value = CCharPtrFunctions<TObjectType>::Get(objectPtr);
01277 }
01278 
01279 template<typename T>
01280 void CPrimitiveTypeInfoCharPtr<T>::SetValueString(TObjectPtr objectPtr,
01281                                                   const string& value) const
01282 {
01283     CCharPtrFunctions<TObjectPtr>::Get(objectPtr) =
01284         NotNull(strdup(value.c_str()));
01285 }
01286 
01287 TTypeInfo CStdTypeInfo<char*>::GetTypeInfo(void)
01288 {
01289     static TTypeInfo info = CreateTypeInfo();
01290     return info;
01291 }
01292 
01293 CTypeInfo* CStdTypeInfo<char*>::CreateTypeInfo(void)
01294 {
01295     return new CPrimitiveTypeInfoCharPtr<char*>();
01296 }
01297 
01298 TTypeInfo CStdTypeInfo<const char*>::GetTypeInfo(void)
01299 {
01300     static TTypeInfo info = CreateTypeInfo();
01301     return info;
01302 }
01303 
01304 CTypeInfo* CStdTypeInfo<const char*>::CreateTypeInfo(void)
01305 {
01306     return new CPrimitiveTypeInfoCharPtr<const char*>();
01307 }
01308 
01309 void ThrowIncompatibleValue(void)
01310 {
01311     NCBI_THROW(CSerialException,eInvalidData, "incompatible value");
01312 }
01313 
01314 void ThrowIllegalCall(void)
01315 {
01316     NCBI_THROW(CSerialException,eIllegalCall, "illegal call");
01317 }
01318 
01319 void ThrowIntegerOverflow(void)
01320 {
01321     NCBI_THROW(CSerialException,eOverflow, "integer overflow");
01322 }
01323 
01324 class CCharVectorFunctionsBase
01325 {
01326 public:
01327     static void Copy(CObjectStreamCopier& copier,
01328                      TTypeInfo )
01329         {
01330             copier.CopyByteBlock();
01331         }
01332     static void Skip(CObjectIStream& in, TTypeInfo )
01333         {
01334             in.SkipByteBlock();
01335         }
01336 };
01337 
01338 template<typename Char>
01339 class CCharVectorFunctions : public CCharVectorFunctionsBase
01340 {
01341 public:
01342     typedef vector<Char> TObjectType;
01343     typedef Char TChar;
01344 
01345     static TObjectType& Get(TObjectPtr object)
01346         {
01347             return CTypeConverter<TObjectType>::Get(object);
01348         }
01349     static const TObjectType& Get(TConstObjectPtr object)
01350         {
01351             return CTypeConverter<TObjectType>::Get(object);
01352         }
01353 
01354     static char* ToChar(TChar* p)
01355         { return reinterpret_cast<char*>(p); }
01356     static const char* ToChar(const TChar* p)
01357         { return reinterpret_cast<const char*>(p); }
01358     static const TChar* ToTChar(const char* p)
01359         { return reinterpret_cast<const TChar*>(p); }
01360 
01361     static TObjectPtr Create(TTypeInfo /*typeInfo*/,
01362                              CObjectMemoryPool* /*memoryPool*/)
01363         {
01364             return new TObjectType();
01365         }
01366     static bool IsDefault(TConstObjectPtr object)
01367         {
01368             return Get(object).empty();
01369         }
01370     static bool Equals(TConstObjectPtr object1, TConstObjectPtr object2,
01371                        ESerialRecursionMode)
01372         {
01373             return Get(object1) == Get(object2);
01374         }
01375     static void SetDefault(TObjectPtr dst)
01376         {
01377             Get(dst).clear();
01378         }
01379     static void Assign(TObjectPtr dst, TConstObjectPtr src,
01380                        ESerialRecursionMode)
01381         {
01382             Get(dst) = Get(src);
01383         }
01384 
01385     static void Read(CObjectIStream& in,
01386                      TTypeInfo , TObjectPtr objectPtr)
01387         {
01388             TObjectType& o = Get(objectPtr);
01389             CObjectIStream::ByteBlock block(in);
01390             if ( block.KnownLength() ) {
01391                 size_t length = block.GetExpectedLength();
01392 #if 1
01393                 o.clear();
01394                 o.reserve(length);
01395                 Char buf[2048];
01396                 size_t count;
01397                 while ( (count = block.Read(ToChar(buf), sizeof(buf))) != 0 ) {
01398                     o.insert(o.end(), buf, buf + count);
01399                 }
01400 #else
01401                 o.resize(length);
01402                 block.Read(ToChar(&o.front()), length, true);
01403 #endif
01404             }
01405             else {
01406                 // length is unknown -> copy via buffer
01407                 o.clear();
01408                 Char buf[4096];
01409                 size_t count;
01410                 while ( (count = block.Read(ToChar(buf), sizeof(buf))) != 0 ) {
01411 #ifdef RESERVE_VECTOR_SIZE
01412                     size_t new_size = o.size() + count;
01413                     if ( new_size > o.capacity() ) {
01414                         o.reserve(RESERVE_VECTOR_SIZE(new_size));
01415                     }
01416 #endif
01417                     o.insert(o.end(), buf, buf + count);
01418                 }
01419             }
01420             block.End();
01421         }
01422     static void Write(CObjectOStream& out,
01423                       TTypeInfo , TConstObjectPtr objectPtr)
01424         {
01425             const TObjectType& o = Get(objectPtr);
01426             size_t length = o.size();
01427             CObjectOStream::ByteBlock block(out, length);
01428             if ( length > 0 )
01429                 block.Write(ToChar(&o.front()), length);
01430             block.End();
01431         }
01432 };
01433 
01434 template<typename Char>
01435 CCharVectorTypeInfo<Char>::CCharVectorTypeInfo(void)
01436     : CParent(sizeof(TObjectType), ePrimitiveValueOctetString)
01437 {
01438     typedef CCharVectorFunctions<Char> TFunctions;
01439     SetMemFunctions(&TFunctions::Create,
01440                     &TFunctions::IsDefault, &TFunctions::SetDefault,
01441                     &TFunctions::Equals, &TFunctions::Assign);
01442     SetIOFunctions(&TFunctions::Read, &TFunctions::Write,
01443                    &TFunctions::Copy, &TFunctions::Skip);
01444 }
01445 
01446 template<typename Char>
01447 void CCharVectorTypeInfo<Char>::GetValueString(TConstObjectPtr objectPtr,
01448                                                string& value) const
01449 {
01450     const TObjectType& obj = CCharVectorFunctions<TChar>::Get(objectPtr);
01451     if (!obj.empty()) {
01452         const char* buffer = CCharVectorFunctions<TChar>::ToChar(&obj.front());
01453         value.assign(buffer, buffer + obj.size());
01454     }
01455 }
01456 
01457 template<typename Char>
01458 void CCharVectorTypeInfo<Char>::SetValueString(TObjectPtr objectPtr,
01459                                                const string& value) const
01460 {
01461     TObjectType& obj = CCharVectorFunctions<TChar>::Get(objectPtr);
01462     obj.clear();
01463     if (!value.empty()) {
01464         const TChar* buffer = CCharVectorFunctions<TChar>::ToTChar(value.data());
01465         obj.insert(obj.end(), buffer, buffer + value.size());
01466     }
01467 }
01468 
01469 template<typename Char>
01470 void CCharVectorTypeInfo<Char>::GetValueOctetString(TConstObjectPtr objectPtr,
01471                                                     vector<char>& value) const
01472 {
01473     const TObjectType& obj = CCharVectorFunctions<TChar>::Get(objectPtr);
01474     value.clear();
01475     if (!obj.empty()) {
01476         const char* buffer = CCharVectorFunctions<TChar>::ToChar(&obj.front());
01477         value.insert(value.end(), buffer, buffer + obj.size());
01478     }
01479 }
01480 
01481 template<typename Char>
01482 void CCharVectorTypeInfo<Char>::SetValueOctetString(TObjectPtr objectPtr,
01483                                                     const vector<char>& value) const
01484 {
01485     TObjectType& obj = CCharVectorFunctions<TChar>::Get(objectPtr);
01486     obj.clear();
01487     if (!value.empty()) {
01488         const TChar* buffer = CCharVectorFunctions<TChar>::ToTChar(&value.front());
01489         obj.insert(obj.end(), buffer, buffer + value.size());
01490     }
01491 }
01492 
01493 TTypeInfo CStdTypeInfo< vector<char> >::GetTypeInfo(void)
01494 {
01495     static TTypeInfo typeInfo = CreateTypeInfo();
01496     return typeInfo;
01497 }
01498 
01499 TTypeInfo CStdTypeInfo< vector<signed char> >::GetTypeInfo(void)
01500 {
01501     static TTypeInfo typeInfo = CreateTypeInfo();
01502     return typeInfo;
01503 }
01504 
01505 TTypeInfo CStdTypeInfo< vector<unsigned char> >::GetTypeInfo(void)
01506 {
01507     static TTypeInfo typeInfo = CreateTypeInfo();
01508     return typeInfo;
01509 }
01510 
01511 CTypeInfo* CStdTypeInfo< vector<char> >::CreateTypeInfo(void)
01512 {
01513     return new CCharVectorTypeInfo<char>;
01514 }
01515 
01516 CTypeInfo* CStdTypeInfo< vector<signed char> >::CreateTypeInfo(void)
01517 {
01518     return new CCharVectorTypeInfo<signed char>;
01519 }
01520 
01521 CTypeInfo* CStdTypeInfo< vector<unsigned char> >::CreateTypeInfo(void)
01522 {
01523     return new CCharVectorTypeInfo<unsigned char>;
01524 }
01525 
01526 
01527 class CAnyContentFunctions : public CPrimitiveTypeFunctions<ncbi::CAnyContentObject>
01528 {
01529 public:
01530     static TObjectPtr Create(TTypeInfo /*typeInfo*/,
01531                              CObjectMemoryPool* /*memoryPool*/)
01532         {
01533             return new TObjectType();
01534         }
01535     static bool IsDefault(TConstObjectPtr objectPtr)
01536         {
01537             return Get(objectPtr) == TObjectType();
01538         }
01539     static void SetDefault(TObjectPtr objectPtr)
01540         {
01541             Get(objectPtr) = TObjectType();
01542         }
01543     static void Read(CObjectIStream& in, TTypeInfo , TObjectPtr objectPtr)
01544         {
01545             in.ReadAnyContentObject(Get(objectPtr));
01546         }
01547     static void Write(CObjectOStream& out, TTypeInfo ,
01548                       TConstObjectPtr objectPtr)
01549         {
01550             out.WriteAnyContentObject(Get(objectPtr));
01551         }
01552     static void Copy(CObjectStreamCopier& copier, TTypeInfo )
01553         {
01554             copier.CopyAnyContentObject();
01555         }
01556     static void Skip(CObjectIStream& in, TTypeInfo )
01557         {
01558             in.SkipAnyContentObject();
01559         }
01560 };
01561 
01562 CPrimitiveTypeInfoAnyContent::CPrimitiveTypeInfoAnyContent(void)
01563     : CParent(sizeof(CAnyContentObject), ePrimitiveValueAny)
01564 {
01565     m_IsCObject = true;
01566     typedef CPrimitiveTypeFunctions<ncbi::CAnyContentObject> TFunctions;
01567     SetMemFunctions(&CAnyContentFunctions::Create,
01568                     &CAnyContentFunctions::IsDefault,
01569                     &CAnyContentFunctions::SetDefault,
01570                     &TFunctions::Equals, &TFunctions::Assign);
01571     SetIOFunctions(&CAnyContentFunctions::Read,
01572                    &CAnyContentFunctions::Write,
01573                    &CAnyContentFunctions::Copy,
01574                    &CAnyContentFunctions::Skip);
01575 }
01576 
01577 TTypeInfo CStdTypeInfo<CAnyContentObject>::GetTypeInfo(void)
01578 {
01579     static TTypeInfo info = CreateTypeInfo();
01580     return info;
01581 }
01582 
01583 CTypeInfo* CStdTypeInfo<ncbi::CAnyContentObject>::CreateTypeInfo(void)
01584 {
01585     return new CPrimitiveTypeInfoAnyContent();
01586 }
01587 
01588 void
01589 CPrimitiveTypeInfoAnyContent::GetValueAnyContent(TConstObjectPtr objectPtr,
01590                                                  CAnyContentObject& value)
01591     const
01592 {
01593     typedef CPrimitiveTypeFunctions<ncbi::CAnyContentObject> TFunctions;
01594     value = TFunctions::Get(objectPtr);
01595 }
01596 
01597 void
01598 CPrimitiveTypeInfoAnyContent::SetValueAnyContent(TObjectPtr objectPtr,
01599                                                  const CAnyContentObject& value)
01600     const
01601 {
01602     typedef CPrimitiveTypeFunctions<ncbi::CAnyContentObject> TFunctions;
01603     TFunctions::Get(objectPtr) = value;
01604 }
01605 
01606 
01607 class CBitStringFunctions : public CPrimitiveTypeFunctions<CBitString>
01608 {
01609 public:
01610     static TObjectPtr Create(TTypeInfo /*typeInfo*/,
01611                              CObjectMemoryPool* /*memoryPool*/)
01612         {
01613             return new TObjectType();
01614         }
01615     static bool IsDefault(TConstObjectPtr objectPtr)
01616         {
01617             return Get(objectPtr) == TObjectType();
01618         }
01619     static void SetDefault(TObjectPtr objectPtr)
01620         {
01621             Get(objectPtr) = TObjectType();
01622         }
01623 };
01624 
01625 CPrimitiveTypeInfoBitString::CPrimitiveTypeInfoBitString(void)
01626     : CParent(sizeof(CBitString), ePrimitiveValueBitString)
01627 {
01628     typedef CPrimitiveTypeFunctions<ncbi::CBitString> TFunctions;
01629     SetMemFunctions(&CBitStringFunctions::Create,
01630                     &CBitStringFunctions::IsDefault,
01631                     &CBitStringFunctions::SetDefault,
01632                     &TFunctions::Equals,
01633                     &TFunctions::Assign);
01634     SetIOFunctions(&TFunctions::Read,
01635                    &TFunctions::Write,
01636                    &TFunctions::Copy,
01637                    &TFunctions::Skip);
01638 //    CPrimitiveTypeFunctions<CBitString>::SetMemFunctions(this);
01639 //    CPrimitiveTypeFunctions<CBitString>::SetIOFunctions(this);
01640 }
01641 
01642 TTypeInfo CStdTypeInfo<CBitString>::GetTypeInfo(void)
01643 {
01644     static TTypeInfo info = CreateTypeInfo();
01645     return info;
01646 }
01647 
01648 CTypeInfo* CStdTypeInfo<CBitString>::CreateTypeInfo(void)
01649 {
01650     return new CPrimitiveTypeInfoBitString();
01651 }
01652 
01653 void CPrimitiveTypeInfoBitString::GetValueBitString(TConstObjectPtr objectPtr,
01654                                                     CBitString& value) const
01655 {
01656     typedef CPrimitiveTypeFunctions<ncbi::CBitString> TFunctions;
01657     value = TFunctions::Get(objectPtr);
01658 }
01659 
01660 void CPrimitiveTypeInfoBitString::SetValueBitString(TObjectPtr objectPtr,
01661                                                     const CBitString& value)
01662     const
01663 {
01664     typedef CPrimitiveTypeFunctions<ncbi::CBitString> TFunctions;
01665     TFunctions::Get(objectPtr) = value;
01666 }
01667 
01668 END_NCBI_SCOPE
01669 
01670 

Generated on Wed Dec 9 05:25:25 2009 for NCBI C++ ToolKit by  doxygen 1.4.6
Modified on Wed Dec 09 08:18:14 2009 by modify_doxy.py rev. 173732