Implement progress output

This commit is contained in:
Leonetienne 2022-06-01 03:28:31 +02:00
parent fb1e6a9e8c
commit e8d81af6f2
No known key found for this signature in database
GPG Key ID: C33879CD92E9708C
9 changed files with 112 additions and 2 deletions

View File

@ -35,6 +35,9 @@ namespace IO {
//! Returns true, if EOF is reached, and there are no more blocks to fetch (GetNextBlock()) //! Returns true, if EOF is reached, and there are no more blocks to fetch (GetNextBlock())
static bool IsFinished(); static bool IsFinished();
//! Returns how many blocks have been read, in total
static std::size_t NBlocksRead();
private: private:
static std::istream* in; static std::istream* in;
@ -57,6 +60,9 @@ namespace IO {
// Are we reading ciphertext or regular text? // Are we reading ciphertext or regular text?
static bool isReadingCiphertext; static bool isReadingCiphertext;
// How many blocks have been read in total
static std::size_t nBlocksRead;
// All read blocks, that haven't been given out yet // All read blocks, that haven't been given out yet
static std::queue<Block> blocks; static std::queue<Block> blocks;

View File

@ -0,0 +1,23 @@
#ifndef GCRYPTCLI_PROGRESSPRINTER_H
#define GCRYPTCLI_PROGRESSPRINTER_H
#include <iostream>
#include "CommandlineInterface.h"
// This class has the task to output progress to stderr, if requested
class ProgressPrinter {
public:
//! Will print progress to stderr, if requested, and the interval matches
static void PrintIfAppropriate(
const std::string& message,
const std::size_t current,
const std::size_t target
);
private:
// No instanciation! >:(
ProgressPrinter() {};
};
#endif

View File

@ -1,7 +1,7 @@
#ifndef GCRYPTCLI_VERSION_H #ifndef GCRYPTCLI_VERSION_H
#define GCRYPTCLI_VERSION_H #define GCRYPTCLI_VERSION_H
#define GCRYPTCLI_VERSION 0.125 #define GCRYPTCLI_VERSION 0.1251
#endif #endif

View File

@ -64,10 +64,13 @@ void CommandlineInterface::Init(int argc, const char* const* argv) {
nupp.RegisterConstraint("--keyask", ParamConstraint(true, DATA_TYPE::VOID, {}, false, { "--key", "--keyfile", "--hash" })); nupp.RegisterConstraint("--keyask", ParamConstraint(true, DATA_TYPE::VOID, {}, false, { "--key", "--keyfile", "--hash" }));
nupp.RegisterAbbreviation("-ka", "--keyask"); nupp.RegisterAbbreviation("-ka", "--keyask");
nupp.RegisterDescription("--progress", "Print digestion progress to stdout. May be advisable for large files, as the cipher is rather slow."); nupp.RegisterDescription("--progress", "Print digestion progress to stderr. May be advisable for large files, as the cipher is rather slow.");
nupp.RegisterConstraint("--progress", ParamConstraint(true, DATA_TYPE::VOID, {}, false, {})); nupp.RegisterConstraint("--progress", ParamConstraint(true, DATA_TYPE::VOID, {}, false, {}));
nupp.RegisterAbbreviation("-p", "--progress"); nupp.RegisterAbbreviation("-p", "--progress");
nupp.RegisterDescription("--progress-interval", "Print digestion progress reports every these many blocks.");
nupp.RegisterConstraint("--progress-interval", ParamConstraint(true, DATA_TYPE::INT, { "1000" }, true, {}));
nupp.RegisterDescription("--iobase-bytes", "Interpret and output ciphertexts as raw bytes."); nupp.RegisterDescription("--iobase-bytes", "Interpret and output ciphertexts as raw bytes.");
nupp.RegisterConstraint("--iobase-bytes", ParamConstraint(true, DATA_TYPE::VOID, {}, false, { "--iobase-2", "--iobase-8", "--iobase-10", "--iobase-16", "--iobase-64", "--iobase-uwu", "--iobase-ugh" })); nupp.RegisterConstraint("--iobase-bytes", ParamConstraint(true, DATA_TYPE::VOID, {}, false, { "--iobase-2", "--iobase-8", "--iobase-10", "--iobase-16", "--iobase-64", "--iobase-uwu", "--iobase-ugh" }));
@ -168,6 +171,14 @@ void CommandlineInterface::SpecialCompatibilityChecking() {
CrashWithMsg("Length of --keyfile is zero! That can't be a valid path!"); CrashWithMsg("Length of --keyfile is zero! That can't be a valid path!");
} }
if (
(nupp.HasParam("--progress")) &&
(!nupp.HasParam("--puffer-input"))
) {
CrashWithMsg("--progress requires --puffer-input to work!");
}
return; return;
} }

