-
Notifications
You must be signed in to change notification settings - Fork 0
Add Media/Filesystem Mounting frontend and Archive mouting backend #18
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
66e794f
7a0f350
ae55f41
f9906fc
a6bff3f
37cd186
37bb01b
24cbf59
6f7f484
13aa943
f927aaa
2e93f55
8dfd60e
7a32c2f
fd30cd8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
#include "MediaManager.h" | ||
|
||
#include "MountManager.h" | ||
|
||
MediaManager::MediaManager() : mount_manager(std::make_unique<MountManager>()) { | ||
} | ||
|
||
MediaManager& MediaManager::instance() { | ||
static MediaManager instance; | ||
return instance; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
#pragma once | ||
|
||
#include <memory> | ||
|
||
class MountManager; | ||
|
||
class MediaManager { | ||
public: | ||
static MediaManager& instance(); | ||
|
||
private: | ||
MediaManager(); | ||
|
||
// Delete copy and move semantics | ||
MediaManager(MediaManager&) = delete; | ||
mposs00 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
void operator=(MediaManager const&) = delete; | ||
|
||
// Access to the underlying storage system | ||
std::unique_ptr<MountManager> mount_manager; | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
#pragma once | ||
|
||
#include <filesystem> | ||
|
||
class Mount { | ||
public: | ||
Mount(const std::filesystem::path& target_path) : path{target_path} {}; | ||
|
||
std::filesystem::path get_path() const { | ||
return path; | ||
}; | ||
|
||
virtual void load() = 0; | ||
|
||
virtual bool seek_file(const std::string& path) const = 0; | ||
virtual std::vector<uint8_t> fetch_data(const std::string& path) = 0; | ||
|
||
protected: | ||
const std::filesystem::path path; | ||
virtual void load_cache() = 0; | ||
mposs00 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
virtual void save_cache() = 0; | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
#include "MountArchive.h" | ||
|
||
#include "bit7z/bitarchivereader.hpp" | ||
#include "utils/Log.h" | ||
|
||
MountArchive::MountArchive(const std::filesystem::path& archive_path) | ||
: Mount(archive_path), reader(std::make_unique<bit7z::BitArchiveReader>(library, path.string())) { | ||
} | ||
|
||
void MountArchive::load() { | ||
reset_reader(); | ||
|
||
try { | ||
reader = std::make_unique<bit7z::BitArchiveReader>(library, get_path().string()); | ||
reader->test(); | ||
} | ||
catch (const std::exception& exception) { | ||
throw exception; | ||
} | ||
|
||
load_cache(); | ||
} | ||
|
||
bool MountArchive::seek_file(const std::string& path) const { | ||
return static_cache.contains(path); | ||
} | ||
|
||
std::vector<uint8_t> MountArchive::fetch_data(const std::string& path) { | ||
uint32_t index = static_cache.at(path); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this can throw std::out_of_range, is that acceptable? |
||
std::vector<uint8_t> buffer; | ||
|
||
try { | ||
reader->extractTo(buffer, index); | ||
} | ||
catch (const std::exception& exception) { | ||
throw exception; | ||
} | ||
|
||
return buffer; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. what are the contents of buffer if we caught an exception? does the caller have a way of knowing that this data is bad? |
||
} | ||
|
||
void MountArchive::load_cache() { | ||
const std::filesystem::path cache_file_path = get_path().replace_filename("cache"); | ||
|
||
if (std::filesystem::exists(cache_file_path)) { | ||
return; | ||
} | ||
|
||
const auto items = reader->items(); | ||
for (const auto& item : items) { | ||
// 7zip returns files with a double-backslash prefix | ||
// These are stripped to be consistent with filesystem relative paths | ||
static_cache.at(item.path().replace(0, 2, "/")) = item.index(); | ||
Salanto marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
} | ||
|
||
void MountArchive::save_cache() { | ||
// TODO: Implement writing cache to disk | ||
} | ||
|
||
void MountArchive::reset_reader() { | ||
try { | ||
if (reader) { | ||
reader.reset(); | ||
} | ||
} | ||
catch (const std::exception& e) { | ||
Log::log_print(ERR, e.what()); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. should we rethrow? |
||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
#ifndef MOUNTARCHIVE_H | ||
#define MOUNTARCHIVE_H | ||
|
||
#include "Mount.h" | ||
|
||
#include <include/bit7z/bit7zlibrary.hpp> | ||
#include <include/bit7z/bitarchivereader.hpp> | ||
|
||
class MountArchive : public Mount { | ||
public: | ||
explicit MountArchive(const std::filesystem::path& archive_path); | ||
~MountArchive() = default; | ||
|
||
void load() override; | ||
|
||
bool seek_file(const std::string& path) const override; | ||
std::vector<uint8_t> fetch_data(const std::string& path) override; | ||
|
||
private: | ||
void load_cache() override; | ||
void save_cache() override; | ||
|
||
void reset_reader(); | ||
|
||
std::unordered_map<std::string, uint32_t> static_cache; | ||
const bit7z::Bit7zLibrary library; | ||
std::unique_ptr<bit7z::BitArchiveReader> reader; | ||
}; | ||
|
||
#endif // MOUNTARCHIVE_H |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
#include "MountManager.h" | ||
|
||
#include "MountArchive.h" | ||
#include "utils/Log.h" | ||
|
||
#include <format> | ||
#include <shared_mutex> | ||
|
||
MountManager::MountManager() { | ||
} | ||
|
||
void MountManager::load_mounts(const std::vector<std::filesystem::path>& target_mount_path) { | ||
std::unique_lock<std::shared_mutex> locker(lock); | ||
|
||
if (!loaded_mounts.empty()) { | ||
loaded_mounts.clear(); | ||
} | ||
|
||
for (const std::filesystem::path& mount_path : target_mount_path) { | ||
|
||
try { | ||
std::unique_ptr<MountArchive> archive = std::make_unique<MountArchive>(mount_path); | ||
archive->load(); | ||
loaded_mounts.push_back(std::move(archive)); | ||
} | ||
catch (std::exception exception) { | ||
Log::log_print( | ||
WARNING, | ||
std::format("Failed to create mount at {}: {}", mount_path.string(), exception.what()).c_str()); | ||
continue; | ||
} | ||
} | ||
} | ||
|
||
std::optional<std::vector<uint8_t>> MountManager::fetch_data(const std::string& relative_path) { | ||
std::shared_lock<std::shared_mutex> locker(lock); | ||
Log::log_print(INFO, std::format("Loading file at {}", relative_path).c_str()); | ||
for (auto& mount : loaded_mounts) { | ||
if (mount->seek_file(relative_path)) { | ||
try { | ||
return std::make_optional<std::vector<uint8_t>>(mount->fetch_data(relative_path)); | ||
} | ||
catch (std::exception exception) { | ||
Log::log_print( | ||
ERR, std::format("Failed to load data due to the following errror {}", exception.what()).c_str()); | ||
} | ||
} | ||
} | ||
return std::nullopt; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
#pragma once | ||
|
||
#include <filesystem> | ||
#include <shared_mutex> | ||
#include <vector> | ||
|
||
#include "Mount.h" | ||
|
||
class MountManager { | ||
public: | ||
MountManager(); | ||
|
||
void load_mounts(const std::vector<std::filesystem::path>& target_mount_path); | ||
std::optional<std::vector<uint8_t>> fetch_data(const std::string& relative_path); | ||
|
||
private: | ||
std::shared_mutex lock; | ||
std::vector<std::unique_ptr<Mount>> loaded_mounts; | ||
}; |
Uh oh!
There was an error while loading. Please reload this page.