The I/O package provides building blocks for I/O-related functionalities.
Timer
Implemented in kouta::io::Timer
.
The Timer
allows performing actions after a certain amount of time. Its duration can be modified at any point, and can also be stopped before it elapses (for instance to cancel a timeout in a request).
Once the Timer
elapses, it is within the context of its parent component, so it is up to the developer to make sure that proper synchronization occurs if calling something outside of that context.
#include <iostream>
{
public:
:
kouta::base::Component{parent}
, m_timer{this, std::chrono::milliseconds{200}, std::bind_front(this, &MyComponent::handle_timeout)}
{
m_timer.start();
}
void handle_timeout(Timer& timer)
{
std::cout << "Timer expired " << std::endl;
timer.set_duration(std::chrono::milliseconds{500});
timer.start();
}
private:
};
Base class for asynchronous components.
Definition: component.hpp:16
Parser
Implemented in kouta::io::Parser
.
The Parser
is supposed to be placed over a sequence of raw bytes in order to help extracting information from said sequence. In particular, the following information can be extracted:
- Integer values (endian-aware via
boost::endian
)
- Floating point values (endian-aware via
boost::endian
)
- String values
Moreover, a read-only view of the underlying sequence can also be obtained.
Note that this is backed by std::span
, meaning that the Parser
does not own the memory it points to (and is not thread-safe).
#include <cstdint>
#include <string>
#include <vector>
std::vector<std::uint8_t> buf{0xFE, 0x84, 0x1D, 0x29, 0xD9, 0x00, 0x04, 0x01, 0xFF};
std::int32_t val2{parser.extract_integral<std::int32_t, 3, parser::Order::little>(3)};
float val3{parser.extract_floating_point<float>(0)};
std::string val4{parser.extract_string(4, 4)};
parser::View view{parser.view()};
Binary data parser.
Definition: parser.hpp:23
TValue extract_integral(std::size_t offset) const
Extract an integral value from the view.
Definition: parser.hpp:83
Packer
Implemented in kouta::io::Packer
.
The Packer
does the opposite from the Parser
: it adds the following to a raw byte sequence:
- Integer values (endian-aware via
boost::endian
)
- Floating point values (endian-aware via
boost::endian
)
- String values
- Sequences of bytes
As opposed to the Parser
, however, the Packer
does own the underlying byte container.
#include <cstdint>
#include <string>
#include <vector>
std::vector<std::uint8_t> buf{0xFE, 0x84, 0x1D, 0x29, 0xD9, 0x00, 0x04, 0x01, 0xFF};
packer.insert_integral<std::int32_t, 3, packer::Order::little>{std::int32_t{2837}};
packer.insert_float(float{48.293});
packer.insert_string("Hello world!");
packer.insert_bytes(buf.begin(), buf.end());
auto& data{packer.data()};
Binary data packer.
Definition: packer.hpp:21
void insert_integral(TValue value)
Insert an integral value in the data container.
Definition: packer.hpp:83