add callback for sync I/O (useful for reporting progress)
This was SVN commit r978.
This commit is contained in:
parent
df9dcc5711
commit
0b452320ef
@ -756,7 +756,7 @@ int file_discard_io(Handle& hio)
|
||||
// whole file.
|
||||
|
||||
ssize_t file_io(File* const f, const off_t data_ofs, size_t data_size, void** const p,
|
||||
const FILE_IO_CB cb, const uintptr_t ctx) // optional
|
||||
const FileIOCB cb, const uintptr_t ctx) // optional
|
||||
{
|
||||
#ifdef PARANOIA
|
||||
debug_out("file_io fd=%d size=%d ofs=%d\n", f->fd, data_size, data_ofs);
|
||||
|
@ -140,13 +140,11 @@ extern int file_discard_io(Handle& hio);
|
||||
|
||||
|
||||
// return value:
|
||||
// < 0: failed (do not call again) - abort transfer.
|
||||
// = 0: done (no more data needed) - stop transfer gracefully.
|
||||
// > 0: bytes output (not used ATM; useful for statistics) - continue.
|
||||
typedef ssize_t(*FILE_IO_CB)(uintptr_t ctx, void* p, size_t size);
|
||||
// < 0: failed; abort transfer.
|
||||
// >= 0: bytes output; continue.
|
||||
typedef ssize_t(*FileIOCB)(uintptr_t ctx, void* p, size_t size);
|
||||
|
||||
extern ssize_t file_io(File* f, off_t ofs, size_t size, void** p,
|
||||
FILE_IO_CB cb = 0, uintptr_t ctx = 0);
|
||||
extern ssize_t file_io(File* f, off_t ofs, size_t size, void** p, FileIOCB cb = 0, uintptr_t ctx = 0);
|
||||
|
||||
|
||||
#endif // #ifndef FILE_H
|
||||
|
@ -1376,7 +1376,7 @@ debug_out("vfs_close %I64x\n", h);
|
||||
// (read or write access was chosen at file-open time).
|
||||
// return bytes of actual data transferred, or a negative error code.
|
||||
// TODO: buffer types
|
||||
ssize_t vfs_io(const Handle hf, const size_t size, void** p)
|
||||
ssize_t vfs_io(const Handle hf, const size_t size, void** p, FileIOCB cb, uintptr_t ctx)
|
||||
{
|
||||
#ifdef PARANOIA
|
||||
debug_out("vfs_io size=%d\n", size);
|
||||
@ -1389,12 +1389,12 @@ debug_out("vfs_io size=%d\n", size);
|
||||
|
||||
// (vfs_open makes sure it's not opened for writing if zip)
|
||||
if(vf_flags(vf) & VF_ZIP)
|
||||
return zip_read(&vf->zf, ofs, size, p);
|
||||
return zip_read(&vf->zf, ofs, size, p, cb, ctx);
|
||||
|
||||
// normal file:
|
||||
// let file_io alloc the buffer if the caller didn't (i.e. p = 0),
|
||||
// because it knows about alignment / padding requirements
|
||||
return file_io(&vf->f, ofs, size, p);
|
||||
return file_io(&vf->f, ofs, size, p, cb, ctx);
|
||||
}
|
||||
|
||||
|
||||
|
@ -165,7 +165,7 @@ extern int vfs_discard_io(Handle& hio);
|
||||
// (read or write access was chosen at file-open time).
|
||||
// return bytes of actual data transferred, or a negative error code.
|
||||
// TODO: buffer types
|
||||
extern ssize_t vfs_io(Handle hf, size_t size, void** p);
|
||||
extern ssize_t vfs_io(Handle hf, size_t size, void** p, FileIOCB cb = 0, uintptr_t ctx = 0);
|
||||
|
||||
// load the entire file <fn> into memory; return a memory handle to the
|
||||
// buffer and its address/size. output parameters are zeroed on failure.
|
||||
|
@ -948,9 +948,31 @@ int zip_close(ZFile* zf)
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
struct IOCBParams
|
||||
{
|
||||
uintptr_t inf_ctx;
|
||||
|
||||
FileIOCB user_cb;
|
||||
uintptr_t user_ctx;
|
||||
};
|
||||
|
||||
|
||||
static ssize_t io_cb(uintptr_t ctx, void* buf, size_t size)
|
||||
{
|
||||
IOCBParams* p = (IOCBParams*)ctx;
|
||||
|
||||
CHECK_ERR(inf_inflate(p->inf_ctx, buf, size));
|
||||
|
||||
if(p->user_cb)
|
||||
return p->user_cb(p->user_ctx, buf, size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// note: we go to a bit of trouble to make sure the buffer we allocated
|
||||
// (if p == 0) is freed when the read fails.
|
||||
ssize_t zip_read(ZFile* zf, off_t raw_ofs, size_t size, void** p)
|
||||
ssize_t zip_read(ZFile* zf, off_t raw_ofs, size_t size, void** p, FileIOCB cb, uintptr_t ctx)
|
||||
{
|
||||
CHECK_ZFILE(zf);
|
||||
|
||||
@ -1012,11 +1034,13 @@ fail:
|
||||
return err;
|
||||
}
|
||||
|
||||
const IOCBParams params = { zf->inf_ctx, cb, ctx };
|
||||
|
||||
// read blocks from the archive's file starting at ofs and pass them to
|
||||
// zip_inflate, until all compressed data has been read, or it indicates
|
||||
// inf_inflate, until all compressed data has been read, or it indicates
|
||||
// the desired output amount has been reached.
|
||||
const size_t raw_size = zf->csize;
|
||||
raw_bytes_read = file_io(&za->f, ofs, raw_size, (void**)0, inf_inflate, zf->inf_ctx);
|
||||
raw_bytes_read = file_io(&za->f, ofs, raw_size, (void**)0, io_cb, (uintptr_t)¶ms);
|
||||
|
||||
zf->last_raw_ofs = raw_ofs + (off_t)raw_bytes_read;
|
||||
|
||||
|
@ -121,7 +121,7 @@ extern int zip_discard_io(Handle& hio);
|
||||
//
|
||||
|
||||
// read from file <zf>, starting at offset <ofs> in the compressed data.
|
||||
extern ssize_t zip_read(ZFile* zf, off_t ofs, size_t size, void** p);
|
||||
extern ssize_t zip_read(ZFile* zf, off_t ofs, size_t size, void** p, FileIOCB cb = 0, uintptr_t ctx = 0);
|
||||
|
||||
|
||||
#endif // #ifndef ZIP_H__
|
||||
|
Loading…
Reference in New Issue
Block a user