obstream Class¶
提供二进制序列化功能。
注意
yasio::obstream
等价于yasio::obstream_any<yasio::dynamic_extent>
- 自3.39.0起,新增
obstream_span
可序列化到std::string
或std::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 | 保存流二进制数据到文件系统 |
要求¶
头文件: obstream.hpp
obstream::obstream¶
构造 obstream
对象。
obstream::write¶
写入数值类型
参数¶
value
要写入的值
注意¶
_Nty 实际类型可以是任意1~8字节整数类型或浮点类型。
obstream::write_ix¶
将32/64位整数值以7Bit Encoded Int方式压缩后写入流。
参数¶
value
要写入的值。
注意¶
_Intty 类型只能是如下类型
- int32_t
- int64_t
此函数压缩编码方式兼容微软dotnet如下函数
obstream::write_v¶
写入二进制数据,包含长度字段(7Bit Encoded Int).
参数¶
sv
要写入的数据。
注意¶
此函数先以7Bit Encoded编码方式写入数据长度, 再调用 write_bytes 写入字节数据.
obstream::write_byte¶
写入1个字节。
参数¶
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¶
判断流是否为空。
返回值¶
true
空; false
非空。
注意¶
此函数等价于 length == 0。
obstream::data¶
获取数据指针。
返回值¶
字节流数据首地址。
obstream::length¶
获取流长度。
返回值¶
返回流中包含的总字节数。
obstream::buffer¶
获取流内部缓冲区。
返回值¶
流内部缓冲区引用,可以使用 std::move
取走。
示例¶
// obstream_buffer.cpp
// compile with: /EHsc
#include "yasio/obstream.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¶
清理流,以便复用。
注意¶
此函数不会释放buffer内存,对于高效地复用序列化器非常有用。
obstream::shrink_to_fit¶
释放流内部缓冲区多余内存。
obstream::save¶
将流中的二进制字节数据保存到文件。
示例¶
// obstream_save.cpp
// compile with: /EHsc
#include "yasio/obstream.hpp"
#include "yasio/ibstream.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/obstream.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/obstream.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/obstream.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/obstream.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/obstream.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;
}