From 2f6df42696f93fdab01aa38a17f5e908b606bd3a Mon Sep 17 00:00:00 2001 From: Leonetienne Date: Tue, 31 May 2022 14:25:23 +0200 Subject: [PATCH] Implement relevant methods for DataIngestionLayer --- GCryptCLI/include/DataIngestionLayer.h | 29 +++++++++++-- GCryptCLI/src/DataIngestionLayer.cpp | 60 ++++++++++++++++++++++++++ 2 files changed, 86 insertions(+), 3 deletions(-) diff --git a/GCryptCLI/include/DataIngestionLayer.h b/GCryptCLI/include/DataIngestionLayer.h index 3fd24e6..1a2c13e 100644 --- a/GCryptCLI/include/DataIngestionLayer.h +++ b/GCryptCLI/include/DataIngestionLayer.h @@ -1,9 +1,11 @@ #ifndef GCRYPTCLI_DATAINGESTIONLAYER_H #define GCRYPTCLI_DATAINGESTIONLAYER_H -#include -#include -#include +#include +#include +#include + +using namespace Leonetienne::GCrypt; namespace IO { @@ -13,6 +15,19 @@ namespace IO { //! Will initialize the ingestion static void Init(); + //! Will attempt to read a data block. + //! Requires Init() to have been called + static void ReadBlock(); + + //! Have we read in all available blocks? + static bool ReachedEOF(); + + //! Will return true if there is at least one block to be GetBlock()'ed + static bool IsBlockReady(); + + //! Will return the next block in the queue + static Block GetNextBlock(); + private: static std::istream* in; @@ -21,6 +36,14 @@ namespace IO { // We still have to CLOSE the file handle afterwards! static std::ifstream ifs; static std::istringstream iss; + + // Indicates whether EOF has been reached + static bool reachedEof; + // Indicates whether this class is initialized + static bool initialized; + + // All read blocks, that haven't been given out yet + static std::queue blocks; }; } diff --git a/GCryptCLI/src/DataIngestionLayer.cpp b/GCryptCLI/src/DataIngestionLayer.cpp index 7c3f543..f4d6eec 100644 --- a/GCryptCLI/src/DataIngestionLayer.cpp +++ b/GCryptCLI/src/DataIngestionLayer.cpp @@ -2,6 +2,9 @@ #include "CommandlineInterface.h" #include "Configuration.h" #include +#include +#include +#include #include using namespace IO; @@ -50,6 +53,9 @@ void DataIngestionLayer::Init() { break; } + initialized = true; + reachedEof = false; + // Temporary std::size_t n_last_bytes_read = 0; char buf[64]; @@ -65,8 +71,62 @@ void DataIngestionLayer::Init() { return; } +void DataIngestionLayer::ReadBlock() { + if (!initialized) { + throw std::runtime_error("Attempted to read on uninitialized DataIngestionLayer!"); + } + + if (!reachedEof) { + // Create buffer to read into + char buf[Block::BLOCK_SIZE]; + memset(buf, 0, sizeof(buf)); + + // Read + in->read(buf, sizeof(buf)); + + // Fetch how much we've read + const std::size_t n_bytes_read = in->gcount(); + + // Is this fewer bytes than we requested? + if (n_bytes_read < sizeof(buf)) { + // Yes: EOF reached. + reachedEof = true; + } + + // Construct a Block from this buf + Block block; + block.FromByteString(std::string(buf)); + + // Enqueue it + blocks.emplace(block); + } + + return; +} + +bool DataIngestionLayer::ReachedEOF() { + return reachedEof; +} + +bool DataIngestionLayer::IsBlockReady() { + return blocks.size() > 0; +} + +Block DataIngestionLayer::GetNextBlock() { + if (!IsBlockReady()) { + throw std::runtime_error("Attempted to get the next block, but there are none left!"); + } + + // Why... why not just return a T in pop()??? + const Block popped = blocks.front(); + blocks.pop(); + return popped; +} std::istream* DataIngestionLayer::in; std::ifstream DataIngestionLayer::ifs; std::istringstream DataIngestionLayer::iss; +bool DataIngestionLayer::reachedEof = false; +bool DataIngestionLayer::initialized = false; +std::queue DataIngestionLayer::blocks;