*: Various cleanup
This commit is contained in:
parent
307e92768c
commit
3786b760fe
8 changed files with 59 additions and 71 deletions
|
@ -82,10 +82,8 @@ namespace europa::io {
|
||||||
PakFileData::Variant variant_;
|
PakFileData::Variant variant_;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Repressents a package file.
|
/// Repressents a package file. Can either hold a memory buffer of contents
|
||||||
/// FIXME: Maybe make this not hold a buffer at some point,
|
/// or a filesystem path (for creating packages).
|
||||||
/// or a sumtype which can contain either buffer OR path to os file
|
|
||||||
/// (which we can then efficiently tee into)
|
|
||||||
struct PakFile {
|
struct PakFile {
|
||||||
using DataType = PakFileData;
|
using DataType = PakFileData;
|
||||||
|
|
||||||
|
@ -181,9 +179,9 @@ namespace europa::io {
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Cb>
|
template <class Visitor>
|
||||||
void Visit(const Cb& cb) {
|
auto Visit(Visitor&& cb) {
|
||||||
std::visit(cb, toc);
|
return std::visit(cb, toc);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -13,30 +13,26 @@
|
||||||
|
|
||||||
namespace europa::io {
|
namespace europa::io {
|
||||||
|
|
||||||
/**
|
/// Interface for [PakWriter] to output detailed progress information.
|
||||||
* Interface for the writer to output detailed progress information.
|
|
||||||
*/
|
|
||||||
struct PakProgressReportSink {
|
struct PakProgressReportSink {
|
||||||
|
|
||||||
struct PakEvent {
|
struct PakEvent {
|
||||||
enum class Type {
|
enum class EventCode {
|
||||||
FillInHeader, ///< Filling in header
|
FillInHeader, /// Filling in header.
|
||||||
WritingHeader, ///< Writing header
|
WritingHeader, /// Writing header.
|
||||||
|
WritingToc /// Writing archive TOC.
|
||||||
WritingToc ///< Writing archive TOC
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Type type;
|
EventCode eventCode;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct FileEvent {
|
struct FileEvent {
|
||||||
enum class Type {
|
enum class EventCode {
|
||||||
FileBeginWrite, ///< File has began write to package
|
FileWriteBegin, /// File has began write to package
|
||||||
FileEndWrite, ///< File writing finished
|
FileWriteEnd, /// File has been written to package
|
||||||
};
|
};
|
||||||
|
|
||||||
Type type;
|
EventCode eventCode;
|
||||||
std::string filename;
|
const std::string& targetFileName;
|
||||||
};
|
};
|
||||||
|
|
||||||
virtual ~PakProgressReportSink() = default;
|
virtual ~PakProgressReportSink() = default;
|
||||||
|
@ -45,7 +41,6 @@ namespace europa::io {
|
||||||
virtual void OnEvent(const FileEvent& event) = 0;
|
virtual void OnEvent(const FileEvent& event) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
} // namespace europa::io
|
} // namespace europa::io
|
||||||
|
|
||||||
#endif // EUROPA_IO_PAKPROGRESSREPORTSINK_H
|
#endif // EUROPA_IO_PAKPROGRESSREPORTSINK_H
|
||||||
|
|
|
@ -15,14 +15,14 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
#include <variant>
|
|
||||||
|
|
||||||
namespace europa::io {
|
namespace europa::io {
|
||||||
|
|
||||||
|
/// Reader for Europa package files (.pak).
|
||||||
struct PakReader {
|
struct PakReader {
|
||||||
using MapType = std::unordered_map<std::string, PakFile>;
|
using MapType = std::unordered_map<std::string, PakFile>;
|
||||||
|
|
||||||
|
/// 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 PakReader(std::istream& is);
|
||||||
|
|
||||||
void ReadData();
|
void ReadData();
|
||||||
|
@ -42,10 +42,12 @@ namespace europa::io {
|
||||||
const MapType& GetFiles() const;
|
const MapType& GetFiles() const;
|
||||||
|
|
||||||
// implement in cpp later, lazy and just wanna get this out :vvv
|
// implement in cpp later, lazy and just wanna get this out :vvv
|
||||||
const structs::PakHeaderVariant& GetHeader() const { return header; }
|
const structs::PakHeaderVariant& GetHeader() const {
|
||||||
|
return header;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
template<class T>
|
template <class T>
|
||||||
void ReadData_Impl();
|
void ReadData_Impl();
|
||||||
|
|
||||||
std::istream& stream;
|
std::istream& stream;
|
||||||
|
|
|
@ -29,6 +29,12 @@ namespace europa::io {
|
||||||
|
|
||||||
using FlattenedType = std::pair<std::string, PakFile>;
|
using FlattenedType = std::pair<std::string, PakFile>;
|
||||||
|
|
||||||
|
constexpr PakWriter() = default;
|
||||||
|
|
||||||
|
PakWriter(structs::PakVersion version) {
|
||||||
|
SetVersion(version);
|
||||||
|
}
|
||||||
|
|
||||||
/// Initalize for the given package version.
|
/// Initalize for the given package version.
|
||||||
void SetVersion(structs::PakVersion version);
|
void SetVersion(structs::PakVersion version);
|
||||||
|
|
||||||
|
|
|
@ -16,9 +16,7 @@
|
||||||
|
|
||||||
namespace europa::io {
|
namespace europa::io {
|
||||||
|
|
||||||
/**
|
/// Reader for PS2 Europa .tex files.
|
||||||
* Reader for PS2 Europa .tex files.
|
|
||||||
*/
|
|
||||||
struct YatfReader {
|
struct YatfReader {
|
||||||
explicit YatfReader(std::istream& is);
|
explicit YatfReader(std::istream& is);
|
||||||
|
|
||||||
|
@ -39,10 +37,6 @@ namespace europa::io {
|
||||||
bool invalid { false };
|
bool invalid { false };
|
||||||
|
|
||||||
structs::YatfHeader header;
|
structs::YatfHeader header;
|
||||||
|
|
||||||
/**
|
|
||||||
* converted image.
|
|
||||||
*/
|
|
||||||
pixel::RgbaImage image;
|
pixel::RgbaImage image;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -81,7 +81,7 @@ namespace europa::io {
|
||||||
|
|
||||||
// Write all the file data
|
// Write all the file data
|
||||||
for(auto& [filename, file] : sortedFiles) {
|
for(auto& [filename, file] : sortedFiles) {
|
||||||
sink.OnEvent({ PakProgressReportSink::FileEvent::Type::FileBeginWrite,
|
sink.OnEvent({ PakProgressReportSink::FileEvent::EventCode::FileWriteBegin,
|
||||||
filename });
|
filename });
|
||||||
|
|
||||||
// Update the offset to where we currently are, since we will be writing the file there
|
// Update the offset to where we currently are, since we will be writing the file there
|
||||||
|
@ -95,6 +95,7 @@ namespace europa::io {
|
||||||
// For filesystem paths, we open the file and then tee it into the package file
|
// For filesystem paths, we open the file and then tee it into the package file
|
||||||
// effiently saving a lot of memory usage when packing (trading off some IO overhead,
|
// effiently saving a lot of memory usage when packing (trading off some IO overhead,
|
||||||
// but hey.)
|
// but hey.)
|
||||||
|
// For buffers, we just write the buffer.
|
||||||
|
|
||||||
// clang-format off
|
// clang-format off
|
||||||
fileData.Visit(overloaded {
|
fileData.Visit(overloaded {
|
||||||
|
@ -119,13 +120,13 @@ namespace europa::io {
|
||||||
AlignBy(os.tellp(), kCDSectorSize),
|
AlignBy(os.tellp(), kCDSectorSize),
|
||||||
std::istream::beg);
|
std::istream::beg);
|
||||||
|
|
||||||
sink.OnEvent({ PakProgressReportSink::FileEvent::Type::FileEndWrite,
|
sink.OnEvent({ PakProgressReportSink::FileEvent::EventCode::FileWriteEnd,
|
||||||
filename });
|
filename });
|
||||||
}
|
}
|
||||||
|
|
||||||
pakHeader.tocOffset = os.tellp();
|
pakHeader.tocOffset = os.tellp();
|
||||||
|
|
||||||
sink.OnEvent({ PakProgressReportSink::PakEvent::Type::WritingToc });
|
sink.OnEvent({ PakProgressReportSink::PakEvent::EventCode::WritingToc });
|
||||||
|
|
||||||
// Write the TOC
|
// Write the TOC
|
||||||
for(auto& [filename, file] : sortedFiles) {
|
for(auto& [filename, file] : sortedFiles) {
|
||||||
|
@ -137,14 +138,14 @@ namespace europa::io {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
sink.OnEvent({ PakProgressReportSink::PakEvent::Type::FillInHeader });
|
sink.OnEvent({ PakProgressReportSink::PakEvent::EventCode::FillInHeader });
|
||||||
|
|
||||||
// Fill out the rest of the header.
|
// Fill out the rest of the header.
|
||||||
pakHeader.fileCount = sortedFiles.size();
|
pakHeader.fileCount = sortedFiles.size();
|
||||||
pakHeader.tocSize = static_cast<std::uint32_t>(os.tellp()) - (pakHeader.tocOffset - 1);
|
pakHeader.tocSize = static_cast<std::uint32_t>(os.tellp()) - (pakHeader.tocOffset - 1);
|
||||||
pakHeader.creationUnixTime = 132890732;
|
pakHeader.creationUnixTime = 132890732;
|
||||||
|
|
||||||
sink.OnEvent({ PakProgressReportSink::PakEvent::Type::WritingHeader });
|
sink.OnEvent({ PakProgressReportSink::PakEvent::EventCode::WritingHeader });
|
||||||
|
|
||||||
// As the last step, write it.
|
// As the last step, write it.
|
||||||
os.seekp(0, std::ostream::beg);
|
os.seekp(0, std::ostream::beg);
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <tasks/CreateTask.hpp>
|
#include <tasks/CreateTask.hpp>
|
||||||
#include <Utils.hpp>
|
#include <Utils.hpp>
|
||||||
|
|
||||||
#include "europa/io/PakFile.hpp"
|
#include "europa/io/PakFile.hpp"
|
||||||
|
|
||||||
namespace eupak::tasks {
|
namespace eupak::tasks {
|
||||||
|
@ -30,8 +31,8 @@ namespace eupak::tasks {
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnEvent(const PakEvent& event) override {
|
void OnEvent(const PakEvent& event) override {
|
||||||
using enum PakEvent::Type;
|
using enum PakEvent::EventCode;
|
||||||
switch(event.type) {
|
switch(event.eventCode) {
|
||||||
case WritingHeader:
|
case WritingHeader:
|
||||||
progress.set_option(indicators::option::PostfixText { "Writing header" });
|
progress.set_option(indicators::option::PostfixText { "Writing header" });
|
||||||
progress.print_progress();
|
progress.print_progress();
|
||||||
|
@ -50,15 +51,15 @@ namespace eupak::tasks {
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnEvent(const FileEvent& event) override {
|
void OnEvent(const FileEvent& event) override {
|
||||||
using enum FileEvent::Type;
|
using enum FileEvent::EventCode;
|
||||||
switch(event.type) {
|
switch(event.eventCode) {
|
||||||
case FileBeginWrite:
|
case FileWriteBegin:
|
||||||
progress.set_option(indicators::option::PostfixText { "Writing " + event.filename });
|
progress.set_option(indicators::option::PostfixText { "Writing " + event.targetFileName });
|
||||||
progress.print_progress();
|
progress.print_progress();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FileEndWrite:
|
case FileWriteEnd:
|
||||||
progress.set_option(indicators::option::PostfixText { "Written " + event.filename });
|
progress.set_option(indicators::option::PostfixText { "Written " + event.targetFileName });
|
||||||
progress.tick();
|
progress.tick();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -77,10 +78,6 @@ namespace eupak::tasks {
|
||||||
};
|
};
|
||||||
|
|
||||||
int CreateTask::Run(Arguments&& args) {
|
int CreateTask::Run(Arguments&& args) {
|
||||||
europa::io::PakWriter writer;
|
|
||||||
|
|
||||||
writer.SetVersion(args.pakVersion);
|
|
||||||
|
|
||||||
auto currFile = 0;
|
auto currFile = 0;
|
||||||
auto fileCount = 0;
|
auto fileCount = 0;
|
||||||
|
|
||||||
|
@ -137,7 +134,7 @@ namespace eupak::tasks {
|
||||||
// Setup other stuff like modtime
|
// Setup other stuff like modtime
|
||||||
file.Visit([&](auto& tocEntry) {
|
file.Visit([&](auto& tocEntry) {
|
||||||
// Need to figure out why this is broken and fucked up
|
// Need to figure out why this is broken and fucked up
|
||||||
//auto casted = std::chrono::clock_cast<std::chrono::system_clock>(lastModified);
|
// auto casted = std::chrono::clock_cast<std::chrono::system_clock>(lastModified);
|
||||||
auto seconds = std::chrono::time_point_cast<std::chrono::seconds>(lastModified);
|
auto seconds = std::chrono::time_point_cast<std::chrono::seconds>(lastModified);
|
||||||
tocEntry.creationUnixTime = static_cast<std::uint32_t>(seconds.time_since_epoch().count());
|
tocEntry.creationUnixTime = static_cast<std::uint32_t>(seconds.time_since_epoch().count());
|
||||||
});
|
});
|
||||||
|
@ -156,9 +153,10 @@ namespace eupak::tasks {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
CreateArchiveReportSink sink(fileCount);
|
CreateArchiveReportSink reportSink(fileCount);
|
||||||
|
europa::io::PakWriter writer(args.pakVersion);
|
||||||
|
|
||||||
writer.Write(ofs, std::move(files), sink);
|
writer.Write(ofs, std::move(files), reportSink);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,13 +6,11 @@
|
||||||
// SPDX-License-Identifier: LGPL-3.0-or-later
|
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||||
//
|
//
|
||||||
|
|
||||||
#include <tasks/InfoTask.hpp>
|
|
||||||
|
|
||||||
#include <europa/io/PakReader.hpp>
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <europa/io/PakReader.hpp>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <tasks/InfoTask.hpp>
|
||||||
#include <Utils.hpp>
|
#include <Utils.hpp>
|
||||||
|
|
||||||
namespace eupak::tasks {
|
namespace eupak::tasks {
|
||||||
|
@ -36,7 +34,7 @@ namespace eupak::tasks {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::visit([&](auto& header){
|
std::visit([&](auto& header) {
|
||||||
std::string version;
|
std::string version;
|
||||||
if constexpr(std::decay_t<decltype(header)>::VERSION == europa::structs::PakVersion::Ver3)
|
if constexpr(std::decay_t<decltype(header)>::VERSION == europa::structs::PakVersion::Ver3)
|
||||||
version = "Version 3 (PMDL)";
|
version = "Version 3 (PMDL)";
|
||||||
|
@ -45,25 +43,21 @@ namespace eupak::tasks {
|
||||||
else if constexpr(std::decay_t<decltype(header)>::VERSION == europa::structs::PakVersion::Ver5)
|
else if constexpr(std::decay_t<decltype(header)>::VERSION == europa::structs::PakVersion::Ver5)
|
||||||
version = "Version 5 (Jedi Starfighter)";
|
version = "Version 5 (Jedi Starfighter)";
|
||||||
|
|
||||||
|
|
||||||
std::cout << "Archive " << args.inputPath << ":\n";
|
std::cout << "Archive " << args.inputPath << ":\n";
|
||||||
std::cout << " Created: " << FormatUnixTimestamp(header.creationUnixTime, DATE_FORMAT) << '\n';
|
std::cout << " Created: " << FormatUnixTimestamp(header.creationUnixTime, DATE_FORMAT) << '\n';
|
||||||
std::cout << " Version: " << version << '\n';
|
std::cout << " Version: " << version << '\n';
|
||||||
std::cout << " Size: " << FormatUnit(header.tocOffset + header.tocSize) << '\n';
|
std::cout << " Size: " << FormatUnit(header.tocOffset + header.tocSize) << '\n';
|
||||||
std::cout << " File Count: " << header.fileCount << " files\n";
|
std::cout << " File Count: " << header.fileCount << " files\n";
|
||||||
|
},
|
||||||
}, reader.GetHeader());
|
reader.GetHeader());
|
||||||
|
|
||||||
|
|
||||||
// Print a detailed file list if verbose.
|
// Print a detailed file list if verbose.
|
||||||
if(args.verbose) {
|
if(args.verbose) {
|
||||||
for(auto& [ filename, file ] : reader.GetFiles()) {
|
for(auto& [filename, file] : reader.GetFiles()) {
|
||||||
std::cout << "File \"" << filename << "\":\n";
|
std::cout << "File \"" << filename << "\":\n";
|
||||||
file.Visit([&](auto& tocEntry) {
|
file.Visit([&](auto& tocEntry) {
|
||||||
|
std::cout << " Created: " << FormatUnixTimestamp(tocEntry.creationUnixTime, DATE_FORMAT) << '\n';
|
||||||
std::cout << " Created: " << FormatUnixTimestamp(tocEntry.creationUnixTime, DATE_FORMAT) << '\n';
|
std::cout << " Size: " << FormatUnit(tocEntry.size) << '\n';
|
||||||
std::cout << " Size: " << FormatUnit(tocEntry.size) << '\n';
|
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -71,4 +65,4 @@ namespace eupak::tasks {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
} // namespace eupak::tasks
|
Loading…
Reference in a new issue