跳转至

obstream Class

提供二进制序列化功能。

注意

  • yasio::obstream 等价于 yasio::obstream_any<yasio::dynamic_extent>
  • 自3.39.0起,新增obstream_span可序列化到std::stringstd::vector<char>,请查看示例序列化到stl容器
  • 自3.37.5起,新增obstream_any类模板具备序列化已知大小的小块栈内存能力,请查看示例: 使用栈空间序列化
  • 自3.35.0起,优化为类模板basic_obstream实现,体现了C++模板强大的代码复用能力。

  • obstream 当写入int16~int64和float/double类型时, 会自动将主机字节序转换为网络字节序。

  • fast_obstream 不会转换任何字节序。

语法

namespace yasio { 
template <size_t _Extent>
using obstream_any = basic_obstream<convert_traits<network_convert_tag>, _Extent>;
using obstream     = obstream_any<dynamic_extent>;

template <size_t _Extent>
using fast_obstream_any = basic_obstream<convert_traits<host_convert_tag>, _Extent>;
using fast_obstream     = fast_obstream_any<dynamic_extent>;
}

template <typename _Cont>
using obstream_span = basic_obstream_span<convert_traits<network_convert_tag>, _Cont>;
template <typename _Cont>
using fast_obstream_span = basic_obstream_span<convert_traits<host_convert_tag>, _Cont>;

成员

公共构造函数

Name Description
obstream::obstream 构造1个obstream 对象

公共方法

Name Description
obstream::write 函数模板,写入数值
obstream::write_ix 函数模板,写入(7bit Encoded Int/Int64)数值
obstream::write_v 写入带长度域(7bit Encoded Int)的二进制数据
obstream::write_byte 写入1个字节
obstream::write_bytes 写入指定长度二进制数据
obstream::empty 检查流是否为空
obstream::data 获取流数据指针
obstream::length 获取流数据大小
obstream::buffer 获取流内部缓冲区
obstream::clear 清理流,以便复用
obstream::shrink_to_fit 释放流内部缓冲区多余内存
obstream::save 保存流二进制数据到文件系统

要求

头文件: yasio/yasio.hpp

obstream::obstream

构造 obstream 对象。

obstream(size_t capacity = 128);

obstream(const obstream& rhs);

obstream(obstream&& rhs);

obstream::write

写入数值类型

template<typename _Nty>
void obstream::write(_Nty value);

参数

value
要写入的值

注意

_Nty 实际类型可以是任意1~8字节整数类型或浮点类型。

obstream::write_ix

将32/64位整数值以7Bit Encoded Int方式压缩后写入流。

template<typename _Intty>
void obstream::write_ix(_Intty value);

参数

value
要写入的值。

注意

_Intty 类型只能是如下类型

  • int32_t
  • int64_t

此函数压缩编码方式兼容微软dotnet如下函数

obstream::write_v

写入二进制数据,包含长度字段(7Bit Encoded Int).

void write_v(cxx17::string_view sv);

参数

sv
要写入的数据。

注意

此函数先以7Bit Encoded编码方式写入数据长度, 再调用 write_bytes 写入字节数据.

obstream::write_byte

写入1个字节。

void write_byte(uint8_t value);

参数

value
要写入的值。

注意

此函数功能等价于 obstream::write<uint8_t>

obstream::write_bytes

写入字节数组。

void write_bytes(cxx17::string_view sv);

void write_bytes(const void* data, int length);

void write_bytes(std::streamoff offset, const void* data, int length);

参数

sv
写入string_view包装的字节数组.

data
要写入字节数组的首地址.

length
要写入字节数组的长度.

offset
要写入字节数组的目标偏移.

注意

offset + length 的值必须小于 obstream::length

obstream::empty

判断流是否为空。

bool empty() const;

返回值

true 空; false 非空。

注意

此函数等价于 length == 0。

obstream::data

获取数据指针。

const char* data() const;

char* data();

返回值

字节流数据首地址。

obstream::length

获取流长度。

size_t length() const;

返回值

返回流中包含的总字节数。

obstream::buffer

获取流内部缓冲区。

const yasio::sbyte_buffer& buffer() const;

