summaryrefslogtreecommitdiff
path: root/src/hasher.cc
diff options
context:
space:
mode:
authorJoel Klinghed <the_jk@spawned.biz>2021-11-17 22:34:57 +0100
committerJoel Klinghed <the_jk@spawned.biz>2021-11-17 22:34:57 +0100
commit6232d13f5321b87ddf12a1aa36b4545da45f173d (patch)
tree23f3316470a14136debd9d02f9e920ca2b06f4cc /src/hasher.cc
Travel3: Simple image and video display site
Reads the images and videos from filesystem and builds a site in memroy.
Diffstat (limited to 'src/hasher.cc')
-rw-r--r--src/hasher.cc71
1 files changed, 71 insertions, 0 deletions
diff --git a/src/hasher.cc b/src/hasher.cc
new file mode 100644
index 0000000..dd94ce4
--- /dev/null
+++ b/src/hasher.cc
@@ -0,0 +1,71 @@
+#include "common.hh"
+
+#include "hash_method.hh"
+#include "hasher.hh"
+#include "io.hh"
+#include "logger.hh"
+#include "task_runner.hh"
+
+#include <errno.h>
+#include <string.h>
+
+namespace {
+
+class HasherImpl : public Hasher {
+public:
+ HasherImpl(std::shared_ptr<Logger> logger,
+ std::shared_ptr<TaskRunner> runner,
+ size_t threads)
+ : logger_(std::move(logger)), runner_(std::move(runner)),
+ workers_(TaskRunner::create(threads)) {
+ }
+
+ void hash(std::filesystem::path path,
+ std::function<void(std::string, uint64_t)> callback) override {
+ workers_->post(std::bind(&HasherImpl::do_hash, this, path, callback));
+ }
+
+private:
+ void do_hash(std::filesystem::path path,
+ std::function<void(std::string, uint64_t)> callback) {
+ auto fd = io::open(path, io::open_flags::rdonly);
+ std::string result;
+ uint64_t size = 0;
+ if (fd) {
+ auto method = HashMethod::sha256();
+ char buffer[1 * 1024 * 1024];
+ while (true) {
+ auto got = io::read(fd.get(), buffer, sizeof(buffer));
+ if (got < 0) {
+ logger_->warn("Error reading: %s: %s", path.c_str(),
+ strerror(errno));
+ size = 0;
+ break;
+ }
+ if (got == 0) {
+ result = method->finish();
+ break;
+ }
+ size += got;
+ method->update(buffer, got);
+ }
+ } else {
+ logger_->warn("Unable to open: %s: %s", path.c_str(),
+ strerror(errno));
+ }
+ runner_->post(std::bind(callback, result, size));
+ }
+
+ std::shared_ptr<Logger> logger_;
+ std::shared_ptr<TaskRunner> runner_;
+ std::unique_ptr<TaskRunner> workers_;
+};
+
+} // namespace
+
+std::unique_ptr<Hasher> Hasher::create(std::shared_ptr<Logger> logger,
+ std::shared_ptr<TaskRunner> runner,
+ size_t threads) {
+ return std::make_unique<HasherImpl>(std::move(logger), std::move(runner),
+ threads);
+}