summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpixel <pixel>2008-08-06 13:10:38 +0000
committerpixel <pixel>2008-08-06 13:10:38 +0000
commit21cfea2b52c2d2003506116798d0449844a113f3 (patch)
tree03e48b74c96e8099b92d75868c70dfeb5c29e886
parent8288e5164e6b18a756c8c0149fe399e795e1add7 (diff)
Rolling read in a loop, instead of recurse calls.
-rw-r--r--mpq-file.c87
1 files changed, 48 insertions, 39 deletions
diff --git a/mpq-file.c b/mpq-file.c
index 2088335..ad5d51b 100644
--- a/mpq-file.c
+++ b/mpq-file.c
@@ -153,56 +153,65 @@ static int cache_sector(struct mpq_file_t * mpq_f, int sector) {
}
/*
- * The read function will call itself recursively, in order to split the calls across the sectors.
+ * The read function will iterate several times, in order to split the calls across the sectors.
*/
uint32_t mpqlib_read(struct mpq_file_t * mpq_f, void * _buffer, uint32_t size) {
- char * buffer = (char *) _buffer;
- int sector_begin, sector_end;
- uint32_t cl_size;
- uint32_t offset_begin, offset_end;
+ int return_size = 0;
+
+ while (1) {
+ char * buffer = (char *) _buffer;
+ int sector_begin, sector_end;
+ uint32_t cl_size;
+ uint32_t offset_begin, offset_end;
- uint32_t first_sector_begins;
+ uint32_t first_sector_begins;
uint32_t last_sector_ends;
__mpqlib_errno = MPQLIB_ERROR_NO_ERROR;
- /* Computing various cursors and stuff. */
- if ((size + mpq_f->cursor) >= mpq_f->file_size)
- size = mpq_f->file_size - mpq_f->cursor;
+ /* Computing various cursors and stuff. */
+ if ((size + mpq_f->cursor) >= mpq_f->file_size)
+ size = mpq_f->file_size - mpq_f->cursor;
- offset_begin = mpq_f->cursor;
- sector_begin = offset_begin / mpq_f->sector_size;
- first_sector_begins = offset_begin % mpq_f->sector_size;
-
- offset_end = size + mpq_f->cursor;
- sector_end = offset_end / mpq_f->sector_size;
- last_sector_ends = offset_end % mpq_f->sector_size;
-
- if (!(offset_end % mpq_f->sector_size)) {
- sector_end--;
- last_sector_ends = mpq_f->sector_size;
- }
-
- /* Let's ask for the first sector */
- if (!cache_sector(mpq_f, sector_begin)) {
- __mpqlib_errno = MPQLIB_ERROR_COMPRESSION;
- return 0;
- }
-
- /* If we've hit the end sector, let's just copy that over and exit. */
- if (sector_begin == sector_end) {
- memcpy(buffer, mpq_f->buffer + first_sector_begins, size);
- mpq_f->cursor += size;
- return size;
+ offset_begin = mpq_f->cursor;
+ sector_begin = offset_begin / mpq_f->sector_size;
+ first_sector_begins = offset_begin % mpq_f->sector_size;
+
+ offset_end = size + mpq_f->cursor;
+ sector_end = offset_end / mpq_f->sector_size;
+ last_sector_ends = offset_end % mpq_f->sector_size;
+
+ if (!(offset_end % mpq_f->sector_size)) {
+ sector_end--;
+ last_sector_ends = mpq_f->sector_size;
+ }
+
+ /* Let's ask for the first sector */
+ if (!cache_sector(mpq_f, sector_begin)) {
+ __mpqlib_errno = MPQLIB_ERROR_COMPRESSION;
+ return 0;
+ }
+
+ /* If we've hit the end sector, let's just copy that over and exit. */
+ if (sector_begin == sector_end) {
+ memcpy(buffer, mpq_f->buffer + first_sector_begins, size);
+ mpq_f->cursor += size;
+ return_size = size;
+ break;
+ }
+
+ /* Else, let's compute the cluster size, copy that chunk, and reiterate. */
+ cl_size = mpq_f->sector_size - first_sector_begins;
+ memcpy(buffer, mpq_f->buffer + first_sector_begins, cl_size);
+ mpq_f->cursor += cl_size;
+
+ return_size += cl_size;
+ _buffer = buffer + cl_size;
+ size = size - cl_size;
}
- /* Else, let's compute the cluster size, copy that chunk, and recurse. */
- cl_size = mpq_f->sector_size - first_sector_begins;
- memcpy(buffer, mpq_f->buffer + first_sector_begins, cl_size);
- mpq_f->cursor += cl_size;
-
- return mpqlib_read(mpq_f, buffer + cl_size, size - cl_size) + cl_size;
+ return return_size;
}
uint32_t mpqlib_seek(struct mpq_file_t * mpq_f, int32_t offset, enum mpqlib_file_seek_t wheel) {