From 84c537c873020f1ed898a4c55db23170ce984fa0 Mon Sep 17 00:00:00 2001 From: modeco80 Date: Wed, 15 Jan 2025 21:50:34 -0500 Subject: [PATCH] libeuropa/io: Split pak into new subdirectory Namespaces exist. Use them, perhaps. --- .../europa/io/{PakFile.hpp => pak/File.hpp} | 34 ++++++++++--------- .../io/{PakReader.hpp => pak/Reader.hpp} | 13 ++++--- .../io/{PakWriter.hpp => pak/Writer.hpp} | 18 +++++----- .../WriterProgressReportSink.hpp} | 6 ++-- src/libeuropa/CMakeLists.txt | 4 +-- .../io/{PakReader.cpp => pak/Reader.cpp} | 30 ++++++++-------- .../io/{PakWriter.cpp => pak/Writer.cpp} | 26 +++++++------- src/tools/eupak/tasks/CreateTask.cpp | 29 ++++++++-------- src/tools/eupak/tasks/CreateTask.hpp | 3 +- src/tools/eupak/tasks/ExtractTask.cpp | 4 +-- src/tools/eupak/tasks/ExtractTask.hpp | 3 +- src/tools/eupak/tasks/InfoTask.cpp | 11 +++--- src/tools/eupak/tasks/InfoTask.hpp | 3 +- src/tools/eupak/tasks/Task.cpp | 8 +++++ src/tools/eupak/tasks/Task.hpp | 9 +++-- 15 files changed, 102 insertions(+), 99 deletions(-) rename include/europa/io/{PakFile.hpp => pak/File.hpp} (87%) rename include/europa/io/{PakReader.hpp => pak/Reader.hpp} (85%) rename include/europa/io/{PakWriter.hpp => pak/Writer.hpp} (74%) rename include/europa/io/{PakProgressReportSink.hpp => pak/WriterProgressReportSink.hpp} (89%) rename src/libeuropa/io/{PakReader.cpp => pak/Reader.cpp} (79%) rename src/libeuropa/io/{PakWriter.cpp => pak/Writer.cpp} (84%) diff --git a/include/europa/io/PakFile.hpp b/include/europa/io/pak/File.hpp similarity index 87% rename from include/europa/io/PakFile.hpp rename to include/europa/io/pak/File.hpp index ef8c012..7d5a862 100644 --- a/include/europa/io/PakFile.hpp +++ b/include/europa/io/pak/File.hpp @@ -18,13 +18,13 @@ #include #include -namespace europa::io { +namespace europa::io::pak { - struct PakReader; - struct PakWriter; + struct Reader; + struct Writer; - /// sumtype - struct PakFileData { + /// sumtype for package file data + struct FileData { // clang-format off using Variant = std::variant< // File data @@ -35,14 +35,14 @@ namespace europa::io { >; // clang-format on - static PakFileData InitAsBuffer(std::vector&& buffer) { - return PakFileData { + static FileData InitAsBuffer(std::vector&& buffer) { + return FileData { .variant_ = Variant(std::move(buffer)) }; } - static PakFileData InitAsPath(const std::filesystem::path& path) { - return PakFileData { + static FileData InitAsPath(const std::filesystem::path& path) { + return FileData { .variant_ = Variant(path) }; } @@ -80,13 +80,13 @@ namespace europa::io { } // private: - PakFileData::Variant variant_; + FileData::Variant variant_; }; /// Repressents a package file. Can either hold a memory buffer of contents /// or a filesystem path (for creating packages). - struct PakFile { - using DataType = PakFileData; + struct File { + using DataType = FileData; template void InitWithExistingTocEntry(const T& value) { @@ -194,13 +194,15 @@ namespace europa::io { } private: - friend PakReader; - friend PakWriter; + // FIXME: Are these `friend`s required? I don't think so, + // we use public APIs now. + friend Reader; + friend Writer; - std::optional fileData; + std::optional fileData; structs::PakTocEntryVariant toc; }; -} // namespace europa::io +} // namespace europa::io::pak #endif // EUROPA_IO_PAKFILE_H diff --git a/include/europa/io/PakReader.hpp b/include/europa/io/pak/Reader.hpp similarity index 85% rename from include/europa/io/PakReader.hpp rename to include/europa/io/pak/Reader.hpp index b4cce2b..18388e3 100644 --- a/include/europa/io/PakReader.hpp +++ b/include/europa/io/pak/Reader.hpp @@ -9,22 +9,21 @@ #ifndef EUROPA_IO_PAKREADER_H #define EUROPA_IO_PAKREADER_H -#include +#include #include #include #include -#include -namespace europa::io { +namespace europa::io::pak { /// Reader for Europa package files (.pak). - struct PakReader { - using FlatType = std::pair; + struct Reader { + using FlatType = std::pair; using MapType = std::vector; /// Constructor. Takes in a input stream to read pak data from. /// This stream should only be used by the PakReader, nothing else. - explicit PakReader(std::istream& is); + explicit Reader(std::istream& is); /// Reads the header and the file TOC. /// This function should be called first. @@ -61,6 +60,6 @@ namespace europa::io { MapType files; }; -} // namespace europa::io +} // namespace europa::io::pak #endif // EUROPA_IO_PAKREADER_H diff --git a/include/europa/io/PakWriter.hpp b/include/europa/io/pak/Writer.hpp similarity index 74% rename from include/europa/io/PakWriter.hpp rename to include/europa/io/pak/Writer.hpp index 75a57bb..834891e 100644 --- a/include/europa/io/PakWriter.hpp +++ b/include/europa/io/pak/Writer.hpp @@ -9,29 +9,29 @@ #ifndef EUROPA_IO_PAKWRITER_H #define EUROPA_IO_PAKWRITER_H -#include -#include +#include +#include #include #include #include #include "europa/structs/Pak.hpp" -namespace europa::io { +namespace europa::io::pak { /// A efficient writer for Europa package (.pak) files. - struct PakWriter { + struct Writer { /// Vocabulary type for making sector alignment stuff a bit easier to see. enum class SectorAlignment { DoNotAlign, /// Do not align to a sector boundary Align /// Align to a sector boundary }; - using FlattenedType = std::pair; + using FlattenedType = std::pair; - constexpr PakWriter() = default; + constexpr Writer() = default; - PakWriter(structs::PakVersion version) { + Writer(structs::PakVersion version) { SetVersion(version); } @@ -42,11 +42,11 @@ namespace europa::io { /// [vec] is all files which should be packaged /// [sink] is a implementation of PakProgressReportsSink which should get events (TODO: Make this optional) /// [sectorAlignment] controls sector alignment. It is ignored unless the package's version is [structs::PakVersion::Ver5]. - void Write(std::ostream& os, std::vector&& vec, PakProgressReportSink& sink, SectorAlignment sectorAlignment = SectorAlignment::DoNotAlign); + void Write(std::ostream& os, std::vector&& vec, WriterProgressReportSink& sink, SectorAlignment sectorAlignment = SectorAlignment::DoNotAlign); private: template - void WriteImpl(std::ostream& os, std::vector&& vec, PakProgressReportSink& sink, SectorAlignment sectorAlignment); + void WriteImpl(std::ostream& os, std::vector&& vec, WriterProgressReportSink& sink, SectorAlignment sectorAlignment); structs::PakVersion version {}; }; diff --git a/include/europa/io/PakProgressReportSink.hpp b/include/europa/io/pak/WriterProgressReportSink.hpp similarity index 89% rename from include/europa/io/PakProgressReportSink.hpp rename to include/europa/io/pak/WriterProgressReportSink.hpp index 751da2f..b77f380 100644 --- a/include/europa/io/PakProgressReportSink.hpp +++ b/include/europa/io/pak/WriterProgressReportSink.hpp @@ -11,10 +11,10 @@ #include -namespace europa::io { +namespace europa::io::pak { /// Interface for [PakWriter] to output detailed progress information. - struct PakProgressReportSink { + struct WriterProgressReportSink { struct PakEvent { enum class EventCode { FillInHeader, /// Filling in header. @@ -35,7 +35,7 @@ namespace europa::io { const std::string& targetFileName; }; - virtual ~PakProgressReportSink() = default; + virtual ~WriterProgressReportSink() = default; virtual void OnEvent(const PakEvent& event) = 0; virtual void OnEvent(const FileEvent& event) = 0; diff --git a/src/libeuropa/CMakeLists.txt b/src/libeuropa/CMakeLists.txt index cdcd8db..50f05e4 100644 --- a/src/libeuropa/CMakeLists.txt +++ b/src/libeuropa/CMakeLists.txt @@ -11,8 +11,8 @@ add_library(europa io/StreamUtils.cpp # Pak IO - io/PakReader.cpp - io/PakWriter.cpp + io/pak/Reader.cpp + io/pak/Writer.cpp # Yatf IO io/YatfReader.cpp diff --git a/src/libeuropa/io/PakReader.cpp b/src/libeuropa/io/pak/Reader.cpp similarity index 79% rename from src/libeuropa/io/PakReader.cpp rename to src/libeuropa/io/pak/Reader.cpp index f863e4e..ce1e075 100644 --- a/src/libeuropa/io/PakReader.cpp +++ b/src/libeuropa/io/pak/Reader.cpp @@ -9,21 +9,21 @@ #include #include #include -#include +#include +#include #include #include -#include "europa/io/PakFile.hpp" -#include "StreamUtils.h" +#include "../StreamUtils.h" -namespace europa::io { +namespace europa::io::pak { - PakReader::PakReader(std::istream& is) + Reader::Reader(std::istream& is) : stream(is) { } template - void PakReader::ReadData_Impl() { + void Reader::ReadData_Impl() { auto header_type = impl::ReadStreamType(stream); if(!header_type.Valid()) { @@ -39,7 +39,7 @@ namespace europa::io { // // Read this in first. auto filename = impl::ReadPString(stream); - auto file = PakFile {}; + auto file = File {}; if constexpr(std::is_same_v) { // Version 5 supports sector aligned packages which have an additional field in them // so we need to handle it here @@ -59,7 +59,7 @@ namespace europa::io { header = header_type; } - void PakReader::ReadHeaderAndTOC() { + void Reader::ReadHeaderAndTOC() { auto commonHeader = impl::ReadStreamType(stream); stream.seekg(0, std::istream::beg); @@ -78,13 +78,13 @@ namespace europa::io { } } - void PakReader::ReadFiles() { + void Reader::ReadFiles() { for(auto& [filename, file] : files) ReadFile(filename); } - void PakReader::ReadFile(const std::string& file) { - auto it = std::find_if(files.begin(), files.end(), [&file](PakReader::FlatType& fl) { return fl.first == file; }); + void Reader::ReadFile(const std::string& file) { + auto it = std::find_if(files.begin(), files.end(), [&file](Reader::FlatType& fl) { return fl.first == file; }); if(it == files.end()) return; @@ -104,16 +104,16 @@ namespace europa::io { if(!stream) throw std::runtime_error("Stream went bad while trying to read file"); - auto data = PakFileData::InitAsBuffer(std::move(buffer)); + auto data = FileData::InitAsBuffer(std::move(buffer)); fileObject.SetData(std::move(data)); } - PakReader::MapType& PakReader::GetFiles() { + Reader::MapType& Reader::GetFiles() { return files; } - const PakReader::MapType& PakReader::GetFiles() const { + const Reader::MapType& Reader::GetFiles() const { return files; } -} // namespace europa::io \ No newline at end of file +} // namespace europa::io::pak \ No newline at end of file diff --git a/src/libeuropa/io/PakWriter.cpp b/src/libeuropa/io/pak/Writer.cpp similarity index 84% rename from src/libeuropa/io/PakWriter.cpp rename to src/libeuropa/io/pak/Writer.cpp index 384d28f..0b2bb48 100644 --- a/src/libeuropa/io/PakWriter.cpp +++ b/src/libeuropa/io/pak/Writer.cpp @@ -8,7 +8,8 @@ #include #include -#include +#include +#include #include #include #include @@ -18,17 +19,16 @@ #include #include -#include "europa/structs/Pak.hpp" -#include "StreamUtils.h" +#include "../StreamUtils.h" -namespace europa::io { +namespace europa::io::pak { - void PakWriter::SetVersion(structs::PakVersion version) { + void Writer::SetVersion(structs::PakVersion version) { // for now. this->version = version; } - void PakWriter::Write(std::ostream& os, std::vector&& vec, PakProgressReportSink& sink, SectorAlignment sectorAlignment) { + void Writer::Write(std::ostream& os, std::vector&& vec, WriterProgressReportSink& sink, SectorAlignment sectorAlignment) { // Depending on the version, do a mix of runtime/compile-time dispatch to the right // package format version we have been told to write. switch(version) { @@ -47,7 +47,7 @@ namespace europa::io { } template - void PakWriter::WriteImpl(std::ostream& os, std::vector&& vec, PakProgressReportSink& sink, SectorAlignment sectorAlignment) { + void Writer::WriteImpl(std::ostream& os, std::vector&& vec, WriterProgressReportSink& sink, SectorAlignment sectorAlignment) { std::vector sortedFiles = std::move(vec); THeader pakHeader {}; @@ -82,7 +82,7 @@ namespace europa::io { // Write all the file data for(auto& [filename, file] : sortedFiles) { - sink.OnEvent({ PakProgressReportSink::FileEvent::EventCode::FileWriteBegin, + sink.OnEvent({ WriterProgressReportSink::FileEvent::EventCode::FileWriteBegin, filename }); // Update the offset to where we currently are, since we will be writing the file there @@ -129,13 +129,13 @@ namespace europa::io { os.seekp(util::AlignBy(static_cast(os.tellp()), util::kCDSectorSize), std::istream::beg); } - sink.OnEvent({ PakProgressReportSink::FileEvent::EventCode::FileWriteEnd, + sink.OnEvent({ WriterProgressReportSink::FileEvent::EventCode::FileWriteEnd, filename }); } pakHeader.tocOffset = os.tellp(); - sink.OnEvent({ PakProgressReportSink::PakEvent::EventCode::WritingToc }); + sink.OnEvent({ WriterProgressReportSink::PakEvent::EventCode::WritingToc }); #if 0 // Sort for toc stuff? idk @@ -154,7 +154,7 @@ namespace europa::io { }); } - sink.OnEvent({ PakProgressReportSink::PakEvent::EventCode::FillInHeader }); + sink.OnEvent({ WriterProgressReportSink::PakEvent::EventCode::FillInHeader }); // Fill out the rest of the header. pakHeader.fileCount = sortedFiles.size(); @@ -164,11 +164,11 @@ namespace europa::io { auto now = std::chrono::system_clock::now(); pakHeader.creationUnixTime = static_cast(std::chrono::time_point_cast(now).time_since_epoch().count()); - sink.OnEvent({ PakProgressReportSink::PakEvent::EventCode::WritingHeader }); + sink.OnEvent({ WriterProgressReportSink::PakEvent::EventCode::WritingHeader }); // As the last step, write it. os.seekp(0, std::ostream::beg); impl::WriteStreamType(os, pakHeader); } -} // namespace europa::io \ No newline at end of file +} // namespace europa::io::pak \ No newline at end of file diff --git a/src/tools/eupak/tasks/CreateTask.cpp b/src/tools/eupak/tasks/CreateTask.cpp index 7982950..79bea7e 100644 --- a/src/tools/eupak/tasks/CreateTask.cpp +++ b/src/tools/eupak/tasks/CreateTask.cpp @@ -8,7 +8,9 @@ #include #include -#include +#include +#include +#include #include #include #include @@ -17,15 +19,14 @@ #include #include "argparse/argparse.hpp" -#include "europa/io/PakFile.hpp" #include "europa/structs/Pak.hpp" #include "tasks/Task.hpp" namespace eupak::tasks { - struct CreateArchiveReportSink : public europa::io::PakProgressReportSink { + struct CreateArchiveReportSink : public eio::pak::WriterProgressReportSink { CreateArchiveReportSink(int fileCount = 0) - : europa::io::PakProgressReportSink() { + : eio::pak::WriterProgressReportSink() { indicators::show_console_cursor(false); progress.set_option(indicators::option::MaxProgress { fileCount }); } @@ -143,8 +144,8 @@ namespace eupak::tasks { auto& args = currentArgs; args.verbose = parser.get("--verbose"); - args.inputDirectory = eupak::fs::path(parser.get("--directory")); - args.outputFile = eupak::fs::path(parser.get("output")); + args.inputDirectory = fs::path(parser.get("--directory")); + args.outputFile = fs::path(parser.get("output")); if(parser.is_used("--archive-version")) { const auto& versionStr = parser.get("--archive-version"); @@ -156,12 +157,12 @@ namespace eupak::tasks { return 1; } } else { - args.pakVersion = europa::structs::PakVersion::Ver4; + args.pakVersion = estructs::PakVersion::Ver4; } args.sectorAligned = parser.get("--sector-aligned"); - if(args.sectorAligned && args.pakVersion != eupak::estructs::PakVersion::Ver5) { + if(args.sectorAligned && args.pakVersion != estructs::PakVersion::Ver5) { std::cout << "Error: --sector-aligned is only valid for creating a package with \"-V jedistarfighter\".\n" << parser; return 1; @@ -212,7 +213,7 @@ namespace eupak::tasks { // TODO: use time to write in the header // also: is there any point to verbosity? could add archive written size ig - std::vector files; + std::vector files; files.reserve(fileCount); for(auto& ent : fs::recursive_directory_iterator(args.inputDirectory)) { @@ -229,8 +230,8 @@ namespace eupak::tasks { progress.set_option(indicators::option::PostfixText { relativePathName + " (" + std::to_string(currFile + 1) + '/' + std::to_string(fileCount) + ")" }); - eio::PakFile file; - eio::PakFile::DataType pakData = eio::PakFileData::InitAsPath(ent.path()); + eio::pak::File file; + eio::pak::FileData pakData = eio::pak::FileData::InitAsPath(ent.path()); file.InitAs(args.pakVersion, args.sectorAligned); @@ -260,11 +261,11 @@ namespace eupak::tasks { } CreateArchiveReportSink reportSink(fileCount); - eio::PakWriter writer(args.pakVersion); + eio::pak::Writer writer(args.pakVersion); - using enum eio::PakWriter::SectorAlignment; + using enum eio::pak::Writer::SectorAlignment; - eio::PakWriter::SectorAlignment alignment = DoNotAlign; + eio::pak::Writer::SectorAlignment alignment = DoNotAlign; if(args.sectorAligned) alignment = Align; diff --git a/src/tools/eupak/tasks/CreateTask.hpp b/src/tools/eupak/tasks/CreateTask.hpp index 20f4002..044738d 100644 --- a/src/tools/eupak/tasks/CreateTask.hpp +++ b/src/tools/eupak/tasks/CreateTask.hpp @@ -9,12 +9,11 @@ #ifndef EUROPA_EUPAK_TASKS_CREATETASK_HPP #define EUROPA_EUPAK_TASKS_CREATETASK_HPP +#include #include #include #include -#include "argparse/argparse.hpp" - namespace eupak::tasks { struct CreateTask : ITask { diff --git a/src/tools/eupak/tasks/ExtractTask.cpp b/src/tools/eupak/tasks/ExtractTask.cpp index 30337cc..4a04cb4 100644 --- a/src/tools/eupak/tasks/ExtractTask.cpp +++ b/src/tools/eupak/tasks/ExtractTask.cpp @@ -7,7 +7,7 @@ // #include -#include +#include #include #include #include @@ -82,7 +82,7 @@ namespace eupak::tasks { return 1; } - eio::PakReader reader(ifs); + eio::pak::Reader reader(ifs); reader.ReadHeaderAndTOC(); diff --git a/src/tools/eupak/tasks/ExtractTask.hpp b/src/tools/eupak/tasks/ExtractTask.hpp index 4a9eebc..8aebc46 100644 --- a/src/tools/eupak/tasks/ExtractTask.hpp +++ b/src/tools/eupak/tasks/ExtractTask.hpp @@ -10,8 +10,7 @@ #define EUROPA_EUPAK_TASKS_EXTRACTTASK_HPP #include - -#include "tasks/Task.hpp" +#include namespace eupak::tasks { diff --git a/src/tools/eupak/tasks/InfoTask.cpp b/src/tools/eupak/tasks/InfoTask.cpp index 0f0f8e2..2d4ee1e 100644 --- a/src/tools/eupak/tasks/InfoTask.cpp +++ b/src/tools/eupak/tasks/InfoTask.cpp @@ -6,17 +6,15 @@ // SPDX-License-Identifier: MIT // +#include #include -#include +#include #include #include #include #include #include -#include "argparse/argparse.hpp" -#include "europa/structs/Pak.hpp" - namespace eupak::tasks { constexpr static auto DATE_FORMAT = "%m/%d/%Y %r"; @@ -78,7 +76,7 @@ namespace eupak::tasks { return 1; } - eio::PakReader reader(ifs); + eio::pak::Reader reader(ifs); reader.ReadHeaderAndTOC(); @@ -120,10 +118,9 @@ namespace eupak::tasks { } }); } else { - file.VisitTocEntry([&](auto& tocEntry) { std::printf("%16s %10s %8s", FormatUnixTimestamp(tocEntry.creationUnixTime, DATE_FORMAT).c_str(), FormatUnit(tocEntry.size).c_str(), filename.c_str()); - + if constexpr(std::is_same_v, estructs::PakHeader_V5::TocEntry_SectorAligned>) { std::printf(" (LBA %u)", tocEntry.startLBA); } diff --git a/src/tools/eupak/tasks/InfoTask.hpp b/src/tools/eupak/tasks/InfoTask.hpp index b9711a9..c62480c 100644 --- a/src/tools/eupak/tasks/InfoTask.hpp +++ b/src/tools/eupak/tasks/InfoTask.hpp @@ -10,8 +10,7 @@ #define EUROPA_EUPAK_TASKS_INFOTASK_HPP #include - -#include "tasks/Task.hpp" +#include namespace eupak::tasks { diff --git a/src/tools/eupak/tasks/Task.cpp b/src/tools/eupak/tasks/Task.cpp index e7ae4a9..46805e8 100644 --- a/src/tools/eupak/tasks/Task.cpp +++ b/src/tools/eupak/tasks/Task.cpp @@ -1,3 +1,11 @@ +// +// EuropaTools +// +// (C) 2021-2025 modeco80 +// +// SPDX-License-Identifier: MIT +// + #include "Task.hpp" #include diff --git a/src/tools/eupak/tasks/Task.hpp b/src/tools/eupak/tasks/Task.hpp index e2ae55a..cbc9064 100644 --- a/src/tools/eupak/tasks/Task.hpp +++ b/src/tools/eupak/tasks/Task.hpp @@ -7,12 +7,11 @@ // #pragma once +#include #include #include #include -#include "argparse/argparse.hpp" - namespace eupak::tasks { /// Base-class for all eupak tasks. @@ -49,7 +48,7 @@ namespace eupak::tasks { } }; - /// Helper template to register into the [TaskFactory]. + /// Helper template to register into the [TaskFactory]. template struct TaskFactoryRegister { TaskFactoryRegister(const std::string& name) { @@ -61,8 +60,8 @@ namespace eupak::tasks { } }; - /// Registers a task. Should be put in the .cpp implementation source file of the - /// task object itself. + /// Registers a task. Should be put in the .cpp implementation source file of the + /// task object itself. #define EUPAK_REGISTER_TASK(Name, TTask) \ static ::eupak::tasks::TaskFactoryRegister __register__##TTask(Name)