Handle short buffers¶
Every rbe::deserialize and rbe::serialize call assumes the buffer is big enough. The try_ forms check
and return std::nullopt instead of undefined behavior.
Narrow and wider contracts
rbe::deserialize has a narrow contract: some inputs it accepts, a short buffer, have undefined
behavior. The try_ forms have a wider one, not a wide one: they check what can be checked, the
size and the alignment, and still assume the span points to live memory. See the
deserialization reference.
Source: example/howto/wide_contracts.cpp, CMake target howto_wide_contracts.
Reading¶
// deserialize() assumes the buffer holds a whole Order; try_deserialize() checks it first
std::optional<Order> order = rbe::try_deserialize<Order>(bytes, rbe::dsrl::eager);
auto truncated = bytes.first(bytes.size() - 1);
auto missing = rbe::try_deserialize<Order>(truncated, rbe::dsrl::eager); // std::nullopt, one byte short
// the same for a lazy view, which is only safe to read if the whole value is there
std::optional<rbe::dsrl::proxy<Order>> view = rbe::try_deserialize<Order>(bytes, rbe::dsrl::lazy);
For the in-place strategies the check covers alignment too (in_place_mut takes a mutable span and returns
std::optional<T&>):
// in_place also needs the buffer aligned for T: try_deserialize checks that too
auto aligned = rbe::try_deserialize<Tick>(bytes, rbe::dsrl::in_place); // a Tick const&
auto misaligned = rbe::try_deserialize<Tick>(bytes.subspan(1), rbe::dsrl::in_place); // std::nullopt
Frames¶
A frame checks its header, then that the payload the header announces fits in what is left.
// A frame checks its header, then that the payload the header announces fits
std::optional<message::dsrl_type> msg = rbe::try_deserialize<message>(bytes);
auto cut = rbe::try_deserialize<message>(bytes.first(bytes.size() - 2)); // std::nullopt: the Order is cut
A run of frames (rbe::frames::many) never fails this way: it stops at the first incomplete element and
hands back the rest. See Walk a run of messages.
Writing¶
Note
The try_ forms check sizes and alignment. They do not, and cannot, check that the memory is live or
that the bytes mean what the type says: a lazy view over a buffer that is freed later is still a bug.
See also: Deserialization reference, Serialization reference.