[Add] seek/tell functions to packfile. Still using "streaming mode" though as it works better with vorbis.

This commit is contained in:
Allanis 2013-02-26 16:24:29 +00:00
parent 301ea07a69
commit 804a6d73a0
2 changed files with 55 additions and 2 deletions

View File

@ -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));

View File

@ -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.