1 #ifndef OBJOSTR__HPP
2 #define OBJOSTR__HPP
3
4 /* $Id: objostr.hpp 574303 2018-11-08 19:59:04Z gouriano $
5 * ===========================================================================
6 *
7 * PUBLIC DOMAIN NOTICE
8 * National Center for Biotechnology Information
9 *
10 * This software/database is a "United States Government Work" under the
11 * terms of the United States Copyright Act. It was written as part of
12 * the author's official duties as a United States Government employee and
13 * thus cannot be copyrighted. This software/database is freely available
14 * to the public for use. The National Library of Medicine and the U.S.
15 * Government have not placed any restriction on its use or reproduction.
16 *
17 * Although all reasonable efforts have been taken to ensure the accuracy
18 * and reliability of the software and data, the NLM and the U.S.
19 * Government do not and cannot warrant the performance or results that
20 * may be obtained by using this software or data. The NLM and the U.S.
21 * Government disclaim all warranties, express or implied, including
22 * warranties of performance, merchantability or fitness for any particular
23 * purpose.
24 *
25 * Please cite the author in any work or product based on this material.
26 *
27 * ===========================================================================
28 *
29 * Author: Eugene Vasilchenko
30 *
31 * File Description:
32 * Base class of object output stream classes
33 * Having a data object, it encodes it and saves in an output stream
34 */
35
36 #include <corelib/ncbistd.hpp>
37 #include <corelib/ncbifloat.h>
38 #include <corelib/ncbiobj.hpp>
39 #include <corelib/ncbiutil.hpp>
40 #include <util/strbuffer.hpp>
41 #include <serial/impl/objlist.hpp>
42 #include <serial/impl/hookdatakey.hpp>
43 #include <serial/objhook.hpp>
44 #include <serial/impl/pathhook.hpp>
45 #include <serial/error_codes.hpp>
46
47
48 /** @addtogroup ObjStreamSupport
49 *
50 * @{
51 */
52
53
54 struct asnio;
55
56 BEGIN_NCBI_SCOPE
57
58 class CMemberId;
59 class CDelayBuffer;
60
61 class CConstObjectInfo;
62 class CConstObjectInfoMI;
63
64 class CWriteObjectHook;
65 class CWriteClassMembersHook;
66 class CWriteChoiceVariantHook;
67
68 class CContainerTypeInfo;
69 class CClassTypeInfo;
70 class CChoiceTypeInfo;
71 class CObjectStreamCopier;
72 class CAliasTypeInfo;
73
74 class CWriteObjectInfo;
75 class CWriteObjectList;
76
77 /////////////////////////////////////////////////////////////////////////////
78 ///
79 /// CObjectOStream --
80 ///
81 /// Base class of serial object stream encoders
82 class NCBI_XSERIAL_EXPORT CObjectOStream : public CObjectStack
83 {
84 public:
85 /// Destructor.
86 ///
87 /// Constructors are protected;
88 /// use any one of 'Create' methods to construct the stream
89 virtual ~CObjectOStream(void);
90
91 //---------------------------------------------------------------------------
92 // Create methods
93 // CObjectOStream will be created on heap, and must be deleted later on
94
95 /// Create serial object writer and attach it to an output stream.
96 ///
97 /// @param format
98 /// Format of the output data
99 /// @param outStream
100 /// Output stream
101 /// @param deleteOutStream
102 /// When TRUE, the output stream will be deleted automatically
103 /// when the writer is deleted
104 /// @return
105 /// Writer (created on heap)
106 /// @deprecated
107 /// Use one with EOwnership enum instead
108 static NCBI_DEPRECATED CObjectOStream* Open(ESerialDataFormat format,
109 CNcbiOstream& outStream,
110 bool deleteOutStream);
111
112 /// Create serial object writer and attach it to an output stream.
113 ///
114 /// @param format
115 /// Format of the output data
116 /// @param outStream
117 /// Output stream
118 /// @param deleteOutStream
119 /// When eTakeOwnership, the output stream will be deleted automatically
120 /// when the writer is deleted
121 /// @param formatFlags
122 /// Formatting flags (see ESerial_xxx_Flags)
123 /// @return
124 /// Writer (created on heap)
125 /// @sa ESerial_AsnText_Flags, ESerial_Xml_Flags, ESerial_Json_Flags
126 static CObjectOStream* Open(ESerialDataFormat format,
127 CNcbiOstream& outStream,
128 EOwnership deleteOutStream = eNoOwnership,
129 TSerial_Format_Flags formatFlags = 0);
130
131 /// Create serial object writer and attach it to a file stream.
132 ///
133 /// @param format
134 /// Format of the output data
135 /// @param fileName
136 /// Output file name
137 /// @param openFlags
138 /// File open flags
139 /// @param formatFlags
140 /// Formatting flags (see ESerial_xxx_Flags)
141 /// @return
142 /// Writer (created on heap)
143 /// @sa ESerialOpenFlags, ESerial_AsnText_Flags, ESerial_Xml_Flags, ESerial_Json_Flags
144 static CObjectOStream* Open(ESerialDataFormat format,
145 const string& fileName,
146 TSerialOpenFlags openFlags = 0,
147 TSerial_Format_Flags formatFlags = 0);
148
149 /// Create serial object writer and attach it to a file stream.
150 ///
151 /// @param fileName
152 /// Output file name
153 /// @param format
154 /// Format of the output data
155 /// @param formatFlags
156 /// Formatting flags (see ESerial_xxx_Flags)
157 /// @return
158 /// Writer (created on heap)
159 /// @sa ESerial_AsnText_Flags, ESerial_Xml_Flags, ESerial_Json_Flags
160 static CObjectOStream* Open(const string& fileName,
161 ESerialDataFormat format,
162 TSerial_Format_Flags formatFlags = 0);
163
164 /// Get data format
165 ///
166 /// @return
167 /// Output data format
168 ESerialDataFormat GetDataFormat(void) const;
169
170 //---------------------------------------------------------------------------
171 // Data verification setup
172
173 // for this particular stream
174 /// Set up output data verification for this particular stream
175 ///
176 /// @param verify
177 /// Data verification parameter
178 void SetVerifyData(ESerialVerifyData verify);
179
180 /// Get output data verification parameter.
181 ///
182 /// When verification is enabled, stream verifies data on output
183 /// and throws CUnassignedMember exception
184 ///
185 /// @return
186 /// Data verification parameter
187 ESerialVerifyData GetVerifyData(void) const;
188
189 /// Set up default output data verification for streams
190 /// created by the current thread
191 ///
192 /// @param verify
193 /// Data verification parameter
194 static void SetVerifyDataThread(ESerialVerifyData verify);
195
196 /// Set up default output data verification for streams
197 /// created by the current process
198 ///
199 /// @param verify
200 /// Data verification parameter
201 static void SetVerifyDataGlobal(ESerialVerifyData verify);
202
FixNonPrint(EFixNonPrint how)203 EFixNonPrint FixNonPrint(EFixNonPrint how)
204 {
205 EFixNonPrint tmp = m_FixMethod;
206 m_FixMethod = how == eFNP_Default ? x_GetFixCharsMethodDefault() : how;
207 return tmp;
208 }
FixNonPrintSubst(char subst)209 void FixNonPrintSubst(char subst) {
210 m_NonPrintSubst = subst;
211 }
212
213 // Enforce explicit writing of values with default,
214 // even when they were never set
215 //
216 // This is dangerous, and contradicts specification
217 // but might be useful to make sure defaults are properly reported to recipient
218 // Use at your own risk
219 void EnforceWritingDefaultValues(bool enforce = true);
220
221 // Is explicit writing of values with default enforced
222 bool IsWritingDefaultValuesEnforced() const;
223
224 //---------------------------------------------------------------------------
225 // Formatting of the output
226
227 /// Set up indentation usage in text streams.
228 ///
229 /// @param set
230 /// When TRUE, the writer puts white space chars in the beginning
231 /// of each line of text
232 void SetUseIndentation(bool set);
233
234 /// Get indentation usage in text streams.
235 ///
236 /// @return
237 /// TRUE or FALSE
238 bool GetUseIndentation(void) const;
239
240 /// Set up end-of-line symbol usage in text streams.
241 ///
242 /// @param set
243 /// When TRUE, the writer puts end-of-line symbol where needed,
244 /// otherwise, the output is a single line.
245 void SetUseEol(bool set);
246
247 /// Get end-of-line symbol usage in text streams.
248 ///
249 /// @return
250 /// TRUE or FALSE
251 bool GetUseEol(void) const;
252
253 /// Set up writing named integers (in ANS.1 sense) by value only.
254 ///
255 /// The setting affects text streams only and is provided
256 /// for convenience: so that legacy applications can read data files
257 /// generated by newer ones.
258 ///
259 /// @param set
260 /// When TRUE, the writer does not write the name of the value,
261 /// but only its numeric value instead
262 void SetWriteNamedIntegersByValue(bool set);
263
264 /// Get writing named integers by value parameter
265 ///
266 /// @return
267 /// TRUE or FALSE
268 bool GetWriteNamedIntegersByValue(void) const;
269
270 /// Get separator.
271 ///
272 /// @return
273 /// Separator string
274 string GetSeparator(void) const;
275
276 /// Set separator.
277 ///
278 /// Separator string is written into text stream after each object
279 ///
280 /// @param sep
281 /// Separator string
282 void SetSeparator(const string sep);
283
284 /// Get separator auto-output paramater
285 ///
286 /// Controls auto-output of the separator after each object. By default
287 /// this flag is true for text ASN.1 streams only.
288 ///
289 /// @return
290 /// TRUE or FALSE
291 bool GetAutoSeparator(void);
292
293 /// Set separator auto-output paramater.
294 ///
295 /// When TRUE, writer puts separator string after each object. By default
296 /// this flag is TRUE for text ASN.1 streams only.
297 ///
298 /// @param value
299 /// TRUE or FALSE
300 void SetAutoSeparator(bool value);
301
302 /// Set output formatting flags
303 ///
304 /// @param flags
305 /// Formatting flag
306 virtual void SetFormattingFlags(TSerial_Format_Flags flags);
307
308 //---------------------------------------------------------------------------
309 // Stream state
310
311 /// Fail flags
312 enum EFailFlags {
313 /// No error
314 fNoError = 0, eNoError = fNoError,
315 // fEOF = 1 << 0, eEOF = fEOF,
316 /// An unknown error when writing into output file
317 fWriteError = 1 << 1, eWriteError = fWriteError,
318 // fFormatError = 1 << 2, eFormatError = fFormatError,
319 /// Internal buffer overflow
320 fOverflow = 1 << 3, eOverflow = fOverflow,
321 /// Output data is incorrect
322 fInvalidData = 1 << 4, eInvalidData = fInvalidData,
323 /// Illegal in a given context function call
324 fIllegalCall = 1 << 5, eIllegalCall = fIllegalCall,
325 /// Internal error, the real reason is unclear
326 fFail = 1 << 6, eFail = fFail,
327 /// No output file
328 fNotOpen = 1 << 7, eNotOpen = fNotOpen,
329 /// Method is not implemented
330 fNotImplemented= 1 << 8, eNotImplemented = fNotImplemented,
331 /// Mandatory object member is unassigned
332 /// Normally this results in throwing CUnassignedMember exception
333 fUnassigned = 1 << 9, eUnassigned = fUnassigned
334 };
335 typedef int TFailFlags;
336
337 /// Check if any of fail flags is set.
338 ///
339 /// @return
340 /// TRUE or FALSE
341 bool fail(void) const;
342
343 /// Get fail flags.
344 ///
345 /// @return
346 /// Fail flags
347 TFailFlags GetFailFlags(void) const;
348
349 /// Set fail flags, but do not ERR_POST any messages
350 ///
351 /// @param flags
352 /// Fail flags
353 TFailFlags SetFailFlagsNoError(TFailFlags flags);
354
355 /// Set fail flags
356 ///
357 /// @param flags
358 /// Fail flags
359 /// @param message
360 /// Text message
361 TFailFlags SetFailFlags(TFailFlags flags, const char* message);
362
363 /// Reset fail flags
364 ///
365 /// @param flags
366 /// Flags to reset
367 TFailFlags ClearFailFlags(TFailFlags flags);
368
369 /// Check fail flags and also the state of output stream
370 ///
371 /// @return
372 /// TRUE is there is no errors
373 bool InGoodState(void);
374
375 /// Set cancellation check callback.
376 /// The stream will periodically check for a cancellation request and
377 /// throw an exception when requested.
378 void SetCanceledCallback(const ICanceled* callback);
379
380 /// @deprecated
381 /// Use GetStreamPos() instead
382 /// @sa GetStreamPos()
383 NCBI_DEPRECATED CNcbiStreampos GetStreamOffset(void) const;
384
385 /// Get the current stream position
386 ///
387 /// NOTE:
388 /// This is not the same as ostream::tellp();
389 /// rather, this is an offset in the current output
390 ///
391 /// @return
392 /// stream position
393 CNcbiStreampos GetStreamPos(void) const;
394
395 /// Get current stack trace as string.
396 /// Useful for diagnostic and information messages.
397 ///
398 /// @return
399 /// string
400 virtual string GetStackTrace(void) const override;
401
402 /// Get current stream position as string.
403 /// Useful for diagnostic and information messages.
404 ///
405 /// @return
406 /// string
407 virtual string GetPosition(void) const override;
408
409 //---------------------------------------------------------------------------
410 // Local write hooks
411 void SetPathWriteObjectHook( const string& path, CWriteObjectHook* hook);
412 void SetPathWriteMemberHook( const string& path, CWriteClassMemberHook* hook);
413 void SetPathWriteVariantHook(const string& path, CWriteChoiceVariantHook* hook);
414
415 /// DelayBuffer parsing policy
416 enum EDelayBufferParsing {
417 /// Parse only if local hook are present
418 eDelayBufferPolicyNotSet,
419 /// Parse always
420 eDelayBufferPolicyAlwaysParse,
421 /// Never parse
422 eDelayBufferPolicyNeverParse
423 };
424 void SetDelayBufferParsingPolicy(EDelayBufferParsing policy);
425 EDelayBufferParsing GetDelayBufferParsingPolicy(void) const;
426 bool ShouldParseDelayBuffer(void) const;
427
428 //---------------------------------------------------------------------------
429 // User interface
430 // flush buffer
431 void FlushBuffer(void);
432 // flush buffer and underlying stream
433 void Flush(void);
434 // perform default flush defined by flags
435 void DefaultFlush(void);
436
437 // root writer
438 void Write(const CConstObjectInfo& object);
439 void Write(TConstObjectPtr object, TTypeInfo type);
440 void Write(TConstObjectPtr object, const CTypeRef& type);
441
442 // file header
443 virtual void WriteFileHeader(TTypeInfo type);
444
445 // subtree writer
446 void WriteObject(const CConstObjectInfo& object);
447 void WriteObject(TConstObjectPtr object, TTypeInfo typeInfo);
448
449 void CopyObject(TTypeInfo objectType,
450 CObjectStreamCopier& copier);
451
452 void WriteSeparateObject(const CConstObjectInfo& object);
453
454 // internal writer
455 void WriteExternalObject(TConstObjectPtr object, TTypeInfo typeInfo);
456
457 // member interface
458 void WriteClassMember(const CConstObjectInfoMI& member);
459
460 // choice variant interface
461 void WriteChoiceVariant(const CConstObjectInfoCV& member);
462
463
464 CObjectOStream& operator<< (CObjectOStream& (*mod)(CObjectOStream& os));
465 friend CObjectOStream& Separator(CObjectOStream& os);
466
467 //---------------------------------------------------------------------------
468 // Standard types
469 // bool
470 void WriteStd(const bool& data);
471
472 // char
473 void WriteStd(const char& data);
474
475 // integer number
476 void WriteStd(const signed char& data);
477 void WriteStd(const unsigned char& data);
478 void WriteStd(const short& data);
479 void WriteStd(const unsigned short& data);
480 void WriteStd(const int& data);
481 void WriteStd(const unsigned int& data);
482 #ifndef NCBI_INT8_IS_LONG
483 void WriteStd(const long& data);
484 void WriteStd(const unsigned long& data);
485 #endif
486 void WriteStd(const Int8& data);
487 void WriteStd(const Uint8& data);
488
489 // float number
490 void WriteStd(const float& data);
491 void WriteStd(const double& data);
492 #if SIZEOF_LONG_DOUBLE != 0
493 void WriteStd(const long double& data);
494 #endif
495
496 // string
497 void WriteStd(const string& data);
498
499 // C string; VisualAge can't cope with refs here.
500 void WriteStd(const char* const data);
501 void WriteStd(char* const data);
502
503 void WriteStd(const CBitString& data);
504
505 // primitive writers
506 // bool
507 virtual void WriteBool(bool data) = 0;
508
509 // char
510 virtual void WriteChar(char data) = 0;
511
512 // integer numbers
513 virtual void WriteInt4(Int4 data) = 0;
514 virtual void WriteUint4(Uint4 data) = 0;
515 virtual void WriteInt8(Int8 data) = 0;
516 virtual void WriteUint8(Uint8 data) = 0;
517
518 // float numbers
519 virtual void WriteFloat(float data);
520 virtual void WriteDouble(double data) = 0;
521 #if SIZEOF_LONG_DOUBLE != 0
522 virtual void WriteLDouble(long double data);
523 #endif
524
525 // string
526 virtual void WriteString(const string& str,
527 EStringType type = eStringTypeVisible) = 0;
528 virtual void CopyString(CObjectIStream& in,
529 EStringType type = eStringTypeVisible) = 0;
530
531 // StringStore
532 virtual void WriteStringStore(const string& data) = 0;
533 virtual void CopyStringStore(CObjectIStream& in) = 0;
534
535 // C string
536 virtual void WriteCString(const char* str) = 0;
537
538 // NULL
539 virtual void WriteNull(void) = 0;
540
541 // enum
542 virtual void WriteEnum(const CEnumeratedTypeValues& values,
543 TEnumValueType value) = 0;
544 virtual void CopyEnum(const CEnumeratedTypeValues& values,
545 CObjectIStream& in) = 0;
546
547 // any content object
548 virtual void WriteAnyContentObject(const CAnyContentObject& obj) = 0;
549 virtual void CopyAnyContentObject(CObjectIStream& in) = 0;
550
551 virtual void WriteBitString(const CBitString& obj) = 0;
552 virtual void CopyBitString(CObjectIStream& in) = 0;
553
554 // delayed buffer
555 virtual bool Write(CByteSource& source);
556 void Write(const char* data, size_t size);
557
558 #ifdef NCBI_STRICT_GI
559 void WriteStd(const TGi& data);
560
561 virtual void WriteGi(const TGi& obj);
562 virtual void CopyGi(CObjectIStream& in);
563 #endif
564
565 //---------------------------------------------------------------------------
566 // Internals
567 void Close(void);
568 virtual void EndOfWrite(void);
569 void ResetLocalHooks(void);
570 void HandleEOF(CEofException&);
571
572 void ThrowError1(const CDiagCompileInfo& diag_info,
573 TFailFlags fail, const char* message,
574 CException* exc = 0);
575 void ThrowError1(const CDiagCompileInfo& diag_info,
576 TFailFlags fail, const string& message,
577 CException* exc = 0);
578 #define RethrowError(flag,mess,exc) \
579 ThrowError1(DIAG_COMPILE_INFO,flag,mess,&exc)
580
581 // report error about unended block
582 void Unended(const string& msg);
583 // report error about unended object stack frame
584 virtual void UnendedFrame(void) override;
585
586 enum EFlags {
587 fFlagNone = 0,
588 eFlagNone = fFlagNone,
589 fFlagAllowNonAsciiChars = 1 << 0,
590 eFlagAllowNonAsciiChars = fFlagAllowNonAsciiChars,
591 fFlagNoAutoFlush = 1 << 1
592 };
593 typedef int TFlags;
594 TFlags GetFlags(void) const;
595 TFlags SetFlags(TFlags flags);
596 TFlags ClearFlags(TFlags flags);
597
598 class ByteBlock;
599 friend class ByteBlock;
600 class NCBI_XSERIAL_EXPORT ByteBlock
601 {
602 public:
603 ByteBlock(CObjectOStream& out, size_t length);
604 ~ByteBlock(void);
605
606 CObjectOStream& GetStream(void) const;
607
608 size_t GetLength(void) const;
609
610 void Write(const void* bytes, size_t length);
611
612 void End(void);
613
614 private:
615 CObjectOStream& m_Stream;
616 size_t m_Length;
617 bool m_Ended;
618 };
619 class CharBlock;
620 friend class CharBlock;
621 class NCBI_XSERIAL_EXPORT CharBlock
622 {
623 public:
624 CharBlock(CObjectOStream& out, size_t length);
625 ~CharBlock(void);
626
627 CObjectOStream& GetStream(void) const;
628
629 size_t GetLength(void) const;
630
631 void Write(const char* chars, size_t length);
632
633 void End(void);
634
635 private:
636 CObjectOStream& m_Stream;
637 size_t m_Length;
638 bool m_Ended;
639 };
640
641 #if HAVE_NCBI_C
642 class NCBI_XSERIAL_EXPORT AsnIo
643 {
644 public:
645 AsnIo(CObjectOStream& out, const string& rootTypeName);
646 ~AsnIo(void);
647
648 CObjectOStream& GetStream(void) const;
649
650 void Write(const char* data, size_t length);
651
652 void End(void);
653
654 operator asnio*(void);
655 asnio* operator->(void);
656 const string& GetRootTypeName(void) const;
657
658 private:
659 CObjectOStream& m_Stream;
660 string m_RootTypeName;
661 asnio* m_AsnIo;
662 bool m_Ended;
663
664 public:
665 size_t m_Count;
666 };
667 friend class AsnIo;
668 public:
669 #endif
670
671 //---------------------------------------------------------------------------
672 // mid level I/O
673 // named type (alias)
674 MLIOVIR void WriteNamedType(TTypeInfo namedTypeInfo,
675 TTypeInfo typeInfo, TConstObjectPtr object);
676 // container
677 MLIOVIR void WriteContainer(const CContainerTypeInfo* containerType,
678 TConstObjectPtr containerPtr);
679 void WriteContainerElement(const CConstObjectInfo& element);
680 // class
681 void WriteClassRandom(const CClassTypeInfo* classType,
682 TConstObjectPtr classPtr);
683 void WriteClassSequential(const CClassTypeInfo* classType,
684 TConstObjectPtr classPtr);
685 MLIOVIR void WriteClass(const CClassTypeInfo* objectType,
686 TConstObjectPtr objectPtr);
687 MLIOVIR void WriteClassMember(const CMemberId& memberId,
688 TTypeInfo memberType,
689 TConstObjectPtr memberPtr);
690 MLIOVIR bool WriteClassMember(const CMemberId& memberId,
691 const CDelayBuffer& buffer);
692 // alias
693 MLIOVIR void WriteAlias(const CAliasTypeInfo* aliasType,
694 TConstObjectPtr aliasPtr);
695
696 //---------------------------------------------------------------------------
697 // Copying
698 // named type (alias)
699 MLIOVIR void CopyNamedType(TTypeInfo namedTypeInfo,
700 TTypeInfo typeInfo,
701 CObjectStreamCopier& copier);
702 // container
703 MLIOVIR void CopyContainer(const CContainerTypeInfo* containerType,
704 CObjectStreamCopier& copier);
705 // class
706 MLIOVIR void CopyClassRandom(const CClassTypeInfo* objectType,
707 CObjectStreamCopier& copier);
708 MLIOVIR void CopyClassSequential(const CClassTypeInfo* objectType,
709 CObjectStreamCopier& copier);
710 // choice
711 MLIOVIR void CopyChoice(const CChoiceTypeInfo* choiceType,
712 CObjectStreamCopier& copier);
713 // alias
714 MLIOVIR void CopyAlias(const CAliasTypeInfo* AliasType,
715 CObjectStreamCopier& copier);
716
717 //---------------------------------------------------------------------------
718 // low level I/O
719 // named type
720 virtual void BeginNamedType(TTypeInfo namedTypeInfo);
721 virtual void EndNamedType(void);
722
723 // container
724 virtual void BeginContainer(const CContainerTypeInfo* containerType) = 0;
725 virtual void EndContainer(void);
726 virtual void BeginContainerElement(TTypeInfo elementType);
727 virtual void EndContainerElement(void);
728
729 // class
730 virtual void BeginClass(const CClassTypeInfo* classInfo) = 0;
731 virtual void EndClass(void);
732
733 virtual void BeginClassMember(const CMemberId& id) = 0;
734 virtual void EndClassMember(void);
735
736 // choice
737 virtual void BeginChoice(const CChoiceTypeInfo* choiceType);
738 virtual void EndChoice(void);
739 virtual void BeginChoiceVariant(const CChoiceTypeInfo* choiceType,
740 const CMemberId& id) = 0;
741 virtual void EndChoiceVariant(void);
742
743 // write byte blocks
744 virtual void BeginBytes(const ByteBlock& block);
745 virtual void WriteBytes(const ByteBlock& block,
746 const char* bytes, size_t length) = 0;
747 virtual void EndBytes(const ByteBlock& block);
748
749 // write char blocks
750 virtual void BeginChars(const CharBlock& block);
751 virtual void WriteChars(const CharBlock& block,
752 const char* chars, size_t length) = 0;
753 virtual void EndChars(const CharBlock& block);
754
755 void WritePointer(TConstObjectPtr object, TTypeInfo typeInfo);
756
757 enum ESpecialCaseWrite {
758 eWriteAsNormal = 0,
759 eWriteAsDefault = 1,
760 eWriteAsNil = 2,
761 eWriteAsBigInt = 3
762 };
SetSpecialCaseWrite(ESpecialCaseWrite how)763 void SetSpecialCaseWrite( ESpecialCaseWrite how) {
764 m_SpecialCaseWrite = how;
765 }
766 MLIOVIR void WriteClassMemberSpecialCase(
767 const CMemberId& memberId, TTypeInfo memberType,
768 TConstObjectPtr memberPtr, ESpecialCaseWrite how);
769
770 protected:
771 CObjectOStream(ESerialDataFormat format,
772 CNcbiOstream& out, EOwnership deleteOut = eNoOwnership);
773
774 // low level writers
775 typedef size_t TObjectIndex;
776 virtual void WriteNullPointer(void) = 0;
777 virtual void WriteObjectReference(TObjectIndex index) = 0;
778 virtual void WriteThis(TConstObjectPtr object,
779 TTypeInfo typeInfo);
780 virtual void WriteOtherBegin(TTypeInfo typeInfo) = 0;
781 virtual void WriteOtherEnd(TTypeInfo typeInfo);
782 virtual void WriteOther(TConstObjectPtr object, TTypeInfo typeInfo);
783
784 void RegisterObject(TTypeInfo typeInfo);
785 void RegisterObject(TConstObjectPtr object, TTypeInfo typeInfo);
786
787 virtual void x_SetPathHooks(bool set) override;
788 EFixNonPrint x_GetFixCharsMethodDefault(void) const;
x_FixCharsMethod(void) const789 EFixNonPrint x_FixCharsMethod(void) const {
790 return m_FixMethod;
791 }
x_FixCharsSubst(void) const792 char x_FixCharsSubst(void) const {
793 return m_NonPrintSubst;
794 }
795 // Write current separator to the stream
796 virtual void WriteSeparator(void);
797
798 COStreamBuffer m_Output;
799 TFailFlags m_Fail;
800 TFlags m_Flags;
801 AutoPtr<CWriteObjectList> m_Objects;
802 string m_Separator;
803 ESerialDataFormat m_DataFormat;
804 EDelayBufferParsing m_ParseDelayBuffers;
805 ESpecialCaseWrite m_SpecialCaseWrite;
806 bool m_AutoSeparator;
807 bool m_WriteNamedIntegersByValue;
808 bool m_FastWriteDouble;
809 bool m_EnforceWritingDefaults;
810 TTypeInfo m_TypeAlias;
811
812 private:
813 static CObjectOStream* OpenObjectOStreamAsn(CNcbiOstream& out,
814 EOwnership deleteOut);
815 static CObjectOStream* OpenObjectOStreamAsnBinary(CNcbiOstream& out,
816 EOwnership deleteOut);
817 static CObjectOStream* OpenObjectOStreamXml(CNcbiOstream& out,
818 EOwnership deleteOut);
819 static CObjectOStream* OpenObjectOStreamJson(CNcbiOstream& out,
820 EOwnership deleteOut);
821 static ESerialVerifyData x_GetVerifyDataDefault(void);
822
823 char m_NonPrintSubst;
824 EFixNonPrint m_FixMethod; // method of fixing wrong (eg, non-printable) chars
825 ESerialVerifyData m_VerifyData;
826 CStreamObjectPathHook<CWriteObjectHook*> m_PathWriteObjectHooks;
827 CStreamPathHook<CMemberInfo*, CWriteClassMemberHook*> m_PathWriteMemberHooks;
828 CStreamPathHook<CVariantInfo*,CWriteChoiceVariantHook*> m_PathWriteVariantHooks;
829
830 public:
831 // hook support
832 CLocalHookSet<CWriteObjectHook> m_ObjectHookKey;
833 CLocalHookSet<CWriteClassMemberHook> m_ClassMemberHookKey;
834 CLocalHookSet<CWriteChoiceVariantHook> m_ChoiceVariantHookKey;
835
836 friend class CObjectStreamCopier;
837 };
838
839 inline void
EnforceWritingDefaultValues(bool enforce)840 CObjectOStream::EnforceWritingDefaultValues(bool enforce) {
841 m_EnforceWritingDefaults = enforce;
842 }
843 inline bool
IsWritingDefaultValuesEnforced() const844 CObjectOStream::IsWritingDefaultValuesEnforced() const {
845 return m_EnforceWritingDefaults;
846 }
847
848
849 /* @} */
850
851
852 #include <serial/impl/objostr.inl>
853
854 END_NCBI_SCOPE
855
856 #endif /* OBJOSTR__HPP */
857