Чтение и запись потоковых объектов
Классы для чтения и записи потоковых объектов модели (потоки для чтения и записи) определены в файле 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 реализует:
Статические функции для создания экземпляра класса:
writer_ptr CreateWriter( std::unique_ptr< iobuf_Seq >, uint16 ) – создать экземпляр класса для последовательного буфера памяти типа iobuf_Seq.
writer_ptr CreateMemWriter( membuf &, uint8 ) – создать экземпляр класса для буфера памяти типа membuf.
Методы для записи в буфер объектов различных типов:
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).
Методы для записи дерева модели и доступа к нему (в данном классе определяются, но не поддерживаются, содержат пустую реализацию):
void WriteModelCatalog() – записать дерево модели.
const c3d:: IModelTree * GetModelTree() const – получить указатель на дерево модели.
Класс writer_ex
Класс writer_ex обеспечивает запись модели в буфер данных (в набор файловых пространств) в расширенном формате. Он наследует от базового класса writer.
Класс writer_ex реализует:
Статические функции для создания экземпляра класса:
std::unique_ptr< writer_ex > CreateWriterEx( std::unique_ptr< iobuf_Seq >, uint16 ) – создать экземпляр класса для последовательного буфера памяти типа iobuf_Seq.
std::unique_ptr< writer_ex > CreateMemWriterEx( membuf &, uint8 ) – создать экземпляр класса для буфера памяти типа membuf.
Методы для записи дерева модели и доступа к нему:
void WriteModelCatalog() – записать дерево модели.
const c3d:: IModelTree * GetModelTree() const – получить указатель на дерево модели.
Чтение модели
Класс reader
Класс reader обеспечивает чтение модели из буфера данных (файлового пространства), записанного в компактном формате. Он наследует от базового класса tape.
Класс reader реализует:
Статические функции для создания экземпляра класса:
reader_ptr CreateReader( std::unique_ptr< iobuf_Seq >, uint16 ) – создать экземпляр класса для последовательного буфера.
reader_ptr CreateMemReader( membuf &, uint8 ) – создать экземпляр класса для буфера в памяти.
Методы для чтения из буфера объектов различных типов:
TapeBase * readObject( TapeBase * ) – прочитать объект.
TapeBase * readObjectPointer() – прочитать указатель на объект.
bool readUInt64( uint64 & ) – прочитать беззнаковое 64‑разрядное целое число.
bool readInt64( int64 & ) – прочитать 64‑разрядное целое число.
int readByte() – прочитать байт из буфера.
bool readBytes( void *, size_t ) – прочитать последовательность байтов из буфера.
Методы управления чтением дерева модели и частичным чтением объектов модели (в данном классе определяются, но не поддерживаются, содержат пустую реализацию):
void ReadObjectCatalog() – прочитать каталог объектов.
membuf * ReadObjectByPosition( const ClusterReference & ) – прочитать объект по позиции чтения.
bool SetReadPosition( ClusterReference & ) – установить позицию чтения.
const c3d:: IModelTree * GetModelTree() const – получить указатель на дерево модели.
bool IsFullRead() – получить признак полного чтения текущего объекта (читается ли текущий объект целиком).
void SetFullRead( bool ) – установить признак полного чтения текущего объекта (читать ли текущий объект целиком).
Метод получения ошибок чтения:
uint32 GetLastError() – получить ошибки чтения.
Методы работы с индикатором прогресса:
void InitProgress( IProgressIndicator * ) – инициализировать индикатор прогресса.
void InitProgress( ProgressBarWrapper & ) – инициализировать индикатор прогресса.
Класс reader_ex
Класс reader_ex обеспечивает чтение модели из буфера данных (набора файловых пространств), записанного в компактном или расширенном формате. Может читать из нескольких файловых пространств по заданным позициям. Наследует от базового класса reader.
Класс reader_ex реализует:
Статические функции для создания экземпляра класса:
std::unique_ptr< reader_ex > CreateReaderEx( std::unique_ptr< iobuf_Seq >, uint16 ) – создать экземпляр класса для последовательного буфера.
std::unique_ptr< reader_ex > CreateMemReaderEx( membuf &, uint8 ) – создать экземпляр класса для буфера в памяти.
Методы управления чтением дерева модели и частичным чтением объектов модели:
void ReadObjectCatalog() – прочитать каталог объектов.
TapeBase * ReadObjectByPosition( const ClusterReference & ) – прочитать объект по позиции чтения.
bool SetReadPosition( ClusterReference & ) – установить позицию чтения.
const c3d:: IModelTree * GetModelTree() const – получить указатель на дерево модели.
bool IsFullRead() – получить признак полного чтения текущего объекта (читается ли текущий объект целиком).
void SetFullRead( bool ) – установить признак полного чтения текущего объекта (читать ли текущий объект целиком).
Метод получения ошибок чтения:
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 – все ошибки.