1 /* $Id: continfo.cpp 463313 2015-03-26 17:05:21Z vasilche $
2 * ===========================================================================
3 *
4 * PUBLIC DOMAIN NOTICE
5 * National Center for Biotechnology Information
6 *
7 * This software/database is a "United States Government Work" under the
8 * terms of the United States Copyright Act. It was written as part of
9 * the author's official duties as a United States Government employee and
10 * thus cannot be copyrighted. This software/database is freely available
11 * to the public for use. The National Library of Medicine and the U.S.
12 * Government have not placed any restriction on its use or reproduction.
13 *
14 * Although all reasonable efforts have been taken to ensure the accuracy
15 * and reliability of the software and data, the NLM and the U.S.
16 * Government do not and cannot warrant the performance or results that
17 * may be obtained by using this software or data. The NLM and the U.S.
18 * Government disclaim all warranties, express or implied, including
19 * warranties of performance, merchantability or fitness for any particular
20 * purpose.
21 *
22 * Please cite the author in any work or product based on this material.
23 *
24 * ===========================================================================
25 *
26 * Author: Eugene Vasilchenko
27 *
28 * File Description:
29 * !!! PUT YOUR DESCRIPTION HERE !!!
30 */
31
32 #include <ncbi_pch.hpp>
33 #include <corelib/ncbistd.hpp>
34 #include <corelib/ncbiutil.hpp>
35 #include <serial/impl/continfo.hpp>
36 #include <serial/objistr.hpp>
37 #include <serial/objostr.hpp>
38 #include <serial/objcopy.hpp>
39 #include <serial/serialutil.hpp>
40 #include <serial/error_codes.hpp>
41
42
43 #define NCBI_USE_ERRCODE_X Serial_TypeInfo
44
45 BEGIN_NCBI_SCOPE
46
CContainerTypeInfo(size_t size,TTypeInfo elementType,bool randomOrder)47 CContainerTypeInfo::CContainerTypeInfo(size_t size,
48 TTypeInfo elementType,
49 bool randomOrder)
50 : CParent(eTypeFamilyContainer, size),
51 m_ElementType(elementType), m_RandomOrder(randomOrder)
52 {
53 InitContainerTypeInfoFunctions();
54 }
55
CContainerTypeInfo(size_t size,const CTypeRef & elementType,bool randomOrder)56 CContainerTypeInfo::CContainerTypeInfo(size_t size,
57 const CTypeRef& elementType,
58 bool randomOrder)
59 : CParent(eTypeFamilyContainer, size),
60 m_ElementType(elementType), m_RandomOrder(randomOrder)
61 {
62 InitContainerTypeInfoFunctions();
63 }
64
CContainerTypeInfo(size_t size,const char * name,TTypeInfo elementType,bool randomOrder)65 CContainerTypeInfo::CContainerTypeInfo(size_t size, const char* name,
66 TTypeInfo elementType,
67 bool randomOrder)
68 : CParent(eTypeFamilyContainer, size, name),
69 m_ElementType(elementType), m_RandomOrder(randomOrder)
70 {
71 InitContainerTypeInfoFunctions();
72 }
73
CContainerTypeInfo(size_t size,const char * name,const CTypeRef & elementType,bool randomOrder)74 CContainerTypeInfo::CContainerTypeInfo(size_t size, const char* name,
75 const CTypeRef& elementType,
76 bool randomOrder)
77 : CParent(eTypeFamilyContainer, size, name),
78 m_ElementType(elementType), m_RandomOrder(randomOrder)
79 {
80 InitContainerTypeInfoFunctions();
81 }
82
CContainerTypeInfo(size_t size,const string & name,TTypeInfo elementType,bool randomOrder)83 CContainerTypeInfo::CContainerTypeInfo(size_t size, const string& name,
84 TTypeInfo elementType,
85 bool randomOrder)
86 : CParent(eTypeFamilyContainer, size, name),
87 m_ElementType(elementType), m_RandomOrder(randomOrder)
88 {
89 InitContainerTypeInfoFunctions();
90 }
91
CContainerTypeInfo(size_t size,const string & name,const CTypeRef & elementType,bool randomOrder)92 CContainerTypeInfo::CContainerTypeInfo(size_t size, const string& name,
93 const CTypeRef& elementType,
94 bool randomOrder)
95 : CParent(eTypeFamilyContainer, size, name),
96 m_ElementType(elementType), m_RandomOrder(randomOrder)
97 {
98 InitContainerTypeInfoFunctions();
99 }
100
101 class CContainerTypeInfoFunctions
102 {
103 public:
104 NCBI_NORETURN
Throw(const char * message)105 static void Throw(const char* message)
106 {
107 NCBI_THROW(CSerialException,eFail, message);
108 }
InitIteratorConst(CContainerTypeInfo::CConstIterator &)109 static bool InitIteratorConst(CContainerTypeInfo::CConstIterator&)
110 {
111 Throw("cannot create iterator");
112 return false;
113 }
InitIterator(CContainerTypeInfo::CIterator &)114 static bool InitIterator(CContainerTypeInfo::CIterator&)
115 {
116 Throw("cannot create iterator");
117 return false;
118 }
AddElement(const CContainerTypeInfo *,TObjectPtr,TConstObjectPtr,ESerialRecursionMode)119 static TObjectPtr AddElement(const CContainerTypeInfo* /*containerType*/,
120 TObjectPtr /*containerPtr*/,
121 TConstObjectPtr /*elementPtr*/,
122 ESerialRecursionMode)
123 {
124 Throw("illegal call");
125 return 0;
126 }
127
AddElementIn(const CContainerTypeInfo *,TObjectPtr,CObjectIStream &)128 static TObjectPtr AddElementIn(const CContainerTypeInfo* /*containerType*/,
129 TObjectPtr /*containerPtr*/,
130 CObjectIStream& /*in*/)
131 {
132 Throw("illegal call");
133 return 0;
134 }
135
GetElementCount(const CContainerTypeInfo *,TConstObjectPtr)136 static size_t GetElementCount(const CContainerTypeInfo*, TConstObjectPtr)
137 {
138 Throw("illegal call");
139 return 0;
140 }
141 };
142
InitContainerTypeInfoFunctions(void)143 void CContainerTypeInfo::InitContainerTypeInfoFunctions(void)
144 {
145 SetTag(m_RandomOrder ? CAsnBinaryDefs::eSetOf : CAsnBinaryDefs::eSequenceOf);
146 SetReadFunction(&ReadContainer);
147 SetWriteFunction(&WriteContainer);
148 SetCopyFunction(&CopyContainer);
149 SetSkipFunction(&SkipContainer);
150 m_InitIteratorConst = &CContainerTypeInfoFunctions::InitIteratorConst;
151 m_InitIterator = &CContainerTypeInfoFunctions::InitIterator;
152 m_AddElement = &CContainerTypeInfoFunctions::AddElement;
153 m_AddElementIn = &CContainerTypeInfoFunctions::AddElementIn;
154 m_GetElementCount = &CContainerTypeInfoFunctions::GetElementCount;
155 }
156
SetAddElementFunctions(TAddElement addElement,TAddElementIn addElementIn)157 void CContainerTypeInfo::SetAddElementFunctions(TAddElement addElement,
158 TAddElementIn addElementIn)
159 {
160 m_AddElement = addElement;
161 m_AddElementIn = addElementIn;
162 }
163
SetCountFunctions(TGetElementCount getElementCount,TReserveElements reserveElements)164 void CContainerTypeInfo::SetCountFunctions(TGetElementCount getElementCount,
165 TReserveElements reserveElements)
166 {
167 m_GetElementCount = getElementCount;
168 m_ReserveElements = reserveElements;
169 }
170
SetConstIteratorFunctions(TInitIteratorConst init,TReleaseIteratorConst release,TCopyIteratorConst copy,TNextElementConst next,TGetElementPtrConst get)171 void CContainerTypeInfo::SetConstIteratorFunctions(TInitIteratorConst init,
172 TReleaseIteratorConst release,
173 TCopyIteratorConst copy,
174 TNextElementConst next,
175 TGetElementPtrConst get)
176 {
177 m_InitIteratorConst = init;
178 m_ReleaseIteratorConst = release;
179 m_CopyIteratorConst = copy;
180 m_NextElementConst = next;
181 m_GetElementPtrConst = get;
182 }
183
SetIteratorFunctions(TInitIterator init,TReleaseIterator release,TCopyIterator copy,TNextElement next,TGetElementPtr get,TEraseElement erase,TEraseAllElements erase_all)184 void CContainerTypeInfo::SetIteratorFunctions(TInitIterator init,
185 TReleaseIterator release,
186 TCopyIterator copy,
187 TNextElement next,
188 TGetElementPtr get,
189 TEraseElement erase,
190 TEraseAllElements erase_all)
191 {
192 m_InitIterator = init;
193 m_ReleaseIterator = release;
194 m_CopyIterator = copy;
195 m_NextElement = next;
196 m_GetElementPtr = get;
197 m_EraseElement = erase;
198 m_EraseAllElements = erase_all;
199 }
200
201 CTypeInfo::EMayContainType
GetMayContainType(TTypeInfo type) const202 CContainerTypeInfo::GetMayContainType(TTypeInfo type) const
203 {
204 return GetElementType()->IsOrMayContainType(type);
205 }
206
Assign(TObjectPtr dst,TConstObjectPtr src,ESerialRecursionMode how) const207 void CContainerTypeInfo::Assign(TObjectPtr dst, TConstObjectPtr src,
208 ESerialRecursionMode how) const
209 {
210 if (how == eShallowChildless) {
211 SetDefault(dst); // clear destination container
212 return;
213 }
214 CIterator idst;
215 CConstIterator isrc;
216 bool old_element = InitIterator(idst,dst);
217 if ( InitIterator(isrc, src) ) {
218 TTypeInfo elementType = GetElementType();
219 do {
220 TConstObjectPtr elementPtr = GetElementPtr(isrc);
221 if (old_element) {
222 elementType->Assign(GetElementPtr(idst), elementPtr, how);
223 old_element = NextElement(idst);
224 } else {
225 AddElement(dst, elementPtr, how);
226 }
227 } while ( NextElement(isrc) );
228 }
229 if (old_element) {
230 EraseAllElements(idst);
231 }
232 }
233
Equals(TConstObjectPtr object1,TConstObjectPtr object2,ESerialRecursionMode how) const234 bool CContainerTypeInfo::Equals(TConstObjectPtr object1, TConstObjectPtr object2,
235 ESerialRecursionMode how) const
236 {
237 if (how == eShallowChildless) {
238 return true;
239 }
240 TTypeInfo elementType = GetElementType();
241 CConstIterator i1, i2;
242 if ( InitIterator(i1, object1) ) {
243 if ( !InitIterator(i2, object2) )
244 return false;
245 if ( !elementType->Equals(GetElementPtr(i1),
246 GetElementPtr(i2), how) )
247 return false;
248 while ( NextElement(i1) ) {
249 if ( !NextElement(i2) )
250 return false;
251 if ( !elementType->Equals(GetElementPtr(i1),
252 GetElementPtr(i2), how) )
253 return false;
254 }
255 return !NextElement(i2);
256 }
257 else {
258 return !InitIterator(i2, object2);
259 }
260 }
261
ReadContainer(CObjectIStream & in,TTypeInfo objectType,TObjectPtr objectPtr)262 void CContainerTypeInfo::ReadContainer(CObjectIStream& in,
263 TTypeInfo objectType,
264 TObjectPtr objectPtr)
265 {
266 const CContainerTypeInfo* containerType =
267 CTypeConverter<CContainerTypeInfo>::SafeCast(objectType);
268
269 in.ReadContainer(containerType, objectPtr);
270 }
271
WriteContainer(CObjectOStream & out,TTypeInfo objectType,TConstObjectPtr objectPtr)272 void CContainerTypeInfo::WriteContainer(CObjectOStream& out,
273 TTypeInfo objectType,
274 TConstObjectPtr objectPtr)
275 {
276 const CContainerTypeInfo* containerType =
277 CTypeConverter<CContainerTypeInfo>::SafeCast(objectType);
278
279 out.WriteContainer(containerType, objectPtr);
280 }
281
CopyContainer(CObjectStreamCopier & copier,TTypeInfo objectType)282 void CContainerTypeInfo::CopyContainer(CObjectStreamCopier& copier,
283 TTypeInfo objectType)
284 {
285 const CContainerTypeInfo* containerType =
286 CTypeConverter<CContainerTypeInfo>::SafeCast(objectType);
287
288 copier.CopyContainer(containerType);
289 }
290
SkipContainer(CObjectIStream & in,TTypeInfo objectType)291 void CContainerTypeInfo::SkipContainer(CObjectIStream& in,
292 TTypeInfo objectType)
293 {
294 const CContainerTypeInfo* containerType =
295 CTypeConverter<CContainerTypeInfo>::SafeCast(objectType);
296
297 in.SkipContainer(containerType);
298 }
299
300 END_NCBI_SCOPE
301