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;
|
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,
|
||||||
|
@ -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,
|
||||||
|
@ -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)
|
||||||
{
|
{
|
||||||
|
@ -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.
|
||||||
*
|
*
|
||||||
|
Loading…
Reference in New Issue
Block a user