Данная компонента содержит основные классы и определения средств ввода/вывода простейших типов.
Вершиной иерархии классов ввода/вывода являются классы istream_t и ostream_t, которые определяют интерфейс потоков ввода-вывода. Классы istream_t, ostream_t являются абстрактными. Предполагается, что сериализация возможна в различные представления, как текстовые, так и двоичные. Поэтому данные классы не привязаны к конкретным форматам представления данных. Вместо этого istream_t, ostream_t определяют типы, которые поддерживаются системой ввода-вывода ObjESSty. Для этих типов определены операторы сдвига из/в istream_t, ostream_t.
Для поддержки ввода/вывода в двоичный формат предназначенные классы ibinstream_t, obinstream_t и производные от них классы. Сами классы ibinstream_t, obinstream_t так же являются абстрактными. Они определяют только процедуры преобразования значений из bin-endian представления в представление конкретной платформы и обратно. Но они не знают откуда именно нужно брать данные или куда их нужно помещать. Этим занимаются производные классы.
Для того, чтобы коротко описать существующие классы ввода/вывода определим структуру на которой использование классов будет демонстрироваться. Пусть есть описание некоторого заголовка запроса/ответа в клиент-сервером приложении:
struct request_header_t { // Номер версии протокола, в котором определен запрос. oess_1::ushort_t m_version; // Идентификатор запроса. oess_1::uint_t m_req_id; // Длина запроса без учета заголовка. oess_1::uint_t m_data_len; // Зарезервированные поля. oess_1::uint_t m_reserved[ 5 ]; };
Для того, чтобы объекты request_header_t можно было читать/записывать из/в потоков ввода/вывода ObjESSty необходимо определить для request_header_t операторы сдвига:
oess_1::io::istream_t & operator>>( oess_1::io::istream_t & s, request_header_t & o ) { s >> o.m_version >> o.m_req_id >> o.m_data_len; s.read( o.m_reserved, sizeof( o.m_reserved ) / sizeof( o.m_reserved[ 0 ] ) ); return s; } oess_1::io::ostream_t & operator<<( oess_1::io::ostream_t & s, const request_header_t & o ) { s << o.m_version << o.m_req_id << o.m_data_len; s.write( o.m_reserved, sizeof( o.m_reserved ) / sizeof( o.m_reserved[ 0 ] ) ); return s; }
Класс ibstring_t полезен в случаях, когда сериализованные данные находятся в объекте std::string. Например, если они были прочитаны блоком из файла или переданы в виде std::string в каком-либо объекте-сообщении. Например, для извлечения request_header_t можно воспользоваться ibstring_t вот так:
request_header_t unpack( const std::string & from ) { oess_1::io::ibstring_t stream( from ); request_header_t result; stream >> result; return result; }
Класс obstring_t, напротив, производит запись данных в объект std::string. Он полезен, если сериализованное представление объекта должно быть передано куда-то или сохранено где-то в виде std::string. Особенностью obstring_t является то, что он всегда дописывает данные в конец строки, расширяя при этом строку. С одной стороны, это позволяет легко сконкатенировать представление нескольких объектов в одной стороке:
request_header_t header; ... some_request_t request; ... std::string request_image; oess_1::io::obstring_t stream( request_image ); stream << header << request;
Классы ifixed_mem_buf_t, ofixed_mem_buf_t предназначены для работы с буферами фиксированного размера. Например, в каком-то протоколе обговаривается, что стороны обмениваются датаграммами фиксированного размера, скажем 2Kb. Тогда, чтобы сериализовать запрос в датаграмму, можно воспользоваться ofixed_mem_buf_t:
void send_request( const request_header_t & header, const some_request_t & request ) { oess_1::char_t datagram[ datagram_size ]; oess_1::io::ofixed_mem_buf_t stream( datagram, datagram_size ); stream << header << request; send( datagram ); }
void receive_request( request_header_t & header, some_request_t & request ) { oess_1::char_t datagram[ datagram_size ]; receive( datagram ); oess_1::io::ifixed_mem_buf_t stream( datagram, datagram_size ); stream >> header >> request; }
Класс isubbinstream_t полезен в случаях, когда нужно организовать самостоятельный "подпоток" в рамках уже существующего входного потока. Например, это часто бывает необходимо при разборе протоколов на основе TLV (Tag, Length, Value). В этих случаях уже есть входной поток из которого сначала считывается Tag, затем Length, а затем Value. Но при чтении Value хорошо было бы ограничить возможность чтения всего Length байтами. В этом случае создается объект isubbinstream_t, который не позволяет прочитать из родительского входного потока более Length байт:
void read_pdu_one( oess_1::io::istream_t & stream ) { stream >> ... } void read_pdu_two( oess_1::io::istream_t & stream ) { stream >> ... } ... void parse_tlv_stream( const oess_1::char_t * datagram, oess_1::uint_t datagram_size ) { oess_1::io::ifixed_mem_buf_t stream( datagram, datagram_size ); oess_1::ushort_t tag; oess_1::uint_t length; stream >> tag >> length; oess_1::io::isubbinstream_t substream( stream, length ); if( pdu_one == tag ) read_pdu_one( substream ); else if( pdu_two == tag ) read_pdu_two( substream ); ... }
Самым сложным и продвинутым классом двоичного ввода-вывода является класс mem_buf_t. Он объединяет в себе функциональность входного и выходного потоков. Работа ведется с буфером памяти, который контролирует mem_buf_t. При необходимости этот буфер динамически расширяется. Важными особенностями класса mem_buf_t являются:
В качестве примера использования mem_buf_t можно представить ситуацию, когда в некотором коммуникационном протоколе необходимо передавать сообщения произвольной длины. При этом каждое сообщение начинается с двух обязательных полей: общей длины данных (без учета этих двух полей) и контрольной суммы. С помощью mem_buf_t реализовать это можно, например, так:
void serialize_and_send( const some_msg_t & msg ) { // Размер двух обязательных полей. const oess_1::uint_t header_size = oess_1::io::bin_data_size_t< oess_1::uint_t >::image_size * 2; oess_1::io::mem_buf_t msg_image( // В начальную емкость буфера нужно включить два // обязательных поля. header_size ); // Пропускаем заголовок, т.к. пока его значение не известно. msg_image.set_size( header_size ); msg_image.set_pos( header_size ); // Сериализуем сообщение. msg_image << msg; // Теперь можно сохранить длину сообщения и CRC. msg_image.set_pos( 0 ); msg_image << oess_1::uint_t( msg_image.size() - header_size ) << calc_crc32( msg_image.ptr() + header_size, msg_image.size() - header_size ); ... }
Класс bin_data_size_t позволяет получить размер образа основных типов ObjESSty в байтах.
Классы | |
class | big_endian_decoder_t |
Класс, который занимается расшифровкой BigEndian представления. Подробнее... | |
class | ibuffer_accessor_t |
Вспомогательный класс. Подробнее... | |
class | obuffer_accessor_t |
Вспомогательный класс. Подробнее... | |
struct | bin_data_size_t |
Средство для определения размера двоичного представления объекта указанного типа. Подробнее... | |
class | ibinbuffer_t |
Интерфейс двоичного входного буфера-потока. Подробнее... | |
class | obinbuffer_t |
Интерфейс двоичного выходного буфера-потока. Подробнее... | |
class | ibinstream_t |
Интерфейс двоичного входного потока. Подробнее... | |
class | obinstream_t |
Интерфейс двоичного выходного потока. Подробнее... | |
class | ibstring_t |
Двоичный входной поток из объекта std::string. Подробнее... | |
class | obstring_t |
Двоичный выходной поток в объекта std::string. Подробнее... | |
class | ifixed_mem_buf_t |
Двоичный поток чтения из фиксированого блока памяти. Подробнее... | |
class | ofixed_mem_buf_t |
Двоичный выходной поток в фиксированный блок памяти. Подробнее... | |
class | mem_buf_t |
буфера памяти. Подробнее... | |
class | istream_t |
Базовый класс входного потока. Подробнее... | |
class | ostream_t |
Базовый класс выходного потока. Подробнее... | |
class | isubbinstream_t |
Двоичный подпоток ввода. Подробнее... | |
struct | bin_data_size_t< oess_1::char_t > |
Специализация для char. Подробнее... | |
struct | bin_data_size_t< oess_1::schar_t > |
Специализация для signed char. Подробнее... | |
struct | bin_data_size_t< oess_1::uchar_t > |
Специализация для unsigned char. Подробнее... | |
struct | bin_data_size_t< oess_1::short_t > |
Специализация для short. Подробнее... | |
struct | bin_data_size_t< oess_1::ushort_t > |
Специализация для unsigned short. Подробнее... | |
struct | bin_data_size_t< oess_1::int_t > |
Специализация для int. Подробнее... | |
struct | bin_data_size_t< oess_1::uint_t > |
Специализация для unsigned int. Подробнее... | |
struct | bin_data_size_t< oess_1::single_t > |
Специализация для flost. Подробнее... | |
struct | bin_data_size_t< oess_1::double_t > |
Специализация для double. Подробнее... | |
Пространства имен | |
namespace | err |
Коды ошибок компоненты io. | |
Функции | |
template<class Type> | |
void | read_helper (ibuffer_accessor_t &s, Type *p, size_t count) |
template<class Type> | |
void | write_helper (obuffer_accessor_t &s, const Type *p, size_t count) |
template<class T> | |
oess_1::io::istream_t & | operator>> (oess_1::io::istream_t &s, std::deque< T > &o) |
Ручная десериализация для std::deque. | |
template<class T> | |
oess_1::io::ostream_t & | operator<< (oess_1::io::ostream_t &s, const std::deque< T > &o) |
Ручная сериализация для std::deque. | |
template<class T> | |
oess_1::io::istream_t & | operator>> (oess_1::io::istream_t &s, std::list< T > &o) |
Ручная десериализация для std::list. | |
template<class T> | |
oess_1::io::ostream_t & | operator<< (oess_1::io::ostream_t &s, const std::list< T > &o) |
Ручная сериализация для std::list. | |
template<class K, class T> | |
oess_1::io::istream_t & | operator>> (oess_1::io::istream_t &s, std::map< K, T > &o) |
Ручная десериализация для std::map. | |
template<class K, class T> | |
oess_1::io::istream_t & | operator>> (oess_1::io::istream_t &s, std::multimap< K, T > &o) |
Ручная десериализация для std::multimap. | |
template<class K, class T> | |
oess_1::io::ostream_t & | operator<< (oess_1::io::ostream_t &s, const std::map< K, T > &o) |
Ручная сериализация для std::map. | |
template<class K, class T> | |
oess_1::io::ostream_t & | operator<< (oess_1::io::ostream_t &s, const std::multimap< K, T > &o) |
Ручная сериализация для std::multimap. | |
template<class T> | |
oess_1::io::istream_t & | operator>> (oess_1::io::istream_t &s, std::set< T > &o) |
Ручная десериализация для std::set. | |
template<class T> | |
oess_1::io::istream_t & | operator>> (oess_1::io::istream_t &s, std::multiset< T > &o) |
Ручная десериализация для std::multiset. | |
template<class T> | |
oess_1::io::ostream_t & | operator<< (oess_1::io::ostream_t &s, const std::set< T > &o) |
Ручная сериализация для std::set. | |
template<class T> | |
oess_1::io::ostream_t & | operator<< (oess_1::io::ostream_t &s, const std::multiset< T > &o) |
Ручная сериализация для std::multiset. | |
template<class T> | |
oess_1::io::istream_t & | operator>> (oess_1::io::istream_t &s, std::vector< T > &o) |
Ручная десериализация для std::vector. | |
template<class T> | |
oess_1::io::ostream_t & | operator<< (oess_1::io::ostream_t &s, const std::vector< T > &o) |
Ручная сериализация для std::vector. | |
istream_t & | operator>> (istream_t &s, oess_1::char_t &o) |
Прочитать одиночный объект o из входного потока s. | |
ostream_t & | operator<< (ostream_t &s, const oess_1::char_t &o) |
Записать одиночный объект o в выходной поток s. | |
istream_t & | operator>> (istream_t &s, oess_1::schar_t &o) |
Прочитать одиночный объект o из входного потока s. | |
ostream_t & | operator<< (ostream_t &s, const oess_1::schar_t &o) |
Записать одиночный объект o в выходной поток s. | |
istream_t & | operator>> (istream_t &s, oess_1::uchar_t &o) |
Прочитать одиночный объект o из входного потока s. | |
ostream_t & | operator<< (ostream_t &s, const oess_1::uchar_t &o) |
Записать одиночный объект o в выходной поток s. | |
istream_t & | operator>> (istream_t &s, oess_1::short_t &o) |
Прочитать одиночный объект o из входного потока s. | |
ostream_t & | operator<< (ostream_t &s, const oess_1::short_t &o) |
Записать одиночный объект o в выходной поток s. | |
istream_t & | operator>> (istream_t &s, oess_1::ushort_t &o) |
Прочитать одиночный объект o из входного потока s. | |
ostream_t & | operator<< (ostream_t &s, const oess_1::ushort_t &o) |
Записать одиночный объект o в выходной поток s. | |
istream_t & | operator>> (istream_t &s, oess_1::int_t &o) |
Прочитать одиночный объект o из входного потока s. | |
ostream_t & | operator<< (ostream_t &s, const oess_1::int_t &o) |
Записать одиночный объект o в выходной поток s. | |
istream_t & | operator>> (istream_t &s, oess_1::uint_t &o) |
Прочитать одиночный объект o из входного потока s. | |
ostream_t & | operator<< (ostream_t &s, const oess_1::uint_t &o) |
Записать одиночный объект o в выходной поток s. | |
istream_t & | operator>> (istream_t &s, oess_1::single_t &o) |
Прочитать одиночный объект o из входного потока s. | |
ostream_t & | operator<< (ostream_t &s, const oess_1::single_t &o) |
Записать одиночный объект o в выходной поток s. | |
istream_t & | operator>> (istream_t &s, oess_1::double_t &o) |
Прочитать одиночный объект o из входного потока s. | |
ostream_t & | operator<< (ostream_t &s, const oess_1::double_t &o) |
Записать одиночный объект o в выходной поток s. | |
istream_t & | operator>> (istream_t &s, std::string &o) |
Прочитать строку o из входного потока s. | |
ostream_t & | operator<< (ostream_t &s, const std::string &o) |
Записать строку o в выходной поток s. | |
istream_t & | operator>> (istream_t &s, oess_1::defs::quantity_t &o) |
Прочитать одиночный объект quantity o из входного потока s. | |
ostream_t & | operator<< (ostream_t &s, const oess_1::defs::quantity_t &o) |
Записать одиночный объект quantity o в выходной поток s. | |
istream_t & | operator>> (istream_t &s, oess_1::ent_id_t &o) |
Прочитать идентификатор o из входного потока s. | |
ostream_t & | operator<< (ostream_t &s, const oess_1::ent_id_t &o) |
Записать идентификатор o в выходной поток s. | |
void | expand_buffer (auto_ptr_3::vect_ptr_t< char > &buf, size_t cur_pos, size_t data_size) |
Переменные | |
static big_endian_decoder_t | g_big_endian_decoder |
const oess_1::uint_t | max_quantity_image_size = 5 |
Максимальная длина образа двоичного представления quantity. |
oess_1::io::istream_t& oess_1::io::operator>> | ( | oess_1::io::istream_t & | s, | |
std::deque< T > & | o | |||
) |
Ручная десериализация для std::deque.
oess_1::io::ostream_t& oess_1::io::operator<< | ( | oess_1::io::ostream_t & | s, | |
const std::deque< T > & | o | |||
) |
Ручная сериализация для std::deque.
oess_1::io::istream_t& oess_1::io::operator>> | ( | oess_1::io::istream_t & | s, | |
std::list< T > & | o | |||
) |
Ручная десериализация для std::list.
oess_1::io::ostream_t& oess_1::io::operator<< | ( | oess_1::io::ostream_t & | s, | |
const std::list< T > & | o | |||
) |
Ручная сериализация для std::list.
oess_1::io::istream_t& oess_1::io::operator>> | ( | oess_1::io::istream_t & | s, | |
std::map< K, T > & | o | |||
) |
Ручная десериализация для std::map.
oess_1::io::istream_t& oess_1::io::operator>> | ( | oess_1::io::istream_t & | s, | |
std::multimap< K, T > & | o | |||
) |
Ручная десериализация для std::multimap.
oess_1::io::ostream_t& oess_1::io::operator<< | ( | oess_1::io::ostream_t & | s, | |
const std::map< K, T > & | o | |||
) |
Ручная сериализация для std::map.
oess_1::io::ostream_t& oess_1::io::operator<< | ( | oess_1::io::ostream_t & | s, | |
const std::multimap< K, T > & | o | |||
) |
Ручная сериализация для std::multimap.
oess_1::io::istream_t& oess_1::io::operator>> | ( | oess_1::io::istream_t & | s, | |
std::set< T > & | o | |||
) |
Ручная десериализация для std::set.
oess_1::io::istream_t& oess_1::io::operator>> | ( | oess_1::io::istream_t & | s, | |
std::multiset< T > & | o | |||
) |
Ручная десериализация для std::multiset.
oess_1::io::ostream_t& oess_1::io::operator<< | ( | oess_1::io::ostream_t & | s, | |
const std::set< T > & | o | |||
) |
Ручная сериализация для std::set.
oess_1::io::ostream_t& oess_1::io::operator<< | ( | oess_1::io::ostream_t & | s, | |
const std::multiset< T > & | o | |||
) |
Ручная сериализация для std::multiset.
oess_1::io::istream_t& oess_1::io::operator>> | ( | oess_1::io::istream_t & | s, | |
std::vector< T > & | o | |||
) |
Ручная десериализация для std::vector.
oess_1::io::ostream_t& oess_1::io::operator<< | ( | oess_1::io::ostream_t & | s, | |
const std::vector< T > & | o | |||
) |
Ручная сериализация для std::vector.
const oess_1::uint_t max_quantity_image_size = 5 |
Максимальная длина образа двоичного представления quantity.