.TH "PHYSFS_Io" 3 "Fri Oct 7 2022" "Version 3.2.0" "physfs" \" -*- nroff -*- .ad l .nh .SH NAME PHYSFS_Io \- An abstract i/o interface\&. .SH SYNOPSIS .br .PP .PP \fC#include \fP .SS "Data Fields" .in +1c .ti -1c .RI "\fBPHYSFS_uint32\fP \fBversion\fP" .br .RI "Binary compatibility information\&. " .ti -1c .RI "void * \fBopaque\fP" .br .RI "Instance data for this struct\&. " .ti -1c .RI "\fBPHYSFS_sint64\fP(* \fBread\fP )(struct \fBPHYSFS_Io\fP *io, void *buf, \fBPHYSFS_uint64\fP len)" .br .RI "Read more data\&. " .ti -1c .RI "\fBPHYSFS_sint64\fP(* \fBwrite\fP )(struct \fBPHYSFS_Io\fP *io, const void *buffer, \fBPHYSFS_uint64\fP len)" .br .RI "Write more data\&. " .ti -1c .RI "int(* \fBseek\fP )(struct \fBPHYSFS_Io\fP *io, \fBPHYSFS_uint64\fP offset)" .br .RI "Move i/o position to a given byte offset from start\&. " .ti -1c .RI "\fBPHYSFS_sint64\fP(* \fBtell\fP )(struct \fBPHYSFS_Io\fP *io)" .br .RI "Report current i/o position\&. " .ti -1c .RI "\fBPHYSFS_sint64\fP(* \fBlength\fP )(struct \fBPHYSFS_Io\fP *io)" .br .RI "Determine size of the i/o instance's dataset\&. " .ti -1c .RI "struct \fBPHYSFS_Io\fP *(* \fBduplicate\fP )(struct \fBPHYSFS_Io\fP *io)" .br .RI "Duplicate this i/o instance\&. " .ti -1c .RI "int(* \fBflush\fP )(struct \fBPHYSFS_Io\fP *io)" .br .RI "Flush resources to media, or wherever\&. " .ti -1c .RI "void(* \fBdestroy\fP )(struct \fBPHYSFS_Io\fP *io)" .br .RI "Cleanup and deallocate i/o instance\&. " .in -1c .SH "Detailed Description" .PP An abstract i/o interface\&. .PP \fBWarning\fP .RS 4 This is advanced, hardcore stuff\&. You don't need this unless you really know what you're doing\&. Most apps will not need this\&. .RE .PP Historically, PhysicsFS provided access to the physical filesystem and archives within that filesystem\&. However, sometimes you need more power than this\&. Perhaps you need to provide an archive that is entirely contained in RAM, or you need to bridge some other file i/o API to PhysicsFS, or you need to translate the bits (perhaps you have a a standard \&.zip file that's encrypted, and you need to decrypt on the fly for the unsuspecting zip archiver)\&. .PP A \fBPHYSFS_Io\fP is the interface that Archivers use to get archive data\&. Historically, this has mapped to file i/o to the physical filesystem, but as of PhysicsFS 2\&.1, applications can provide their own i/o implementations at runtime\&. .PP This interface isn't necessarily a good universal fit for i/o\&. There are a few requirements of note: .PP .IP "\(bu" 2 They only do blocking i/o (at least, for now)\&. .IP "\(bu" 2 They need to be able to duplicate\&. If you have a file handle from fopen(), you need to be able to create a unique clone of it (so we have two handles to the same file that can both seek/read/etc without stepping on each other)\&. .IP "\(bu" 2 They need to know the size of their entire data set\&. .IP "\(bu" 2 They need to be able to seek and rewind on demand\&. .PP .PP \&.\&.\&.in short, you're probably not going to write an HTTP implementation\&. .PP Thread safety: \fBPHYSFS_Io\fP implementations are not guaranteed to be thread safe in themselves\&. Under the hood where PhysicsFS uses them, the library provides its own locks\&. If you plan to use them directly from separate threads, you should either use mutexes to protect them, or don't use the same \fBPHYSFS_Io\fP from two threads at the same time\&. .PP \fBSee also\fP .RS 4 \fBPHYSFS_mountIo\fP .RE .PP .SH "Field Documentation" .PP .SS "void(* PHYSFS_Io::destroy) (struct \fBPHYSFS_Io\fP *io)" .PP Cleanup and deallocate i/o instance\&. Free associated resources, including (opaque) if applicable\&. .PP This function must always succeed: as such, it returns void\&. The system may call your \fBflush()\fP method before this\&. You may report failure there if necessary\&. This method may still be called if \fBflush()\fP fails, in which case you'll have to abandon unflushed data and other failing conditions and clean up\&. .PP Once this method is called for a given instance, the system will assume it is unsafe to touch that instance again and will discard any references to it\&. .PP \fBParameters\fP .RS 4 \fIs\fP The i/o instance to destroy\&. .RE .PP .SS "struct \fBPHYSFS_Io\fP *(* PHYSFS_Io::duplicate) (struct \fBPHYSFS_Io\fP *io)" .PP Duplicate this i/o instance\&. This needs to result in a full copy of this \fBPHYSFS_Io\fP, that can live completely independently\&. The copy needs to be able to perform all its operations without altering the original, including either object being destroyed separately (so, for example: they can't share a file handle; they each need their own)\&. .PP If you can't duplicate a handle, it's legal to return NULL, but you almost certainly need this functionality if you want to use this to \fBPHYSFS_Io\fP to back an archive\&. .PP \fBParameters\fP .RS 4 \fIio\fP The i/o instance to duplicate\&. .RE .PP \fBReturns\fP .RS 4 A new value for a stream's (opaque) field, or NULL on error\&. .RE .PP .SS "int(* PHYSFS_Io::flush) (struct \fBPHYSFS_Io\fP *io)" .PP Flush resources to media, or wherever\&. This is the chance to report failure for writes that had claimed success earlier, but still had a chance to actually fail\&. This method can be NULL if flushing isn't necessary\&. .PP This function may be called before \fBdestroy()\fP, as it can report failure and \fBdestroy()\fP can not\&. It may be called at other times, too\&. .PP \fBParameters\fP .RS 4 \fIio\fP The i/o instance to flush\&. .RE .PP \fBReturns\fP .RS 4 Zero on error, non-zero on success\&. .RE .PP .SS "\fBPHYSFS_sint64\fP(* PHYSFS_Io::length) (struct \fBPHYSFS_Io\fP *io)" .PP Determine size of the i/o instance's dataset\&. Return number of bytes available in the file, or -1 if you aren't able to determine\&. A failure will almost certainly be fatal to further use of this stream, so you may not leave this unimplemented\&. .PP \fBParameters\fP .RS 4 \fIio\fP The i/o instance to query\&. .RE .PP \fBReturns\fP .RS 4 Total size, in bytes, of the dataset\&. .RE .PP .SS "void* PHYSFS_Io::opaque" .PP Instance data for this struct\&. Each instance has a pointer associated with it that can be used to store anything it likes\&. This pointer is per-instance of the stream, so presumably it will change when calling \fBduplicate()\fP\&. This can be deallocated during the \fBdestroy()\fP method\&. .SS "\fBPHYSFS_sint64\fP(* PHYSFS_Io::read) (struct \fBPHYSFS_Io\fP *io, void *buf, \fBPHYSFS_uint64\fP len)" .PP Read more data\&. Read (len) bytes from the interface, at the current i/o position, and store them in (buffer)\&. The current i/o position should move ahead by the number of bytes successfully read\&. .PP You don't have to implement this; set it to NULL if not implemented\&. This will only be used if the file is opened for reading\&. If set to NULL, a default implementation that immediately reports failure will be used\&. .PP \fBParameters\fP .RS 4 \fIio\fP The i/o instance to read from\&. .br \fIbuf\fP The buffer to store data into\&. It must be at least (len) bytes long and can't be NULL\&. .br \fIlen\fP The number of bytes to read from the interface\&. .RE .PP \fBReturns\fP .RS 4 number of bytes read from file, 0 on EOF, -1 if complete failure\&. .RE .PP .SS "int(* PHYSFS_Io::seek) (struct \fBPHYSFS_Io\fP *io, \fBPHYSFS_uint64\fP offset)" .PP Move i/o position to a given byte offset from start\&. This method moves the i/o position, so the next read/write will be of the byte at (offset) offset\&. Seeks past the end of file should be treated as an error condition\&. .PP \fBParameters\fP .RS 4 \fIio\fP The i/o instance to seek\&. .br \fIoffset\fP The new byte offset for the i/o position\&. .RE .PP \fBReturns\fP .RS 4 non-zero on success, zero on error\&. .RE .PP .SS "\fBPHYSFS_sint64\fP(* PHYSFS_Io::tell) (struct \fBPHYSFS_Io\fP *io)" .PP Report current i/o position\&. Return bytes offset, or -1 if you aren't able to determine\&. A failure will almost certainly be fatal to further use of this stream, so you may not leave this unimplemented\&. .PP \fBParameters\fP .RS 4 \fIio\fP The i/o instance to query\&. .RE .PP \fBReturns\fP .RS 4 The current byte offset for the i/o position, -1 if unknown\&. .RE .PP .SS "\fBPHYSFS_uint32\fP PHYSFS_Io::version" .PP Binary compatibility information\&. This must be set to zero at this time\&. Future versions of this struct will increment this field, so we know what a given implementation supports\&. We'll presumably keep supporting older versions as we offer new features, though\&. .SS "\fBPHYSFS_sint64\fP(* PHYSFS_Io::write) (struct \fBPHYSFS_Io\fP *io, const void *buffer, \fBPHYSFS_uint64\fP len)" .PP Write more data\&. Write (len) bytes from (buffer) to the interface at the current i/o position\&. The current i/o position should move ahead by the number of bytes successfully written\&. .PP You don't have to implement this; set it to NULL if not implemented\&. This will only be used if the file is opened for writing\&. If set to NULL, a default implementation that immediately reports failure will be used\&. .PP You are allowed to buffer; a write can succeed here and then later fail when flushing\&. Note that \fBPHYSFS_setBuffer()\fP may be operating a level above your i/o, so you should usually not implement your own buffering routines\&. .PP \fBParameters\fP .RS 4 \fIio\fP The i/o instance to write to\&. .br \fIbuffer\fP The buffer to read data from\&. It must be at least (len) bytes long and can't be NULL\&. .br \fIlen\fP The number of bytes to read from (buffer)\&. .RE .PP \fBReturns\fP .RS 4 number of bytes written to file, -1 if complete failure\&. .RE .PP .SH "Author" .PP Generated automatically by Doxygen for physfs from the source code\&.