Last active
July 16, 2024 00:31
-
-
Save Mabuchin/59aa6aef05b879fc3dc8ccba6671d5c0 to your computer and use it in GitHub Desktop.
dataio
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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