- Continue en altre comp

This commit is contained in:
2023-02-13 17:52:17 +01:00
parent 952d567d07
commit ba824154a2

View File

@@ -2,10 +2,20 @@
#include <iostream>
#include <fstream>
#include <filesystem>
#include <vector>
using namespace std;
namespace fs = std::filesystem;
struct file_t
{
string path;
uint32_t size;
uint32_t offset;
};
vector<file_t> toc;
void printHelp()
{
cout << "Usage: respak2 <command>" << 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<num_files; ++i)
{
uint32_t file_offset, file_size;
fi.read( (char*)&file_offset, 4 );
fi.read( (char*)&file_size, 4 );
uint8_t path_size;
fi.read( (char*)&path_size, 1 );
char file_name[path_size+1];
fi.read( file_name, path_size );
file_name[path_size] = 0;
string filename = file_name;
// cout << filename << " : " << file_size << " : " << file_offset << endl;
toc.push_back({filename, file_size, file_offset});
}
for (auto file : toc)
{
fi.seekg(file.offset);
if (!createDirectories(file.path)) printErrorAndExit("ERROR: No s'ha pogut crear la ruta '"+file.path+"'.");
ofstream fo (file.path, ios::binary);
if (!fo.is_open()) printErrorAndExit("ERROR: No s'ha pogut obrir l'arxiu '"+file.path+"'.");
char* buffer = (char*)malloc(file.size);
fi.read(buffer, file.size);
fo.write(buffer, file.size);
fo.close();
}
fi.close();
}
void doList()
{
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<num_files; ++i)
{
uint32_t file_offset, file_size;
fi.read( (char*)&file_offset, 4 );
fi.read( (char*)&file_size, 4 );
uint8_t path_size;
fi.read( (char*)&path_size, 1 );
char file_name[path_size+1];
fi.read( file_name, path_size );
file_name[path_size] = 0;
string filename = file_name;
cout << filename << " : " << file_size << " : " << file_offset << endl;
toc.push_back({filename, file_size, file_offset});
}
fi.close();
}
int main(int argc, char *argv[])