.. role:: blue :class: blue Чтение и запись потоковых объектов ================================== .. _Read_and_write_streaming_objects: .. версия ядра: Классы для чтения и записи потоковых объектов модели (потоки для чтения и записи) определены в файле **tape.h**. Они наследуют от базового класса :blue:`tape`. Базовый класс для потоков чтения и записи ----------------------------------------- Базовый класс потока для чтения и записи :blue:`tape` содержит ссылки на буфер данных, менеджер потоков чтения (записи) и структуру для регистрации прочитанных (записанных) объектов. Он предоставляет методы управления буфером данных, регистрацией объектов и методы работы с индикатором прогресса. Доступ к буферу данных: - const :blue:`iobuf_Seq` & GetIOBuffer() – доступ к буферу данных. - :blue:`iobuf_Seq` & GetIOBuffer() – доступ к буферу данных. - bool :blue:`IsOwnBuffer`\() – владеем ли буфером? - void :blue:`SetOwnBuffer`\( bool ) – установить флаг владения буфером. Управление режимом работы буфера данных: - uint8 mode() – узнать режим работы буфера. - void setMode( uint8 ) – установить режим работы буфера. - void clearState( :blue:`state` ) – убрать состояние буфера. - void setState( :blue:`state` ) – добавить состояние буфера. Опрос состояния буфера данных: - int fresh() – свежий ли буфер? - bool good() – корректно ли состояние буфера? - uint8 eof() – достигнут ли конец файла? - uint32 state() – получить флаг состояния буфера. - io::pos tell() – получить текущую позицию в потоке. Управление версиями: - void SetVersionsByStorage() – установить текущую версию равной версии хранилища. - :blue:`VERSION` MathVersion() – вернуть главную версию (версию математического ядра). - :blue:`VERSION` AppVersion( size_t ind ) – вернуть дополнительную версию (версию конечного приложения). - const :blue:`VersionContainer` & GetVersionsContainer() – получить доступ к контейнеру версий. - void SetVersionsContainer( const :blue:`VersionContainer` & ) – установить версию открытого файла. - :blue:`VERSION` SetStorageVersion( :blue:`VERSION` ) – установить версию хранилища. Управление регистрацией объектов: - void registrate( const :blue:`TapeBase` * ) – зарегистрировать указатель. - void unregistrate( const :blue:`TapeBase` * ) – отменить регистрацию указателя. - bool exist( const :blue:`TapeBase` * ) – есть ли зарегистрированный объект? - void flushRegister() – очистить массив регистрации. - size_t RegisteredCount() – получить количество зарегистрированных объектов. - size_t GetMaxRegisteredCount() – получить максимально возможное количество объектов для регистрации. - void ReserveRegistered( size_t n ) – зарезервировать память под n объектов. - uint8 GetIndexType( size_t index ) – получить тип индекса. Работа с индикатором прогресса: - void InitProgress( IProgressIndicator * pr ) – инициализировать индикатор прогресса. - void InitProgress( ProgressBarWrapper & pr ) – инициализировать индикатор прогресса. - void ResetProgress() – освободить текущий индикатор прогресса, установить родительский индикатор прогресса, если он есть. - ProgressBarWrapper * GetProgress() – получить индикатор прогресса. Запись модели ------------- **Класс writer** Класс :blue:`writer` обеспечивает запись модели в буфер данных (файловое пространство) в компактном формате. Он наследует от базового класса :blue:`tape`. Класс :blue:`writer` реализует: 1. Статические функции для создания экземпляра класса: - writer_ptr CreateWriter( std::unique_ptr\< iobuf_Seq \>, uint16 ) – создать экземпляр класса для последовательного буфера памяти типа :blue:`iobuf_Seq`. - writer_ptr CreateMemWriter( :blue:`membuf` &, uint8 ) – создать экземпляр класса для буфера памяти типа :blue:`membuf`. 2. Методы для записи в буфер объектов различных типов: - void writeObject( const :blue:`TapeBase` * ) – записать объект. - void writeObjectPointer( const :blue:`TapeBase` * ) – записать указатель на объект. - void writeByte( uint8 ) – записать байт в буфер. - void writeBytes( const void *, size_t ) – записать последовательность байтов в буфер. - void writeUInt64( const uint64 & ) – записать беззнаковое 64‑разрядное целое число. Возвращает количество записанных байт. - void writeInt64( const int64 & ) – записать 64‑разрядное целое число. Возвращает количество записанных байт. - writer & _writeChar( const char * ) – записать CHAR‑строку в поток (кодировка ANSI, русская локаль). - writer & _writeWchar( const TCHAR * ) – записать WCHAR‑строку в поток (в потоке хранится как UTF‑16). - writer & _writeWcharT( const wchar_t * ) – записать WCHAR‑строку в поток (в потоке хранится как UTF‑16). - size_t _lenWchar( const TCHAR * ) – получить длину записи WCHAR‑строки в поток (в потоке хранится как UTF‑16). 3. Методы для записи дерева модели и доступа к нему (в данном классе определяются, но не поддерживаются, содержат пустую реализацию): - void WriteModelCatalog() – записать дерево модели. - const c3d:: :blue:`IModelTree` * GetModelTree() const – получить указатель на дерево модели. **Класс writer_ex** Класс :blue:`writer_ex` обеспечивает запись модели в буфер данных (в набор файловых пространств) в расширенном формате. Он наследует от базового класса :blue:`writer`. Класс :blue:`writer_ex` реализует: 1. Статические функции для создания экземпляра класса: - std::unique_ptr\< :blue:`writer_ex` \> CreateWriterEx( std::unique_ptr\< :blue:`iobuf_Seq` \>, uint16 ) – создать экземпляр класса для последовательного буфера памяти типа :blue:`iobuf_Seq`. - std::unique_ptr\< :blue:`writer_ex` \> CreateMemWriterEx( :blue:`membuf` &, uint8 ) – создать экземпляр класса для буфера памяти типа :blue:`membuf`. 2. Методы для записи дерева модели и доступа к нему: - void WriteModelCatalog() – записать дерево модели. - const c3d:: :blue:`IModelTree` * GetModelTree() const – получить указатель на дерево модели. Чтение модели ------------- **Класс reader** Класс :blue:`reader` обеспечивает чтение модели из буфера данных (файлового пространства), записанного в компактном формате. Он наследует от базового класса :blue:`tape`. Класс **reader** реализует: 1. Статические функции для создания экземпляра класса: - reader_ptr CreateReader( std::unique_ptr\< :blue:`iobuf_Seq` \>, uint16 ) – создать экземпляр класса для последовательного буфера. - reader_ptr CreateMemReader( :blue:`membuf` &, uint8 ) – создать экземпляр класса для буфера в памяти. 2. Методы для чтения из буфера объектов различных типов: - :blue:`TapeBase` * readObject( :blue:`TapeBase` * ) – прочитать объект. - :blue:`TapeBase` * readObjectPointer() – прочитать указатель на объект. - bool readUInt64( uint64 & ) – прочитать беззнаковое 64‑разрядное целое число. - bool readInt64( int64 & ) – прочитать 64‑разрядное целое число. - int readByte() – прочитать байт из буфера. - bool readBytes( void *, size_t ) – прочитать последовательность байтов из буфера. 3. Методы управления чтением дерева модели и частичным чтением объектов модели (в данном классе определяются, но не поддерживаются, содержат пустую реализацию): - void ReadObjectCatalog() – прочитать каталог объектов. - :blue:`membuf` * ReadObjectByPosition( const :blue:`ClusterReference` & ) – прочитать объект по позиции чтения. - bool SetReadPosition( :blue:`ClusterReference` & ) – установить позицию чтения. - const c3d:: :blue:`IModelTree` * GetModelTree() const – получить указатель на дерево модели. - bool IsFullRead() – получить признак полного чтения текущего объекта (читается ли текущий объект целиком). - void SetFullRead( bool ) – установить признак полного чтения текущего объекта (читать ли текущий объект целиком). 4. Метод получения ошибок чтения: - uint32 GetLastError() – получить ошибки чтения. 5. Методы работы с индикатором прогресса: - void InitProgress( IProgressIndicator * ) – инициализировать индикатор прогресса. - void InitProgress( ProgressBarWrapper & ) – инициализировать индикатор прогресса. **Класс reader_ex** Класс :blue:`reader_ex` обеспечивает чтение модели из буфера данных (набора файловых пространств), записанного в компактном или расширенном формате. Может читать из нескольких файловых пространств по заданным позициям. Наследует от базового класса :blue:`reader`. Класс :blue:`reader_ex` реализует: 1. Статические функции для создания экземпляра класса: - std::unique_ptr\< :blue:`reader_ex` \> CreateReaderEx( std::unique_ptr\< :blue:`iobuf_Seq` \>, uint16 ) – создать экземпляр класса для последовательного буфера. - std::unique_ptr\< :blue:`reader_ex` \> CreateMemReaderEx( :blue:`membuf` &, uint8 ) – создать экземпляр класса для буфера в памяти. 2. Методы управления чтением дерева модели и частичным чтением объектов модели: - void ReadObjectCatalog() – прочитать каталог объектов. - :blue:`TapeBase` * ReadObjectByPosition( const :blue:`ClusterReference` & ) – прочитать объект по позиции чтения. - bool SetReadPosition( :blue:`ClusterReference` & ) – установить позицию чтения. - const c3d:: :blue:`IModelTree` * GetModelTree() const – получить указатель на дерево модели. - bool IsFullRead() – получить признак полного чтения текущего объекта (читается ли текущий объект целиком). - void SetFullRead( bool ) – установить признак полного чтения текущего объекта (читать ли текущий объект целиком). 3. Метод получения ошибок чтения: - uint32 GetLastError() – получить ошибки чтения. Индикатор прогресса в области видимости для классов чтения --------------------------------------------------------- Класс **ScopedReadProgress** реализует индикатор прогресса в области видимости для классов чтения модели. Он создает дочерний индикатор прогресса для индикатора прогресса в заданном экземпляре класса :blue:`reader` или :blue:`reader_ex`. При выходе из области видимости текущий индикатор прогресса освобождается и устанавливается родительский индикатор прогресса. Класс определяет оператор доступа к текущему индикатору прогресса: - ProgressBarWrapper * operator()(). Чтение и запись модели ---------------------- Класс :blue:`rw` обеспечивает чтение и запись модели в буфер данных (в набор файловых пространств) в компактном формате. Он наследует от классов :blue:`reader` и :blue:`writer`. Класс реализует статическую функцию для создания экземпляра класса: - rw_ptr CreateMemWriter( :blue:`membuf` &, uint8 ). Дерево модели ------------- Классы дерева модели определены в файле *io_tree.h*. Данные узла дерева объявлены как структура :blue:`MbItemData`. Класс :blue:`IModelTreeNode` определяет интерфейс для узла дерева модели, который может иметь несколько потомков, умеет записываться в поток и читаться из потока. Класс :blue:`IModelTreeNode` содержит упорядоченные массивы указателей на непосредственных потомков узла и непосредственных предков узла. Класс :blue:`IModelTreeNode` объявляет методы: - std::set\< const :blue:`IModelTreeNode` * \> & GetParents() – доступ к непосредственным предкам узла. - const std::set\< const :blue:`IModelTreeNode` * \> & GetParents() const – доступ к непосредственным предкам узла. - std::set\< const :blue:`IModelTreeNode` * \> & GetChildren() – доступ к непосредственным потомкам узла. - const std::set\< const :blue:`IModelTreeNode` * \> & GetChildren() const – доступ к непосредственным потомкам узла. - void AddParent( :blue:`IModelTreeNode` * parent ) – добавить предка. - void AddChild( :blue:`IModelTreeNode` * child ) – добавить потомка. - :blue:`MbItemData` & GetData() – доступ к данным узла. - const :blue:`MbItemData` & GetData() const – доступ к данным узла. - :blue:`ClusterReference` & GetPosition() – доступ к позиции чтения/записи узла. - bool PartialRead() – узнать, читать ли только часть узла. При чтении объекта может возникнуть необходимость чтения некоторых данных его родителя. В этом случае объект родителя читается частично и имеет соответствующий флаг. - void SetPartialRead( bool partial ) – установить признак частичного или полного чтения узла. - :blue:`writer` & operator >>( :blue:`writer` & ) – записать узел в поток. - :blue:`reader` & operator <<( :blue:`reader` & ) – прочитать узел из потока. Класс :blue:`IModelTree` определяет интерфейс обобщенного дерева модели, которое используется для формирования, записи и чтения оглавления модели в буфере памяти. Класс определяет типы callback‑функций: - FilterNodesFunc – тип функции для выбора узлов дерева по фильтрам. - NodeToAddFunc – тип функции для определения, нужно ли добавлять объект в дерево модели, и заполнения данных узла дерева. Класс :blue:`IModelTree` определяет перечисление :blue:`TreeType` для типов дерева: - mtt_Model – дерево содержит стандартную модель (объект :blue:`MbModel`). - mtt_Embodiment – дерево содержит исполнения. Класс объявляет методы: - :blue:`TreeType` GetType() const – выдать тип дерева. - void SetType( :blue:`TreeType` type ) – установить тип дерева. - void AddNode( const :blue:`TapeBase` *, const :blue:`ClusterReference` & ) – добавить узел в дерево. - void CloseNode( const :blue:`IModelTreeNode` * ) – нотификация об окончании чтения/записи текущего узла (функция должна вызываться по окончании чтения/записи заданного узла дерева). - std::unique_ptr\< const :blue:`IModelTree` \> GetFilteredTree( const std::vector\< :blue:`MbItemData` \> & filters ) – построить и выдать дерево из узлов текущего дерева, выбранных по фильтрам. В случае дерева с типом :blue:`mtt_Embodiment` функция работает с первым исполнением. - std::unique_ptr\< const :blue:`IModelTree` \> GetFilteredTree( std::vector\< const :blue:`IModelTreeNode` * \> & nodes ) – построить и выдать дерево из заданных узлов. Не применимо к дереву с типом :blue:`mtt_Embodiment` (в этом случае возвращает NULL). - const :blue:`IEmbodimentTree` * GetEmbodimentsTree() const – выдать указатель на дерево исполнений. Выдает NULL, если не применимо (в случае дерева с типом :blue:`mtt_Model`). - void SetNodeToAddFunction( :blue:`NodeToAddFunc` callback ) – установить функцию для выбора геометрического объекта для добавления в дерево модели и заполнения данных узла дерева. - void SetFilterFunction( :blue:`FilterNodesFunc` callback ) – установить функцию для выбора узлов из дерева модели. - :blue:`writer` & operator >>( :blue:`writer` & ) – записать дерево в поток. - :blue:`reader` & operator <<( :blue:`reader` & ) – прочитать дерево из потока. - Доступ к корням дерева. Узел дерева может быть рекурсивно вложен (например, объект вставка может содержать сборку, которая содержит другой объект вставка, ссылающийся на эту же сборку): - const std::vector\< const :blue:`IModelTreeNode` * \> & GetRoots() – получить корни дерева. - std::vector\< const :blue:`IModelTreeNode` * \> & GetRoots() – получить корни дерева. - :blue:`VERSION` GetVersion() – получить версию дерева. - void SetVersion( :blue:`VERSION` ) – задать версию дерева. - static :blue:`IModelTree` * CreateModelTree() – создать экземпляр дерева. Класс :blue:`IEmbodimentNode` определяет интерфейс для узла дерева исполнений. Он содержит упорядоченный массив указателей на непосредственных потомков узла в дереве исполнений. Класс объявляет методы: - std::unique_ptr\< const :blue:`IModelTree` \> GetEmbodiment() const – построить дерево модели типа :blue:`mtt_Model`, которое содержится в данном исполнении. - const :blue:`MbItemData` & GetEmbodimentData() const – доступ к информации об исполнении. - std::set\< const :blue:`IEmbodimentNode` * \> & GetChildren() – доступ к непосредственным потомкам узла. - const std::set\< const :blue:`IEmbodimentNode` * \> & GetChildren() const – доступ к непосредственным потомкам узла. - void AddChild( :blue:`IEmbodimentNode` * child ) – добавить потомка. Класс :blue:`IEmbodimentTree` определяет интерфейс для дерева, которое отражает иерархию вариантов реализации модели (исполнений). Каждый узел дерева представляет одно исполнение. Класс объявляет методы: - const std::vector\< const :blue:`IEmbodimentNode` * \> & GetRoots() const – доступ к корням дерева. - std::vector\< const :blue:`IEmbodimentNode` * \> & GetRoots() – доступ к корням дерева. Потоковые объекты ----------------- Объекты модели, которые могут сериализоваться (представлять себя в виде последовательности байтов), называются потоковыми. Все классы потоковых объектов модели наследуются от базового класса :blue:`TapeBase`, который определен в файле *tape.h*. Потоковые объекты могут быть регистрируемыми и нерегистрируемыми. От этого зависит, как они будут записаны в поток. Регистрируемый объект пишется отдельно, и объекты модели, которые ссылаются на него, содержат ссылку. Нерегистрируемый объект пишется внутри объекта, который на него ссылается. **Типы регистрации потоковых объектов** Типы регистрации потоковых объектов определены в перечислении :blue:`RegistrableRec`: - noRegistrable – нерегистрируемый объект. - registrable – регистрируемый объект. **Базовый класс потоковых объектов TapeBase** Класс :blue:`ClassDescriptor` определяет упакованное имя потокового класса. Он хранит хэш имени класса и идентификатор приложения. Классы потоковых объектов модели наследуются от базового класса :blue:`TapeBase`, который определяет следующие методы: - :blue:`RegistrableRec` GetRegistrable() const – получить тип регистрации потокового класса. - void SetRegistrable( :blue:`RegistrableRec` regs ) – установить состояние регистрации потокового класса. - :blue:`ClassDescriptor` GetClassDescriptor( const :blue:`VersionContainer` & ) – получить дескриптор класса. - const char * GetPureName( const :blue:`VersionContainer` & ) – получить имя класса. - bool :blue:`IsFamilyRegistrable`\() const – принадлежит ли объект к регистрируемому семейству. Режимы потоковых операций ------------------------- Режимы потоковых операций описываются перечислением io:: :blue:`mode_flags` в файле *io_buffer.h*: - in – открыть поток для чтения. - out – открыть поток для записи. - trunc – открыть существующий файл и удалить его содержимое. - speedOnClose – упорядочить поток при закрытии. - delIfEmpty – удалить файл, если он оказался пустым. - delOnClose – удалить файл при закрытии. - recovery – режим восстановления. - appSpecial – вспомогательный флаг приложения. - createNew – создать новый файл. Выдается ошибка, если такой файл уже существует. - createAlways – создать новый файл. Если такой файл уже существует, то он перезаписывается. - openExisting – открыть существующий файл. Выдается ошибка, если файл не существует. - openAlways – открыть существующий файл. Если файл не существует, то создается новый. - truncExisting – открыть файл с удалением его содержимого. Флаги состояния потока ---------------------- Флаги состояния потока определены в перечислении :blue:`state` в файле *io_buffer.h*: - good – все в порядке (никакие биты не выставлены). - eof – конец файла. - outOfRead – выход за пределы файла. - outOfMemory – не получилось выделить необходимую память. - fail – ошибка операции ввода‑вывода. - badData – неверная структура файла. - notFound – файл не найден. - accessViolation – доступ запрещен. - cantOpenStore – не получилось открыть хранилище. - cantCreateStore – не получилось создать хранилище. - badSig – нет подписи или подпись чужая. - cantReadCatalog – не получилось прочитать каталог хранилища. - cantWriteCatalog – не получилось записать каталог хранилища. - cantFind – не получилось найти файл в каталоге. - cantRead – не получилось прочитать файл. - cantWrite – не получилось записать файл. - badClassId – прочитанный идентификатор класса не найден в базе данных. - doubledClassId – попытка повторной регистрации идентификатора класса. - verViolation – версия файла старше версии задачи. - hardFail – ошибка файловой операции. - closed – буфер закрыт. - writeProtect – у файла установлен атрибут «Только чтение». - cantWriteObject – не могу записать объект (версия потока младше версии появления нового класса объектов). - underflow64to32 – не могу прочитать файл с 64‑битными данными в 32‑битной задаче (потеря старшего слова uint32 при чтении uint64 в 32‑битной задаче). - encrypted – файл защищен или закодирован. - skippedUnknown – файл в расширенном формате прочитан частично (неизвестные объекты пропущены). - readAborted – чтение файла прервано пользователем. - allMask – все ошибки.