Какие типы могут быть отображены в TLV?
Какие правила и ограничения существуют для наследования?
Допускается ли множественное наследование?
Как быть, если в базовом и производном типах есть атрибуты, являющиеся одним и тем же TLV?
Как быть с абстрактными типами?
Как описывать отображение схемы данных в TLV.
Правила отображения схемы данных в TLV.
Что получается в результате трансляции описания отображения схемы данных в TLV?
Тип не имеет собственных атрибутов (пустой тип).
Атрибутами типа являтся скаляры простейших атомарных типов (char, uchar, schar, short, ushort, int, uint, float, double) или фиксированные вектора простейших атомарных типов.
В этом случае все атрибуты типа должны присутствовать в сериализованном потоке и порядок следования атрибутов должен точно повторять порядок следования атрибутов в DDL-описании типа.
Пример.
{type tlv_rnd_t {attr m_rnd {of oess_1::uint_t}} } {type tlv_date_t {attr m_year {of oess_1::ushort_t}} {attr m_mon {of oess_1::uchar_t}} {attr m_day {of oess_1::uchar_t}} } {type tlv_des_params_t {attr m_des_type {of oess_1::uint_t}} {attr m_des_key {fixed-vector 8} {of oess_1::uchar_t}} }
Единственным атрибутом типа является контейнер переменного размера (std::string, stl::vector, stl::list, stl::deque, stl::set, std::multiset). Тип элемента контейнера не может быть контейнером (т.е. нельзя объявить stl::list из std::string).
Размерность контейнера вычисляется на основе Length из TLV. (Алгоритм вычисления может быть и не тривиальным. Например, для строки Length сразу указывает количество элементов. Если элементом контейнера является объект фиксированного размера, то из Length так же легко вычислить количество элементов. В остальных случаях количество элементов из Length не вычисляется -- Length может использоваться как показатель конца потока, из которого последовательно считываются элементы.)
Важно. Контейнеры map и multimap не могут быть сериализованы в TLV.
Пример.
{type tlv_msisdn_t {attr m_msisdn {of std::string}} } {type hilevel_tlv_t } {type tlv_container_t {attr m_tlvs {std::list} {of {ptr} hilevel_tlv_t}} }
Тип состоит только из одиночных атрибутов пользовательских типов. Использование контейнеров не допускается.
Атрибуты в сериализованном потоке могут следовать в любом порядке. Обязательно в сериализованном потоке должны присутствовать атрибуты, не являющиеся указателями. Атрибуты-указатели рассматриваются как необязательные атрибуты, которые могут отсутствовать в сериализованном потоке.
Пример.
{type tlv_user_status_request_t {attr m_rnd {of tlv_rnd_t}} {attr m_msisdn {of tlv_msisdn_t}} } {type tlv_user_status_reply_t {attr m_rnd {of tlv_rnd_t}} {attr m_bank_status {of tlv_bank_status_t}} {attr m_user_status {of {ptr} tlv_user_status_t}} {attr m_card_names {of {ptr} tlv_card_names_t}} } {type tlv_card_names_t {attr m_names {std::list} {of tlv_card_name_t}} }
Т.о. получаются следующие категории отображаемых в TLV типов:
Множественное наследование не допускается.
Возможно, в дальнейшем, ситуация с множественным наследованием изменится. Пока проектирование множественного наследования для отображения в TLV является слишком трудоемким.
{type имя-типа {mandatory-attr имя-обязательного-атрибута} }
Объявить атрибут-не указатель необязательным атрибутом нельзя. Объясняется это тем, что при сериализации нельзя определить, должен ли сериализироваться необязательный атрибут или не должен.
Для отображения схемы данных в TLV необходимо создать описание отображения следующего формата.
{tlv-params {tag-type ( oess_1::uchar_t | oess_1::ushort_t | oess_1::uint_t ) } {length-type ( oess_1::uchar_t | oess_1::ushort_t | oess_1::uint_t ) } {i-class имя-класса-десериализатора [{cpp-namespace имя-пространства-имен-C++}] } {o-class имя-класса-сериализатора [{cpp-namespace имя-пространства-имен-C++}] } } [ {type имя-типа-схемы {tag целочисленное-значение } } ]*
Для отображаемых в TLV типов существуют следующие ограничения:
Результатом трансляции описания отображения схемы данных в TLV являются два C++ класса: один для сериализации, другой для десериализации сущности. Имена классов задаются в описании отображения (теги i-class и o-class).
Для сериализации/десериализации объектов в/из TLV должны применяться объекты сгенерированных классов. Например, если в tlv-map указывается:
{tlv-params {tag-type oess_1::uchar_t} {length-type oess_1::uint_t} {i-class itlv_t } {o-class otlv_t } }
То в программе на C++:
// Сериализация объекта. tlv_my_t my_tlv; otlv_t oent( ... ); oent << my_tlv; // Десериализация объекта. tlv_my_t my_tlv; itlv_t ient( ... ); ient >> my_tlv;