mirror of
https://github.com/mudita/MuditaOS.git
synced 2026-05-24 16:47:00 -04:00
* Adding document describing how to use logger * Adjusting logs to follow a new guide * Change order in log header: line number is now before function name
152 lines
4.0 KiB
C++
152 lines
4.0 KiB
C++
// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
|
|
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
|
|
|
|
#include <endpoints/filesystem/FileContext.hpp>
|
|
#include <log/log.hpp>
|
|
#include <utility>
|
|
#include <fstream>
|
|
|
|
FileContext::FileContext(const std::filesystem::path &path, std::size_t size, std::size_t chunkSize, std::size_t offset)
|
|
: path(path), size(size), offset(offset), chunkSize(chunkSize)
|
|
{
|
|
if (!size || !chunkSize) {
|
|
throw std::invalid_argument("Invalid FileContext arguments");
|
|
}
|
|
|
|
runningCrc32Digest.reset();
|
|
}
|
|
|
|
FileContext::~FileContext()
|
|
{}
|
|
|
|
FileReadContext::FileReadContext(const std::filesystem::path &path,
|
|
std::size_t size,
|
|
std::size_t chunkSize,
|
|
std::size_t offset)
|
|
: FileContext(path, size, chunkSize, offset)
|
|
{}
|
|
|
|
FileReadContext::~FileReadContext()
|
|
{}
|
|
|
|
FileWriteContext::FileWriteContext(const std::filesystem::path &path,
|
|
std::size_t size,
|
|
std::size_t chunkSize,
|
|
std::string crc32Digest,
|
|
std::size_t offset)
|
|
: FileContext(path, size, chunkSize, offset), crc32Digest(std::move(crc32Digest)),
|
|
file(path, std::ios::binary | std::ios::out)
|
|
{}
|
|
|
|
FileWriteContext::~FileWriteContext()
|
|
{}
|
|
|
|
auto FileContext::advanceFileOffset(std::size_t bySize) -> void
|
|
{
|
|
offset += bySize;
|
|
}
|
|
|
|
auto FileContext::reachedEOF() const -> bool
|
|
{
|
|
return offset >= size;
|
|
}
|
|
|
|
auto FileContext::chunksInQuantity(std::size_t quantity) const -> std::size_t
|
|
{
|
|
return (quantity + chunkSize - 1) / chunkSize;
|
|
}
|
|
|
|
auto FileContext::totalChunksInFile() const -> std::size_t
|
|
{
|
|
return chunksInQuantity(size);
|
|
}
|
|
|
|
auto FileContext::expectedChunkInFile() const -> std::size_t
|
|
{
|
|
return 1 + chunksInQuantity(offset);
|
|
}
|
|
|
|
auto FileContext::validateChunkRequest(std::uint32_t chunkNo) const -> bool
|
|
{
|
|
return !(chunkNo < 1 || chunkNo > totalChunksInFile() || chunkNo != expectedChunkInFile());
|
|
}
|
|
|
|
auto FileContext::fileHash() const -> std::string
|
|
{
|
|
return runningCrc32Digest.getHash();
|
|
}
|
|
|
|
auto FileReadContext::read() -> std::vector<std::uint8_t>
|
|
{
|
|
LOG_DEBUG("Getting file data");
|
|
|
|
std::ifstream file(path, std::ios::binary);
|
|
|
|
if (!file.is_open() || file.fail()) {
|
|
LOG_ERROR("File %s open error", path.c_str());
|
|
throw std::runtime_error("File open error");
|
|
}
|
|
|
|
file.seekg(offset);
|
|
|
|
auto dataLeft = std::min(static_cast<std::size_t>(chunkSize), (size - offset));
|
|
|
|
std::vector<std::uint8_t> buffer(dataLeft);
|
|
|
|
file.read(reinterpret_cast<char *>(buffer.data()), dataLeft);
|
|
|
|
if (file.bad()) {
|
|
LOG_ERROR("File %s read error", path.c_str());
|
|
throw std::runtime_error("File read error");
|
|
}
|
|
|
|
runningCrc32Digest.add(buffer.data(), dataLeft);
|
|
|
|
LOG_DEBUG("Read %u bytes", static_cast<unsigned int>(dataLeft));
|
|
advanceFileOffset(dataLeft);
|
|
|
|
if (reachedEOF()) {
|
|
LOG_DEBUG("Reached EOF");
|
|
}
|
|
|
|
return buffer;
|
|
}
|
|
|
|
auto FileWriteContext::write(const std::vector<std::uint8_t> &data) -> void
|
|
{
|
|
if (!file.is_open() || file.fail()) {
|
|
LOG_ERROR("File %s open error", path.c_str());
|
|
throw std::runtime_error("File open error");
|
|
}
|
|
|
|
auto dataLeft = std::min(static_cast<std::size_t>(chunkSize), (size - offset));
|
|
|
|
file.write(reinterpret_cast<const char *>(data.data()), dataLeft);
|
|
file.flush();
|
|
|
|
if (file.bad()) {
|
|
LOG_ERROR("File %s write error", path.c_str());
|
|
throw std::runtime_error("File write error");
|
|
}
|
|
|
|
runningCrc32Digest.add(data.data(), dataLeft);
|
|
|
|
advanceFileOffset(dataLeft);
|
|
|
|
if (reachedEOF()) {
|
|
LOG_DEBUG("Reached EOF of %s", path.c_str());
|
|
}
|
|
}
|
|
|
|
auto FileWriteContext::crc32Matches() const -> bool
|
|
{
|
|
LOG_DEBUG("Hash: %s", fileHash().c_str());
|
|
return crc32Digest == fileHash();
|
|
}
|
|
|
|
auto FileWriteContext::removeFile() -> void
|
|
{
|
|
std::error_code ec;
|
|
std::filesystem::remove(path, ec);
|
|
}
|