yasio::sbyte_buffer& buffer();

返回值

流内部缓冲区引用,可以使用 std::move 取走。

示例

// obstream_buffer.cpp
// compile with: /EHsc
#include "yasio/yasio.hpp"

int main( )
{
   using namespace yasio;
   using namespace cxx17;

   obstream obs;
   obs.write_v("hello world!");

   const auto& const_buffer = obs.buffer();

   // after this line, the obs will be empty
   auto move_buffer = std::move(obs.buffer());

   return 0;
}

obstream::clear

清理流,以便复用。

void clear();

注意

此函数不会释放buffer内存,对于高效地复用序列化器非常有用。

obstream::shrink_to_fit

释放流内部缓冲区多余内存。

void shrink_to_fit();

obstream::save

将流中的二进制字节数据保存到文件。

void save(const char* filename) const;

示例

// obstream_save.cpp
// compile with: /EHsc
#include "yasio/yasio.hpp"

int main( )
{
   using namespace yasio;
   using namespace cxx17;

   obstream obs;
   obs.write_v("hello world!");
   obs.save("obstream_save.bin");

   ibstream ibs;
   if(ibs.load("obstream_save.bin")) {
       // output should be: hello world!
       try {
           std::count << ibs.read_v() << "\n";
       }
       catch(const std::exception& ex) {
           std::count << "read_v fail: " <<
               << ex.message() << "\n";
       }
   }

   return 0;
}

使用栈内存序列化示例

注意事项

  • 序列化过程中,当 fixed_buffer 检测到内存空间不足时会抛出 std::out_of_range 异常

obstream_any用法

#include "yasio/yasio.hpp"

int main() {
    yasio::obstream_any<128> obs; // 使用栈空间, 注意不要太大,防止栈空间溢出
    auto where = obs.push<uint16_t>();
    obs.write(3.141592654);
    obs.write(1.17723f);
    obs.write_ix<int32_t>(20201125);
    obs.write_ix<int64_t>(-9223372036854775807);
    obs.pop<uint16_t>(where);
    return 0;
}

obstream_span + std::array用法

#include "yasio/yasio.hpp"

int main() {
    std::array<char, 128> fb; // 使用栈空间, 注意不要太大,防止栈空间溢出
    yasio::obstream_span<yasio::fixed_buffer_span> obs(fb);
    auto where = obs.push<uint16_t>();
    obs.write(3.141592654);
    obs.write(1.17723f);
    obs.write_ix<int32_t>(20201125);
    obs.write_ix<int64_t>(-9223372036854775807);
    obs.pop<uint16_t>(where);
    return 0;
}

obstream_span + char[]用法

#include "yasio/yasio.hpp"

int main() {
    char raw_fb[128]; // 使用栈空间, 注意不要太大,防止栈空间溢出
    yasio::obstream_span<yasio::fixed_buffer_span> obs(raw_fb);
    auto where = obs.push<uint16_t>();
    obs.write(3.141592654);
    obs.write(1.17723f);
    obs.write_ix<int32_t>(20201125);
    obs.write_ix<int64_t>(-9223372036854775807);
    obs.pop<uint16_t>(where);
    return 0;
}

序列化到std::vector和std::string

obstream_span + std::vector用法

#include "yasio/yasio.hpp"

int main() {
    std::vector<char> buf;
    yasio::obstream_span<std::vector<char>> obs(buf);
    auto where = obs.push<uint16_t>();
    obs.write(3.141592654);
    obs.write(1.17723f);
    obs.write_ix<int32_t>(20201125);
    obs.write_ix<int64_t>(-9223372036854775807);
    obs.pop<uint16_t>(where);
    return 0;
}

obstream_span + std::string用法

#include "yasio/yasio.hpp"

int main() {
    std::string buf;
    yasio::obstream_span<std::string> obs(buf);
    auto where = obs.push<uint16_t>();
    obs.write(3.141592654);
    obs.write(1.17723f);
    obs.write_ix<int32_t>(20201125);
    obs.write_ix<int64_t>(-9223372036854775807);
    obs.pop<uint16_t>(where);
    return 0;
}

请参阅

ibstream_view Class

ibstream Class