Данный компонент содержит основные классы и определения для стандарного способа сериализации сущностей.
Реализованный в данном компоненте способ сериализации называется стандартным (штатным) потому, что только этот способ сериализации может использоваться для сохранения объектов в oess_1::db.
Идея этого способа состоит в том, что по специальному описанию на языке DDL (подробнее см. oess_1::scheme) для сериализации/десериализации объектов строится вспомогательный код. Когда объект сериализуется ObjESSty использует этот код для преобразования объекта в двоичный образ. При десериализации объекта этот код используется для извлечения значений атрибутов объекта из двоичного образа и сохранения в объекте.
Для того, чтобы сделать объект сериализуемым необходимо:
Может показаться, что для объявления какого-либо типа требуется слишком много действий. На самом деле это не так. Можно взять в качестве примера сериализуемыe типы oess_1::db::storage::impl::stream_storage_dir_item_t, oess_1::db::storage::impl::stream_storage_dir_t:
#include <map> // Этот заголовочный файл нужен для доступа к типам oess_1::char_t,... #include <oess_1/defs/h/types.hpp> // Здесь описывается serializable_t. #include <oess_1/stdsn/h/serializable.hpp> // А здесь -- макросы OESS_SERIALIZER(), ... #include <oess_1/stdsn/h/macro.hpp> ... class stream_storage_dir_item_t : public oess_1::stdsn::serializable_t { typedef oess_1::stdsn::serializable_t base_type_t; OESS_SERIALIZER( stream_storage_dir_item_t ) public : stream_storage_dir_item_t(); stream_storage_dir_item_t( const oess_1::uint_t & id, const chain_id_t & description_chain ); stream_storage_dir_item_t( const stream_storage_dir_item_t & o ); virtual ~stream_storage_dir_item_t(); stream_storage_dir_item_t & operator=( const stream_storage_dir_item_t & o ); oess_1::uint_t id() const; const chain_id_t & description_chain() const; private : oess_1::uint_t m_id; chain_id_t m_description_chain; }; ... class stream_storage_dir_t : public oess_1::stdsn::serializable_t { typedef oess_1::stdsn::serializable_t base_type_t; OESS_SERIALIZER( stream_storage_dir_t ) public : stream_storage_dir_t(); stream_storage_dir_t( const stream_storage_dir_t & o ); virtual ~stream_storage_dir_t(); stream_storage_dir_t & operator=( const stream_storage_dir_t & o ); oess_1::uint_t allocate_id(); void add( const std::string & name, const oess_1::uint_t & id, const chain_id_t & description_chain ); void destroy( const std::string & name ); oess_1::uint_t find_id( const std::string & name ) const; bool is_exists( const std::string & name ) const; std::set< std::string > names() const; const stream_storage_dir_item_t & item( const std::string & name ) const; private : typedef std::map< std::string, stream_storage_dir_item_t > dir_t; dir_t m_dir; oess_1::uint_t m_id; dir_t::iterator locate_existent_item( const std::string & name ); dir_t::const_iterator locate_existent_item( const std::string & name ) const; }; ...
Видно, что в этих двух сериализуемых типах описание сериализуемости занимает всего по две строки: указание в качестве базового типа класса oess_1::stdsn::serializable_t и использование OESS_SERIALIZER(). DDL описание для этих типов так же весьма компактное:
{type oess_1::db::storage::impl::stream_storage_dir_item_t
{attr m_id {of oess_1::uint_t}}
{attr m_description_chain {of oess_1::uint_t}}
}
{type oess_1::db::storage::impl::stream_storage_dir_t
{attr m_dir
{stl-map {key std::string}}
{of oess_1::db::storage::impl::stream_storage_dir_item_t}
}
}
Сгенерированный вспомогательный код подключается в файл stream_storage_dir.cpp с помощью нескольких строк:
... // Этот заголовочный файл содержит описание типов, необходимых для // работы вспомогательного кода. #include <oess_1/stdsn/h/inout_templ.hpp> ... #include "stream_storage_dir.ddl.cpp" ...
Остается вопрос запуска утилиты oess_cpp_serializer при компиляции проекта для генерации stream_storage_dir.ddl.cpp из stream_storage_dir.ddl. Но это уже вопрос удобства применяемых средств управления компиляцией. Например, при использовании mxx_ru (http://eao197.narod.ru/mxx_ru) это делается с помощью нескольких строк в проектном файле:
require 'mxx_ru/cpp'
...
require 'oess_1/util_cpp_serializer/gen'
Mxx_ru::setup_target(
Mxx_ru::Cpp::Dll_target.new( "oess_1/db/prj.rb" ) {
...
ddl_cpp_generator = generator(
Oess_1::Util_cpp_serializer::Gen.new( self ) )
...
sources_root( "storage" ) {
...
sources_root( "impl" ) {
...
cpp_source( "stream_storage_dir.cpp" )
ddl_cpp_generator.ddl_file( "stream_storage_dir.ddl" )
...
}
}
...
}
)
Для того, чтобы сериализовать объект в какой-либо выходной поток (см. oess_1::io) необходим дополнительный объект, который будет управлять формированием образа объекта при сериализации. Класс oent_t является вершиной иерархии классов, которые занимаются разметкой образа объекта при сериализации. Класс ient_t является вершиной иерархии классов, выполняющих обратную задачу -- десериализующих объект из его образа.
Изначально идея состояла в том, что вспомогательный код используется для предоставления доступа к атрибутам объекта. Но сам объект может быть сериализован различными способами. Например, только двоичных сериализаций может быть несколько видов: на основе порядка следования атрибутов (a-la ASN1 PER) или принципа Tag-Length-Value (a-la ASN1 BER). А еще, теоритически, возможна сериализация в текствое представление, так же разных форматов: XML, YAML, Curl-подобный и др. Поэтому сгенерированный для сериализуемого класса вспомогательный код не знает, как будет выглядеть полученный после сериализации образ объекта. Эта функциональность вынесена в семейство классов oent_t/ient_t.
На данный момент поддерживается только один способ упаковки образа объектов, называемый стандартным (штатным). Он реализуется классами oent_std_t и ient_std_t. В этом способе все атрибуты сохраняются в двоичном виде, в той последовательности, в которой они описанны в DDL (похожий подход, но в более развитой форме используется в ASN1 PER). Унаследованные атрибуты предшествуют собственным атрибутам объекта. Никаких маркеров, которые могли бы показать где заканчивается значение одного объекта и начинается значение второго объекта нет (поэтому этот способ раньше назывался "способом без маркеров"). Т.к. никаких маркеров в двоичном образе объекта нет, то на программисте лежит ответственность за то, чтобы из двоичного образа объекта десериализация осуществлялась в объект нужного типа. Т.е., если в образе находится объект типа A, а десериализовать образ пытаются в объект типа B, то ObjESSty никак не сможет этому воспрепятствовать. И результат такой операции не определен.
Итак, чтобы сериализовать объект необходимо:
// Сериализуем объект некоторого типа A в std::string для того, // чтобы этот std::string можно было куда-нибудь передать или // где-нибудь сохранить. std::string serialize( A & a ) { std::string image; oess_1::io::obstring_t stream( image ); oess_1::stdsn::oent_std_t oent( stream ); oent << a; return image; }
Для того, чтобы десериализовать объект необходимо:
// Десериализуем объект некоторого типа A из std::string. A deserialize( const std::string & image ) { A a; oess_1::io::ibstring_t stream( image ); oess_1::stdsn::ient_std_t ient( stream ); ient >> a; return a; }
Так же здесь не затрагивались вопросы языка DDL, это сделано в описании oess_1::scheme.
Классы | |
| class | operation_history_t |
| Информация о сериализуемых объектах. Подробнее... | |
| class | ient_t |
| Базовый класс для управления разметкой сущности во входном потоке. Подробнее... | |
| class | iextension_t |
| Базовый класс для управления разметкой расширения объекта во входном потоке. Подробнее... | |
| class | oent_t |
| Базовый класс для управления разметкой сущности в выходном потоке. Подробнее... | |
| class | oextension_t |
| Базовый класс для управления разметкой расширения сущности в выходном потоке. Подробнее... | |
| class | isubclass_extension_t |
| Интерфейс десериализатора расширения производного класса для механизма subclassing_by_extension. Подробнее... | |
| class | osubclass_extension_t |
| Интерфейс сериализатора расширения производного класса для механизма subclassing_by_extension. Подробнее... | |
| class | isubclass_extension_template_t |
| Реализация интерфейса isubclass_extension_t в виде шаблона. Подробнее... | |
| class | osubclass_extension_template_t |
| Реализация интерфейса osubclass_extension_t в виде шаблона. Подробнее... | |
| class | ient_std_t |
| Реализация интерфейса ient_t для случая, когда во входном потоке вообще нет маркеров. Подробнее... | |
| class | iextension_std_t |
| Реализация интерфейса iextension_t для случая, когда во входном потоке вообще нет маркеров. Подробнее... | |
| class | oent_std_t |
| Реализация интерфейса oent_t для случая, когда в выходном потоке вообще нет маркеров. Подробнее... | |
| class | oextension_std_t |
| Реализация интерфейса oextension_t для случая, когда в выходном потоке вообще нет маркеров. Подробнее... | |
| class | iobj_t |
| Внутренний класс ObjESSty. Подробнее... | |
| class | oobj_t |
| Внутренний класс ObjESSty. Подробнее... | |
| class | iptr_t |
| Внутренний класс ObjESSty. Подробнее... | |
| class | optr_t |
| Внутренний класс ObjESSty. Подробнее... | |
| class | iextension_of_t |
| Класс для десериализации атрибутов указателей на производные классы-расширения. Подробнее... | |
| class | oextension_of_t |
| Класс для сериализации атрибутов, которые являются указателями на производные классы-расширения. Подробнее... | |
| class | ilist_t |
| Внутренний класс ObjESSty. Подробнее... | |
| class | olist_t |
| Внутренний класс ObjESSty. Подробнее... | |
| class | iset_t |
| Внутренний класс ObjESSty. Подробнее... | |
| class | oset_t |
| Внутренний класс ObjESSty. Подробнее... | |
| class | imap_t |
| Внутренний класс ObjESSty. Подробнее... | |
| class | omap_t |
| Внутренний класс ObjESSty. Подробнее... | |
| class | ifixed_vector_t |
| Внутренний класс ObjESSty. Подробнее... | |
| class | ofixed_vector_t |
| Внутренний класс ObjESSty. Подробнее... | |
| class | unknown_extension_t |
| Хранилище неизвестного расширения. Подробнее... | |
| class | all_unknown_extensions_t |
| Хранилище всех неизвестных расширений объекта. Подробнее... | |
| class | subclass_extension_path_t |
| Класс для сохранения элементов в цепочке наследования при использовании механизма subclassing_by_extension. Подробнее... | |
| class | serializable_t |
| Интерфейс, который должны наследовать все сериализуемые типы. Подробнее... | |
| class | factory_registrator_t |
| Внутренний класс ObjESSty. Подробнее... | |
| class | obj_factory_t |
| Внутренний класс ObjESSty. Подробнее... | |
| class | refcountable_policy_t |
| Политика владения указателем на основе подсчета ссылок. Подробнее... | |
| class | cloneable_policy_t |
| Класс политики умного указателя, основанной на клонировании объектов при копировании. Подробнее... | |
| struct | shptr_type_tag |
| Тег, который должен показывать, к какому типу нужно делать кастинг в классе умного указателя. Подробнее... | |
| class | shptr_skeleton_t |
| Каркас для реализации функциональности умных указателей. Подробнее... | |
| class | shptr_t |
| Класс умного указателя на сериализуемый объект. Подробнее... | |
| struct | all_unknown_extensions_data_t |
| Структура реального содержимого объекта all_unknown_extensions_t. Подробнее... | |
Пространства имен | |
| namespace | err |
| Коды ошибок компоненты stdsn. | |
Определения типов | |
| typedef ient_std_t | ient_no_markers_t |
| Псевдоним для совместимости с предыдущими версиями. | |
| typedef iextension_std_t | iextension_no_markers_t |
| Псевдоним для совместимости с предыдущими версиями. | |
| typedef oent_std_t | oent_no_markers_t |
| Псевдоним для совместимости с предыдущими версиями. | |
| typedef oextension_std_t | oextension_no_markers_t |
| Псевдоним для совместимости с предыдущими версиями. | |
| typedef serializable_t *(*) | pfn_factory_t () |
|
typedef std::map< std::string, pfn_factory_t, std::less< std::string > > | factory_map_t |
Функции | |
| template<class Type> | |
| oess_1::stdsn::oent_t & | operator<< (oess_1::stdsn::oent_t &s, const oobj_t< Type > &o) |
| template<class Type> | |
| oess_1::stdsn::ient_t & | operator>> (oess_1::stdsn::ient_t &s, iobj_t< Type > &o) |
| template<class Type> | |
| oess_1::stdsn::oent_t & | operator<< (oess_1::stdsn::oent_t &s, const optr_t< Type > &o) |
| template<class Type> | |
| oess_1::stdsn::ient_t & | operator>> (oess_1::stdsn::ient_t &s, iptr_t< Type > &o) |
| void | operator>> (oess_1::stdsn::ient_t &s, oess_1::stdsn::subclass_extension_path_t &path) |
| Извлечение цепочки наследования из сериализованного представления. | |
| template<class Type> | |
| oess_1::stdsn::ient_t & | operator>> (oess_1::stdsn::ient_t &s, iextension_of_t< Type > &o) |
| void | operator<< (oess_1::stdsn::oent_t &s, const oess_1::stdsn::subclass_extension_path_t &path) |
| Сериализация цепочки наследования. | |
| template<class Type> | |
| oess_1::stdsn::oent_t & | operator<< (oess_1::stdsn::oent_t &s, const oextension_of_t< Type > &o) |
| operator<< (oent_t &writter, const serializable_t &o) | |
| operator>> (ient_t &reader, serializable_t &o) | |
| static ACE_Thread_Mutex & | obj_factory_lock () |
| static factory_map_t & | factories () |
Переменные | |
| const oess_1::uchar_t | opt_attr_missing_flag = 0 |
| Метка отсутствия сериализованного представления опционального атрибута. | |
| const oess_1::uchar_t | opt_attr_present_flag = 1 |
| Метка присутствия сериализованного представления опционального атрибута. | |
| typedef ient_std_t ient_no_markers_t |
| typedef oent_std_t oent_no_markers_t |
| void oess_1::stdsn::operator>> | ( | oess_1::stdsn::ient_t & | s, | |
| oess_1::stdsn::subclass_extension_path_t & | path | |||
| ) | [inline] |
Извлечение цепочки наследования из сериализованного представления.
| void oess_1::stdsn::operator<< | ( | oess_1::stdsn::oent_t & | s, | |
| const oess_1::stdsn::subclass_extension_path_t & | path | |||
| ) | [inline] |
Сериализация цепочки наследования.
| const oess_1::uchar_t opt_attr_missing_flag = 0 |
Метка отсутствия сериализованного представления опционального атрибута.
| const oess_1::uchar_t opt_attr_present_flag = 1 |
Метка присутствия сериализованного представления опционального атрибута.
1.4.7