1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
|
#pragma once
#include "common.hpp"
#include "components/logger.hpp"
#include "errors.hpp"
#include "ipc/msg.hpp"
#include <cstdint>
POLYBAR_NS
namespace ipc {
/**
* Decoder for the IPC message format.
*/
class decoder {
public:
DEFINE_ERROR(error);
/**
* Callback is called whenever a full message is received.
* The message version, message type, and the data is passed.
*/
using cb = std::function<void(uint8_t, type_t, const std::vector<uint8_t>&)>;
decoder(const logger&, cb callback);
/**
* Call this function whenever new data arrives.
*
* Will throw deocder::error in case of error.
* If an error is thrown, this instance is closed and this function may not be called again.
*/
void on_read(const uint8_t* buf, size_t size);
void close() noexcept;
bool closed() const;
protected:
void process_data(const uint8_t*, size_t size);
ssize_t process_header_data(const uint8_t*, size_t size);
ssize_t process_msg_data(const uint8_t*, size_t size);
ipc::header header;
size_t to_read_header{ipc::HEADER_SIZE};
std::vector<uint8_t> buf;
size_t to_read_buf{0};
cb callback;
private:
enum class state {
// Waiting for header data (header does not contain full header)
HEADER,
// Waiting for message data (header contains valid header)
PAYLOAD,
CLOSED,
} state{state::HEADER};
const logger& m_log;
};
} // namespace ipc
POLYBAR_NS_END
|