diff --git a/respak2.cpp b/respak2.cpp index 9e97f62..cc3c2fc 100644 --- a/respak2.cpp +++ b/respak2.cpp @@ -2,10 +2,20 @@ #include #include #include +#include using namespace std; namespace fs = std::filesystem; +struct file_t +{ + string path; + uint32_t size; + uint32_t offset; +}; + +vector toc; + void printHelp() { cout << "Usage: respak2 " << endl; @@ -21,6 +31,24 @@ void printErrorAndExit(string errorMsg) { exit(1); } +bool createDirectories(const string& dirName) +{ + fs::path path(dirName); + + std::error_code err; + if (!fs::create_directories(path.remove_filename(), err)) + { + if (fs::exists(path.remove_filename())) + { + return true; // the folder probably already existed + } + + printf("createDirectories: FAILED to create [%s], err:%s\n", dirName.c_str(), err.message().c_str()); + return false; + } + return true; +} + void printDirectory(string path, int tabs=0) { for (const auto & entry : fs::directory_iterator(path)) @@ -31,20 +59,37 @@ void printDirectory(string path, int tabs=0) } } -void packDirectory(string path, ofstream fo, uint32_t& num_files, uint32_t& toc_index) +void packDirectory(string path, ofstream& fo, uint32_t& num_files, uint32_t& offset) { - + for (const auto & entry : fs::directory_iterator(path)) + { + if (entry.is_directory()) + packDirectory(entry.path().string(), fo, num_files, offset); + else + { + const string filename = entry.path().string(); + ifstream fi(filename, ios::binary |ios::ate); + if (!fi.is_open()) printErrorAndExit("ERROR: Error al obrir l'arxiu '"+filename+"'."); + const uint32_t size = fi.tellg(); + fi.seekg(0); + fo << fi.rdbuf(); + fi.close(); + toc.push_back({filename, size, offset}); + cout << filename << ":" << size << ":" << offset << endl; + num_files++; + offset+=size; + } + } } void doPack() { - printDirectory("data"); + //printDirectory("data"); - uint32_t num_files = 4; - uint32_t toc_offset = 512; + uint32_t num_files = 0; + uint32_t toc_offset = 12; - ofstream fo; - fo.open("data.jf2", ios::binary); + ofstream fo ("data.jf2", ios::binary); if (!fo.is_open()) printErrorAndExit("ERROR: No s'ha pogut obrir l'arxiu 'data.jf2'."); fo.write("PK2",4); fo.write( (char*)&num_files, 4 ); @@ -52,6 +97,15 @@ void doPack() packDirectory("data", fo, num_files, toc_offset); + for (auto file : toc) + { + fo.write( (char*)&file.offset, 4 ); + fo.write( (char*)&file.size, 4 ); + const uint8_t path_size = file.path.size(); + fo.write( (char*)&path_size, 1 ); + fo.write( file.path.c_str(), path_size ); + } + fo.seekp(4); fo.write( (char*)&num_files, 4 ); fo.write( (char*)&toc_offset, 4 ); @@ -61,12 +115,71 @@ void doPack() void doUnpack() { + ifstream fi ("data.jf2", ios::binary); + if (!fi.is_open()) printErrorAndExit("ERROR: No s'ha pogut obrir l'arxiu 'data.jf2'."); + char header[4]; + fi.read(header, 4); + uint32_t num_files, toc_offset; + fi.read((char*)&num_files, 4); + fi.read((char*)&toc_offset, 4); + fi.seekg(toc_offset); + for (int i=0; i