|
@@ -26,6 +26,7 @@ namespace
|
|
|
{
|
|
{
|
|
|
char *current_entry_data = &data[index * 24];
|
|
char *current_entry_data = &data[index * 24];
|
|
|
memcpy(entries[index].filename, current_entry_data, 8);
|
|
memcpy(entries[index].filename, current_entry_data, 8);
|
|
|
|
|
+ entries[index].filename[8] = '\0'; // Makin' sure.
|
|
|
entries[index].file_type =
|
|
entries[index].file_type =
|
|
|
(FileType) read_big_endian_value<uint32_t>(¤t_entry_data[8]);
|
|
(FileType) read_big_endian_value<uint32_t>(¤t_entry_data[8]);
|
|
|
entries[index].compression_type =
|
|
entries[index].compression_type =
|
|
@@ -39,16 +40,22 @@ namespace
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-Archive::Archive(char *filepath)
|
|
|
|
|
|
|
+Archive::Archive(std::string &filepath) : Archive(filepath.c_str())
|
|
|
|
|
+{
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+Archive::Archive(const char *filepath) : file(nullptr), entries(nullptr)
|
|
|
{
|
|
{
|
|
|
if (filepath == nullptr)
|
|
if (filepath == nullptr)
|
|
|
{
|
|
{
|
|
|
|
|
+ // TODO : throw NPE
|
|
|
|
|
+ //fprintf(stderr, "Null filepath\n");
|
|
|
}
|
|
}
|
|
|
- // TODO : throw NPE
|
|
|
|
|
file = fopen(filepath, "rb");
|
|
file = fopen(filepath, "rb");
|
|
|
if (file == nullptr)
|
|
if (file == nullptr)
|
|
|
{
|
|
{
|
|
|
// TODO : throw Couldn't open
|
|
// TODO : throw Couldn't open
|
|
|
|
|
+ //fprintf(stderr, "Unable to open %s\n", filepath);
|
|
|
}
|
|
}
|
|
|
// loading stuff happens NOW
|
|
// loading stuff happens NOW
|
|
|
// checking if the file is long enough to have a header
|
|
// checking if the file is long enough to have a header
|
|
@@ -58,6 +65,7 @@ Archive::Archive(char *filepath)
|
|
|
if (filesize < 32)
|
|
if (filesize < 32)
|
|
|
{
|
|
{
|
|
|
// TODO : throw file too small
|
|
// TODO : throw file too small
|
|
|
|
|
+ //fprintf(stderr, "File too small\n");
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
char header_container[32] = {0};
|
|
char header_container[32] = {0};
|
|
@@ -65,11 +73,14 @@ Archive::Archive(char *filepath)
|
|
|
if (strncmp(header_container, "WRPGPIAF", 8) != 0)
|
|
if (strncmp(header_container, "WRPGPIAF", 8) != 0)
|
|
|
{
|
|
{
|
|
|
// TODO throw bad header
|
|
// TODO throw bad header
|
|
|
|
|
+ //fprintf(stderr, "Bad header magic word\n");
|
|
|
}
|
|
}
|
|
|
uint32_t expected_checksum = read_big_endian_value<uint32_t>(&header_container[8]);
|
|
uint32_t expected_checksum = read_big_endian_value<uint32_t>(&header_container[8]);
|
|
|
- if (expected_checksum != crc32(0L, (unsigned char *) header_container, 32))
|
|
|
|
|
|
|
+ uint32_t calculated_checksum = crc32(0L, (unsigned char *) &header_container[16], 16);
|
|
|
|
|
+ if (expected_checksum != calculated_checksum)
|
|
|
{
|
|
{
|
|
|
// TODO throw bad checksum
|
|
// TODO throw bad checksum
|
|
|
|
|
+ //fprintf(stderr, "Bad header checksum : %x != %x\n", expected_checksum, calculated_checksum);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// TODO : version checking
|
|
// TODO : version checking
|
|
@@ -81,24 +92,28 @@ Archive::Archive(char *filepath)
|
|
|
* }
|
|
* }
|
|
|
*/
|
|
*/
|
|
|
nb_files = read_big_endian_value<uint32_t>(&header_container[20]);
|
|
nb_files = read_big_endian_value<uint32_t>(&header_container[20]);
|
|
|
|
|
+ // printf("nb_files : %u\n", nb_files);
|
|
|
|
|
|
|
|
data_size = read_big_endian_value<uint32_t>(&header_container[24]);
|
|
data_size = read_big_endian_value<uint32_t>(&header_container[24]);
|
|
|
- if (data_size != filesize - 32 - 24 * nb_files)
|
|
|
|
|
|
|
+ uint64_t calculated_data_size = filesize - 32 - 24 * nb_files;
|
|
|
|
|
+ if (data_size != calculated_data_size)
|
|
|
{
|
|
{
|
|
|
// T0D0 : throw wrong size exception
|
|
// T0D0 : throw wrong size exception
|
|
|
|
|
+ // fprintf(stderr, "Bad data size : expected %u, got %lld\n", data_size, calculated_data_size);
|
|
|
}
|
|
}
|
|
|
if (nb_files != 0)
|
|
if (nb_files != 0)
|
|
|
{
|
|
{
|
|
|
uint32_t expected_filetable_checksum =
|
|
uint32_t expected_filetable_checksum =
|
|
|
read_big_endian_value<uint32_t>(&header_container[12]);
|
|
read_big_endian_value<uint32_t>(&header_container[12]);
|
|
|
char *file_entry_data = new char[24 * nb_files];
|
|
char *file_entry_data = new char[24 * nb_files];
|
|
|
|
|
+ fseek(file, 32, SEEK_SET);
|
|
|
|
|
+ fread(file_entry_data, sizeof(char), 24 * nb_files, file);
|
|
|
if (expected_filetable_checksum !=
|
|
if (expected_filetable_checksum !=
|
|
|
crc32(0L, (unsigned char *) file_entry_data, 24 * nb_files))
|
|
crc32(0L, (unsigned char *) file_entry_data, 24 * nb_files))
|
|
|
{
|
|
{
|
|
|
// TODO : checksum exception
|
|
// TODO : checksum exception
|
|
|
|
|
+ // fprintf(stderr, "Bad filetable checksum\n");
|
|
|
}
|
|
}
|
|
|
- fseek(file, 32, SEEK_SET);
|
|
|
|
|
- fread(file_entry_data, sizeof(char), 24 * nb_files, file);
|
|
|
|
|
entries = new FileEntry[nb_files];
|
|
entries = new FileEntry[nb_files];
|
|
|
load_file_table(entries, file_entry_data, nb_files);
|
|
load_file_table(entries, file_entry_data, nb_files);
|
|
|
delete[] file_entry_data;
|
|
delete[] file_entry_data;
|
|
@@ -107,8 +122,10 @@ Archive::Archive(char *filepath)
|
|
|
|
|
|
|
|
Archive::~Archive()
|
|
Archive::~Archive()
|
|
|
{
|
|
{
|
|
|
- fclose(file);
|
|
|
|
|
- delete[] entries;
|
|
|
|
|
|
|
+ if(file != nullptr)
|
|
|
|
|
+ fclose(file);
|
|
|
|
|
+ if( entries != nullptr)
|
|
|
|
|
+ delete[] entries;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
FileEntry Archive::get_file_entry(char *filename)
|
|
FileEntry Archive::get_file_entry(char *filename)
|