Skip to content

Commit

Permalink
Adds file_hash and file_number_from_hash
Browse files Browse the repository at this point in the history
Allows the user to avoid hash recalculation when looking up the file in
multiple MPQ archives.

Fixes mbroemme#17
  • Loading branch information
glebm committed Nov 2, 2021
1 parent ce151ca commit 7081f22
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 10 deletions.
29 changes: 19 additions & 10 deletions libmpq/mpq.c
Original file line number Diff line number Diff line change
Expand Up @@ -590,26 +590,27 @@ int32_t libmpq__file_imploded(mpq_archive_s *mpq_archive, uint32_t file_number,
return LIBMPQ_SUCCESS;
}

/* this function return filenumber by the given name. */
int32_t libmpq__file_number(mpq_archive_s *mpq_archive, const char *filename, uint32_t *number) {

/* some common variables. */
uint32_t i, hash1, hash2, hash3, ht_count;
/* calculates the filename hash. */
void libmpq__file_hash(const char *filename, uint32_t *hash1, uint32_t *hash2, uint32_t *hash3) {
*hash1 = libmpq__hash_string(filename, 0x0);
*hash2 = libmpq__hash_string(filename, 0x100);
*hash3 = libmpq__hash_string(filename, 0x200);
}

/* finds the file number with the given filename hash. */
int32_t libmpq__file_number_from_hash(mpq_archive_s *mpq_archive, uint32_t hash1, uint32_t hash2, uint32_t hash3, uint32_t *number) {
/* if the list of file names doesn't include this one, we'll have
* to figure out the file number the "hard" way.
*/
ht_count = mpq_archive->mpq_header.hash_table_count;
uint32_t ht_count = mpq_archive->mpq_header.hash_table_count;

hash1 = libmpq__hash_string (filename, 0x0) & (ht_count - 1);
hash2 = libmpq__hash_string (filename, 0x100);
hash3 = libmpq__hash_string (filename, 0x200);
hash1 &= (ht_count - 1);

/* loop through all files in mpq archive.
* hash1 gives us a clue about the starting position of this
* search.
*/
for (i = hash1; mpq_archive->mpq_hash[i].block_table_index != LIBMPQ_HASH_FREE; i = (i + 1) & (ht_count - 1)) {
for (uint32_t i = hash1; mpq_archive->mpq_hash[i].block_table_index != LIBMPQ_HASH_FREE; i = (i + 1) & (ht_count - 1)) {

/* if the other two hashes match, we found our file number. */
if (mpq_archive->mpq_hash[i].hash_a == hash2 &&
Expand All @@ -632,6 +633,14 @@ int32_t libmpq__file_number(mpq_archive_s *mpq_archive, const char *filename, ui
return LIBMPQ_ERROR_EXIST;
}


/* this function return filenumber by the given name. */
int32_t libmpq__file_number(mpq_archive_s *mpq_archive, const char *filename, uint32_t *number) {
uint32_t hash1, hash2, hash3;
libmpq__file_hash(filename, &hash1, &hash2, &hash3);
return libmpq__file_number_from_hash(mpq_archive, hash1, hash2, hash3, number);
}

/* this function read the given file from archive into a buffer. */
int32_t libmpq__file_read(mpq_archive_s *mpq_archive, uint32_t file_number, uint8_t *out_buf, libmpq__off_t out_size, libmpq__off_t *transferred) {

Expand Down
2 changes: 2 additions & 0 deletions libmpq/mpq.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,8 @@ extern LIBMPQ_API int32_t libmpq__file_encrypted(mpq_archive_s *mpq_archive, uin
extern LIBMPQ_API int32_t libmpq__file_compressed(mpq_archive_s *mpq_archive, uint32_t file_number, uint32_t *compressed);
extern LIBMPQ_API int32_t libmpq__file_imploded(mpq_archive_s *mpq_archive, uint32_t file_number, uint32_t *imploded);
extern LIBMPQ_API int32_t libmpq__file_number(mpq_archive_s *mpq_archive, const char *filename, uint32_t *number);
extern LIBMPQ_API void libmpq__file_hash(const char *filename, uint32_t *hash1, uint32_t *hash2, uint32_t *hash3);
extern LIBMPQ_API int32_t libmpq__file_number_from_hash(mpq_archive_s *mpq_archive, uint32_t hash1, uint32_t hash2, uint32_t hash3, uint32_t *number);
extern LIBMPQ_API int32_t libmpq__file_read(mpq_archive_s *mpq_archive, uint32_t file_number, uint8_t *out_buf, libmpq__off_t out_size, libmpq__off_t *transferred);
extern LIBMPQ_API int32_t libmpq__file_read_with_filename(mpq_archive_s *mpq_archive, uint32_t file_number, const char *filename, uint8_t *out_buf, libmpq__off_t out_size, libmpq__off_t *transferred);

Expand Down

0 comments on commit 7081f22

Please sign in to comment.