5

How can we know how many bytes were read when calling a synchronous read operation on a random-access device and it throws an exception, for example random_access_file ?

Is this not supported, and to know how many bytes were read, one is supposed to take the boost::system::error_code ec overload?

error_code ec;
size_t s = a.read_some_at(offset, buffers, ec);
offset += s; // need to be done before unwinding
if (ec) throw system_error(ec);
return s;
Johannes Schaub - litb
  • 496,577
  • 130
  • 894
  • 1,212

1 Answers1

4

Short answer: Yes. Take the ec overload. This has been the case for partial-success operations in Asio.

Slightly longer (irrelevant) answer: when using e.g. c++20 coroutines you can make the error-code and byte-count be returned as a tuple, which you might find more convenient:

auto [ec, s] = a.async_read_some_at(offset, buffers, asio::as_tuple(asio::use_awaitable)));

Pet peeve: as_tuple doesn't at current (last checked 1.80.0) appear to work well with asio::use_future :(

sehe
  • 374,641
  • 47
  • 450
  • 633
  • 2
    I prefer to _almost always_ take the `ec` overload, you can always throw an exception in your application layer if you need to. Seldom does boost have *all* of the relevant details when throwing an exception to let you properly diagnose an issue. – Chad Feb 15 '23 at 14:14
  • Thanks! I'm writing a stream-like-class that simply wraps a random-access-file and passing it an offset, and has an offset integer in it that increments whenever read_some / async_read_some is called on it. That's why I need to know how many bytes were read. Still need to figure out how I get the number of read/written bytes in the async_{read,write}_some case. Seems like I need to wrap the token and intercept the "bytes_read" integer. I'm still investivating how to properly do that without losing anything like associated executor etc. Is this the "Completion Token Adapters" stuff? – Johannes Schaub - litb Feb 15 '23 at 15:18
  • The goal is that then I can use boost::buffered_stream with the random access file, when reading contiguous records from the file. – Johannes Schaub - litb Feb 15 '23 at 15:24
  • @JohannesSchaub-litb in general using async completion exposes both the error code and the bytes transferred just fine (e.g using a handler `void(error_code, size_t)` or indeed using `as_tuple(use_awaitable)`. The latter is indeed described under Completion Token Adaptors. As mentioned it doesn't play well with `use_future`, but that is not asynchronous anyways. – sehe Feb 15 '23 at 21:52
  • 1
    Thanks! I made my own completion token adapter that takes the size and adds it to a size reference. It works with any kind of completion token as a wrapper. – Johannes Schaub - litb Feb 16 '23 at 19:50