|
|
@@ -67,134 +67,128 @@ Archive::Archive(string &filepath) : Archive(filepath.c_str())
|
|
|
Archive::Archive(const char *filepath)
|
|
|
: file(nullptr), entries(nullptr), files_data(nullptr), files_loaded(nullptr)
|
|
|
{
|
|
|
- try
|
|
|
+#if NSPIRE
|
|
|
+ Interrupts::off();
|
|
|
+#endif
|
|
|
+ // Null pointer exception trigger
|
|
|
+ if (filepath == nullptr)
|
|
|
{
|
|
|
- #if NSPIRE
|
|
|
- Interrupts::off();
|
|
|
- #endif
|
|
|
- // Null pointer exception trigger
|
|
|
- if (filepath == nullptr)
|
|
|
- {
|
|
|
- throw PIAF::PIAFException("%s: Null path given", __FILE__);
|
|
|
- }
|
|
|
- // Solves the absolute path for given relative path.
|
|
|
- // Must be needed in targets like Ndless as it doesn't support environment
|
|
|
- // vars and thus PATH.
|
|
|
- std::unique_ptr<char> real_filename(Quirks::solve_absolute_path(filepath));
|
|
|
+ throw PIAF::PIAFException("%s: Null path given", __FILE__);
|
|
|
+ }
|
|
|
+ // Solves the absolute path for given relative path.
|
|
|
+ // Must be needed in targets like Ndless as it doesn't support environment
|
|
|
+ // vars and thus PATH.
|
|
|
+ std::unique_ptr<char> real_filename(Quirks::solve_absolute_path(filepath));
|
|
|
|
|
|
- // Open the archive
|
|
|
- file = fopen(real_filename.get(), "rb");
|
|
|
- // Again another null pointer trigger
|
|
|
- if (file == nullptr || file == NULL)
|
|
|
- {
|
|
|
- throw PIAF::PIAFException("%s: Missing file : %s", __FILE__, filepath);
|
|
|
- }
|
|
|
+ // Open the archive
|
|
|
+ file = fopen(real_filename.get(), "rb");
|
|
|
+ // Again another null pointer trigger
|
|
|
+ if (file == nullptr || file == NULL)
|
|
|
+ {
|
|
|
+ throw PIAF::PIAFException("%s: Missing file : %s", __FILE__, filepath);
|
|
|
+ }
|
|
|
|
|
|
- // Loading stuff happens NOW
|
|
|
- // Checking if the file is long enough to have a header
|
|
|
- fseek(file, 0L, SEEK_END);
|
|
|
- uint64_t filesize = ftell(file);
|
|
|
- fseek(file, 0L, SEEK_SET);
|
|
|
- // File to small exception trigger
|
|
|
- if (filesize < 32)
|
|
|
- {
|
|
|
- throw PIAF::PIAFException("%s: File too small (%s): %d", __FILE__, filepath, filesize);
|
|
|
- }
|
|
|
+ // Loading stuff happens NOW
|
|
|
+ // Checking if the file is long enough to have a header
|
|
|
+ fseek(file, 0L, SEEK_END);
|
|
|
+ uint64_t filesize = ftell(file);
|
|
|
+ fseek(file, 0L, SEEK_SET);
|
|
|
+ // File to small exception trigger
|
|
|
+ if (filesize < 32)
|
|
|
+ {
|
|
|
+ throw PIAF::PIAFException("%s: File too small (%s): %d", __FILE__, filepath, filesize);
|
|
|
+ }
|
|
|
|
|
|
- // Tempoary buffer to contain the header.
|
|
|
- char header_container[32] = {0};
|
|
|
- // Read the headers and trigger exceptions on errors
|
|
|
- if (fread(header_container, sizeof(char), 32, file) != 32)
|
|
|
- {
|
|
|
- throw PIAF::PIAFException("%s: Errorneous header : %s", __FILE__, filepath);
|
|
|
- }
|
|
|
- // Check if the magic cookie is the same.
|
|
|
- // It's a first way to detect if the file is correctly an archive.
|
|
|
- if (strncmp(header_container, "WRPGPIAF", 8) != 0)
|
|
|
- {
|
|
|
- // TODO throw bad header
|
|
|
- // fprintf(stderr, "Bad header magic word\n");
|
|
|
- throw PIAF::PIAFException("%s: Magic cookie mismatch : %s", __FILE__, filepath);
|
|
|
- }
|
|
|
- // Checksum time! Let's check if the header hasn"t been altered.
|
|
|
- uint32_t expected_checksum = read_big_endian_value<uint32_t>(&header_container[8]);
|
|
|
- uint32_t calculated_checksum = crc32(0L, (unsigned char *) &header_container[16], 16);
|
|
|
- if (expected_checksum != calculated_checksum)
|
|
|
- {
|
|
|
- // TODO throw bad checksum
|
|
|
- // fprintf(stderr, "Bad header checksum : %x != %x\n", expected_checksum,
|
|
|
- // calculated_checksum);
|
|
|
- throw PIAF::PIAFException("%s: Bad checksum : %s", __FILE__, filepath);
|
|
|
- }
|
|
|
+ // Tempoary buffer to contain the header.
|
|
|
+ char header_container[32] = {0};
|
|
|
+ // Read the headers and trigger exceptions on errors
|
|
|
+ if (fread(header_container, sizeof(char), 32, file) != 32)
|
|
|
+ {
|
|
|
+ throw PIAF::PIAFException("%s: Errorneous header : %s", __FILE__, filepath);
|
|
|
+ }
|
|
|
+ // Check if the magic cookie is the same.
|
|
|
+ // It's a first way to detect if the file is correctly an archive.
|
|
|
+ if (strncmp(header_container, "WRPGPIAF", 8) != 0)
|
|
|
+ {
|
|
|
+ // TODO throw bad header
|
|
|
+ // fprintf(stderr, "Bad header magic word\n");
|
|
|
+ throw PIAF::PIAFException("%s: Magic cookie mismatch : %s", __FILE__, filepath);
|
|
|
+ }
|
|
|
+ // Checksum time! Let's check if the header hasn"t been altered.
|
|
|
+ uint32_t expected_checksum = read_big_endian_value<uint32_t>(&header_container[8]);
|
|
|
+ uint32_t calculated_checksum = crc32(0L, (unsigned char *) &header_container[16], 16);
|
|
|
+ if (expected_checksum != calculated_checksum)
|
|
|
+ {
|
|
|
+ // TODO throw bad checksum
|
|
|
+ // fprintf(stderr, "Bad header checksum : %x != %x\n", expected_checksum,
|
|
|
+ // calculated_checksum);
|
|
|
+ throw PIAF::PIAFException("%s: Bad checksum : %s", __FILE__, filepath);
|
|
|
+ }
|
|
|
|
|
|
- // TODO : version checking
|
|
|
- version = read_big_endian_value<uint32_t>(&header_container[16]);
|
|
|
- if (version != ARCHIVE_VERSION)
|
|
|
- {
|
|
|
- // std::exception up;
|
|
|
- // throw up; // haha
|
|
|
- throw PIAF::PIAFException("%s: Wrong(%s) : %08x is not supported by %08x", __FILE__, filepath, version, ARCHIVE_VERSION);
|
|
|
- }
|
|
|
+ // TODO : version checking
|
|
|
+ version = read_big_endian_value<uint32_t>(&header_container[16]);
|
|
|
+ if (version != ARCHIVE_VERSION)
|
|
|
+ {
|
|
|
+ // std::exception up;
|
|
|
+ // throw up; // haha
|
|
|
+ throw PIAF::PIAFException("%s: Wrong(%s) : %08x is not supported by %08x", __FILE__, filepath, version, ARCHIVE_VERSION);
|
|
|
+ }
|
|
|
|
|
|
|
|
|
- // At this point, the archive header looks unaltered and we finally can parse
|
|
|
- // and load the header.
|
|
|
+ // At this point, the archive header looks unaltered and we finally can parse
|
|
|
+ // and load the header.
|
|
|
|
|
|
- // Read the archive's number of files
|
|
|
- nb_files = read_big_endian_value<uint32_t>(&header_container[20]);
|
|
|
- // printf("nb_files : %u\n", nb_files);
|
|
|
+ // Read the archive's number of files
|
|
|
+ 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]);
|
|
|
- uint64_t calculated_data_size = filesize - 32 - 24 * nb_files;
|
|
|
- if (data_size != calculated_data_size)
|
|
|
+ data_size = read_big_endian_value<uint32_t>(&header_container[24]);
|
|
|
+ uint64_t calculated_data_size = filesize - 32 - 24 * nb_files;
|
|
|
+ if (data_size != calculated_data_size)
|
|
|
+ {
|
|
|
+ // T0D0 : throw wrong size exception
|
|
|
+ // fprintf(stderr, "Bad data size : expected %u, got %lld\n", data_size,
|
|
|
+ // calculated_data_size);
|
|
|
+ throw PIAF::PIAFException("Data size mismatch", __LINE__, filepath);
|
|
|
+ }
|
|
|
+ // Check if there are files to manage.
|
|
|
+ if (nb_files != 0)
|
|
|
+ {
|
|
|
+ // So, the file table is not empty. let's check if it's
|
|
|
+ // not altered.
|
|
|
+ uint32_t expected_filetable_checksum =
|
|
|
+ read_big_endian_value<uint32_t>(&header_container[12]);
|
|
|
+ char *file_entry_data = new char[24 * nb_files];
|
|
|
+ fseek(file, 32, SEEK_SET);
|
|
|
+ fread(file_entry_data, sizeof(char), 24 * nb_files, file);
|
|
|
+ // Compare and trigger an exception if the checksum doesn't match.
|
|
|
+ if (expected_filetable_checksum !=
|
|
|
+ crc32(0L, (unsigned char *) file_entry_data, 24 * nb_files))
|
|
|
{
|
|
|
- // T0D0 : throw wrong size exception
|
|
|
- // fprintf(stderr, "Bad data size : expected %u, got %lld\n", data_size,
|
|
|
- // calculated_data_size);
|
|
|
- throw PIAF::PIAFException("Data size mismatch", __LINE__, filepath);
|
|
|
+ // TODO : checksum exception
|
|
|
+ // fprintf(stderr, "Bad filetable checksum\n");
|
|
|
+ throw PIAF::PIAFException("Bad Filetable checksum", __LINE__, filepath);
|
|
|
}
|
|
|
- // Check if there are files to manage.
|
|
|
- if (nb_files != 0)
|
|
|
- {
|
|
|
- // So, the file table is not empty. let's check if it's
|
|
|
- // not altered.
|
|
|
- uint32_t expected_filetable_checksum =
|
|
|
- read_big_endian_value<uint32_t>(&header_container[12]);
|
|
|
- char *file_entry_data = new char[24 * nb_files];
|
|
|
- fseek(file, 32, SEEK_SET);
|
|
|
- fread(file_entry_data, sizeof(char), 24 * nb_files, file);
|
|
|
- // Compare and trigger an exception if the checksum doesn't match.
|
|
|
- if (expected_filetable_checksum !=
|
|
|
- crc32(0L, (unsigned char *) file_entry_data, 24 * nb_files))
|
|
|
- {
|
|
|
- // TODO : checksum exception
|
|
|
- // fprintf(stderr, "Bad filetable checksum\n");
|
|
|
- throw PIAF::PIAFException("Bad Filetable checksum", __LINE__, filepath);
|
|
|
- }
|
|
|
- // Create the filetable.
|
|
|
- entries = new File[nb_files];
|
|
|
- // Parse and story the filetable.
|
|
|
-
|
|
|
- files_data = new uint8_t *[nb_files];
|
|
|
- files_loaded = new bool[nb_files];
|
|
|
- files_data_offset = new uint32_t[nb_files];
|
|
|
- for (unsigned i = 0; i < nb_files; i++)
|
|
|
- {
|
|
|
- files_data[i] = nullptr;
|
|
|
- files_loaded[i] = false;
|
|
|
- files_data_offset[i] = 0;
|
|
|
- }
|
|
|
+ // Create the filetable.
|
|
|
+ entries = new File[nb_files];
|
|
|
+ // Parse and story the filetable.
|
|
|
|
|
|
- load_file_table(entries, files_data_offset, file_entry_data, nb_files);
|
|
|
- delete[] file_entry_data;
|
|
|
+ files_data = new uint8_t *[nb_files];
|
|
|
+ files_loaded = new bool[nb_files];
|
|
|
+ files_data_offset = new uint32_t[nb_files];
|
|
|
+ for (unsigned i = 0; i < nb_files; i++)
|
|
|
+ {
|
|
|
+ files_data[i] = nullptr;
|
|
|
+ files_loaded[i] = false;
|
|
|
+ files_data_offset[i] = 0;
|
|
|
}
|
|
|
- #if NSPIRE
|
|
|
- Interrupts::init();
|
|
|
- #endif
|
|
|
- } catch(PIAF::PIAFException &e)
|
|
|
- {
|
|
|
- throw e;
|
|
|
+
|
|
|
+ load_file_table(entries, files_data_offset, file_entry_data, nb_files);
|
|
|
+ delete[] file_entry_data;
|
|
|
}
|
|
|
+#if NSPIRE
|
|
|
+ Interrupts::init();
|
|
|
+#endif
|
|
|
|
|
|
}
|
|
|
|