diff --git a/src/pack.c b/src/pack.c index 28f41ad..fd89d3c 100644 --- a/src/pack.c +++ b/src/pack.c @@ -11,7 +11,7 @@ // == Store data in a funky format. ======================= // Format: -// -- Index (in 512 byte chunks). +// -- Index. // -- Magic number (16 bytes). // -- Number of files (uint32_t). // -- Files in format name/location. @@ -307,7 +307,8 @@ int pack_open(Packfile* file, const char* packfile, const char* filename) { // Read count bytes from file and put them into buf. ssize_t pack_read(Packfile* file, void* buf, size_t count) { - if(file->pos + count > file->end) count = file->end - file->pos; // Can't go past the end! + if(file->pos + count > file->end) + count = file->end - file->pos; // Can't go past the end! if(count == 0) return 0; int bytes; @@ -325,6 +326,56 @@ ssize_t pack_read(Packfile* file, void* buf, size_t count) { return bytes; } +// Seek in the packfile. +off_t pack_seek(Packfile* file, off_t offset, int whence) { + DEBUG("Attempting to seek offset: %d, whence: %d", offset, whence); + off_t ret; + switch(whence) { +#ifdef _POSIX_SOURCE + case SEEK_SET: + if((file->start + offset) > file->end) return -1; + ret = lseek(file->fd, file->start + offset, SEEK_SET); + if(ret != (file->start + offset)) return -1; + break; + case SEEK_CUR: + if((file->start + offset) > file->end) return -1; + ret = lseek(file->fd, file->pos + offset, SEEK_SET); + if(ret != (file->pos + offset)) return -1; + break; + case SEEK_END: + if((file->end - offset) < file->start) return -1; + ret = lseek(file->fd, file->end - offset - 1, SEEK_SET); + if(ret != (file->end - offset)) return -1; + break; +#else + case SEEK_SET: + if((file->start + offset) > file->end) return -1; + ret = fseek(file->fd, file->start + offset, SEEK_SET); + if(ret != (file->start + offset)) return -1; + break; + case SEEK_CUR: + if((file->start + offset) > file->end) return -1; + ret = flseek(file->fd, file->pos + offset, SEEK_SET); + if(ret != (file->pos + offset)) return -1; + break; + case SEEK_END: + if((file->end - offset) < file->start) return -1; + ret = flseek(file->fd, file->end - offset - 1, SEEK_SET); + if(ret != (file->end - offset)) return -1; + break; +#endif + default: + ERR("Whence is not one of SEEK_SET, SEEK_CUR or SEEK_END"); + return -1; + } + return ret - file->start; +} + +// Return current pointer position. +long pack_tell(Packfile* file) { + return file->pos - file->start; +} + // Loads an entire file into memory and returns a pointer to it. void* pack_readfile(const char* packfile, const char* filename, uint32_t* filesize) { Packfile* file = (Packfile*)malloc(sizeof(Packfile)); diff --git a/src/pack.h b/src/pack.h index bdfd436..1070cab 100644 --- a/src/pack.h +++ b/src/pack.h @@ -22,6 +22,8 @@ int pack_check(const char* filename); int pack_files(const char* outfile, const char** infiles, const uint32_t nfiles); int pack_open(Packfile* file, const char* packfile, const char* filename); ssize_t pack_read(Packfile* file, void* buf, const size_t count); +off_t pack_seek(Packfile* file, off_t offset, int whence); +long pack_tell(Packfile* file); int pack_close(Packfile* file); // Fancy stuff.