Add lseek() function to IsoFileSource.

This commit is contained in:
Vreixo Formoso 2008-03-08 18:34:41 +01:00
parent 69fe1d6074
commit bad03a9a2b
4 changed files with 146 additions and 0 deletions

View File

@ -632,6 +632,60 @@ int ifs_read(IsoFileSource *src, void *buf, size_t count)
return read; return read;
} }
static
off_t ifs_lseek(IsoFileSource *src, off_t offset, int flag)
{
ImageFileSourceData *data;
if (src == NULL) {
return (off_t)ISO_NULL_POINTER;
}
if (offset < (off_t)0) {
return (off_t)ISO_WRONG_ARG_VALUE;
}
data = src->data;
if (!data->opened) {
return (off_t)ISO_FILE_NOT_OPENED;
} else if (data->opened != 1) {
return (off_t)ISO_FILE_IS_DIR;
}
switch (flag) {
case 0: /* SEEK_SET */
data->data.offset = offset;
break;
case 1: /* SEEK_CUR */
data->data.offset += offset;
break;
case 2: /* SEEK_END */
/* do this make sense? */
data->data.offset = data->info.st_size + offset;
break;
default:
return (off_t)ISO_WRONG_ARG_VALUE;
}
if (data->data.offset % BLOCK_SIZE != 0) {
/* we need to buffer the block */
uint32_t block;
_ImageFsData *fsdata;
if (data->data.offset < data->info.st_size) {
int ret;
fsdata = data->fs->data;
block = data->block + (data->data.offset / BLOCK_SIZE);
ret = fsdata->src->read_block(fsdata->src, block,
data->data.content);
if (ret < 0) {
return (off_t)ret;
}
}
}
return data->data.offset;
}
static static
int ifs_readdir(IsoFileSource *src, IsoFileSource **child) int ifs_readdir(IsoFileSource *src, IsoFileSource **child)
{ {
@ -771,6 +825,7 @@ IsoFileSourceIface ifs_class = {
ifs_open, ifs_open,
ifs_close, ifs_close,
ifs_read, ifs_read,
ifs_lseek,
ifs_readdir, ifs_readdir,
ifs_readlink, ifs_readlink,
ifs_get_filesystem, ifs_get_filesystem,

View File

@ -304,6 +304,52 @@ int lfs_read(IsoFileSource *src, void *buf, size_t count)
} }
} }
static
off_t lfs_lseek(IsoFileSource *src, off_t offset, int flag)
{
_LocalFsFileSource *data;
int whence;
if (src == NULL) {
return (off_t)ISO_NULL_POINTER;
}
switch (flag) {
case 0:
whence = SEEK_SET; break;
case 1:
whence = SEEK_CUR; break;
case 2:
whence = SEEK_END; break;
default:
return (off_t)ISO_WRONG_ARG_VALUE;
}
data = src->data;
switch (data->openned) {
case 1: /* not dir */
{
off_t ret;
ret = lseek(data->info.fd, offset, whence);
if (ret < 0) {
/* error on read */
switch (errno) {
case ESPIPE:
ret = (off_t)ISO_FILE_ERROR;
break;
default:
ret = (off_t)ISO_ERROR;
break;
}
}
return ret;
}
case 2: /* directory */
return (off_t)ISO_FILE_IS_DIR;
default:
return (off_t)ISO_FILE_NOT_OPENED;
}
}
static static
int lfs_readdir(IsoFileSource *src, IsoFileSource **child) int lfs_readdir(IsoFileSource *src, IsoFileSource **child)
{ {
@ -430,6 +476,7 @@ IsoFileSourceIface lfs_class = {
lfs_open, lfs_open,
lfs_close, lfs_close,
lfs_read, lfs_read,
lfs_lseek,
lfs_readdir, lfs_readdir,
lfs_readlink, lfs_readlink,
lfs_get_filesystem, lfs_get_filesystem,

View File

@ -92,6 +92,12 @@ int iso_file_source_read(IsoFileSource *src, void *buf, size_t count)
return src->class->read(src, buf, count); return src->class->read(src, buf, count);
} }
inline
off_t iso_file_source_lseek(IsoFileSource *src, off_t offset, int flag)
{
return src->class->lseek(src, offset, flag);
}
inline inline
int iso_file_source_readdir(IsoFileSource *src, IsoFileSource **child) int iso_file_source_readdir(IsoFileSource *src, IsoFileSource **child)
{ {

View File

@ -559,6 +559,25 @@ struct IsoFileSource_Iface
* ISO_INTERRUPTED * ISO_INTERRUPTED
*/ */
int (*read)(IsoFileSource *src, void *buf, size_t count); int (*read)(IsoFileSource *src, void *buf, size_t count);
/**
* Repositions the offset of the IsoFileSource (must be opened) to the
* given offset according to the value of flag.
*
* @param offset
* in bytes
* @param flag
* 0 The offset is set to offset bytes (SEEK_SET)
* 1 The offset is set to its current location plus offset bytes
* (SEEK_CUR)
* 2 The offset is set to the size of the file plus offset bytes
* (SEEK_END).
* @return
* Absolute offset posistion on the file, or < 0 on error. Cast the
* returning value to int to get a valid libisofs error.
* @since 0.6.4
*/
off_t (*lseek)(IsoFileSource *src, off_t offset, int flag);
/** /**
* Read a directory. * Read a directory.
@ -3216,6 +3235,25 @@ int iso_file_source_close(IsoFileSource *src);
*/ */
int iso_file_source_read(IsoFileSource *src, void *buf, size_t count); int iso_file_source_read(IsoFileSource *src, void *buf, size_t count);
/**
* Repositions the offset of the given IsoFileSource (must be opened) to the
* given offset according to the value of flag.
*
* @param offset
* in bytes
* @param flag
* 0 The offset is set to offset bytes (SEEK_SET)
* 1 The offset is set to its current location plus offset bytes
* (SEEK_CUR)
* 2 The offset is set to the size of the file plus offset bytes
* (SEEK_END).
* @return
* Absolute offset posistion on the file, or < 0 on error. Cast the
* returning value to int to get a valid libisofs error.
* @since 0.6.4
*/
off_t iso_file_source_lseek(IsoFileSource *src, off_t offset, int flag);
/** /**
* Read a directory. * Read a directory.
* *