diff --git a/SharpPhysFS/Interop.cs b/SharpPhysFS/Interop.cs
index 698c59d..c608c89 100644
--- a/SharpPhysFS/Interop.cs
+++ b/SharpPhysFS/Interop.cs
@@ -98,10 +98,8 @@ namespace SharpPhysFS
#endregion
}
- static class Interop
+ class Interop
{
- public static bool init = false;
-
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void FnGetLinkedVersion(ref Version v);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
@@ -148,53 +146,61 @@ namespace SharpPhysFS
// When the callbacks are not yet initialized, instead of throwing a
// null reference exception we explain the problem.
// I think it makes for a more graceful failure.
- public static FnGetLinkedVersion PHYSFS_getLinkedVersion = (ref Version v) => { throw new InvalidOperationException("Callbacks not initialized yet"); };
- public static FnInit PHYSFS_init = (a) => { throw new InvalidOperationException("Callbacks not initialized yet"); };
- public static FnDeinit PHYSFS_deinit = () => { throw new InvalidOperationException("Callbacks not initialized yet"); };
- public static FnSupportedArchiveTypes PHYSFS_supportedArchiveTypes = () => { throw new InvalidOperationException("Callbacks not initialized yet"); };
- public static FnFreeList PHYSFS_freeList = (a) => { throw new InvalidOperationException("Callbacks not initialized yet"); };
- public static FnGetLastError PHYSFS_getLastError = () => { throw new InvalidOperationException("Callbacks not initialized yet"); };
- public static FnGetLastError PHYSFS_getDirSeparator = () => { throw new InvalidOperationException("Callbacks not initialized yet"); };
- public static FnPermitSymbolicLinks PHYSFS_permitSymbolicLinks = (a) => { throw new InvalidOperationException("Callbacks not initialized yet"); };
- public static FnSupportedArchiveTypes PHYSFS_getCdRomDirs = () => { throw new InvalidOperationException("Callbacks not initialized yet"); };
- public static FnGetLastError PHYSFS_getBaseDir = () => { throw new InvalidOperationException("Callbacks not initialized yet"); };
- public static FnGetLastError PHYSFS_getUserDir = () => { throw new InvalidOperationException("Callbacks not initialized yet"); };
- public static FnGetLastError PHYSFS_getWriteDir = () => { throw new InvalidOperationException("Callbacks not initialized yet"); };
- public static FnSetWriteDir PHYSFS_setWriteDir = (a) => { throw new InvalidOperationException("Callbacks not initialized yet"); };
- public static FnAddToSearchPath PHYSFS_addToSearchPath = (a, b) => { throw new InvalidOperationException("Callbacks not initialized yet"); };
- public static FnSetWriteDir PHYSFS_removeFromSearchPath = (a) => { throw new InvalidOperationException("Callbacks not initialized yet"); };
- public static FnSupportedArchiveTypes PHYSFS_getSearchPath = () => { throw new InvalidOperationException("Callbacks not initialized yet"); };
- public static FnSetSaneConfig PHYSFS_setSaneConfig = (a, b, c, d, e) => { throw new InvalidOperationException("Callbacks not initialized yet"); };
- public static FnSetWriteDir PHYSFS_mkdir = (a) => { throw new InvalidOperationException("Callbacks not initialized yet"); };
- public static FnSetWriteDir PHYSFS_delete = (a) => { throw new InvalidOperationException("Callbacks not initialized yet"); };
- public static FnEnumerateFiles PHYSFS_getRealDir = (a) => { throw new InvalidOperationException("Callbacks not initialized yet"); };
- public static FnEnumerateFiles PHYSFS_enumerateFiles = (a) => { throw new InvalidOperationException("Callbacks not initialized yet"); };
- public static FnSetWriteDir PHYSFS_exists = (a) => { throw new InvalidOperationException("Callbacks not initialized yet"); };
- public static FnSetWriteDir PHYSFS_isDirectory = (a) => { throw new InvalidOperationException("Callbacks not initialized yet"); };
- public static FnSetWriteDir PHYSFS_isSymbolicLink = (a) => { throw new InvalidOperationException("Callbacks not initialized yet"); };
- public static FnGetLastModTime PHYSFS_getLastModTime = (a) => { throw new InvalidOperationException("Callbacks not initialized yet"); };
- public static FnEnumerateFiles PHYSFS_openWrite = (a) => { throw new InvalidOperationException("Callbacks not initialized yet"); };
- public static FnEnumerateFiles PHYSFS_openAppend = (a) => { throw new InvalidOperationException("Callbacks not initialized yet"); };
- public static FnEnumerateFiles PHYSFS_openRead = (a) => { throw new InvalidOperationException("Callbacks not initialized yet"); };
- public static FnClose PHYSFS_close = (a) => { throw new InvalidOperationException("Callbacks not initialized yet"); };
- public static FnRead PHYSFS_read = (a, b, c, d) => { throw new InvalidOperationException("Callbacks not initialized yet"); };
- public static FnRead PHYSFS_write = (a, b, c,d ) => { throw new InvalidOperationException("Callbacks not initialized yet"); };
- public static FnClose PHYSFS_eof = (a) => { throw new InvalidOperationException("Callbacks not initialized yet"); };
- public static FnTell PHYSFS_tell = (a) => { throw new InvalidOperationException("Callbacks not initialized yet"); };
- public static FnSeek PHYSFS_seek = (a, b) => { throw new InvalidOperationException("Callbacks not initialized yet"); };
- public static FnFileLength PHYSFS_fileLength = (a) => { throw new InvalidOperationException("Callbacks not initialized yet"); };
- public static FnSeek PHYSFS_setBuffer = (a, b) => { throw new InvalidOperationException("Callbacks not initialized yet"); };
- public static FnClose PHYSFS_flush = (a) => { throw new InvalidOperationException("Callbacks not initialized yet"); };
- public static FnDeinit PHYSFS_isInit = () => { throw new InvalidOperationException("Callbacks not initialized yet"); };
- public static FnDeinit PHYSFS_symbolicLinksPermitted = () => { throw new InvalidOperationException("Callbacks not initialized yet"); };
- public static FnSetAllocator PHYSFS_setAllocator = (a) => { throw new InvalidOperationException("Callbacks not initialized yet"); };
- public static FnMount PHYSFS_mount = (a, b, c) => { throw new InvalidOperationException("Callbacks not initialized yet"); };
- public static FnEnumerateFiles PHYSFS_getMountPoint = (a) => { throw new InvalidOperationException("Callbacks not initialized yet"); };
- public static FnGetCdRomDirsCallback PHYSFS_getCdRomDirsCallback = (a, b) => { throw new InvalidOperationException("Callbacks not initialized yet"); };
- public static FnGetCdRomDirsCallback PHYSFS_getSearchPathCallback = (a, b) => { throw new InvalidOperationException("Callbacks not initialized yet"); };
- public static FnEnumerateFilesCallback PHYSFS_enumerateFilesCallback = (a, b, c) => { throw new InvalidOperationException("Callbacks not initialized yet"); };
+ public FnGetLinkedVersion PHYSFS_getLinkedVersion = (ref Version v) => { throw new InvalidOperationException("Callbacks not initialized yet"); };
+ public FnInit PHYSFS_init = (a) => { throw new InvalidOperationException("Callbacks not initialized yet"); };
+ public FnDeinit PHYSFS_deinit = () => { throw new InvalidOperationException("Callbacks not initialized yet"); };
+ public FnSupportedArchiveTypes PHYSFS_supportedArchiveTypes = () => { throw new InvalidOperationException("Callbacks not initialized yet"); };
+ public FnFreeList PHYSFS_freeList = (a) => { throw new InvalidOperationException("Callbacks not initialized yet"); };
+ public FnGetLastError PHYSFS_getLastError = () => { throw new InvalidOperationException("Callbacks not initialized yet"); };
+ public FnGetLastError PHYSFS_getDirSeparator = () => { throw new InvalidOperationException("Callbacks not initialized yet"); };
+ public FnPermitSymbolicLinks PHYSFS_permitSymbolicLinks = (a) => { throw new InvalidOperationException("Callbacks not initialized yet"); };
+ public FnSupportedArchiveTypes PHYSFS_getCdRomDirs = () => { throw new InvalidOperationException("Callbacks not initialized yet"); };
+ public FnGetLastError PHYSFS_getBaseDir = () => { throw new InvalidOperationException("Callbacks not initialized yet"); };
+ public FnGetLastError PHYSFS_getUserDir = () => { throw new InvalidOperationException("Callbacks not initialized yet"); };
+ public FnGetLastError PHYSFS_getWriteDir = () => { throw new InvalidOperationException("Callbacks not initialized yet"); };
+ public FnSetWriteDir PHYSFS_setWriteDir = (a) => { throw new InvalidOperationException("Callbacks not initialized yet"); };
+ public FnAddToSearchPath PHYSFS_addToSearchPath = (a, b) => { throw new InvalidOperationException("Callbacks not initialized yet"); };
+ public FnSetWriteDir PHYSFS_removeFromSearchPath = (a) => { throw new InvalidOperationException("Callbacks not initialized yet"); };
+ public FnSupportedArchiveTypes PHYSFS_getSearchPath = () => { throw new InvalidOperationException("Callbacks not initialized yet"); };
+ public FnSetSaneConfig PHYSFS_setSaneConfig = (a, b, c, d, e) => { throw new InvalidOperationException("Callbacks not initialized yet"); };
+ public FnSetWriteDir PHYSFS_mkdir = (a) => { throw new InvalidOperationException("Callbacks not initialized yet"); };
+ public FnSetWriteDir PHYSFS_delete = (a) => { throw new InvalidOperationException("Callbacks not initialized yet"); };
+ public FnEnumerateFiles PHYSFS_getRealDir = (a) => { throw new InvalidOperationException("Callbacks not initialized yet"); };
+ public FnEnumerateFiles PHYSFS_enumerateFiles = (a) => { throw new InvalidOperationException("Callbacks not initialized yet"); };
+ public FnSetWriteDir PHYSFS_exists = (a) => { throw new InvalidOperationException("Callbacks not initialized yet"); };
+ public FnSetWriteDir PHYSFS_isDirectory = (a) => { throw new InvalidOperationException("Callbacks not initialized yet"); };
+ public FnSetWriteDir PHYSFS_isSymbolicLink = (a) => { throw new InvalidOperationException("Callbacks not initialized yet"); };
+ public FnGetLastModTime PHYSFS_getLastModTime = (a) => { throw new InvalidOperationException("Callbacks not initialized yet"); };
+ public FnEnumerateFiles PHYSFS_openWrite = (a) => { throw new InvalidOperationException("Callbacks not initialized yet"); };
+ public FnEnumerateFiles PHYSFS_openAppend = (a) => { throw new InvalidOperationException("Callbacks not initialized yet"); };
+ public FnEnumerateFiles PHYSFS_openRead = (a) => { throw new InvalidOperationException("Callbacks not initialized yet"); };
+ public FnClose PHYSFS_close = (a) => { throw new InvalidOperationException("Callbacks not initialized yet"); };
+ public FnRead PHYSFS_read = (a, b, c, d) => { throw new InvalidOperationException("Callbacks not initialized yet"); };
+ public FnRead PHYSFS_write = (a, b, c,d ) => { throw new InvalidOperationException("Callbacks not initialized yet"); };
+ public FnClose PHYSFS_eof = (a) => { throw new InvalidOperationException("Callbacks not initialized yet"); };
+ public FnTell PHYSFS_tell = (a) => { throw new InvalidOperationException("Callbacks not initialized yet"); };
+ public FnSeek PHYSFS_seek = (a, b) => { throw new InvalidOperationException("Callbacks not initialized yet"); };
+ public FnFileLength PHYSFS_fileLength = (a) => { throw new InvalidOperationException("Callbacks not initialized yet"); };
+ public FnSeek PHYSFS_setBuffer = (a, b) => { throw new InvalidOperationException("Callbacks not initialized yet"); };
+ public FnClose PHYSFS_flush = (a) => { throw new InvalidOperationException("Callbacks not initialized yet"); };
+ public FnDeinit PHYSFS_isInit = () => { throw new InvalidOperationException("Callbacks not initialized yet"); };
+ public FnDeinit PHYSFS_symbolicLinksPermitted = () => { throw new InvalidOperationException("Callbacks not initialized yet"); };
+ public FnSetAllocator PHYSFS_setAllocator = (a) => { throw new InvalidOperationException("Callbacks not initialized yet"); };
+ public FnMount PHYSFS_mount = (a, b, c) => { throw new InvalidOperationException("Callbacks not initialized yet"); };
+ public FnEnumerateFiles PHYSFS_getMountPoint = (a) => { throw new InvalidOperationException("Callbacks not initialized yet"); };
+ public FnGetCdRomDirsCallback PHYSFS_getCdRomDirsCallback = (a, b) => { throw new InvalidOperationException("Callbacks not initialized yet"); };
+ public FnGetCdRomDirsCallback PHYSFS_getSearchPathCallback = (a, b) => { throw new InvalidOperationException("Callbacks not initialized yet"); };
+ public FnEnumerateFilesCallback PHYSFS_enumerateFilesCallback = (a, b, c) => { throw new InvalidOperationException("Callbacks not initialized yet"); };
- public static void SetUpInterop()
+ public Interop()
+ : this("physfs.dll", "libphysfs.dylib", "libphysfs.so")
+ { }
+
+ public Interop(string libname)
+ : this($"{libname}.dll", $"{libname}.dylib", $"{libname}.so")
+ { }
+
+ public Interop(string winlib, string maclib, string unixlib)
{
/* This method is used to dynamically load the physfs
* library. It works by detecting the current platform
@@ -215,19 +221,19 @@ namespace SharpPhysFS
{
loadLibrary = DynamicLoader.LoadLibrary;
loadSymbol = DynamicLoader.GetProcAddress;
- libraryName = "physfs.dll";
+ libraryName = winlib;
}
else if(Environment.OSVersion.Platform == PlatformID.MacOSX)
{
loadLibrary = n => DynamicLoader.osx_dlopen(n, 1);
loadSymbol = DynamicLoader.osx_dlsym;
- libraryName = "libphysfs.dylib";
+ libraryName = maclib;
}
else
{
loadLibrary = n => DynamicLoader.unix_dlopen(n, 1);
loadSymbol = DynamicLoader.unix_dlsym;
- libraryName = "libphysfs.so";
+ libraryName = unixlib;
}
library = loadLibrary(libraryName);
@@ -245,8 +251,6 @@ namespace SharpPhysFS
field.SetValue(null, del);
}
-
- init = true;
}
}
}
diff --git a/SharpPhysFS/PhysFS.LowLevel.cs b/SharpPhysFS/PhysFS.LowLevel.cs
new file mode 100644
index 0000000..d1db0b1
--- /dev/null
+++ b/SharpPhysFS/PhysFS.LowLevel.cs
@@ -0,0 +1,99 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace SharpPhysFS
+{
+ public partial class PhysFS
+ {
+ public static class LowLevel
+ {
+ public static IntPtr OpenWrite(string filename, PhysFS physFS)
+ {
+ var val = physFS.interop.PHYSFS_openWrite(filename);
+ if (val == null)
+ throw new PhysFSException(physFS);
+ return val;
+ }
+
+ public static IntPtr OpenAppend(string filename, PhysFS physFS)
+ {
+ var val = physFS.interop.PHYSFS_openAppend(filename);
+ if (val == null)
+ throw new PhysFSException(physFS);
+ return val;
+ }
+
+ public static IntPtr OpenRead(string filename, PhysFS physFS)
+ {
+ var val = physFS.interop.PHYSFS_openRead(filename);
+ if (val == null)
+ throw new PhysFSException(physFS);
+ return val;
+ }
+
+ public static void Close(IntPtr file, PhysFS physFS)
+ {
+ int err = physFS.interop.PHYSFS_close(file);
+ physFS.ThrowException(err);
+ }
+
+ public static long Read(IntPtr file, byte[] buffer, uint objSize, uint objCount, PhysFS physFS)
+ {
+ unsafe
+ {
+ fixed (void* ptr = buffer)
+ {
+ return physFS.interop.PHYSFS_read(file, (IntPtr)ptr, objSize, objCount);
+ }
+ }
+ }
+
+ public static long Write(IntPtr file, byte[] buffer, uint objSize, uint objCount, PhysFS physFS)
+ {
+ unsafe
+ {
+ fixed (void* ptr = buffer)
+ {
+ return physFS.interop.PHYSFS_write(file, (IntPtr)ptr, objSize, objCount);
+ }
+ }
+ }
+
+ public static bool EOF(IntPtr file, PhysFS physFS)
+ {
+ return physFS.interop.PHYSFS_eof(file) != 0;
+ }
+
+ public static long Tell(IntPtr file, PhysFS physFS)
+ {
+ return physFS.interop.PHYSFS_tell(file);
+ }
+
+ public static void Seek(IntPtr file, ulong pos, PhysFS physFS)
+ {
+ int err = physFS.interop.PHYSFS_seek(file, pos);
+ physFS.ThrowException(err);
+ }
+
+ public static long FileLength(IntPtr file, PhysFS physFS)
+ {
+ return physFS.interop.PHYSFS_fileLength(file);
+ }
+
+ public static void SetBuffer(IntPtr file, ulong bufSize, PhysFS physFS)
+ {
+ int err = physFS.interop.PHYSFS_setBuffer(file, bufSize);
+ physFS.ThrowException(err);
+ }
+
+ public static void Flush(IntPtr file, PhysFS physFS)
+ {
+ int err = physFS.interop.PHYSFS_flush(file);
+ physFS.ThrowException(err);
+ }
+ }
+ }
+}
diff --git a/SharpPhysFS/PhysFS.cs b/SharpPhysFS/PhysFS.cs
index 5314539..dee5389 100644
--- a/SharpPhysFS/PhysFS.cs
+++ b/SharpPhysFS/PhysFS.cs
@@ -4,13 +4,6 @@ using System.Runtime.InteropServices;
namespace SharpPhysFS
{
- public class PhysFSException : Exception
- {
- public PhysFSException()
- : base(PhysFS.GetLastError())
- { }
- }
-
public class PhysFSLibNotFound : Exception
{
public PhysFSLibNotFound()
@@ -21,94 +14,22 @@ namespace SharpPhysFS
///
/// Main class for SharpPhysFS
///
- public static class PhysFS
+ public partial class PhysFS
+ : IDisposable
{
- public static class LowLevel
+ public class PhysFSException : Exception
{
- public static IntPtr OpenWrite(string filename)
- {
- var val = Interop.PHYSFS_openWrite(filename);
- if (val == null)
- throw new PhysFSException();
- return val;
- }
+ public PhysFSException(PhysFS physFS)
+ : base(physFS.GetLastError())
+ { }
+ }
- public static IntPtr OpenAppend(string filename)
- {
- var val = Interop.PHYSFS_openAppend(filename);
- if (val == null)
- throw new PhysFSException();
- return val;
- }
+ Interop interop;
- public static IntPtr OpenRead(string filename)
- {
- var val = Interop.PHYSFS_openRead(filename);
- if (val == null)
- throw new PhysFSException();
- return val;
- }
-
- public static void Close(IntPtr file)
- {
- int err = Interop.PHYSFS_close(file);
- ThrowException(err);
- }
-
- public static long Read(IntPtr file, byte[] buffer, uint objSize, uint objCount)
- {
- unsafe
- {
- fixed (void* ptr = buffer)
- {
- return Interop.PHYSFS_read(file, (IntPtr)ptr, objSize, objCount);
- }
- }
- }
-
- public static long Write(IntPtr file, byte[] buffer, uint objSize, uint objCount)
- {
- unsafe
- {
- fixed (void* ptr = buffer)
- {
- return Interop.PHYSFS_write(file, (IntPtr)ptr, objSize, objCount);
- }
- }
- }
-
- public static bool EOF(IntPtr file)
- {
- return Interop.PHYSFS_eof(file) != 0;
- }
-
- public static long Tell(IntPtr file)
- {
- return Interop.PHYSFS_tell(file);
- }
-
- public static void Seek(IntPtr file, ulong pos)
- {
- int err = Interop.PHYSFS_seek(file, pos);
- ThrowException(err);
- }
-
- public static long FileLength(IntPtr file)
- {
- return Interop.PHYSFS_fileLength(file);
- }
-
- public static void SetBuffer(IntPtr file, ulong bufSize)
- {
- int err = Interop.PHYSFS_setBuffer(file, bufSize);
- ThrowException(err);
- }
-
- public static void Flush(IntPtr file)
- {
- int err = Interop.PHYSFS_flush(file);
- ThrowException(err);
- }
+ public PhysFS(string argv0)
+ {
+ interop = new Interop();
+ Init(argv0);
}
static T FromPtr(IntPtr ptr)
@@ -116,38 +37,22 @@ namespace SharpPhysFS
return (T)Marshal.PtrToStructure(ptr, typeof(T));
}
- static void ThrowException(int err)
+ void ThrowException(int err)
{
if (err == 0)
{
- throw new PhysFSException();
+ throw new PhysFSException(this);
}
}
- ///
- /// Sets up the library callbacks for use.
- ///
- ///
- /// This method will dynamically load the right library according to the
- /// current platform, whether it is Windows of *nix
- ///
- ///
- /// This method must be called before any other method in this class is available.
- /// Not doing so will result in NullReferenceException
- ///
- public static void InitializeCallbacks()
- {
- Interop.SetUpInterop();
- }
-
///
/// Get the version of PhysicsFS that is linked against your program
///
/// The version of PhysicsFS that is linked against your program
- public static Version GetLinkedVersion()
+ public Version GetLinkedVersion()
{
Version v = new Version();
- Interop.PHYSFS_getLinkedVersion(ref v);
+ interop.PHYSFS_getLinkedVersion(ref v);
return v;
}
@@ -157,11 +62,12 @@ namespace SharpPhysFS
///
/// Must be called before any other PhysicsFS function.
/// This should be called prior to any attempts to change your process's current working directory.
+ /// NOTE: This is automatically called when the class is created.
///
/// This should be the path of the executable (first arguments passed to main function in C programs)
- public static void Init(string argv0)
+ public void Init(string argv0)
{
- int err = Interop.PHYSFS_init(argv0);
+ int err = interop.PHYSFS_init(argv0);
ThrowException(err);
}
@@ -180,10 +86,11 @@ namespace SharpPhysFS
/// close all write handles yourself before calling this function, so that you can gracefully handle a specific failure.
/// Once successfully deinitialized, Init can be called again to restart the subsystem.
/// All default API states are restored at this point, with the exception of any custom allocator you might have specified, which survives between initializations.
+ /// NOTE: This is called automatically on disposal.
///
- public static void Deinit()
+ public void Deinit()
{
- int err = Interop.PHYSFS_deinit();
+ int err = interop.PHYSFS_deinit();
ThrowException(err);
}
@@ -208,9 +115,9 @@ namespace SharpPhysFS
/// directory or archive to add to the path, in platform-dependent notation.
/// Location in the interpolated tree that this archive will be "mounted", in platform-independent notation. null or "" is equivalent to "/".
/// True to append to search path, false to prepend.
- public static void Mount(string dir, string mountPoint, bool appendToPath)
+ public void Mount(string dir, string mountPoint, bool appendToPath)
{
- int err = Interop.PHYSFS_mount(dir, mountPoint, appendToPath ? 1 : 0);
+ int err = interop.PHYSFS_mount(dir, mountPoint, appendToPath ? 1 : 0);
ThrowException(err);
}
@@ -225,9 +132,9 @@ namespace SharpPhysFS
/// It is safe to call this function at anytime, even before PhysFS.Init().
///
/// String of last error message.
- public static string GetLastError()
+ public string GetLastError()
{
- return Marshal.PtrToStringAnsi(Interop.PHYSFS_getLastError());
+ return Marshal.PtrToStringAnsi(interop.PHYSFS_getLastError());
}
///
@@ -241,9 +148,9 @@ namespace SharpPhysFS
/// This is only useful for setting up the search/write paths, since access into those dirs always use '/' (platform-independent notation)
///
/// Platform-dependent dir separator string
- public static string GetDirSeparator()
+ public string GetDirSeparator()
{
- return Marshal.PtrToStringAnsi(Interop.PHYSFS_getDirSeparator());
+ return Marshal.PtrToStringAnsi(interop.PHYSFS_getDirSeparator());
}
///
@@ -268,7 +175,7 @@ namespace SharpPhysFS
///
///
/// Directory in platform-independent notation to enumerate.
- public static string[] EnumerateFiles(string dir)
+ public string[] EnumerateFiles(string dir)
{
var list = new List();
EnumerateFilesCallback(dir, (d, o, f) =>
@@ -290,9 +197,9 @@ namespace SharpPhysFS
/// The extension listed is merely convention: if we list "ZIP", you can open a PkZip-compatible archive with an extension of "XYZ", if you like.
///
/// An enumeration of supported archive types
- public static IEnumerable SupportedArchiveTypes()
+ public IEnumerable SupportedArchiveTypes()
{
- IntPtr archives = Interop.PHYSFS_supportedArchiveTypes();
+ IntPtr archives = interop.PHYSFS_supportedArchiveTypes();
IntPtr i = archives;
for (i = archives; Marshal.ReadIntPtr(i) != IntPtr.Zero; i = IntPtr.Add(i, IntPtr.Size))
{
@@ -325,9 +232,9 @@ namespace SharpPhysFS
/// That is, when setting up your search and write paths, etc, symlinks are never checked for.
///
/// true to permit symlinks, false to deny linking.
- public static void PermitSymbolicLinks(bool permit)
+ public void PermitSymbolicLinks(bool permit)
{
- Interop.PHYSFS_permitSymbolicLinks(permit ? 1 : 0);
+ interop.PHYSFS_permitSymbolicLinks(permit ? 1 : 0);
}
///
@@ -348,7 +255,7 @@ namespace SharpPhysFS
/// This call may block while drives spin up. Be forewarned.
///
/// An enumeration of paths to available CD-ROM drives.
- public static string[] GetCdRomDirs()
+ public string[] GetCdRomDirs()
{
var list = new List();
GetCdRomDirsCallback((d, s) =>
@@ -365,9 +272,9 @@ namespace SharpPhysFS
/// It is probably better to use managed methods for this.
///
///
- public static string GetBaseDir()
+ public string GetBaseDir()
{
- return Marshal.PtrToStringAnsi(Interop.PHYSFS_getBaseDir());
+ return Marshal.PtrToStringAnsi(interop.PHYSFS_getBaseDir());
}
///
@@ -383,9 +290,9 @@ namespace SharpPhysFS
/// You should probably use the user dir as the basis for your write dir, and also put it near the beginning of your search path.
///
/// String of user dir in platform-dependent notation.
- public static string GetUserDir()
+ public string GetUserDir()
{
- return Marshal.PtrToStringAnsi(Interop.PHYSFS_getUserDir());
+ return Marshal.PtrToStringAnsi(interop.PHYSFS_getUserDir());
}
///
@@ -395,9 +302,9 @@ namespace SharpPhysFS
/// Get the current write dir. The default write dir is "".
///
/// String of write dir in platform-dependent notation, OR null IF NO WRITE PATH IS CURRENTLY SET
- public static string GetWriteDir()
+ public string GetWriteDir()
{
- return Marshal.PtrToStringAnsi(Interop.PHYSFS_getWriteDir());
+ return Marshal.PtrToStringAnsi(interop.PHYSFS_getWriteDir());
}
///
@@ -413,9 +320,9 @@ namespace SharpPhysFS
/// The new directory to be the root of the write dir, specified in platform-dependent notation.
/// Setting to null disables the write dir, so no files can be opened for writing via PhysicsFS.
///
- public static void SetWriteDir(string path)
+ public void SetWriteDir(string path)
{
- int err = Interop.PHYSFS_setWriteDir(path);
+ int err = interop.PHYSFS_setWriteDir(path);
ThrowException(err);
}
@@ -425,9 +332,9 @@ namespace SharpPhysFS
/// Directory or archive to add to the path, in platform-dependent notation
/// true to append to search path, false to prepend
[Obsolete("AddToSearchPath is deprecated, please use Mount instead")]
- public static void AddToSearchPath(string newDir, bool appendToPath)
+ public void AddToSearchPath(string newDir, bool appendToPath)
{
- int err = Interop.PHYSFS_addToSearchPath(newDir, appendToPath ? 1 : 0);
+ int err = interop.PHYSFS_addToSearchPath(newDir, appendToPath ? 1 : 0);
ThrowException(err);
}
@@ -441,16 +348,16 @@ namespace SharpPhysFS
/// This call will fail (and fail to remove from the path) if the element still has files open in it.
///
/// dir/archive to remove.
- public static void RemoveFromSearchPath(string oldDir)
+ public void RemoveFromSearchPath(string oldDir)
{
- int err = Interop.PHYSFS_removeFromSearchPath(oldDir);
+ int err = interop.PHYSFS_removeFromSearchPath(oldDir);
ThrowException(err);
}
///
/// Get the current search path.
///
- public static string[] GetSearchPath()
+ public string[] GetSearchPath()
{
//var dirs = Interop.PHYSFS_getSearchPath();
//return GenEnumerable(dirs);
@@ -516,9 +423,9 @@ namespace SharpPhysFS
/// then they may not be made available anyhow. You may want to specify false and handle the disc setup yourself.
///
/// True to prepend the archives to the search path. False to append them. Ignored if !.
- public static void SetSaneConfig(string organization, string appName, string archiveExt, bool includeCdRoms, bool archivesFirst)
+ public void SetSaneConfig(string organization, string appName, string archiveExt, bool includeCdRoms, bool archivesFirst)
{
- int err = Interop.PHYSFS_setSaneConfig(organization, appName, archiveExt, includeCdRoms ? 1 : 0, archivesFirst ? 1 : 0);
+ int err = interop.PHYSFS_setSaneConfig(organization, appName, archiveExt, includeCdRoms ? 1 : 0, archivesFirst ? 1 : 0);
ThrowException(err);
}
@@ -536,9 +443,9 @@ namespace SharpPhysFS
/// then the function leaves the created directory behind and reports failure.
///
/// New dir to create.
- public static void Mkdir(string dirName)
+ public void Mkdir(string dirName)
{
- int err = Interop.PHYSFS_mkdir(dirName);
+ int err = interop.PHYSFS_mkdir(dirName);
ThrowException(err);
}
@@ -563,9 +470,9 @@ namespace SharpPhysFS
/// Don't consider this a security method or anything. :)
///
/// Filename to delete.
- public static void Delete(string filename)
+ public void Delete(string filename)
{
- int err = Interop.PHYSFS_delete(filename);
+ int err = interop.PHYSFS_delete(filename);
ThrowException(err);
}
@@ -587,9 +494,9 @@ namespace SharpPhysFS
///
/// File to look for.
/// String of element of search path containing the the file in question. null if not found.
- public static string GetRealDir(string filename)
+ public string GetRealDir(string filename)
{
- return Marshal.PtrToStringAnsi(Interop.PHYSFS_getRealDir(filename));
+ return Marshal.PtrToStringAnsi(interop.PHYSFS_getRealDir(filename));
}
///
@@ -602,9 +509,9 @@ namespace SharpPhysFS
///
/// Filename in platform-independent notation.
/// True if filename exists. false otherwise.
- public static bool Exists(string fname)
+ public bool Exists(string fname)
{
- return Interop.PHYSFS_exists(fname) != 0;
+ return interop.PHYSFS_exists(fname) != 0;
}
///
@@ -614,9 +521,9 @@ namespace SharpPhysFS
/// Note that entries that are symlinks are ignored if PhysFS.PermitSymbolicLinks(true) hasn't been called, so you might end up further down in the search path than expected.
/// Filename in platform-independent notation.
/// True if filename exists and is a directory. False otherwise.
- public static bool IsDirectory(string fname)
+ public bool IsDirectory(string fname)
{
- return Interop.PHYSFS_isDirectory(fname) != 0;
+ return interop.PHYSFS_isDirectory(fname) != 0;
}
///
@@ -626,9 +533,9 @@ namespace SharpPhysFS
/// Note that entries that are symlinks are ignored if PhysFS.PermitSymbolicLinks(true) hasn't been called, and as such, this function will always return false in that case.
/// Filename in platform-independent notation.
/// True if filename exists and is a symlink. False otherwise.
- public static bool IsSymbolicLink(string fname)
+ public bool IsSymbolicLink(string fname)
{
- return Interop.PHYSFS_isSymbolicLink(fname) != 0;
+ return interop.PHYSFS_isSymbolicLink(fname) != 0;
}
///
@@ -641,9 +548,9 @@ namespace SharpPhysFS
///
/// Filename to check, in platform-independent notation.
/// Last modified time of the file. -1 if it can't be determined.
- public static long GetLastModTime(string fname)
+ public long GetLastModTime(string fname)
{
- return Interop.PHYSFS_getLastModTime(fname);
+ return interop.PHYSFS_getLastModTime(fname);
}
///
@@ -654,9 +561,9 @@ namespace SharpPhysFS
/// Before a successful PhysFS.Init() and after PhysFS.Deinit() returns successfully, this will return false. This function is safe to call at any time.
///
/// True if library is initialized, false if library is not.
- public static bool IsInit()
+ public bool IsInit()
{
- return Interop.PHYSFS_isInit() != 0;
+ return interop.PHYSFS_isInit() != 0;
}
///
@@ -667,14 +574,14 @@ namespace SharpPhysFS
/// If PhysFS.PermitSymbolicLinks() hasn't been called since the library was last initialized, symbolic links are implicitly disabled.
///
/// True if symlinks are permitted, false if not.
- public static bool SymbolicLinksPermitted()
+ public bool SymbolicLinksPermitted()
{
- return Interop.PHYSFS_symbolicLinksPermitted() != 0;
+ return interop.PHYSFS_symbolicLinksPermitted() != 0;
}
- public static void SetAllocator(Allocator allocator)
+ public void SetAllocator(Allocator allocator)
{
- int err = Interop.PHYSFS_setAllocator(allocator);
+ int err = interop.PHYSFS_setAllocator(allocator);
ThrowException(err);
}
@@ -690,17 +597,17 @@ namespace SharpPhysFS
/// This must match the string used when adding, even if your string would also reference the same file with a different string of characters.
///
/// String of mount point if added to path
- public static string GetMountPoint(string dir)
+ public string GetMountPoint(string dir)
{
- var s = Marshal.PtrToStringAnsi(Interop.PHYSFS_getMountPoint(dir));
+ var s = Marshal.PtrToStringAnsi(interop.PHYSFS_getMountPoint(dir));
if(s == null)
{
- throw new PhysFSException();
+ throw new PhysFSException(this);
}
return s;
}
- static StringCallback WrapStringCallback(Action c)
+ StringCallback WrapStringCallback(Action c)
{
return (d, s) =>
{
@@ -709,10 +616,10 @@ namespace SharpPhysFS
};
}
- public static void GetCdRomDirsCallback(StringCallback c, object data)
+ public void GetCdRomDirsCallback(StringCallback c, object data)
{
GCHandle objHandle = GCHandle.Alloc(data);
- Interop.PHYSFS_getCdRomDirsCallback(c, GCHandle.ToIntPtr(objHandle));
+ interop.PHYSFS_getCdRomDirsCallback(c, GCHandle.ToIntPtr(objHandle));
objHandle.Free();
}
@@ -722,15 +629,15 @@ namespace SharpPhysFS
/// Type of data passed to callback
/// Callback function to notify about detected drives.
/// Application-defined data passed to callback. Can be null.
- public static void GetCdRomDirsCallback(Action c, T data)
+ public void GetCdRomDirsCallback(Action c, T data)
{
GetCdRomDirsCallback(WrapStringCallback(c), data);
}
- public static void GetSearchPathCallback(StringCallback c, object data)
+ public void GetSearchPathCallback(StringCallback c, object data)
{
GCHandle objHandle = GCHandle.Alloc(data);
- Interop.PHYSFS_getSearchPathCallback(c, GCHandle.ToIntPtr(objHandle));
+ interop.PHYSFS_getSearchPathCallback(c, GCHandle.ToIntPtr(objHandle));
objHandle.Free();
}
@@ -740,15 +647,15 @@ namespace SharpPhysFS
/// Type of data passed to callback
/// Callback function to notify about search path elements.
/// Application-defined data passed to callback. Can be null.
- public static void GetSearchPathCallback(Action c, T data)
+ public void GetSearchPathCallback(Action c, T data)
{
GetSearchPathCallback(WrapStringCallback(c), data);
}
- public static void EnumerateFilesCallback(string dir, EnumFilesCallback c, object data)
+ public void EnumerateFilesCallback(string dir, EnumFilesCallback c, object data)
{
GCHandle objHandle = GCHandle.Alloc(data);
- Interop.PHYSFS_enumerateFilesCallback(dir, c, GCHandle.ToIntPtr(objHandle));
+ interop.PHYSFS_enumerateFilesCallback(dir, c, GCHandle.ToIntPtr(objHandle));
objHandle.Free();
}
@@ -759,7 +666,7 @@ namespace SharpPhysFS
/// Directory, in platform-independent notation, to enumerate.
/// Callback function to notify about search path elements.
/// Application-defined data passed to callback. Can be null.
- public static void EnumerateFilesCallback(string dir, Action c, T data)
+ public void EnumerateFilesCallback(string dir, Action c, T data)
{
EnumerateFilesCallback(dir, (d, o, n) =>
{
@@ -767,5 +674,28 @@ namespace SharpPhysFS
c(obj, o, n);
}, data);
}
+
+ public PhysFSStream OpenAppend(string file)
+ {
+ var handle = LowLevel.OpenAppend(file, this);
+ return new PhysFSStream(this, handle, false);
+ }
+
+ public PhysFSStream OpenRead(string file)
+ {
+ var handle = LowLevel.OpenRead(file, this);
+ return new PhysFSStream(this, handle, true);
+ }
+
+ public PhysFSStream OpenWrite(string file)
+ {
+ var handle = LowLevel.OpenWrite(file, this);
+ return new PhysFSStream(this, handle, false);
+ }
+
+ public void Dispose()
+ {
+ Deinit();
+ }
}
}
diff --git a/SharpPhysFS/PhysFSStream.cs b/SharpPhysFS/PhysFSStream.cs
index 5d21cc7..d77e742 100644
--- a/SharpPhysFS/PhysFSStream.cs
+++ b/SharpPhysFS/PhysFSStream.cs
@@ -3,33 +3,17 @@ using System.IO;
namespace SharpPhysFS
{
- public enum OpenMode
- {
- Append,
- Read,
- Write
- }
-
public class PhysFSStream : Stream
{
IntPtr handle;
bool readOnly = false;
+ PhysFS physFS;
- public PhysFSStream(string filename, OpenMode mode)
+ internal PhysFSStream(PhysFS pfs, IntPtr ptr, bool readOnly)
{
- switch (mode)
- {
- case OpenMode.Append:
- handle = PhysFS.LowLevel.OpenAppend(filename);
- break;
- case OpenMode.Read:
- handle = PhysFS.LowLevel.OpenRead(filename);
- readOnly = true;
- break;
- case OpenMode.Write:
- handle = PhysFS.LowLevel.OpenAppend(filename);
- break;
- }
+ handle = ptr;
+ this.readOnly = readOnly;
+ physFS = pfs;
}
public override bool CanRead
@@ -58,14 +42,14 @@ namespace SharpPhysFS
public override void Flush()
{
- PhysFS.LowLevel.Flush(handle);
+ PhysFS.LowLevel.Flush(handle, physFS);
}
public override long Length
{
get
{
- return PhysFS.LowLevel.FileLength(handle);
+ return PhysFS.LowLevel.FileLength(handle, physFS);
}
}
@@ -73,17 +57,17 @@ namespace SharpPhysFS
{
get
{
- return PhysFS.LowLevel.Tell(handle);
+ return PhysFS.LowLevel.Tell(handle, physFS);
}
set
{
- PhysFS.LowLevel.Seek(handle, (ulong)value);
+ PhysFS.LowLevel.Seek(handle, (ulong)value, physFS);
}
}
public long Read(byte[] buffer, uint offset, uint count)
{
- return PhysFS.LowLevel.Read(handle, buffer, 1, count);
+ return PhysFS.LowLevel.Read(handle, buffer, 1, count, physFS);
}
public override int Read(byte[] buffer, int offset, int count)
@@ -97,22 +81,17 @@ namespace SharpPhysFS
if (origin == SeekOrigin.Begin)
pos = 0;
else if (origin == SeekOrigin.Current)
- pos = PhysFS.LowLevel.Tell(handle);
+ pos = PhysFS.LowLevel.Tell(handle, physFS);
else
- pos = PhysFS.LowLevel.FileLength(handle);
+ pos = PhysFS.LowLevel.FileLength(handle, physFS);
- PhysFS.LowLevel.Seek(handle, (ulong)(pos + offset));
+ PhysFS.LowLevel.Seek(handle, (ulong)(pos + offset), physFS);
return pos + offset;
}
- public override void SetLength(long value)
- {
- throw new NotImplementedException();
- }
-
public long Write(byte[] buffer, uint offset, uint count)
{
- return PhysFS.LowLevel.Write(handle, buffer, 1, count);
+ return PhysFS.LowLevel.Write(handle, buffer, 1, count, physFS);
}
public override void Write(byte[] buffer, int offset, int count)
@@ -120,18 +99,20 @@ namespace SharpPhysFS
Write(buffer, (uint)offset, (uint)count);
}
- public override void Close()
+ public override void SetLength(long value)
{
- PhysFS.LowLevel.Close(handle);
- handle = IntPtr.Zero;
- base.Close();
+ throw new NotImplementedException();
}
protected override void Dispose(bool disposing)
{
- if(handle != IntPtr.Zero)
+ if(disposing)
{
- Close();
+ if (handle != IntPtr.Zero)
+ {
+ PhysFS.LowLevel.Close(handle, physFS);
+ handle = IntPtr.Zero;
+ }
}
base.Dispose(disposing);
}
diff --git a/SharpPhysFS/SharpPhysFS.csproj b/SharpPhysFS/SharpPhysFS.csproj
index 6f9d7a1..9cc4be1 100644
--- a/SharpPhysFS/SharpPhysFS.csproj
+++ b/SharpPhysFS/SharpPhysFS.csproj
@@ -37,6 +37,7 @@
+
diff --git a/Test/Program.cs b/Test/Program.cs
index 09dcbed..73508e5 100644
--- a/Test/Program.cs
+++ b/Test/Program.cs
@@ -10,11 +10,13 @@ namespace Test
{
class Program
{
+ static PhysFS physFS;
+
static void PrintSupportedArchives()
{
Console.Write("Supported archive types: ");
bool any = false;
- foreach (var archive in PhysFS.SupportedArchiveTypes())
+ foreach (var archive in physFS.SupportedArchiveTypes())
{
any = true;
Console.WriteLine("\n - {0}: {1}", archive.extension, archive.description);
@@ -103,7 +105,7 @@ namespace Test
Console.WriteLine("append can only be true or false");
}
- PhysFS.Mount(args[0], args[1], append);
+ physFS.Mount(args[0], args[1], append);
return true;
}
@@ -115,7 +117,7 @@ namespace Test
return false;
}
- foreach (var f in PhysFS.EnumerateFiles(args[0]))
+ foreach (var f in physFS.EnumerateFiles(args[0]))
{
Console.WriteLine(" - {0}", f);
}
@@ -124,19 +126,19 @@ namespace Test
static bool GetLastError(string[] args)
{
- Console.WriteLine(PhysFS.GetLastError());
+ Console.WriteLine(physFS.GetLastError());
return true;
}
static bool GetDirSeparator(string[] args)
{
- Console.WriteLine(PhysFS.GetDirSeparator());
+ Console.WriteLine(physFS.GetDirSeparator());
return true;
}
static bool GetCdRomDirectories(string[] args)
{
- foreach(var d in PhysFS.GetCdRomDirs())
+ foreach(var d in physFS.GetCdRomDirs())
{
Console.WriteLine(" - {0}", d);
}
@@ -145,7 +147,7 @@ namespace Test
static bool GetSearchPath(string[] args)
{
- foreach (var d in PhysFS.GetSearchPath())
+ foreach (var d in physFS.GetSearchPath())
{
Console.WriteLine(" - {0}", d);
}
@@ -154,19 +156,19 @@ namespace Test
static bool GetBaseDirectory(string[] args)
{
- Console.WriteLine(PhysFS.GetBaseDir());
+ Console.WriteLine(physFS.GetBaseDir());
return true;
}
static bool GetUserDirectory(string[] args)
{
- Console.WriteLine(PhysFS.GetUserDir());
+ Console.WriteLine(physFS.GetUserDir());
return true;
}
static bool GetWriteDirectory(string[] args)
{
- Console.WriteLine(PhysFS.GetWriteDir());
+ Console.WriteLine(physFS.GetWriteDir());
return true;
}
@@ -177,7 +179,7 @@ namespace Test
Console.WriteLine("Usage: setwritedir ");
return false;
}
- PhysFS.SetWriteDir(args[0]);
+ physFS.SetWriteDir(args[0]);
return true;
}
@@ -193,7 +195,7 @@ namespace Test
{
Console.WriteLine("Usage: permitsymlinks ");
}
- PhysFS.PermitSymbolicLinks(permit);
+ physFS.PermitSymbolicLinks(permit);
return true;
}
@@ -207,7 +209,7 @@ namespace Test
bool includeCdRoms, archivesFirst;
if(bool.TryParse(args[3], out includeCdRoms) && bool.TryParse(args[4], out archivesFirst))
{
- PhysFS.SetSaneConfig(args[0], args[1], args[2], includeCdRoms, archivesFirst);
+ physFS.SetSaneConfig(args[0], args[1], args[2], includeCdRoms, archivesFirst);
}
else
{
@@ -223,7 +225,7 @@ namespace Test
Console.WriteLine("Usage: mkdir ");
return false;
}
- PhysFS.Mkdir(args[0]);
+ physFS.Mkdir(args[0]);
return true;
}
@@ -234,7 +236,7 @@ namespace Test
Console.WriteLine("Usage: delete ");
return false;
}
- PhysFS.Delete(args[0]);
+ physFS.Delete(args[0]);
return true;
}
@@ -245,7 +247,7 @@ namespace Test
Console.WriteLine("Usage: getrealdir ");
return false;
}
- Console.WriteLine(PhysFS.GetRealDir(args[0]));
+ Console.WriteLine(physFS.GetRealDir(args[0]));
return true;
}
@@ -256,7 +258,7 @@ namespace Test
Console.WriteLine("Usage: exists ");
return false;
}
- Console.WriteLine(PhysFS.Exists(args[0]));
+ Console.WriteLine(physFS.Exists(args[0]));
return true;
}
@@ -267,7 +269,7 @@ namespace Test
Console.WriteLine("Usage: isdir ");
return false;
}
- Console.WriteLine(PhysFS.IsDirectory(args[0]));
+ Console.WriteLine(physFS.IsDirectory(args[0]));
return true;
}
@@ -278,7 +280,7 @@ namespace Test
Console.WriteLine("Usage: issymlink ");
return false;
}
- Console.WriteLine(PhysFS.IsSymbolicLink(args[0]));
+ Console.WriteLine(physFS.IsSymbolicLink(args[0]));
return true;
}
@@ -289,7 +291,7 @@ namespace Test
Console.WriteLine("Usage: cat ");
return false;
}
- using (var reader = new System.IO.StreamReader(new PhysFSStream(args[0], OpenMode.Read)))
+ using (var reader = new System.IO.StreamReader(physFS.OpenRead(args[0])))
{
Console.WriteLine(reader.ReadToEnd());
}
@@ -303,7 +305,7 @@ namespace Test
Console.WriteLine("Usage: filelength ");
return false;
}
- using (var stream = new PhysFSStream(args[0], OpenMode.Read))
+ using (var stream = physFS.OpenRead(args[0]))
{
Console.WriteLine(stream.Length);
}
@@ -316,7 +318,7 @@ namespace Test
{
try
{
- PhysFS.InitializeCallbacks();
+ physFS = new PhysFS("");
}
catch (PhysFSLibNotFound)
{
@@ -324,9 +326,8 @@ namespace Test
Console.Error.WriteLine("ERROR: PhysFS could not be loaded. Are you sure it is installed or a suitable module is in your working directory?");
return;
}
- PhysFS.Init("");
- var version = PhysFS.GetLinkedVersion();
+ var version = physFS.GetLinkedVersion();
Console.WriteLine("SharpPhysFS Test console");
Console.WriteLine("Loaded PhysFS version: {0}.{1}.{2}", version.major, version.minor, version.patch);
@@ -382,7 +383,7 @@ namespace Test
Console.WriteLine("Done.");
}
}
- catch (PhysFSException e)
+ catch (PhysFS.PhysFSException e)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.Error.WriteLine("ERROR: {0}", e.Message);
@@ -396,7 +397,7 @@ namespace Test
}
}
- PhysFS.Deinit();
+ physFS.Dispose();
}
}
}