\section{P\+H\+Y\+S\+F\+S\+\_\+\+Archiver Struct Reference}
\label{structPHYSFS__Archiver}\index{P\+H\+Y\+S\+F\+S\+\_\+\+Archiver@{P\+H\+Y\+S\+F\+S\+\_\+\+Archiver}}


Abstract interface to provide support for user-\/defined archives.  




{\ttfamily \#include $<$physfs.\+h$>$}

\subsection*{Data Fields}
\begin{DoxyCompactItemize}
\item 
\textbf{ P\+H\+Y\+S\+F\+S\+\_\+uint32} \textbf{ version}
\begin{DoxyCompactList}\small\item\em Binary compatibility information. \end{DoxyCompactList}\item 
\textbf{ P\+H\+Y\+S\+F\+S\+\_\+\+Archive\+Info} \textbf{ info}
\begin{DoxyCompactList}\small\item\em Basic info about this archiver. \end{DoxyCompactList}\item 
void $\ast$($\ast$ \textbf{ open\+Archive} )(\textbf{ P\+H\+Y\+S\+F\+S\+\_\+\+Io} $\ast$io, const char $\ast$name, int for\+Write, int $\ast$claimed)
\begin{DoxyCompactList}\small\item\em Open an archive provided by (io). \end{DoxyCompactList}\item 
\textbf{ P\+H\+Y\+S\+F\+S\+\_\+\+Enumerate\+Callback\+Result}($\ast$ \textbf{ enumerate} )(void $\ast$opaque, const char $\ast$dirname, \textbf{ P\+H\+Y\+S\+F\+S\+\_\+\+Enumerate\+Callback} cb, const char $\ast$origdir, void $\ast$callbackdata)
\begin{DoxyCompactList}\small\item\em List all files in (dirname). \end{DoxyCompactList}\item 
\textbf{ P\+H\+Y\+S\+F\+S\+\_\+\+Io} $\ast$($\ast$ \textbf{ open\+Read} )(void $\ast$opaque, const char $\ast$fnm)
\begin{DoxyCompactList}\small\item\em Open a file in this archive for reading. \end{DoxyCompactList}\item 
\textbf{ P\+H\+Y\+S\+F\+S\+\_\+\+Io} $\ast$($\ast$ \textbf{ open\+Write} )(void $\ast$opaque, const char $\ast$filename)
\begin{DoxyCompactList}\small\item\em Open a file in this archive for writing. \end{DoxyCompactList}\item 
\textbf{ P\+H\+Y\+S\+F\+S\+\_\+\+Io} $\ast$($\ast$ \textbf{ open\+Append} )(void $\ast$opaque, const char $\ast$filename)
\begin{DoxyCompactList}\small\item\em Open a file in this archive for appending. \end{DoxyCompactList}\item 
int($\ast$ \textbf{ remove} )(void $\ast$opaque, const char $\ast$filename)
\begin{DoxyCompactList}\small\item\em Delete a file or directory in the archive. \end{DoxyCompactList}\item 
int($\ast$ \textbf{ mkdir} )(void $\ast$opaque, const char $\ast$filename)
\begin{DoxyCompactList}\small\item\em Create a directory in the archive. \end{DoxyCompactList}\item 
int($\ast$ \textbf{ stat} )(void $\ast$opaque, const char $\ast$fn, \textbf{ P\+H\+Y\+S\+F\+S\+\_\+\+Stat} $\ast$stat)
\begin{DoxyCompactList}\small\item\em Obtain basic file metadata. \end{DoxyCompactList}\item 
void($\ast$ \textbf{ close\+Archive} )(void $\ast$opaque)
\begin{DoxyCompactList}\small\item\em Destruct a previously-\/opened archive. \end{DoxyCompactList}\end{DoxyCompactItemize}


\subsection{Detailed Description}
Abstract interface to provide support for user-\/defined archives. 

\begin{DoxyWarning}{Warning}
This is advanced, hardcore stuff. You don\textquotesingle{}t need this unless you really know what you\textquotesingle{}re doing. Most apps will not need this.
\end{DoxyWarning}
Historically, Physics\+FS 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.

Conceptually, a \doxyref{P\+H\+Y\+S\+F\+S\+\_\+\+Archiver}{p.}{structPHYSFS__Archiver} provides directory entries, while \doxyref{P\+H\+Y\+S\+F\+S\+\_\+\+Io}{p.}{structPHYSFS__Io} provides data streams for those directory entries. The most obvious use of \doxyref{P\+H\+Y\+S\+F\+S\+\_\+\+Archiver}{p.}{structPHYSFS__Archiver} is to provide support for an archive file type that isn\textquotesingle{}t provided by Physics\+FS directly\+: perhaps some proprietary format that only your application needs to understand.

Internally, all the built-\/in archive support uses this interface, so the best examples for building a \doxyref{P\+H\+Y\+S\+F\+S\+\_\+\+Archiver}{p.}{structPHYSFS__Archiver} is the source code to Physics\+FS itself.

An archiver is added to the system with \doxyref{P\+H\+Y\+S\+F\+S\+\_\+register\+Archiver()}{p.}{physfs_8h_ace0ecda857dc622e2d005af02972237d}, and then it will be available for use automatically with \doxyref{P\+H\+Y\+S\+F\+S\+\_\+mount()}{p.}{physfs_8h_a8eb320e9af03dcdb4c05bbff3ea604d4}; if a given archive can be handled with your archiver, it will be given control as appropriate.

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 \doxyref{open\+Archive()}{p.}{structPHYSFS__Archiver_a2cc593f1ba701070668ffa43c8a7c0c3} method. Since the lifetime of an Archiver (not an archive) is generally the entire lifetime of the process, and it\textquotesingle{}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.

Symlinks should always be followed (except in \doxyref{stat()}{p.}{structPHYSFS__Archiver_a328a2e28430dfab9abe53678b29d0dbb}); Physics\+FS will use the \doxyref{stat()}{p.}{structPHYSFS__Archiver_a328a2e28430dfab9abe53678b29d0dbb} method to check for symlinks and make a judgement on whether to continue to call other methods based on that.

Archivers, when necessary, should set the Physics\+FS error state with \doxyref{P\+H\+Y\+S\+F\+S\+\_\+set\+Error\+Code()}{p.}{physfs_8h_ade2c854542c68abc2015649fadd3a623} before returning. Physics\+FS will pass these errors back to the application unmolested in most cases.

Thread safety\+: \doxyref{P\+H\+Y\+S\+F\+S\+\_\+\+Archiver}{p.}{structPHYSFS__Archiver} implementations are not guaranteed to be thread safe in themselves. Physics\+FS provides thread safety when it calls into a given archiver inside the library, but it does not promise that using the same \doxyref{P\+H\+Y\+S\+F\+S\+\_\+\+File}{p.}{structPHYSFS__File} from two threads at once is thread-\/safe; as such, your \doxyref{P\+H\+Y\+S\+F\+S\+\_\+\+Archiver}{p.}{structPHYSFS__Archiver} can assume that locking is handled for you so long as the \doxyref{P\+H\+Y\+S\+F\+S\+\_\+\+Io}{p.}{structPHYSFS__Io} you return from P\+H\+Y\+S\+F\+S\+\_\+open$\ast$ doesn\textquotesingle{}t change any of your Archiver state, as the \doxyref{P\+H\+Y\+S\+F\+S\+\_\+\+Io}{p.}{structPHYSFS__Io} won\textquotesingle{}t be as aggressively protected.

\begin{DoxySeeAlso}{See also}
\doxyref{P\+H\+Y\+S\+F\+S\+\_\+register\+Archiver}{p.}{physfs_8h_ace0ecda857dc622e2d005af02972237d} 

\doxyref{P\+H\+Y\+S\+F\+S\+\_\+deregister\+Archiver}{p.}{physfs_8h_abbc7cce9112c5ddc2f3a9ad5d0edf6e0} 

\doxyref{P\+H\+Y\+S\+F\+S\+\_\+supported\+Archive\+Types}{p.}{physfs_8h_a4ca65fbaa485d68113912bbbd70bd19e} 
\end{DoxySeeAlso}


\subsection{Field Documentation}
\mbox{\label{structPHYSFS__Archiver_a28a949a909f8ee4688077d3339b2f3f9}} 
\index{P\+H\+Y\+S\+F\+S\+\_\+\+Archiver@{P\+H\+Y\+S\+F\+S\+\_\+\+Archiver}!close\+Archive@{close\+Archive}}
\index{close\+Archive@{close\+Archive}!P\+H\+Y\+S\+F\+S\+\_\+\+Archiver@{P\+H\+Y\+S\+F\+S\+\_\+\+Archiver}}
\subsubsection{close\+Archive}
{\footnotesize\ttfamily void($\ast$ P\+H\+Y\+S\+F\+S\+\_\+\+Archiver\+::close\+Archive) (void $\ast$opaque)}



Destruct a previously-\/opened archive. 

Close this archive, and free any associated memory, including the original \doxyref{P\+H\+Y\+S\+F\+S\+\_\+\+Io}{p.}{structPHYSFS__Io} and (opaque) itself, if applicable. Implementation can assume that it won\textquotesingle{}t be called if there are still files open from this archive. \mbox{\label{structPHYSFS__Archiver_a9ae4a30fb4095aa90259da021ebc3ff6}} 
\index{P\+H\+Y\+S\+F\+S\+\_\+\+Archiver@{P\+H\+Y\+S\+F\+S\+\_\+\+Archiver}!enumerate@{enumerate}}
\index{enumerate@{enumerate}!P\+H\+Y\+S\+F\+S\+\_\+\+Archiver@{P\+H\+Y\+S\+F\+S\+\_\+\+Archiver}}
\subsubsection{enumerate}
{\footnotesize\ttfamily \textbf{ P\+H\+Y\+S\+F\+S\+\_\+\+Enumerate\+Callback\+Result}($\ast$ P\+H\+Y\+S\+F\+S\+\_\+\+Archiver\+::enumerate) (void $\ast$opaque, const char $\ast$dirname, \textbf{ P\+H\+Y\+S\+F\+S\+\_\+\+Enumerate\+Callback} cb, const char $\ast$origdir, void $\ast$callbackdata)}



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 P\+H\+Y\+S\+F\+S\+\_\+\+Set\+Error\+Code() with whatever code seem appropriate and return P\+H\+Y\+S\+F\+S\+\_\+\+E\+N\+U\+M\+\_\+\+E\+R\+R\+OR. If the callback returns P\+H\+Y\+S\+F\+S\+\_\+\+E\+N\+U\+M\+\_\+\+E\+R\+R\+OR, please call P\+H\+Y\+S\+F\+S\+\_\+\+Set\+Error\+Code(\+P\+H\+Y\+S\+F\+S\+\_\+\+E\+R\+R\+\_\+\+A\+P\+P\+\_\+\+C\+A\+L\+L\+B\+A\+C\+K) and then return P\+H\+Y\+S\+F\+S\+\_\+\+E\+N\+U\+M\+\_\+\+E\+R\+R\+OR as well. Don\textquotesingle{}t call the callback again in any circumstances. If the callback returns P\+H\+Y\+S\+F\+S\+\_\+\+E\+N\+U\+M\+\_\+\+S\+T\+OP, stop enumerating and return P\+H\+Y\+S\+F\+S\+\_\+\+E\+N\+U\+M\+\_\+\+S\+T\+OP as well. Don\textquotesingle{}t call the callback again in any circumstances. Don\textquotesingle{}t set an error code in this case. Callbacks are only supposed to return a value from P\+H\+Y\+S\+F\+S\+\_\+\+Enumerate\+Callback\+Result. Any other result has undefined behavior. As long as the callback returned P\+H\+Y\+S\+F\+S\+\_\+\+E\+N\+U\+M\+\_\+\+OK and you haven\textquotesingle{}t experienced any errors of your own, keep enumerating until you\textquotesingle{}re done and then return P\+H\+Y\+S\+F\+S\+\_\+\+E\+N\+U\+M\+\_\+\+OK without setting an error code.

\begin{DoxyWarning}{Warning}
P\+H\+Y\+S\+F\+S\+\_\+enumerate returns zero or non-\/zero (success or failure), so be aware this function pointer returns different values! 
\end{DoxyWarning}
\mbox{\label{structPHYSFS__Archiver_ac5352f0640f0e2bcb9b8adfd467c8096}} 
\index{P\+H\+Y\+S\+F\+S\+\_\+\+Archiver@{P\+H\+Y\+S\+F\+S\+\_\+\+Archiver}!info@{info}}
\index{info@{info}!P\+H\+Y\+S\+F\+S\+\_\+\+Archiver@{P\+H\+Y\+S\+F\+S\+\_\+\+Archiver}}
\subsubsection{info}
{\footnotesize\ttfamily \textbf{ P\+H\+Y\+S\+F\+S\+\_\+\+Archive\+Info} P\+H\+Y\+S\+F\+S\+\_\+\+Archiver\+::info}



Basic info about this archiver. 

This is used to identify your archive, and is returned in \doxyref{P\+H\+Y\+S\+F\+S\+\_\+supported\+Archive\+Types()}{p.}{physfs_8h_a4ca65fbaa485d68113912bbbd70bd19e}. \mbox{\label{structPHYSFS__Archiver_abd95b2a3afb0f94025c486b514d72189}} 
\index{P\+H\+Y\+S\+F\+S\+\_\+\+Archiver@{P\+H\+Y\+S\+F\+S\+\_\+\+Archiver}!mkdir@{mkdir}}
\index{mkdir@{mkdir}!P\+H\+Y\+S\+F\+S\+\_\+\+Archiver@{P\+H\+Y\+S\+F\+S\+\_\+\+Archiver}}
\subsubsection{mkdir}
{\footnotesize\ttfamily int($\ast$ P\+H\+Y\+S\+F\+S\+\_\+\+Archiver\+::mkdir) (void $\ast$opaque, const char $\ast$filename)}



Create a directory in the archive. 

If the application is trying to make multiple dirs, Physics\+FS 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 \doxyref{P\+H\+Y\+S\+F\+S\+\_\+set\+Error\+Code()}{p.}{physfs_8h_ade2c854542c68abc2015649fadd3a623}. \mbox{\label{structPHYSFS__Archiver_a2f0c79cf149c6084451835e112eaed44}} 
\index{P\+H\+Y\+S\+F\+S\+\_\+\+Archiver@{P\+H\+Y\+S\+F\+S\+\_\+\+Archiver}!open\+Append@{open\+Append}}
\index{open\+Append@{open\+Append}!P\+H\+Y\+S\+F\+S\+\_\+\+Archiver@{P\+H\+Y\+S\+F\+S\+\_\+\+Archiver}}
\subsubsection{open\+Append}
{\footnotesize\ttfamily \textbf{ P\+H\+Y\+S\+F\+S\+\_\+\+Io}$\ast$($\ast$ P\+H\+Y\+S\+F\+S\+\_\+\+Archiver\+::open\+Append) (void $\ast$opaque, const char $\ast$filename)}



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 N\+U\+LL on failure, and calls \doxyref{P\+H\+Y\+S\+F\+S\+\_\+set\+Error\+Code()}{p.}{physfs_8h_ade2c854542c68abc2015649fadd3a623}. Returns non-\/\+N\+U\+LL on success. The pointer returned will be passed as the \char`\"{}opaque\char`\"{} parameter for later file calls. \mbox{\label{structPHYSFS__Archiver_a2cc593f1ba701070668ffa43c8a7c0c3}} 
\index{P\+H\+Y\+S\+F\+S\+\_\+\+Archiver@{P\+H\+Y\+S\+F\+S\+\_\+\+Archiver}!open\+Archive@{open\+Archive}}
\index{open\+Archive@{open\+Archive}!P\+H\+Y\+S\+F\+S\+\_\+\+Archiver@{P\+H\+Y\+S\+F\+S\+\_\+\+Archiver}}
\subsubsection{open\+Archive}
{\footnotesize\ttfamily void$\ast$($\ast$ P\+H\+Y\+S\+F\+S\+\_\+\+Archiver\+::open\+Archive) (\textbf{ P\+H\+Y\+S\+F\+S\+\_\+\+Io} $\ast$io, const char $\ast$name, int for\+Write, int $\ast$claimed)}



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\textquotesingle{}t necessarily map to anything, let alone a real filename. This possibly-\/ meaningless name is in platform-\/dependent notation. (for\+Write) 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\textquotesingle{}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 N\+U\+LL on failure and set (claimed) appropriately. If no archiver opened the archive or set (claimed), \doxyref{P\+H\+Y\+S\+F\+S\+\_\+mount()}{p.}{physfs_8h_a8eb320e9af03dcdb4c05bbff3ea604d4} will report P\+H\+Y\+S\+F\+S\+\_\+\+E\+R\+R\+\_\+\+U\+N\+S\+U\+P\+P\+O\+R\+T\+ED. Otherwise, it will report the error from the archiver that claimed the data through (claimed). Return non-\/\+N\+U\+LL on success. The pointer returned will be passed as the \char`\"{}opaque\char`\"{} parameter for later calls. \mbox{\label{structPHYSFS__Archiver_aefe6f91fc7f129fc62c6d354957978f2}} 
\index{P\+H\+Y\+S\+F\+S\+\_\+\+Archiver@{P\+H\+Y\+S\+F\+S\+\_\+\+Archiver}!open\+Read@{open\+Read}}
\index{open\+Read@{open\+Read}!P\+H\+Y\+S\+F\+S\+\_\+\+Archiver@{P\+H\+Y\+S\+F\+S\+\_\+\+Archiver}}
\subsubsection{open\+Read}
{\footnotesize\ttfamily \textbf{ P\+H\+Y\+S\+F\+S\+\_\+\+Io}$\ast$($\ast$ P\+H\+Y\+S\+F\+S\+\_\+\+Archiver\+::open\+Read) (void $\ast$opaque, const char $\ast$fnm)}



Open a file in this archive for reading. 

This filename, (fnm), is in platform-\/independent notation. Fail if the file does not exist. Returns N\+U\+LL on failure, and calls \doxyref{P\+H\+Y\+S\+F\+S\+\_\+set\+Error\+Code()}{p.}{physfs_8h_ade2c854542c68abc2015649fadd3a623}. Returns non-\/\+N\+U\+LL on success. The pointer returned will be passed as the \char`\"{}opaque\char`\"{} parameter for later file calls. \mbox{\label{structPHYSFS__Archiver_a28fa4fdcca14c9eb1a71601d4589bd45}} 
\index{P\+H\+Y\+S\+F\+S\+\_\+\+Archiver@{P\+H\+Y\+S\+F\+S\+\_\+\+Archiver}!open\+Write@{open\+Write}}
\index{open\+Write@{open\+Write}!P\+H\+Y\+S\+F\+S\+\_\+\+Archiver@{P\+H\+Y\+S\+F\+S\+\_\+\+Archiver}}
\subsubsection{open\+Write}
{\footnotesize\ttfamily \textbf{ P\+H\+Y\+S\+F\+S\+\_\+\+Io}$\ast$($\ast$ P\+H\+Y\+S\+F\+S\+\_\+\+Archiver\+::open\+Write) (void $\ast$opaque, const char $\ast$filename)}



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 N\+U\+LL on failure, and calls \doxyref{P\+H\+Y\+S\+F\+S\+\_\+set\+Error\+Code()}{p.}{physfs_8h_ade2c854542c68abc2015649fadd3a623}. Returns non-\/\+N\+U\+LL on success. The pointer returned will be passed as the \char`\"{}opaque\char`\"{} parameter for later file calls. \mbox{\label{structPHYSFS__Archiver_add84976a1713102f38fde19a8ee8a5c7}} 
\index{P\+H\+Y\+S\+F\+S\+\_\+\+Archiver@{P\+H\+Y\+S\+F\+S\+\_\+\+Archiver}!remove@{remove}}
\index{remove@{remove}!P\+H\+Y\+S\+F\+S\+\_\+\+Archiver@{P\+H\+Y\+S\+F\+S\+\_\+\+Archiver}}
\subsubsection{remove}
{\footnotesize\ttfamily int($\ast$ P\+H\+Y\+S\+F\+S\+\_\+\+Archiver\+::remove) (void $\ast$opaque, const char $\ast$filename)}



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.

Return non-\/zero on success, zero on failure. This filename is in platform-\/independent notation. On failure, call \doxyref{P\+H\+Y\+S\+F\+S\+\_\+set\+Error\+Code()}{p.}{physfs_8h_ade2c854542c68abc2015649fadd3a623}. \mbox{\label{structPHYSFS__Archiver_a328a2e28430dfab9abe53678b29d0dbb}} 
\index{P\+H\+Y\+S\+F\+S\+\_\+\+Archiver@{P\+H\+Y\+S\+F\+S\+\_\+\+Archiver}!stat@{stat}}
\index{stat@{stat}!P\+H\+Y\+S\+F\+S\+\_\+\+Archiver@{P\+H\+Y\+S\+F\+S\+\_\+\+Archiver}}
\subsubsection{stat}
{\footnotesize\ttfamily int($\ast$ P\+H\+Y\+S\+F\+S\+\_\+\+Archiver\+::stat) (void $\ast$opaque, const char $\ast$fn, \textbf{ P\+H\+Y\+S\+F\+S\+\_\+\+Stat} $\ast$stat)}



Obtain basic file metadata. 

On success, fill in all the fields in (stat), using reasonable defaults for fields that apply to your archive.

Returns non-\/zero on success, zero on failure. This filename is in platform-\/independent notation. On failure, call \doxyref{P\+H\+Y\+S\+F\+S\+\_\+set\+Error\+Code()}{p.}{physfs_8h_ade2c854542c68abc2015649fadd3a623}. \mbox{\label{structPHYSFS__Archiver_aa8b70f3e0cf85eea8b4959a3c6a5f695}} 
\index{P\+H\+Y\+S\+F\+S\+\_\+\+Archiver@{P\+H\+Y\+S\+F\+S\+\_\+\+Archiver}!version@{version}}
\index{version@{version}!P\+H\+Y\+S\+F\+S\+\_\+\+Archiver@{P\+H\+Y\+S\+F\+S\+\_\+\+Archiver}}
\subsubsection{version}
{\footnotesize\ttfamily \textbf{ P\+H\+Y\+S\+F\+S\+\_\+uint32} P\+H\+Y\+S\+F\+S\+\_\+\+Archiver\+::version}



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\textquotesingle{}ll presumably keep supporting older versions as we offer new features, though. 

The documentation for this struct was generated from the following file\+:\begin{DoxyCompactItemize}
\item 
\textbf{ physfs.\+h}\end{DoxyCompactItemize}