View File

@ -68,6 +68,7 @@ void DataIngestionLayer::Init() {
initialized = true; initialized = true;
reachedEof = false; reachedEof = false;
nBlocksRead = 0;
return; return;
} }
@ -142,6 +143,7 @@ void DataIngestionLayer::ReadBlock() {
} }
blocks.emplace(newBlock); blocks.emplace(newBlock);
nBlocksRead++;
break; break;
} }
@ -247,6 +249,7 @@ void DataIngestionLayer::ReadBlock() {
// Enqueue it to be processed by some module // Enqueue it to be processed by some module
blocks.emplace(newBlock); blocks.emplace(newBlock);
nBlocksRead++;
foundBlock = true; foundBlock = true;
// Now we have to calculate how many bytes we've read TOO MANY. // Now we have to calculate how many bytes we've read TOO MANY.
@ -351,11 +354,16 @@ Block DataIngestionLayer::GetNextBlock() {
return popped; return popped;
} }
std::size_t DataIngestionLayer::NBlocksRead() {
return nBlocksRead;
}
std::istream* DataIngestionLayer::in; std::istream* DataIngestionLayer::in;
std::ifstream DataIngestionLayer::ifs; std::ifstream DataIngestionLayer::ifs;
std::istringstream DataIngestionLayer::iss; std::istringstream DataIngestionLayer::iss;
bool DataIngestionLayer::reachedEof = false; bool DataIngestionLayer::reachedEof = false;
bool DataIngestionLayer::initialized = false; bool DataIngestionLayer::initialized = false;
bool DataIngestionLayer::isReadingCiphertext; bool DataIngestionLayer::isReadingCiphertext;
std::size_t DataIngestionLayer::nBlocksRead = 0;
std::queue<Block> DataIngestionLayer::blocks; std::queue<Block> DataIngestionLayer::blocks;

View File

