diff options
| author | Joel Klinghed <the_jk@spawned.biz> | 2021-11-17 22:34:57 +0100 |
|---|---|---|
| committer | Joel Klinghed <the_jk@spawned.biz> | 2021-11-17 22:34:57 +0100 |
| commit | 6232d13f5321b87ddf12a1aa36b4545da45f173d (patch) | |
| tree | 23f3316470a14136debd9d02f9e920ca2b06f4cc /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.cc | 71 |
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); +} |
