00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
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
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 )
00058 {
00059 return false;
00060 }
00061 #if SIZEOF_LONG == 4
00062
00063 static bool IsNegative(long value)
00064 {
00065 return value < 0;
00066 }
00067 static bool IsNegative(unsigned long )
00068 {
00069 return false;
00070 }
00071 #endif
00072 static bool IsNegative(Int8 value)
00073 {
00074 return value < 0;
00075 }
00076 static bool IsNegative(Uint8 )
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 ,
00110 CObjectMemoryPool* )
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
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* )
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 ) 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 , bool ) const
00360 {
00361 ThrowIncompatibleValue();
00362 }
00363
00364 char CPrimitiveTypeInfo::GetValueChar(TConstObjectPtr ) const
00365 {
00366 ThrowIncompatibleValue();
00367 return 0;
00368 }
00369
00370 void CPrimitiveTypeInfo::SetValueChar(TObjectPtr , char ) const
00371 {
00372 ThrowIncompatibleValue();
00373 }
00374
00375 Int4 CPrimitiveTypeInfo::GetValueInt4(TConstObjectPtr ) const
00376 {
00377 ThrowIncompatibleValue();
00378 return 0;
00379 }
00380
00381 void CPrimitiveTypeInfo::SetValueInt4(TObjectPtr ,
00382 Int4 ) const
00383 {
00384 ThrowIncompatibleValue();
00385 }
00386
00387 Uint4 CPrimitiveTypeInfo::GetValueUint4(TConstObjectPtr ) const
00388 {
00389 ThrowIncompatibleValue();
00390 return 0;
00391 }
00392
00393 void CPrimitiveTypeInfo::SetValueUint4(TObjectPtr ,
00394 Uint4 ) const
00395 {
00396 ThrowIncompatibleValue();
00397 }
00398
00399 Int8 CPrimitiveTypeInfo::GetValueInt8(TConstObjectPtr ) const
00400 {
00401 ThrowIncompatibleValue();
00402 return 0;
00403 }
00404
00405 void CPrimitiveTypeInfo::SetValueInt8(TObjectPtr ,
00406 Int8 ) const
00407 {
00408 ThrowIncompatibleValue();
00409 }
00410
00411 Uint8 CPrimitiveTypeInfo::GetValueUint8(TConstObjectPtr ) const
00412 {
00413 ThrowIncompatibleValue();
00414 return 0;
00415 }
00416
00417 void CPrimitiveTypeInfo::SetValueUint8(TObjectPtr ,
00418 Uint8 ) const
00419 {
00420 ThrowIncompatibleValue();
00421 }
00422
00423 double CPrimitiveTypeInfo::GetValueDouble(TConstObjectPtr ) const
00424 {
00425 ThrowIncompatibleValue();
00426 return 0;
00427 }
00428
00429 void CPrimitiveTypeInfo::SetValueDouble(TObjectPtr ,
00430 double ) 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 ,
00449 string& ) const
00450 {
00451 ThrowIncompatibleValue();
00452 }
00453
00454 void CPrimitiveTypeInfo::SetValueString(TObjectPtr ,
00455 const string& ) const
00456 {
00457 ThrowIncompatibleValue();
00458 }
00459
00460 void CPrimitiveTypeInfo::GetValueOctetString(TConstObjectPtr ,
00461 vector<char>& ) const
00462 {
00463 ThrowIncompatibleValue();
00464 }
00465
00466 void CPrimitiveTypeInfo::SetValueOctetString(TObjectPtr ,
00467 const vector<char>& )
00468 const
00469 {
00470 ThrowIncompatibleValue();
00471 }
00472
00473 void CPrimitiveTypeInfo::GetValueBitString(TConstObjectPtr ,
00474 CBitString& ) const
00475 {
00476 ThrowIncompatibleValue();
00477 }
00478 void CPrimitiveTypeInfo::SetValueBitString(TObjectPtr ,
00479 const CBitString& ) const
00480 {
00481 ThrowIncompatibleValue();
00482 }
00483
00484 void CPrimitiveTypeInfo::GetValueAnyContent(TConstObjectPtr ,
00485 CAnyContentObject& ) const
00486 {
00487 ThrowIncompatibleValue();
00488 }
00489
00490 void CPrimitiveTypeInfo::SetValueAnyContent(TObjectPtr ,
00491 const CAnyContentObject& )
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 ,
00530 CObjectMemoryPool* )
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 )
00556 {
00557 in.ReadNull();
00558 }
00559 static void Write(CObjectOStream& out, TTypeInfo ,
00560 TConstObjectPtr )
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
00704 if ( sizeof(value) == sizeof(result) ) {
00705
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
00722
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
00737
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
00752 if ( sizeof(value) == sizeof(result) ) {
00753
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
00770 if ( sizeof(value) == sizeof(result) ) {
00771
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
00788
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
00803
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
00818 if ( sizeof(value) == sizeof(result) ) {
00819
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 ,
01076 CObjectMemoryPool* )
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 ,
01362 CObjectMemoryPool* )
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
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 ,
01531 CObjectMemoryPool* )
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 ,
01611 CObjectMemoryPool* )
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
01639
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