@ -1,6 +1,7 @@
#include "ModuleDecryption.h" #include "ModuleDecryption.h"
#include "DataIngestionLayer.h" #include "DataIngestionLayer.h"
#include "DataOutputLayer.h" #include "DataOutputLayer.h"
#include "ProgressPrinter.h"
#include "KeyManager.h" #include "KeyManager.h"
#include <GCrypt/GCipher.h> #include <GCrypt/GCipher.h>
@ -21,6 +22,7 @@ void Decryption::Run() {
GCipher::DIRECTION::DECIPHER GCipher::DIRECTION::DECIPHER
); );
std::size_t nBlocksDigested = 0;
while (!IO::DataOutputLayer::IsFinished()) { while (!IO::DataOutputLayer::IsFinished()) {
// Read in new blocks, if not reached eof // Read in new blocks, if not reached eof
if (!IO::DataIngestionLayer::ReachedEOF()) { if (!IO::DataIngestionLayer::ReachedEOF()) {
@ -29,8 +31,17 @@ void Decryption::Run() {
// Process a block, if one is ready // Process a block, if one is ready
if (IO::DataIngestionLayer::IsBlockReady()) { if (IO::DataIngestionLayer::IsBlockReady()) {
// Print progress, if appropriate
ProgressPrinter::PrintIfAppropriate(
"Decrypting",
nBlocksDigested,
IO::DataIngestionLayer::NBlocksRead()
);
const Block cleartext = IO::DataIngestionLayer::GetNextBlock(); const Block cleartext = IO::DataIngestionLayer::GetNextBlock();
const Block ciphertext = cipher.Digest(cleartext); const Block ciphertext = cipher.Digest(cleartext);
nBlocksDigested++;
// Enqueue the block for output // Enqueue the block for output
IO::DataOutputLayer::Enqueue(ciphertext); IO::DataOutputLayer::Enqueue(ciphertext);

View File

@ -2,7 +2,9 @@
#include "DataIngestionLayer.h" #include "DataIngestionLayer.h"
#include "DataOutputLayer.h" #include "DataOutputLayer.h"
#include "KeyManager.h" #include "KeyManager.h"
#include "ProgressPrinter.h"
#include <GCrypt/GCipher.h> #include <GCrypt/GCipher.h>
#include <iostream>
using namespace Module; using namespace Module;
using namespace Leonetienne::GCrypt; using namespace Leonetienne::GCrypt;
@ -21,6 +23,7 @@ void Encryption::Run() {
GCipher::DIRECTION::ENCIPHER GCipher::DIRECTION::ENCIPHER
); );
std::size_t nBlocksDigested = 0;
while (!IO::DataOutputLayer::IsFinished()) { while (!IO::DataOutputLayer::IsFinished()) {
// Read in new blocks, if not reached eof // Read in new blocks, if not reached eof
if (!IO::DataIngestionLayer::ReachedEOF()) { if (!IO::DataIngestionLayer::ReachedEOF()) {
@ -29,8 +32,17 @@ void Encryption::Run() {
// Process a block, if one is ready // Process a block, if one is ready
if (IO::DataIngestionLayer::IsBlockReady()) { if (IO::DataIngestionLayer::IsBlockReady()) {
// Print progress, if appropriate
ProgressPrinter::PrintIfAppropriate(
"Encrypting",
nBlocksDigested,
IO::DataIngestionLayer::NBlocksRead()
);
const Block cleartext = IO::DataIngestionLayer::GetNextBlock(); const Block cleartext = IO::DataIngestionLayer::GetNextBlock();
const Block ciphertext = cipher.Digest(cleartext); const Block ciphertext = cipher.Digest(cleartext);
nBlocksDigested++;
// Enqueue the block for output // Enqueue the block for output
IO::DataOutputLayer::Enqueue(ciphertext); IO::DataOutputLayer::Enqueue(ciphertext);

View File

@ -1,6 +1,7 @@
#include "ModuleHashing.h" #include "ModuleHashing.h"
#include "DataIngestionLayer.h" #include "DataIngestionLayer.h"
#include "DataOutputLayer.h" #include "DataOutputLayer.h"
#include "ProgressPrinter.h"
#include "KeyManager.h" #include "KeyManager.h"
#include <GCrypt/GHash.h> #include <GCrypt/GHash.h>
@ -19,6 +20,7 @@ void Hashing::Run() {
GHash hasher; GHash hasher;
// Read in new blocks, if not reached eof // Read in new blocks, if not reached eof
std::size_t nBlocksDigested = 0;
while (!IO::DataIngestionLayer::IsFinished()) { while (!IO::DataIngestionLayer::IsFinished()) {
if (!IO::DataIngestionLayer::ReachedEOF()) { if (!IO::DataIngestionLayer::ReachedEOF()) {
IO::DataIngestionLayer::ReadBlock(); IO::DataIngestionLayer::ReadBlock();
@ -26,8 +28,17 @@ void Hashing::Run() {
// Process a block, if one is ready // Process a block, if one is ready
if (IO::DataIngestionLayer::IsBlockReady()) { if (IO::DataIngestionLayer::IsBlockReady()) {
// Print progress, if appropriate
ProgressPrinter::PrintIfAppropriate(
"Hashing",
nBlocksDigested,
IO::DataIngestionLayer::NBlocksRead()
);
const Block cleartext = IO::DataIngestionLayer::GetNextBlock(); const Block cleartext = IO::DataIngestionLayer::GetNextBlock();
hasher.Digest(cleartext); hasher.Digest(cleartext);
nBlocksDigested++;
} }
} }

View File

@ -0,0 +1,28 @@
#include "ProgressPrinter.h"
#include "CommandlineInterface.h"
#include <iostream>
void ProgressPrinter::PrintIfAppropriate(
const std::string& message,
const std::size_t current,
const std::size_t target
) {
if (
(CommandlineInterface::Get().HasParam("--progress")) &&
(current % CommandlineInterface::Get()["--progress-interval"].GetInt32() == 0)
) {
std::cerr
<< message
<< "... (Block "
<< current + 1
<< " / "
<< target
<< " - " << ((float)(current+1)*100 / target)
<< "%)"
<< std::endl
;
}
return;
}