.. role:: blue :class: blue Read and Write Streaming Objects ================================ .. _Read_and_write_streaming_objects_: .. версия ядра: Classes for reading and writing streaming objects of the model (read and write streams) are defined in the **tape.h** file. They inherit from the base class :blue:`tape`. Base Class for Read and Write Streams ------------------------------------- The base class for read and write streams :blue:`tape`\() contains references to a data buffer, a manager of write/read streams and a structure for registration of written (read) objects. It implements methods for managing the data buffer, registering objects and working with a progress indicator. Access to a data buffer: - const :blue:`iobuf_Seq` & GetIOBuffer() – access to a data buffer. - :blue:`iobuf_Seq` & GetIOBuffer() – access to a data buffer. - bool IsOwnBuffer() – whether owning the buffer. - void SetOwnBuffer( bool ) – set a flag of owning the buffer. Managing an operation mode of the data buffer: - uint8 mode() – get the operation mode of the buffer. - void setMode( uint8 ) – set the operation mode of the buffer. - void clearState( :blue:`state` ) – clear the buffer state. - void setState( :blue:`state` ) – add the buffer state. Requesting the data buffer state: - int fresh() – is the buffer fresh. - bool good() – whether the buffer state is correct. - uint8 eof() – is the end of the file reached. - uint32 state() – get the flag of the buffer state. - io::pos tell() – get the current position in the stream. Managing versions: - void SetVersionsByStorage() – set the current version to be equal to the storage version. - :blue:`VERSION` MathVersion() – return the main version (version of the mathematical kernel). - :blue:`VERSION` AppVersion( size_t ind ) – return the additional version (version of the target application). - const :blue:`VersionContainer` & GetVersionsContainer() – get access to the version container. - void SetVersionsContainer( const :blue:`VersionContainer` & ) – set the version of the open file. - :blue:`VERSION` SetStorageVersion( :blue:`VERSION` ) – set the storage version. Managing registration of objects: - void registrate( const :blue:`TapeBase` * ) – register the pointer. - void unregistrate( const :blue:`TapeBase` * ) – unregister the pointer. - bool exist( const :blue:`TapeBase` * ) – does a registered object exist. - void flushRegister() – flush the registration array. - size_t RegisteredCount() – get the number of registered objects. - size_t GetMaxRegisteredCount() – get the maximal possible number of objects for registration. - void ReserveRegistered( size_t n ) – reserve memory for n objects. - uint8 GetIndexType( size_t index ) – get the index type. Working with a progress indicator: - void InitProgress( IProgressIndicator * pr ) – initialize the progress indicator. - void InitProgress( ProgressBarWrapper & pr ) – initialize the progress indicator. - void ResetProgress() – release the current progress indicator and set the parent progress indicator, if it exists. - ProgressBarWrapper * GetProgress() – get the progress indicator. Write Streams ------------- **Class writer** The :blue:`writer` class provides writing the model to a data buffer (to a file space) in the compact format. It inherits from the base class :blue:`tape`. The **writer** class implements: 1. Static functions for creating the class instance: - writer_ptr CreateWriter( std::unique_ptr\< iobuf_Seq \>, uint16 ) – create the class instance for a given sequential memory buffer of type :blue:`iobuf_Seq`. - writer_ptr CreateMemWriter( :blue:`membuf` &, uint8 ) – create the class instance for a given memory buffer of type :blue:`membuf`. 2. Methods for writing objects of different types to the buffer: - void writeObject( const :blue:`TapeBase` * ) – write an object. - void writeObjectPointer( const :blue:`TapeBase` * ) – write a pointer to an object. - void writeByte( uint8 ) – write a byte to the buffer. - void writeBytes( const void *, size_t ) – write a bytes sequence to the buffer. - void writeUInt64( const uint64 & ) – write an unsigned 64‑bit integer; returns the number of written bytes. - void writeInt64( const int64 & ) – write a 64‑bit integer; returns the number of written bytes. - writer & __writeChar( const char * ) – write a CHAR string to the stream (ANSI encoding, Russian locale). - writer & __writeWchar( const TCHAR * ) – write a WCHAR string to the stream (stored in the stream as UTF‑16). - writer & __writeWcharT( const wchar_t * ) – write a WCHAR string to the stream (stored in the stream as UTF‑16). - size_t __lenWchar( const TCHAR * ) – get the length of a WCHAR string record in the stream (stored in the stream as UTF‑16). 3. Methods for writing a model tree and access to it (these methods are not supported by this class, they have an empty implementation): - void WriteModelCatalog() – write a model tree. - const c3d:: :blue:`IModelTree` * GetModelTree() const – get a pointer to the model tree. **Class writer_ex** The :blue:`writer_ex` class provides writing the model to a data buffer (to a set of file spaces) in the extended format. It inherits from the :blue:`writer` class. The :blue:`writer_ex` class implements: 1. Static functions for creating the class instance: - std::unique_ptr\< :blue:`writer_ex` \> CreateWriterEx( std::unique_ptr\< :blue:`iobuf_Seq` \>, uint16 ) – create the class instance for a given sequential memory buffer of type :blue:`iobuf_Seq`. - std::unique_ptr\< :blue:`writer_ex` \> CreateMemWriterEx( :blue:`membuf` &, uint8 ) – create the class instance for a given memory buffer of type :blue:`membuf`. 2. Methods for writing a model tree and access to it: - void WriteModelCatalog() – write a model tree. - const c3d:: :blue:`IModelTree` * GetModelTree() const – get a pointer to the model tree. Read Streams ------------ **Class reader** The :blue:`reader` class provides reading from a data buffer (a file space) written in the compact format. It inherits from the base class :blue:`tape`. The **reader** class implements: 1. Static functions for creating the class instance: - reader_ptr CreateReader( std::unique_ptr\< :blue:`iobuf_Seq` \>, uint16 ) – create the class instance for a sequential memory buffer. - reader_ptr CreateMemReader( :blue:`membuf` &, uint8 ) – create the class instance for a memory buffer. 2. Methods for reading objects of different types from the buffer: - :blue:`TapeBase` * readObject( :blue:`TapeBase` * ) – read an object. - :blue:`TapeBase` * readObjectPointer() – read a pointer to an object. - bool readUInt64( uint64 & ) – read an unsigned 64‑bit integer from the buffer. - bool readInt64( int64 & ) – read a 64‑bit integer from the buffer. - int readByte() – read a byte from the buffer. - bool readBytes( void *, size_t ) – read a bytes sequence from the buffer. 3. Methods for managing reading of the model tree and partial reading of the model objects (these methods are not supported by this class, they have an empty implementation): - void ReadObjectCatalog() – read the model table of contents. - :blue:`membuf` * ReadObjectByPosition( const :blue:`ClusterReference` & ) – read an object by its position in the buffer. - bool SetReadPosition( :blue:`ClusterReference` & ) – set the reading position. - const c3d:: :blue:`IModelTree` * GetModelTree() const – get a pointer to the model tree. - bool IsFullRead() – get an indicator of full reading of the current object (whether the current object is read in full). - void SetFullRead( bool ) – set an indicator of full reading of the current object (read the current object in full). 4. Method to get reading errors: - uint32 GetLastError() – get reading errors. 5. Methods for working with the progress indicator: - void InitProgress( IProgressIndicator * ) – initialize the progress indicator. - void InitProgress( ProgressBarWrapper & ) – initialize the progress indicator. **Class reader_ex** The :blue:`reader_ex` class provides reading from a data buffer (a set of file spaces) written in the compact or extended format. It can read objects from several file spaces by given positions. It inherits from the :blue:`reader` class. The :blue:`reader_ex` class implements: 1. Static functions for creating the class instance: - std::unique_ptr\< :blue:`reader_ex` \> CreateReaderEx( std::unique_ptr\< :blue:`iobuf_Seq` \>, uint16 ) – create the class instance for a sequential memory buffer. - std::unique_ptr\< :blue:`reader_ex` \> CreateMemReaderEx( :blue:`membuf` &, uint8 ) – create the class instance for a memory buffer. 2. Methods for managing reading of the model tree and partial reading of the model objects: - void ReadObjectCatalog() – read the model table of contents. - :blue:`TapeBase` * ReadObjectByPosition( const :blue:`ClusterReference` & ) – read an object by its position in the buffer. - bool SetReadPosition( :blue:`ClusterReference` & ) – set the reading position. - const c3d:: :blue:`IModelTree` * GetModelTree() const – get a pointer to the model tree. - bool IsFullRead() – get an indicator of full reading of the current object (whether the current object is read in full). - void SetFullRead( bool ) – set an indicator of full reading of the current object (read the current object in full). 3. Method to get reading errors: - uint32 GetLastError() – get reading errors. Scoped Progress Indicator for Reading Classes --------------------------------------------- The **ScopedReadProgress** class implements a progress indicator in the scope for classes of model reading. It creates a child progress indicator in the scope for the current instance of :blue:`reader` or :blue:`reader_ex`. When exiting the scope, the current progress indicator is released and the parent progress indicator is set. The class defines an operator for accessing the current progress indicator: - ProgressBarWrapper * operator()(). Read-Write Stream ----------------- The :blue:`rw` class provides reading and writing the model in the data buffer (in a file space) in the compact format. It inherits from the :blue:`reader` and :blue:`writer` classes. The class implements a static function for creating the class instance: - rw_ptr CreateMemWriter( :blue:`membuf` &, uint8 ). Model Tree ---------- The classes for the model tree are defined in the **io_tree.h** file. A tree node data is declared as the :blue:`MbItemData` structure. The :blue:`IModelTreeNode` class defines an interface for a tree node, which can have several descendants and is able to write itself to the stream and read itself from the stream. The :blue:`IModelTreeNode` class contains ordered arrays of pointers to the immediate descendants and the immediate ancestors of the node. The :blue:`IModelTreeNode` class declares the methods: - std::set\< const :blue:`IModelTreeNode` * \> & GetParents() – access to the immediate node ancestors. - const std::set\< const :blue:`IModelTreeNode` * \> & GetParents() const – access to the immediate node ancestors. - std::set\< const :blue:`IModelTreeNode` * \> & GetChildren() – access to the immediate node descendants. - const std::set\< const :blue:`IModelTreeNode` * \> & GetChildren() const – access to the immediate node descendants. - void AddParent( :blue:`IModelTreeNode` * parent ) – add an ancestor. - void AddChild( :blue:`IModelTreeNode` * child ) – add a descendant. - :blue:`MbItemData` & GetData() – access to the node data. - const :blue:`MbItemData` & GetData() const – access to the node data. - :blue:`ClusterReference` & GetPosition() – access to the position of the node reading/writing. - bool PartialRead() – check whether to read the node partially. While separate reading an object there can be a need to read some data from its parent; in this case the parent object is read partially and has a corresponding flag. - void SetPartialRead( bool partial ) – set an indication of full or partial node reading. - :blue:`writer` & operator >>( :blue:`writer` & ) – write the node to the stream. - :blue:`reader` & operator <<( :blue:`reader` & ) – read the node from the stream. The :blue:`IModelTree` class defines an interface for a generic model tree, which is used for creating, writing and reading the model table of contents in the memory buffer. The class defines types of callback functions: - FilterNodesFunc – the type of a function for selecting tree nodes by filters. - NodeToAddFunc – the type of a function for determining whether to add an object to the model tree and for filling the node data. The :blue:`IModelTree` class defines the :blue:`TreeType` enumeration for tree types: - mtt_Model – the tree contains a standard model (the :blue:`MbModel` object). - mtt_Embodiment – the tree contains embodiments. The class declares the methods: - :blue:`TreeType` GetType() const – get the tree type. - void SetType( :blue:`TreeType` type ) – set the tree type. - void AddNode( const :blue:`TapeBase` *, const :blue:`ClusterReference` & ) – add a node to the tree. - void CloseNode( const :blue:`IModelTreeNode` * ) – notification about the end of current node writing/reading (the function must be called when the read/write of the given node is complete). - std::unique_ptr\< const :blue:`IModelTree` \> GetFilteredTree( const std::vector\< :blue:`MbItemData` \> & filters ) – build a tree of nodes, selected by filters, from the current tree. For a tree of :blue:`mtt_Embodiment` type, the function works with the first embodiment. - std::unique_ptr\< const :blue:`IModelTree` \> GetFilteredTree( std::vector\< const :blue:`IModelTreeNode` * \> & nodes ) – build a tree for given nodes. Not applicable to a tree of :blue:`mtt_Embodiment` type (in this case returns NULL). - const :blue:`IEmbodimentTree` * GetEmbodimentsTree() const – get a pointer to the embodiments tree; returns NULL if not applicable (in case of a tree of :blue:`mtt_Model` type). - void SetNodeToAddFunction( :blue:`NodeToAddFunc` callback ) – define a function for selecting a geometric object for adding to the model tree and filling the node data. - void SetFilterFunction( :blue:`FilterNodesFunc` callback ) – define a function for selecting nodes from the model tree. - :blue:`writer` & operator >>( :blue:`writer` & ) – write the tree to the stream. - :blue:`reader` & operator <<( :blue:`reader` & ) – read the tree from the stream. - Access to the tree roots. A tree node can be nested recursively (for example, an Instance can contain an Assembly which contains another Instance which includes this Assembly): - const std::vector\< const :blue:`IModelTreeNode` * \> & GetRoots() – get the tree roots. - std::vector\< const :blue:`IModelTreeNode` * \> & GetRoots() – get the tree roots. - :blue:`VERSION` GetVersion() – get the tree version. - void SetVersion( :blue:`VERSION` ) – set the tree version. - static :blue:`IModelTree` * CreateModelTree() – create a tree instance. The :blue:`IEmbodimentNode` class defines an interface for an embodiment tree node. It contains ordered arrays of pointers to the immediate descendants of the node in an embodiment tree. The class declares the methods: - std::unique_ptr\< const :blue:`IModelTree` \> GetEmbodiment() const – build a tree of a model of type :blue:`mtt_Model` which is contained in a given embodiment. - const :blue:`MbItemData` & GetEmbodimentData() const – access to the embodiment info. - std::set\< const :blue:`IEmbodimentNode` * \> & GetChildren() – access to the immediate node children. - const std::set\< const :blue:`IEmbodimentNode` * \> & GetChildren() const – access to the immediate node children. - void AddChild( :blue:`IEmbodimentNode` * child ) – add a child. The :blue:`IEmbodimentTree` class defines an interface for an embodiment tree which presents a hierarchy of variants of model implementation (embodiments). Each node of the tree presents one embodiment. The class declares the methods: - const std::vector\< const :blue:`IEmbodimentNode` * \> & GetRoots() const – access to the tree roots. - std::vector\< const :blue:`IEmbodimentNode` * \> & GetRoots() – access to the tree roots. Streaming Objects ----------------- Model objects which can be serialized (represented as a sequence of bytes) are called streaming objects. Classes of streaming objects inherit from the base class :blue:`TapeBase`, which is defined in the **tape.h** file. Streaming objects can be registered and not registered. This determines how they should be written to the stream. A registered object is written separately, and model objects which refer to it contain a link to it. A not registered object is written inside the object which refers to it. **Types of streaming object registration** Types of streaming object registration are defined in the :blue:`RegistrableRec` enumeration: - noRegistrable – not registered object. - registrable – registered object. **Base class of streaming objects TapeBase** The :blue:`ClassDescriptor` class defines a packed name of a streaming class. It keeps a class name hash and an application identifier. Classes of streaming objects inherit from the base class :blue:`TapeBase`, which defines the following methods: - :blue:`RegistrableRec` GetRegistrable() const – get the registration type of the streaming class. - void SetRegistrable( :blue:`RegistrableRec` regs ) – set the registration state of the streaming class. - :blue:`ClassDescriptor` GetClassDescriptor( const :blue:`VersionContainer` & ) – get the class descriptor. - const char * GetPureName( const :blue:`VersionContainer` & ) – get the class name. - bool :blue:`IsFamilyRegistrable`\() const – whether the object belongs to a registrable family. Modes of Streaming Operations ----------------------------- Modes of streaming operations are described in the io:: :blue:`mode_flags` enumeration in the **io_buffer.h** file: - in – open stream for reading. - out – open stream for writing. - trunc – open an existing file and clear its content. - speedOnClose – sort while closing. - delIfEmpty – delete the file if it is empty. - delOnClose – delete the file while closing. - recovery – recovery mode. - appSpecial – an auxiliary flag of the application. - createNew – create a new file; an error is generated if the file already exists. - createAlways – create a new file; if the file already exists, it is rewritten. - openExisting – open an existing file; an error is generated if the file does not exist. - openAlways – open an existing file; if the file does not exist, a new file is created. - truncExisting – open the file with clearing its content. Stream States ------------- Flags of stream state are defined in the :blue:`state` enumeration in the **io_buffer.h** file: - good – everything is all right (no bits are set). - eof – the end of the file. - outOfRead – out of limits of the file. - outOfMemory – failed to allocate requested memory. - fail – input‑output error. - badData – incorrect file structure. - notFound – file not found. - accessViolation – access is denied. - cantOpenStore – cannot open the storage. - cantCreateStore – cannot create a storage. - badSig – there is no signature or the signature is wrong. - cantReadCatalog – cannot read the storage catalog. - cantWriteCatalog – cannot write the catalog of the storage. - cantFind – cannot find a file in the catalog. - cantRead – cannot read the file. - cantWrite – cannot write the file. - badClassId – the class identifier was not found in the database. - doubledClassId – attempt of repeated registration of the class identifier. - verViolation – the file version is older than the task version. - hardFail – file operation error. - closed – the buffer is closed. - writeProtect – the “Read only” attribute is set for the file. - cantWriteObject – cannot write the object (the stream version is newer than the new object class occurrence version). - underflow64to32 – cannot read a file with 64‑bit data in a 32‑bit task (loss of upper word uint32 while reading uint64 in a 32‑bit task). - encrypted – the file is protected or encrypted. - skippedUnknown – partial read of a file in the extended format (unknown objects skipped). - readAborted – file reading aborted by user. - allMask – all errors.