3 Commits

Author SHA1 Message Date
8cab591f98 Update FileTable.h
copy constructor
2025-03-20 20:03:42 -04:00
0e17d02451 Cleanup & update 2025-03-20 19:49:34 -04:00
44c2ea3a3a Update FileTable.h
Remove TODO I forgot to remove 🤷
2025-03-19 22:11:28 -04:00
4 changed files with 50 additions and 18 deletions

View File

@@ -13,6 +13,11 @@ namespace ReArchive {
/// @returns True if success.
[[nodiscard]] bool CreateArchive(const std::filesystem::path& archive, bool use_compression = false, FileTable* running_tally = nullptr);
/// @param archive The archive on the disk.
/// @returns std::pair bool, FileTable. bool is success, FileTable is only valid if success.
/// @note *Always* check if bool is true before using the file table for anything.
[[nodiscard]] std::pair<bool, FileTable> ReadFileTable(const std::filesystem::path& archive);
/// Add a file to an archive.
/// @param archive The archive on the disk.
/// @param file_data The raw data of the file to be written.

View File

@@ -11,16 +11,18 @@ namespace ReArchive {
class ReArchive::FileTable {
protected:
// count
// TODO unordered_set so time to find a particular entry doesn't depend on the length.
std::unordered_map<std::filesystem::path, FileEntry> entries;
public:
void Append(const FileEntry& file_entry);
void Remove(const FileEntry& file_entry);
[[nodiscard]] bool Contains(std::filesystem::path& entry ) const { return entries.contains(entry); }
[[nodiscard]] std::unordered_map<std::filesystem::path, FileEntry> GetEntries() const { return entries; }
[[nodiscard]] int64_t Count() const { return entries.size(); }
public:
[[nodiscard]] static std::vector<unsigned char> Serialize(const FileTable& file_table);
public:
FileTable(const FileTable& rhs) : entries(rhs.entries) {};
FileTable(FileTable& rhs) : entries(rhs.entries) {};
FileTable() = default;
~FileTable() = default;

View File

@@ -29,4 +29,6 @@ int main() {
for (auto& e : running_tally.GetEntries())
std::cout << e.second.Path() << std::endl;
ReArchive::FileTable copy = running_tally;
}

View File

@@ -16,19 +16,6 @@ Header GetHeader(const unsigned char* archive) {
return h;
}
Header GetHeader(const std::filesystem::path& archive) {
std::ifstream file(archive, std::ios::binary);
if (!file)
throw std::runtime_error("Trying to get the header of an archive which doesn't exist?");
std::vector<unsigned char> buffer(ReArchive::Header::Size());
file.read(reinterpret_cast<char *>(buffer.data()), (int64_t) buffer.size());
file.close();
return GetHeader(buffer.data());
}
/// @param header our header.
/// @param in Our input stream to the file.
/// @note Does not close the input stream.
@@ -70,6 +57,40 @@ FileTable GetFileTable(const Header& header, std::ifstream& in) {
return result;
}
std::pair<bool, FileTable> ReArchive::ReadFileTable(const std::filesystem::path& archive) {
if (!std::filesystem::exists(archive))
return {false, {}};
// Busy-wait.
while (locked.contains(archive)) {}
locked.insert(archive);
std::ifstream in(archive, std::ios::binary);
if (!in)
return {false, {}};
in.seekg(0, std::ios::end);
if (in.tellg() < Header::Size())
return {false, {}};
in.seekg(0, std::ios::beg);
std::vector<unsigned char> buffer (Header::Size());
in.read(reinterpret_cast<char *>(buffer.data()), (int64_t) buffer.size());
if (buffer[0] != 'R' || buffer[1] != 'S' || buffer[2] != 'A')
return {false, {}};
auto header = GetHeader(buffer.data());
auto file_table = GetFileTable(header, in);
in.close();
// Remove lock.
auto position = locked.find(archive);
if (position != locked.end())
locked.erase(position);
return {true, file_table};
}
bool ReArchive::CreateArchive(const std::filesystem::path& filesystem_path, bool use_compression, FileTable* running_tally) {
if (std::filesystem::exists(filesystem_path))
return false;
@@ -301,6 +322,7 @@ bool ReArchive::EraseFile(const std::filesystem::path& archive, const std::files
auto current_header = GetHeader(buffer.data());
auto current_file_table = GetFileTable(current_header, in);
// TODO randomize the name more than that.
if (!CreateArchive(archive.string() + ".tmp", current_header.Compressed()))
return false;
@@ -329,9 +351,10 @@ bool ReArchive::EraseFile(const std::filesystem::path& archive, const std::files
if (position != locked.end())
locked.erase(position);
// TODO read the header from the file we just wrote.
if (running_tally)
*running_tally = current_file_table;
if (running_tally) {
auto result = ReadFileTable(archive);
if (result.first)
*running_tally = result.second;
}
return true;
}