9#include <QtCore/QtGlobal>
18 explicit Framer(std::span<uint8_t> buffer)
22 Q_DISABLE_COPY_MOVE(
Framer)
26 if (_buffer.size() < 6) {
42 }
else if (
byte ==
'*') {
43 _state = State::ChecksumHigh;
48 if (_size >= _buffer.size() - 5) {
51 _buffer[_size++] = byte;
54 case State::ChecksumHigh:
55 _buffer[_size++] = byte;
56 _state = State::ChecksumLow;
58 case State::ChecksumLow: {
59 _buffer[_size++] = byte;
61 _buffer[_size - 2] == _hexDigit(_checksum >> 4) && _buffer[_size - 1] == _hexDigit(_checksum)
73 _state = State::Waiting;
79 static constexpr char _hexDigit(
unsigned value) {
return "0123456789ABCDEF"[value & 0xf]; }
88 std::span<uint8_t> _buffer;
90 uint8_t _checksum = 0;
91 State _state = State::Waiting;
103 std::optional<std::string_view>
addByte(uint8_t
byte)
105 const char ch =
static_cast<char>(byte);
107 if (_active && !_discard) {
114 std::optional<std::string_view> line;
115 if (_active && !_discard && _size > 0) {
116 line = std::string_view(_buffer.data(), _size);
122 if (_startsLine(ch)) {
133 if (_lineEnded || ch <
' ' || ch >
'~' || _size == _buffer.size()) {
153 static bool _startsLine(
char ch) {
return ch ==
'$' || ch ==
'#'; }
155 void _append(
char ch)
157 if (_discard || _size == _buffer.size()) {
162 _buffer[_size++] = ch;
165 std::span<char> _buffer;
167 bool _active =
false;
168 bool _discard =
false;
169 bool _lineEnded =
false;
size_t addByte(uint8_t byte)
Framer(std::span< uint8_t > buffer)
Frames printable ASCII lines. A '$' or '#' restarts the line, so a sentence or log is not lost after ...
std::optional< std::string_view > addByte(uint8_t byte)
Returns a completed line without its terminator; the view is valid until the next byte.
LineFramer(std::span< char > buffer)