Add lseek() function to IsoFileSource.
This commit is contained in:
parent
69fe1d6074
commit
bad03a9a2b
@ -632,6 +632,60 @@ int ifs_read(IsoFileSource *src, void *buf, size_t count)
|
||||
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
|
||||
int ifs_readdir(IsoFileSource *src, IsoFileSource **child)
|
||||
{
|
||||
@ -771,6 +825,7 @@ IsoFileSourceIface ifs_class = {
|
||||
ifs_open,
|
||||
ifs_close,
|
||||
ifs_read,
|
||||
ifs_lseek,
|
||||
ifs_readdir,
|
||||
ifs_readlink,
|
||||
ifs_get_filesystem,
|
||||
|
@ -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
|
||||
int lfs_readdir(IsoFileSource *src, IsoFileSource **child)
|
||||
{
|
||||
@ -430,6 +476,7 @@ IsoFileSourceIface lfs_class = {
|
||||
lfs_open,
|
||||
lfs_close,
|
||||
lfs_read,
|
||||
lfs_lseek,
|
||||
lfs_readdir,
|
||||
lfs_readlink,
|
||||
lfs_get_filesystem,
|
||||
|
@ -92,6 +92,12 @@ int iso_file_source_read(IsoFileSource *src, void *buf, size_t 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
|
||||
int iso_file_source_readdir(IsoFileSource *src, IsoFileSource **child)
|
||||
{
|
||||
|
@ -559,6 +559,25 @@ struct IsoFileSource_Iface
|
||||
* ISO_INTERRUPTED
|
||||
*/
|
||||
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.
|
||||
@ -3216,6 +3235,25 @@ int iso_file_source_close(IsoFileSource *src);
|
||||
*/
|
||||
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.
|
||||
*
|
||||
|
Loading…
Reference in New Issue
Block a user