From 21cfea2b52c2d2003506116798d0449844a113f3 Mon Sep 17 00:00:00 2001 From: pixel Date: Wed, 6 Aug 2008 13:10:38 +0000 Subject: Rolling read in a loop, instead of recurse calls. --- mpq-file.c | 87 ++++++++++++++++++++++++++++++++++---------------------------- 1 file 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) { -- cgit v1.2.3