Чтение и запись потоковых объектов

Классы для чтения и записи потоковых объектов модели (потоки для чтения и записи) определены в файле tape.h. Они наследуют от базового класса tape.

Базовый класс для потоков чтения и записи

Базовый класс потока для чтения и записи tape содержит ссылки на буфер данных, менеджер потоков чтения (записи) и структуру для регистрации прочитанных (записанных) объектов.

Он предоставляет методы управления буфером данных, регистрацией объектов и методы работы с индикатором прогресса.

Доступ к буферу данных:

  • const iobuf_Seq & GetIOBuffer() – доступ к буферу данных.

  • iobuf_Seq & GetIOBuffer() – доступ к буферу данных.

  • bool IsOwnBuffer() – владеем ли буфером?

  • void SetOwnBuffer( bool ) – установить флаг владения буфером.

Управление режимом работы буфера данных:

  • uint8 mode() – узнать режим работы буфера.

  • void setMode( uint8 ) – установить режим работы буфера.

  • void clearState( state ) – убрать состояние буфера.

  • void setState( state ) – добавить состояние буфера.

Опрос состояния буфера данных:

  • int fresh() – свежий ли буфер?

  • bool good() – корректно ли состояние буфера?

  • uint8 eof() – достигнут ли конец файла?

  • uint32 state() – получить флаг состояния буфера.

  • io::pos tell() – получить текущую позицию в потоке.

Управление версиями:

  • void SetVersionsByStorage() – установить текущую версию равной версии хранилища.

  • VERSION MathVersion() – вернуть главную версию (версию математического ядра).

  • VERSION AppVersion( size_t ind ) – вернуть дополнительную версию (версию конечного приложения).

  • const VersionContainer & GetVersionsContainer() – получить доступ к контейнеру версий.

  • void SetVersionsContainer( const VersionContainer & ) – установить версию открытого файла.

  • VERSION SetStorageVersion( VERSION ) – установить версию хранилища.

