[Change] Cleaned up pack_seek

This commit is contained in:
Allanis 2014-11-16 00:19:57 +00:00
parent b9c52585e8
commit 023c8dff0e

View File

@ -551,56 +551,49 @@ ssize_t pack_read(Packfile_t* file, void* buf, size_t count) {
* @brief Seeks within a file inside a packfile. * @brief Seeks within a file inside a packfile.
* *
* Behaves like lseek/fseek. * Behaves like lseek/fseek.
*
* @todo It's broken, needs fixing.
* @param file File to seek. * @param file File to seek.
* @param offset Position to seek to. * @param offset Position to seek to.
* @param whence Either SEEK_SET, SEEK_CUR or SEEK_END. * @param whence Either SEEK_SET, SEEK_CUR or SEEK_END.
* @return The position moved to. * @return The position moved to.
*/ */
off_t pack_seek(Packfile_t* file, off_t offset, int whence) { off_t pack_seek(Packfile_t* file, off_t offset, int whence) {
off_t ret; off_t base, target, ret;
DEBUG("Attempting to seek offset: %d, whence: %d", offset, whence); DEBUG("Attempting to seek offset: %d, whence: %d", offset, whence);
/* Find where offset is relative to. */
switch(whence) { switch(whence) {
#if HAS_POSIX
case SEEK_SET: case SEEK_SET:
if((file->start + offset) > file->end) return -1; base = file->start;
ret = lseek(file->fd, file->start + offset, SEEK_SET);
if(ret != ((off_t)file->start + offset)) return -1;
break; break;
case SEEK_CUR: case SEEK_CUR:
if((file->start + offset) > file->end) return -1; base = file->pos;
ret = lseek(file->fd, file->pos + offset, SEEK_SET);
if(ret != ((off_t)file->pos + offset)) return -1;
break; break;
case SEEK_END: case SEEK_END:
if((file->end + offset) < file->start) return -1; base = file->end;
ret = lseek(file->fd, file->end + offset, SEEK_SET);
if(ret != ((off_t)file->end - offset)) return -1;
break; 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 = fseek(file->fd, file->pos + offset -1, SEEK_SET);
if(ret != (file->pos + offset)) return -1;
break;
case SEEK_END:
if((file->end + offset) < file->start) return -1;
ret = fseek(file->fd, file->end + offset, SEEK_SET);
if(ret != (file->end - offset)) return -1;
break;
#endif /* HAS_POSIX */
default: default:
ERR("Whence is not one of SEEK_SET, SEEK_CUR or SEEK_END"); ERR("Whence is not one of SEEK_SET, SEEK_CUR or SEEK_END");
return -1; return -1;
} }
/* Get the target. */
target = base + offset;
/* Limit checks. */
if((target < file->start) || (target >= file->end))
return -1;
#if HAS_POSIX
ret = lseek(file->fd, target, SEEK_SET);
if(ret != target)
return -1;
#else
ret = fseek(file->fp, target, SEEK_SET);
if(ret != 0)
return -1;
#endif
return ret - file->start; return ret - file->start;
} }