.TH "PHYSFS_Archiver" 3 "Fri Oct 7 2022" "Version 3.2.0" "physfs" \" -*- nroff -*- .ad l .nh .SH NAME PHYSFS_Archiver \- Abstract interface to provide support for user-defined archives\&. .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 "\fBPHYSFS_ArchiveInfo\fP \fBinfo\fP" .br .RI "Basic info about this archiver\&. " .ti -1c .RI "void *(* \fBopenArchive\fP )(\fBPHYSFS_Io\fP *io, const char *name, int forWrite, int *claimed)" .br .RI "Open an archive provided by (io)\&. " .ti -1c .RI "\fBPHYSFS_EnumerateCallbackResult\fP(* \fBenumerate\fP )(void *opaque, const char *dirname, \fBPHYSFS_EnumerateCallback\fP cb, const char *origdir, void *callbackdata)" .br .RI "List all files in (dirname)\&. " .ti -1c .RI "\fBPHYSFS_Io\fP *(* \fBopenRead\fP )(void *opaque, const char *fnm)" .br .RI "Open a file in this archive for reading\&. " .ti -1c .RI "\fBPHYSFS_Io\fP *(* \fBopenWrite\fP )(void *opaque, const char *filename)" .br .RI "Open a file in this archive for writing\&. " .ti -1c .RI "\fBPHYSFS_Io\fP *(* \fBopenAppend\fP )(void *opaque, const char *filename)" .br .RI "Open a file in this archive for appending\&. " .ti -1c .RI "int(* \fBremove\fP )(void *opaque, const char *filename)" .br .RI "Delete a file or directory in the archive\&. " .ti -1c .RI "int(* \fBmkdir\fP )(void *opaque, const char *filename)" .br .RI "Create a directory in the archive\&. " .ti -1c .RI "int(* \fBstat\fP )(void *opaque, const char *fn, \fBPHYSFS_Stat\fP *stat)" .br .RI "Obtain basic file metadata\&. " .ti -1c .RI "void(* \fBcloseArchive\fP )(void *opaque)" .br .RI "Destruct a previously-opened archive\&. " .in -1c .SH "Detailed Description" .PP Abstract interface to provide support for user-defined archives\&. .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 a means to mount various archive file formats, and physical directories in the native filesystem\&. However, applications have been limited to the file formats provided by the library\&. This interface allows an application to provide their own archive file types\&. .PP Conceptually, a \fBPHYSFS_Archiver\fP provides directory entries, while \fBPHYSFS_Io\fP provides data streams for those directory entries\&. The most obvious use of \fBPHYSFS_Archiver\fP is to provide support for an archive file type that isn't provided by PhysicsFS directly: perhaps some proprietary format that only your application needs to understand\&. .PP Internally, all the built-in archive support uses this interface, so the best examples for building a \fBPHYSFS_Archiver\fP is the source code to PhysicsFS itself\&. .PP An archiver is added to the system with \fBPHYSFS_registerArchiver()\fP, and then it will be available for use automatically with \fBPHYSFS_mount()\fP; if a given archive can be handled with your archiver, it will be given control as appropriate\&. .PP These methods deal with dir handles\&. You have one instance of your archiver, and it generates a unique, opaque handle for each opened archive in its \fBopenArchive()\fP method\&. Since the lifetime of an Archiver (not an archive) is generally the entire lifetime of the process, and it's assumed to be a singleton, we do not provide any instance data for the archiver itself; the app can just use some static variables if necessary\&. .PP Symlinks should always be followed (except in \fBstat()\fP); PhysicsFS will use the \fBstat()\fP method to check for symlinks and make a judgement on whether to continue to call other methods based on that\&. .PP Archivers, when necessary, should set the PhysicsFS error state with \fBPHYSFS_setErrorCode()\fP before returning\&. PhysicsFS will pass these errors back to the application unmolested in most cases\&. .PP Thread safety: \fBPHYSFS_Archiver\fP implementations are not guaranteed to be thread safe in themselves\&. PhysicsFS provides thread safety when it calls into a given archiver inside the library, but it does not promise that using the same \fBPHYSFS_File\fP from two threads at once is thread-safe; as such, your \fBPHYSFS_Archiver\fP can assume that locking is handled for you so long as the \fBPHYSFS_Io\fP you return from PHYSFS_open* doesn't change any of your Archiver state, as the \fBPHYSFS_Io\fP won't be as aggressively protected\&. .PP \fBSee also\fP .RS 4 \fBPHYSFS_registerArchiver\fP .PP \fBPHYSFS_deregisterArchiver\fP .PP \fBPHYSFS_supportedArchiveTypes\fP .RE .PP .SH "Field Documentation" .PP .SS "void(* PHYSFS_Archiver::closeArchive) (void *opaque)" .PP Destruct a previously-opened archive\&. Close this archive, and free any associated memory, including the original \fBPHYSFS_Io\fP and (opaque) itself, if applicable\&. Implementation can assume that it won't be called if there are still files open from this archive\&. .SS "\fBPHYSFS_EnumerateCallbackResult\fP(* PHYSFS_Archiver::enumerate) (void *opaque, const char *dirname, \fBPHYSFS_EnumerateCallback\fP cb, const char *origdir, void *callbackdata)" .PP List all files in (dirname)\&. Each file is passed to (cb), where a copy is made if appropriate, so you can dispose of it upon return from the callback\&. (dirname) is in platform-independent notation\&. If you have a failure, call PHYSFS_SetErrorCode() with whatever code seem appropriate and return PHYSFS_ENUM_ERROR\&. If the callback returns PHYSFS_ENUM_ERROR, please call PHYSFS_SetErrorCode(PHYSFS_ERR_APP_CALLBACK) and then return PHYSFS_ENUM_ERROR as well\&. Don't call the callback again in any circumstances\&. If the callback returns PHYSFS_ENUM_STOP, stop enumerating and return PHYSFS_ENUM_STOP as well\&. Don't call the callback again in any circumstances\&. Don't set an error code in this case\&. Callbacks are only supposed to return a value from PHYSFS_EnumerateCallbackResult\&. Any other result has undefined behavior\&. As long as the callback returned PHYSFS_ENUM_OK and you haven't experienced any errors of your own, keep enumerating until you're done and then return PHYSFS_ENUM_OK without setting an error code\&. .PP \fBWarning\fP .RS 4 PHYSFS_enumerate returns zero or non-zero (success or failure), so be aware this function pointer returns different values! .RE .PP .SS "\fBPHYSFS_ArchiveInfo\fP PHYSFS_Archiver::info" .PP Basic info about this archiver\&. This is used to identify your archive, and is returned in \fBPHYSFS_supportedArchiveTypes()\fP\&. .SS "int(* PHYSFS_Archiver::mkdir) (void *opaque, const char *filename)" .PP Create a directory in the archive\&. If the application is trying to make multiple dirs, PhysicsFS will split them up into multiple calls before passing them to your driver\&. If the archive is read-only, this operation should fail\&. Return non-zero on success, zero on failure\&. This filename is in platform-independent notation\&. On failure, call \fBPHYSFS_setErrorCode()\fP\&. .SS "\fBPHYSFS_Io\fP *(* PHYSFS_Archiver::openAppend) (void *opaque, const char *filename)" .PP Open a file in this archive for appending\&. If the file does not exist, it should be created\&. The writing offset should be the end of the file\&. If the archive is read-only, this operation should fail\&. This filename is in platform-independent notation\&. Returns NULL on failure, and calls \fBPHYSFS_setErrorCode()\fP\&. Returns non-NULL on success\&. The pointer returned will be passed as the 'opaque' parameter for later file calls\&. .SS "void *(* PHYSFS_Archiver::openArchive) (\fBPHYSFS_Io\fP *io, const char *name, int forWrite, int *claimed)" .PP Open an archive provided by (io)\&. This is where resources are allocated and data is parsed when mounting an archive\&. (name) is a filename associated with (io), but doesn't necessarily map to anything, let alone a real filename\&. This possibly- meaningless name is in platform-dependent notation\&. (forWrite) is non-zero if this is to be used for the write directory, and zero if this is to be used for an element of the search path\&. (claimed) should be set to 1 if this is definitely an archive your archiver implementation can handle, even if it fails\&. We use to decide if we should stop trying other archivers if you fail to open it\&. For example: the \&.zip archiver will set this to 1 for something that's got a \&.zip file signature, even if it failed because the file was also truncated\&. No sense in trying other archivers here, we already tried to handle it with the appropriate implementation!\&. Return NULL on failure and set (claimed) appropriately\&. If no archiver opened the archive or set (claimed), \fBPHYSFS_mount()\fP will report PHYSFS_ERR_UNSUPPORTED\&. Otherwise, it will report the error from the archiver that claimed the data through (claimed)\&. Return non-NULL on success\&. The pointer returned will be passed as the 'opaque' parameter for later calls\&. .SS "\fBPHYSFS_Io\fP *(* PHYSFS_Archiver::openRead) (void *opaque, const char *fnm)" .PP Open a file in this archive for reading\&. This filename, (fnm), is in platform-independent notation\&. Fail if the file does not exist\&. Returns NULL on failure, and calls \fBPHYSFS_setErrorCode()\fP\&. Returns non-NULL on success\&. The pointer returned will be passed as the 'opaque' parameter for later file calls\&. .SS "\fBPHYSFS_Io\fP *(* PHYSFS_Archiver::openWrite) (void *opaque, const char *filename)" .PP Open a file in this archive for writing\&. If the file does not exist, it should be created\&. If it exists, it should be truncated to zero bytes\&. The writing offset should be the start of the file\&. If the archive is read-only, this operation should fail\&. This filename is in platform-independent notation\&. Returns NULL on failure, and calls \fBPHYSFS_setErrorCode()\fP\&. Returns non-NULL on success\&. The pointer returned will be passed as the 'opaque' parameter for later file calls\&. .SS "int(* PHYSFS_Archiver::remove) (void *opaque, const char *filename)" .PP Delete a file or directory in the archive\&. This same call is used for both files and directories; there is not a separate rmdir() call\&. Directories are only meant to be removed if they are empty\&. If the archive is read-only, this operation should fail\&. .PP Return non-zero on success, zero on failure\&. This filename is in platform-independent notation\&. On failure, call \fBPHYSFS_setErrorCode()\fP\&. .SS "int(* PHYSFS_Archiver::stat) (void *opaque, const char *fn, \fBPHYSFS_Stat\fP *stat)" .PP Obtain basic file metadata\&. On success, fill in all the fields in (stat), using reasonable defaults for fields that apply to your archive\&. .PP Returns non-zero on success, zero on failure\&. This filename is in platform-independent notation\&. On failure, call \fBPHYSFS_setErrorCode()\fP\&. .SS "\fBPHYSFS_uint32\fP PHYSFS_Archiver::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\&. .SH "Author" .PP Generated automatically by Doxygen for physfs from the source code\&.