Skip to content

Instantly share code, notes, and snippets.

@Mabuchin
Last active July 16, 2024 00:31
Show Gist options
  • Save Mabuchin/59aa6aef05b879fc3dc8ccba6671d5c0 to your computer and use it in GitHub Desktop.
Save Mabuchin/59aa6aef05b879fc3dc8ccba6671d5c0 to your computer and use it in GitHub Desktop.
dataio
#include <array>
#include <functional>
#include <algorithm>
#include <stdexcept>
#include <cstdint>
#include <cstring>
#include <iostream>
int main() {
DataIO dataIO;
// コールバック関数を登録
dataIO.registerCallback([](const uint8_t* data, size_t size) {
std::cout << "Callback called. Data size: " << size << std::endl;
});
// データを書き込む
uint8_t writeData[] = {1, 2, 3, 4, 5};
dataIO.write(1, 2, writeData, sizeof(writeData));
// データを読み取る
uint8_t channelID, typeID;
uint8_t readData[256];
size_t readSize;
if (dataIO.read(channelID, typeID, readData, readSize)) {
std::cout << "Read successful. ChannelID: " << static_cast<int>(channelID)
<< ", TypeID: " << static_cast<int>(typeID)
<< ", Data size: " << readSize << std::endl;
}
return 0;
}
class DataIO {
public:
static constexpr size_t MAX_BUFFER_SIZE = 1024;
struct Header {
uint8_t channelID;
uint8_t typeID;
uint16_t dataSize;
};
static constexpr size_t HEADER_SIZE = sizeof(Header);
using CallbackFunction = std::function<void(const uint8_t*, size_t)>;
DataIO() = default;
void write(uint8_t channelID, uint8_t typeID, const uint8_t* data, size_t size) {
Header header{channelID, typeID, static_cast<uint16_t>(size)};
size_t totalSize = HEADER_SIZE + size;
if (totalSize > MAX_BUFFER_SIZE - currentPosition_) {
throw std::overflow_error("Buffer overflow");
}
// ヘッダを書き込む
std::memcpy(buffer_.data() + currentPosition_, &header, HEADER_SIZE);
currentPosition_ += HEADER_SIZE;
// データを書き込む
std::copy(data, data + size, buffer_.begin() + currentPosition_);
currentPosition_ += size;
notifyCallbacks();
}
bool read(uint8_t& channelID, uint8_t& typeID, uint8_t* data, size_t& size) {
if (currentPosition_ < HEADER_SIZE) {
return false; // ヘッダを読み取るのに十分なデータがない
}
Header header;
std::memcpy(&header, buffer_.data(), HEADER_SIZE);
if (currentPosition_ < HEADER_SIZE + header.dataSize) {
return false; // データ全体を読み取るのに十分なデータがない
}
channelID = header.channelID;
typeID = header.typeID;
size = header.dataSize;
std::copy(buffer_.begin() + HEADER_SIZE, buffer_.begin() + HEADER_SIZE + header.dataSize, data);
// 読み取ったデータをバッファから削除
std::copy(buffer_.begin() + HEADER_SIZE + header.dataSize, buffer_.begin() + currentPosition_, buffer_.begin());
currentPosition_ -= (HEADER_SIZE + header.dataSize);
return true;
}
void registerCallback(CallbackFunction callback) {
callback_ = callback;
}
void clearBuffer() {
currentPosition_ = 0;
}
size_t getAvailableSpace() const {
return MAX_BUFFER_SIZE - currentPosition_;
}
void appendToBuffer(const uint8_t* data, size_t size) {
if (size > getAvailableSpace()) {
throw std::overflow_error("Buffer overflow");
}
std::copy(data, data + size, buffer_.begin() + currentPosition_);
currentPosition_ += size;
}
private:
std::array<uint8_t, MAX_BUFFER_SIZE> buffer_;
size_t currentPosition_ = 0;
CallbackFunction callback_;
void notifyCallbacks() {
if (callback_) {
callback_(buffer_.data(), currentPosition_);
}
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment