Данный компонент содержит основные классы и определения для стандарного способа сериализации сущностей.
Реализованный в данном компоненте способ сериализации называется стандартным (штатным) потому, что только этот способ сериализации может использоваться для сохранения объектов в 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 |
Метка присутствия сериализованного представления опционального атрибута.