/*! \file volseek.c \ingroup (PSIO) */ #include #include namespace psi3 { namespace libpsio { /* This is strictly used to avoid overflow errors on lseek() calls */ #define PSIO_BIGNUM 10000 /*! ** PSIO_VOLSEEK() ** ** \ingroup (PSIO) */ int psio_volseek(psio_vol *vol, ULI page, ULI offset, ULI numvols) { int stream, errcod; ULI bignum, total_offset; bignum = PSIO_BIGNUM*numvols; stream = vol->stream; /* Set file pointer to beginning of file */ errcod = lseek(stream, (ULI) 0, SEEK_SET); if(errcod == -1) return(errcod); /* lseek() through large chunks of the file to avoid offset overflows */ for(; page > bignum; page -= bignum) { total_offset = PSIO_BIGNUM * PSIO_PAGELEN; errcod = lseek(stream, total_offset, SEEK_CUR); if(errcod == -1) return(errcod); } /* Now compute the final offset including the page-relative term */ total_offset = (ULI) page/numvols; /* This should truncate */ total_offset *= PSIO_PAGELEN; total_offset += offset; /* Add the page-relative term */ errcod = lseek(stream, total_offset, SEEK_CUR); if(errcod == -1) return(errcod); return(0); } } }