Управление регистрацией объектов:

  • void registrate( const TapeBase * ) – зарегистрировать указатель.

  • void unregistrate( const TapeBase * ) – отменить регистрацию указателя.

  • bool exist( const 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

Класс writer обеспечивает запись модели в буфер данных (файловое пространство) в компактном формате. Он наследует от базового класса tape.

Класс writer реализует:

  1. Статические функции для создания экземпляра класса:

  • writer_ptr CreateWriter( std::unique_ptr< iobuf_Seq >, uint16 ) – создать экземпляр класса для последовательного буфера памяти типа iobuf_Seq.

  • writer_ptr CreateMemWriter( membuf &, uint8 ) – создать экземпляр класса для буфера памяти типа membuf.

  1. Методы для записи в буфер объектов различных типов:

  • void writeObject( const TapeBase * ) – записать объект.

  • void writeObjectPointer( const 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).

  1. Методы для записи дерева модели и доступа к нему (в данном классе определяются, но не поддерживаются, содержат пустую реализацию):

  • void WriteModelCatalog() – записать дерево модели.

  • const c3d:: IModelTree * GetModelTree() const – получить указатель на дерево модели.

Класс writer_ex

Класс writer_ex обеспечивает запись модели в буфер данных (в набор файловых пространств) в расширенном формате. Он наследует от базового класса writer.

Класс writer_ex реализует:

  1. Статические функции для создания экземпляра класса:

  • std::unique_ptr< writer_ex > CreateWriterEx( std::unique_ptr< iobuf_Seq >, uint16 ) – создать экземпляр класса для последовательного буфера памяти типа iobuf_Seq.

  • std::unique_ptr< writer_ex > CreateMemWriterEx( membuf &, uint8 ) – создать экземпляр класса для буфера памяти типа membuf.

  1. Методы для записи дерева модели и доступа к нему:

  • void WriteModelCatalog() – записать дерево модели.

  • const c3d:: IModelTree * GetModelTree() const – получить указатель на дерево модели.

Чтение модели

Класс reader

Класс reader обеспечивает чтение модели из буфера данных (файлового пространства), записанного в компактном формате. Он наследует от базового класса tape.

Класс reader реализует:

  1. Статические функции для создания экземпляра класса:

  • reader_ptr CreateReader( std::unique_ptr< iobuf_Seq >, uint16 ) – создать экземпляр класса для последовательного буфера.

  • reader_ptr CreateMemReader( membuf &, uint8 ) – создать экземпляр класса для буфера в памяти.

  1. Методы для чтения из буфера объектов различных типов:

  • TapeBase * readObject( TapeBase * ) – прочитать объект.

  • TapeBase * readObjectPointer() – прочитать указатель на объект.

  • bool readUInt64( uint64 & ) – прочитать беззнаковое 64‑разрядное целое число.

  • bool readInt64( int64 & ) – прочитать 64‑разрядное целое число.

  • int readByte() – прочитать байт из буфера.

  • bool readBytes( void *, size_t ) – прочитать последовательность байтов из буфера.

  1. Методы управления чтением дерева модели и частичным чтением объектов модели (в данном классе определяются, но не поддерживаются, содержат пустую реализацию):

  • void ReadObjectCatalog() – прочитать каталог объектов.

  • membuf * ReadObjectByPosition( const ClusterReference & ) – прочитать объект по позиции чтения.

  • bool SetReadPosition( ClusterReference & ) – установить позицию чтения.

  • const c3d:: IModelTree * GetModelTree() const – получить указатель на дерево модели.

  • bool IsFullRead() – получить признак полного чтения текущего объекта (читается ли текущий объект целиком).

  • void SetFullRead( bool ) – установить признак полного чтения текущего объекта (читать ли текущий объект целиком).

  1. Метод получения ошибок чтения:

  • uint32 GetLastError() – получить ошибки чтения.

  1. Методы работы с индикатором прогресса:

  • void InitProgress( IProgressIndicator * ) – инициализировать индикатор прогресса.

  • void InitProgress( ProgressBarWrapper & ) – инициализировать индикатор прогресса.

Класс reader_ex

Класс reader_ex обеспечивает чтение модели из буфера данных (набора файловых пространств), записанного в компактном или расширенном формате. Может читать из нескольких файловых пространств по заданным позициям. Наследует от базового класса reader.

Класс reader_ex реализует:

  1. Статические функции для создания экземпляра класса:

  • std::unique_ptr< reader_ex > CreateReaderEx( std::unique_ptr< iobuf_Seq >, uint16 ) – создать экземпляр класса для последовательного буфера.

  • std::unique_ptr< reader_ex > CreateMemReaderEx( membuf &, uint8 ) – создать экземпляр класса для буфера в памяти.

  1. Методы управления чтением дерева модели и частичным чтением объектов модели:

  • void ReadObjectCatalog() – прочитать каталог объектов.

  • TapeBase * ReadObjectByPosition( const ClusterReference & ) – прочитать объект по позиции чтения.

  • bool SetReadPosition( ClusterReference & ) – установить позицию чтения.

  • const c3d:: IModelTree * GetModelTree() const – получить указатель на дерево модели.

  • bool IsFullRead() – получить признак полного чтения текущего объекта (читается ли текущий объект целиком).

  • void SetFullRead( bool ) – установить признак полного чтения текущего объекта (читать ли текущий объект целиком).

  1. Метод получения ошибок чтения:

  • uint32 GetLastError() – получить ошибки чтения.

Индикатор прогресса в области видимости для классов чтения

Класс ScopedReadProgress реализует индикатор прогресса в области видимости для классов чтения модели. Он создает дочерний индикатор прогресса для индикатора прогресса в заданном экземпляре класса reader или reader_ex. При выходе из области видимости текущий индикатор прогресса освобождается и устанавливается родительский индикатор прогресса.

Класс определяет оператор доступа к текущему индикатору прогресса:

  • ProgressBarWrapper * operator()().

Чтение и запись модели

Класс rw обеспечивает чтение и запись модели в буфер данных (в набор файловых пространств) в компактном формате. Он наследует от классов reader и writer.

Класс реализует статическую функцию для создания экземпляра класса:

  • rw_ptr CreateMemWriter( membuf &, uint8 ).

Дерево модели

Классы дерева модели определены в файле io_tree.h.

Данные узла дерева объявлены как структура MbItemData.

Класс IModelTreeNode определяет интерфейс для узла дерева модели, который может иметь несколько потомков, умеет записываться в поток и читаться из потока.

Класс IModelTreeNode содержит упорядоченные массивы указателей на непосредственных потомков узла и непосредственных предков узла.

Класс IModelTreeNode объявляет методы:

  • std::set< const IModelTreeNode * > & GetParents() – доступ к непосредственным предкам узла.

  • const std::set< const IModelTreeNode * > & GetParents() const – доступ к непосредственным предкам узла.

  • std::set< const IModelTreeNode * > & GetChildren() – доступ к непосредственным потомкам узла.

  • const std::set< const IModelTreeNode * > & GetChildren() const – доступ к непосредственным потомкам узла.

  • void AddParent( IModelTreeNode * parent ) – добавить предка.

  • void AddChild( IModelTreeNode * child ) – добавить потомка.

  • MbItemData & GetData() – доступ к данным узла.

  • const MbItemData & GetData() const – доступ к данным узла.

  • ClusterReference & GetPosition() – доступ к позиции чтения/записи узла.

  • bool PartialRead() – узнать, читать ли только часть узла. При чтении объекта может возникнуть необходимость чтения некоторых данных его родителя. В этом случае объект родителя читается частично и имеет соответствующий флаг.

  • void SetPartialRead( bool partial ) – установить признак частичного или полного чтения узла.

  • writer & operator >>( writer & ) – записать узел в поток.

  • reader & operator <<( reader & ) – прочитать узел из потока.

Класс IModelTree определяет интерфейс обобщенного дерева модели, которое используется для формирования, записи и чтения оглавления модели в буфере памяти.

Класс определяет типы callback‑функций:

  • FilterNodesFunc – тип функции для выбора узлов дерева по фильтрам.

  • NodeToAddFunc – тип функции для определения, нужно ли добавлять объект в дерево модели, и заполнения данных узла дерева.

Класс IModelTree определяет перечисление TreeType для типов дерева:

  • mtt_Model – дерево содержит стандартную модель (объект MbModel).

  • mtt_Embodiment – дерево содержит исполнения.

Класс объявляет методы:

  • TreeType GetType() const – выдать тип дерева.

  • void SetType( TreeType type ) – установить тип дерева.

  • void AddNode( const TapeBase *, const ClusterReference & ) – добавить узел в дерево.

  • void CloseNode( const IModelTreeNode * ) – нотификация об окончании чтения/записи текущего узла (функция должна вызываться по окончании чтения/записи заданного узла дерева).

  • std::unique_ptr< const IModelTree > GetFilteredTree( const std::vector< MbItemData > & filters ) – построить и выдать дерево из узлов текущего дерева, выбранных по фильтрам. В случае дерева с типом mtt_Embodiment функция работает с первым исполнением.

  • std::unique_ptr< const IModelTree > GetFilteredTree( std::vector< const IModelTreeNode * > & nodes ) – построить и выдать дерево из заданных узлов. Не применимо к дереву с типом mtt_Embodiment (в этом случае возвращает NULL).

  • const IEmbodimentTree * GetEmbodimentsTree() const – выдать указатель на дерево исполнений. Выдает NULL, если не применимо (в случае дерева с типом mtt_Model).

  • void SetNodeToAddFunction( NodeToAddFunc callback ) – установить функцию для выбора геометрического объекта для добавления в дерево модели и заполнения данных узла дерева.

  • void SetFilterFunction( FilterNodesFunc callback ) – установить функцию для выбора узлов из дерева модели.

  • writer & operator >>( writer & ) – записать дерево в поток.

  • reader & operator <<( reader & ) – прочитать дерево из потока.

  • Доступ к корням дерева. Узел дерева может быть рекурсивно вложен (например, объект вставка может содержать сборку, которая содержит другой объект вставка, ссылающийся на эту же сборку):

    • const std::vector< const IModelTreeNode * > & GetRoots() – получить корни дерева.

    • std::vector< const IModelTreeNode * > & GetRoots() – получить корни дерева.

  • VERSION GetVersion() – получить версию дерева.

  • void SetVersion( VERSION ) – задать версию дерева.

  • static IModelTree * CreateModelTree() – создать экземпляр дерева.

Класс IEmbodimentNode определяет интерфейс для узла дерева исполнений. Он содержит упорядоченный массив указателей на непосредственных потомков узла в дереве исполнений.

Класс объявляет методы:

  • std::unique_ptr< const IModelTree > GetEmbodiment() const – построить дерево модели типа mtt_Model, которое содержится в данном исполнении.

  • const MbItemData & GetEmbodimentData() const – доступ к информации об исполнении.

  • std::set< const IEmbodimentNode * > & GetChildren() – доступ к непосредственным потомкам узла.

  • const std::set< const IEmbodimentNode * > & GetChildren() const – доступ к непосредственным потомкам узла.

  • void AddChild( IEmbodimentNode * child ) – добавить потомка.

Класс IEmbodimentTree определяет интерфейс для дерева, которое отражает иерархию вариантов реализации модели (исполнений). Каждый узел дерева представляет одно исполнение.

Класс объявляет методы:

  • const std::vector< const IEmbodimentNode * > & GetRoots() const – доступ к корням дерева.

  • std::vector< const IEmbodimentNode * > & GetRoots() – доступ к корням дерева.

Потоковые объекты

Объекты модели, которые могут сериализоваться (представлять себя в виде последовательности байтов), называются потоковыми. Все классы потоковых объектов модели наследуются от базового класса TapeBase, который определен в файле tape.h.

Потоковые объекты могут быть регистрируемыми и нерегистрируемыми. От этого зависит, как они будут записаны в поток. Регистрируемый объект пишется отдельно, и объекты модели, которые ссылаются на него, содержат ссылку. Нерегистрируемый объект пишется внутри объекта, который на него ссылается.

Типы регистрации потоковых объектов

Типы регистрации потоковых объектов определены в перечислении RegistrableRec:

  • noRegistrable – нерегистрируемый объект.

  • registrable – регистрируемый объект.

Базовый класс потоковых объектов TapeBase

Класс ClassDescriptor определяет упакованное имя потокового класса. Он хранит хэш имени класса и идентификатор приложения.

Классы потоковых объектов модели наследуются от базового класса TapeBase, который определяет следующие методы:

  • RegistrableRec GetRegistrable() const – получить тип регистрации потокового класса.

  • void SetRegistrable( RegistrableRec regs ) – установить состояние регистрации потокового класса.

  • ClassDescriptor GetClassDescriptor( const VersionContainer & ) – получить дескриптор класса.

  • const char * GetPureName( const VersionContainer & ) – получить имя класса.

  • bool IsFamilyRegistrable() const – принадлежит ли объект к регистрируемому семейству.

Режимы потоковых операций

Режимы потоковых операций описываются перечислением io:: mode_flags в файле io_buffer.h:

  • in – открыть поток для чтения.

  • out – открыть поток для записи.

  • trunc – открыть существующий файл и удалить его содержимое.

  • speedOnClose – упорядочить поток при закрытии.

  • delIfEmpty – удалить файл, если он оказался пустым.

  • delOnClose – удалить файл при закрытии.

  • recovery – режим восстановления.

  • appSpecial – вспомогательный флаг приложения.

  • createNew – создать новый файл. Выдается ошибка, если такой файл уже существует.

  • createAlways – создать новый файл. Если такой файл уже существует, то он перезаписывается.

  • openExisting – открыть существующий файл. Выдается ошибка, если файл не существует.

  • openAlways – открыть существующий файл. Если файл не существует, то создается новый.

  • truncExisting – открыть файл с удалением его содержимого.

Флаги состояния потока

Флаги состояния потока определены в перечислении 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 – все ошибки.