diff --git a/include/ReArchive/ReArchive.h b/include/ReArchive/ReArchive.h index a2ed29f..0d0d62d 100644 --- a/include/ReArchive/ReArchive.h +++ b/include/ReArchive/ReArchive.h @@ -4,6 +4,7 @@ #include // TODO compression. +// TODO allow the user to pass in the file table if they already have it to avoid de-serializing it over and over. namespace ReArchive { /// Creates a new empty archive. /// @param filesystem_path where the archive is to be created. diff --git a/include/ReArchive/types/FileTable.h b/include/ReArchive/types/FileTable.h index 2a93669..5d63740 100644 --- a/include/ReArchive/types/FileTable.h +++ b/include/ReArchive/types/FileTable.h @@ -16,7 +16,8 @@ public: void Append(const FileEntry& file_entry); void Remove(const FileEntry& file_entry); [[nodiscard]] bool Contains(const std::filesystem::path& entry ) const { return entries.contains(entry); } - [[nodiscard]] std::unordered_map GetEntries() const { return entries; } + [[nodiscard]] std::unordered_map* GetEntries() { return &entries; } + [[nodiscard]] const std::unordered_map* GetEntries() const { return &entries; } [[nodiscard]] int64_t Count() const { return entries.size(); } public: [[nodiscard]] static std::vector Serialize(const FileTable& file_table); diff --git a/main.cpp b/main.cpp index 8545996..8d2fb30 100644 --- a/main.cpp +++ b/main.cpp @@ -85,7 +85,7 @@ void DisplayArchiveContents(const std::filesystem::path& archive) { auto file_table = result.second; std::cout << "path" << " | " << "size (bytes)" << std::endl; - for (const auto& e : file_table.GetEntries()) + for (const auto& e : *file_table.GetEntries()) std::cout << e.second.Path() << " " << e.second.Size() << std::endl; } @@ -104,23 +104,11 @@ void AddFileToArchive(const std::filesystem::path& file_to_add, const std::files return; } - auto file_table_result = ReArchive::ReadFileTable(archive); - if (!file_table_result.first) { - std::cerr << "The specified path is inaccessible or not a valid archive." << std::endl; - return; - } - - auto file_table = file_table_result.second; - if (file_table.Contains(file_to_add)) { - std::cerr << "The specified path for the file to be added already exists within the archive." << std::endl; - return; - } - auto file_data = ReadFileFromDisk(file_to_add); auto result = ReArchive::WriteFile(archive, file_to_add, file_data.data(), file_data.size()); if (!result) - std::cerr << "The specified path is inaccessible or not a valid archive." << std::endl; + std::cerr << "The specified path for the file to be added already exists within the archive." << std::endl; } void AddDirectoryToArchive(const std::filesystem::path& directory_to_add, const std::filesystem::path& archive) { @@ -171,7 +159,7 @@ void ExtractArchive(const std::filesystem::path& archive) { return; } - for (const auto& entry : file_table_result.second.GetEntries()) { + for (const auto& entry : *file_table_result.second.GetEntries()) { if (std::filesystem::exists(entry.first)) if (!GetConfirmation("File " + entry.first.string() + " already exists, overwrite?")) continue; diff --git a/src/ReArchive.cpp b/src/ReArchive.cpp index 5e31e96..8f2104d 100644 --- a/src/ReArchive.cpp +++ b/src/ReArchive.cpp @@ -49,7 +49,7 @@ FileTable GetFileTable(const Header& header, std::ifstream& in) { int64_t data_offset = be64toh(*reinterpret_cast(ptr)); ptr += sizeof(int64_t); - result.Append(FileEntry(data_size, data_offset, path)); + result.Append({ data_size, data_offset, path }); } return result; } @@ -122,9 +122,6 @@ bool ReArchive::WriteFile(const std::filesystem::path& archive, const std::files if (!std::filesystem::exists(archive)) return false; - if (std::filesystem::is_directory(archive)) - return false; - // Busy-wait. while (locked.contains(archive)) {} locked.insert(archive); @@ -146,9 +143,7 @@ bool ReArchive::WriteFile(const std::filesystem::path& archive, const std::files auto header = GetHeader(buffer.data()); auto file_table = GetFileTable(header, in); - auto file_entries = file_table.GetEntries(); - auto value = file_entries.find(file_path); - if (value != file_entries.end()) + if (file_table.Contains(file_path)) return false; in.close(); @@ -210,10 +205,10 @@ bool ReArchive::OverwriteFile(const std::filesystem::path& archive, const std::f const FileEntry* target = nullptr; auto file_entries = file_table.GetEntries(); - auto value = file_entries.find(file_path); - if (value != file_entries.end()) + auto value = file_entries->find(file_path); + if (value != file_entries->end()) target = &value->second; - + if (!target) return false; @@ -265,8 +260,8 @@ std::vector ReArchive::ReadFile(const std::filesystem::path& arch const FileEntry* target = nullptr; auto file_entries = file_table.GetEntries(); - auto value = file_entries.find(file_path); - if (value != file_entries.end()) + auto value = file_entries->find(file_path); + if (value != file_entries->end()) target = &value->second; if (!target) @@ -317,11 +312,11 @@ bool ReArchive::EraseFile(const std::filesystem::path& archive, const std::files return false; auto file_entries = current_file_table.GetEntries(); - auto value = file_entries.find(file_path); - if (value != file_entries.end()) - file_entries.erase(value); + auto value = file_entries->find(file_path); + if (value != file_entries->end()) + file_entries->erase(value); - for (auto& e : file_entries) { + for (auto& e : *file_entries) { auto file_buffer = ReadFile(archive, e.first); if (!WriteFile(archive.string() + ".tmp", e.first, file_buffer.data(), (int64_t) file_buffer.size())) { std::filesystem::remove(archive.string() + ".tmp"); diff --git a/src/types/FileTable.cpp b/src/types/FileTable.cpp index 198d1b8..dcb861e 100644 --- a/src/types/FileTable.cpp +++ b/src/types/FileTable.cpp @@ -18,14 +18,14 @@ void FileTable::Remove(const FileEntry& file_entry) { std::vector FileTable::Serialize(const FileTable& file_table) { auto files = file_table.GetEntries(); - int64_t count = files.size(); + int64_t count = files->size(); auto network_count = htobe64(count); std::vector result(reinterpret_cast(&network_count), reinterpret_cast(&network_count) + sizeof(network_count)); - if (files.empty()) + if (files->empty()) return result; - for (const auto& file : files) { + for (const auto& file : *files) { size_t current_size = result.size(); auto serialization = FileEntry::Serialize(file.second);