oess_1.2.0. Опциональные поля

Введение

Сериализация объекта требует затрат как времени процессора, так и пространства для хранения сериализованных атрибутов объекта. Стандартная сериализация ObjESSty, выполняемая средствами компонента oess_1::stdsn, не является самой экономичной с точки зрения компактности получаемого двоичного образа. Например, упаковка ASN1 PER дает намного более компактное представление.

Поэтому, для улучшения параметров скорости/экономичности сериализации объектов необходимо для каждого сериализуемого объекта сократить к минимуму количество сериализуемых полей (атрибутов). Одним из способов является использование опциональных полей.

Опциональным полем является атрибут объекта, которому можно назначить значение по-умолчанию, использующееся в подавляющем большинстве случаев. Если при сериализации проверить, что поле содержит такое значение, то поле можно не сериализовать. Достаточно указать в двоичном представлении, что поле имеет значение по-умолчанию. При десериализации можно определить, что поле не было сериализовано и назначить ему значение по-умолчанию сразу после десериализации всего объекта.

Пример. Пусть есть некое сообщение handshake, в котором требуется передать параметры коммуникационной сессии. Среди прочих параметров в нем содержатся: параметры использования подписи передаваемых данных и параметры компрессии передаваемых данных. При этом, в большинстве случаев в качестве подписи будет использоваться алгоритм md5. Компрессия по умолчанию не используется, но если используется, то обычно применяется gzip со средней степенью сжатия. Представить это на DDL можно следующим образом:

|| Параметры компрессии.
{type	compression_t
	|| Алгоритм копрессии.
	{attr	m_algorithm {of std::string}
		{default
			|| По-умолчанию в C++ значение задается константой gzip.
			{c++ compression_t::gzip}
			|| Сериализовать атрибут необходимо только, если
			|| значение отличается от gzip.
			{present_if {c++ m_algorithm != compression_t::gzip}}
		}
	}
	|| Степень сжатия.
	{attr	m_level {of oess_1::uint_t}}
}

|| Описание параметров для коммуникационной сессии.
{type	handshake_t
	|| Остальные атрибуты опущены за ненадобностью.
	
	|| Алгоритм подписи данных.
	{attr	m_signature {of std::string}
		{default
			|| По-умолчанию в C++ значение задается константой md5.
			{c++ handshake_t::signature_md5}
			|| Сериализовать атрибут необходимо только, если
			|| значение отличается от md5.
			{present_if
				{c++ handshake_t::signature_md5 != m_signature}
			}
		}
	}
	
	|| Признак необходимости использования компрессии данных.
	{attr	m_is_compression {of oess_1::uchar_t}}
	|| Параметры компрессии.
	{attr	m_compression {of compression_t}
		{default
			|| По-умолчанию должен использоваться конструктор
			|| класса compression_t.
			{c++ compression_t() }
			|| Сериализовать атрибут нужно только, если флаг
			|| m_is_compression отличен от 0.
			{present_if {c++ m_is_compression}}
		}
	}
}

Теги DDL для описания опциональных полей

Для того, чтобы сделать атрибут объекта опциональным полем необходимо использовать следующие теги:

Использование escape-последовательностей
Из-за правил синтаксиса cls_2 C++ выражениях необходимо так же использовать escape-последовательности для представления символов:

Предикаты сериализации атрибутов
Предикат сериализации атрибута, указываемый в теге {attr {default {present_if {c++ ...}}}} может быть произвольным C++ выражением. Т.е. он может содержать обращения не только к самому опциональному атрибуту, но и к другим атрибутам объекта, к любым константным методам этого объекта, к любым функциям или статическим методам любых C++ классов.

Дополнения во вспомогательном коде

Для поддержки опциональных полей во вспомогательном коде для сериализуемого класса генерируется два новых метода:

В версии 1.2.0 для приведенного выше DDL описания методы oess_present_if, oess_set_default будут иметь вид:

bool compression_t::oess_present_if( const std::string & a ) const {
  if( a == "m_algorithm" )
    return ( m_algorithm != compression_t::gzip );
  return false;
}
void compression_t::oess_set_default( const std::string & a ) {
  if( a == "m_algorithm" )
    m_algorithm = compression_t::gzip ;
}

bool handshake_t::oess_present_if( const std::string & a ) const {
  if( a == "m_signature" )
    return ( handshake_t::signature_md5 != m_signature );
  if( a == "m_compression" )
    return ( m_is_compression );
  return false;
}
void handshake_t::oess_set_default( const std::string & a ) {
  if( a == "m_signature" )
    m_signature = handshake_t::signature_md5 ;
  if( a == "m_compression" )
    m_compression = compression_t() ;
}

Двоичное представление

В двоичном представлении каждому опциональному полю предшествует байтовое значение, равное:
Документация по ObjESSty. Последние изменения: Fri Oct 13 18:35:37 2006. Создано системой  doxygen 1.4.7
Hosted by uCoz