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())
static bool IsFinished();
//! Returns how many blocks have been read, in total
static std::size_t NBlocksRead();
private:
static std::istream* in;
@ -57,6 +60,9 @@ namespace IO {
// Are we reading ciphertext or regular text?
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
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
#define GCRYPTCLI_VERSION_H
#define GCRYPTCLI_VERSION 0.125
#define GCRYPTCLI_VERSION 0.1251
#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.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.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.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!");
}
if (
(nupp.HasParam("--progress")) &&
(!nupp.HasParam("--puffer-input"))
) {
CrashWithMsg("--progress requires --puffer-input to work!");
}
return;
}

View File

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

View File

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

View File

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

View File

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