Begin refactoring

pull/2/head
Francesco Bertolaccini 2016-02-08 22:25:37 +01:00
parent 3aaddd6729
commit 1fce35a11c
6 changed files with 312 additions and 296 deletions

View File

@ -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;
}
}
}

View File

@ -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);
}
}
}
}

View File

@ -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
/// <summary>
/// Main class for SharpPhysFS
/// </summary>
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<T>(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);
}
}
/// <summary>
/// Sets up the library callbacks for use.
/// </summary>
/// <para>
/// This method will dynamically load the right library according to the
/// current platform, whether it is Windows of *nix
/// </para>
/// <para>
/// This method must be called before any other method in this class is available.
/// Not doing so will result in NullReferenceException
/// </para>
public static void InitializeCallbacks()
{
Interop.SetUpInterop();
}
/// <summary>
/// Get the version of PhysicsFS that is linked against your program
/// </summary>
/// <returns>The version of PhysicsFS that is linked against your program</returns>
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
/// <remarks>
/// 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.
/// </remarks>
/// <param name="argv0">This should be the path of the executable (first arguments passed to main function in C programs)</param>
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.
/// </remarks>
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
/// <param name="dir">directory or archive to add to the path, in platform-dependent notation.</param>
/// <param name="mountPoint">Location in the interpolated tree that this archive will be "mounted", in platform-independent notation. null or "" is equivalent to "/".</param>
/// <param name="appendToPath">True to append to search path, false to prepend.</param>
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().
/// </para>
/// <returns>String of last error message.</returns>
public static string GetLastError()
public string GetLastError()
{
return Marshal.PtrToStringAnsi(Interop.PHYSFS_getLastError());
return Marshal.PtrToStringAnsi(interop.PHYSFS_getLastError());
}
/// <summary>
@ -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)
/// </remarks>
/// <returns>Platform-dependent dir separator string</returns>
public static string GetDirSeparator()
public string GetDirSeparator()
{
return Marshal.PtrToStringAnsi(Interop.PHYSFS_getDirSeparator());
return Marshal.PtrToStringAnsi(interop.PHYSFS_getDirSeparator());
}
/// <summary>
@ -268,7 +175,7 @@ namespace SharpPhysFS
/// </code>
/// </para>
/// <param name="dir">Directory in platform-independent notation to enumerate.</param>
public static string[] EnumerateFiles(string dir)
public string[] EnumerateFiles(string dir)
{
var list = new List<string>();
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.
/// </remarks>
/// <returns>An enumeration of supported archive types</returns>
public static IEnumerable<ArchiveInfo> SupportedArchiveTypes()
public IEnumerable<ArchiveInfo> 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.
/// </remarks>
/// <param name="permit">true to permit symlinks, false to deny linking.</param>
public static void PermitSymbolicLinks(bool permit)
public void PermitSymbolicLinks(bool permit)
{
Interop.PHYSFS_permitSymbolicLinks(permit ? 1 : 0);
interop.PHYSFS_permitSymbolicLinks(permit ? 1 : 0);
}
/// <summary>
@ -348,7 +255,7 @@ namespace SharpPhysFS
/// This call may block while drives spin up. Be forewarned.
/// </remarks>
/// <returns>An enumeration of paths to available CD-ROM drives.</returns>
public static string[] GetCdRomDirs()
public string[] GetCdRomDirs()
{
var list = new List<string>();
GetCdRomDirsCallback((d, s) =>
@ -365,9 +272,9 @@ namespace SharpPhysFS
/// It is probably better to use managed methods for this.
/// </remarks>
/// <returns></returns>
public static string GetBaseDir()
public string GetBaseDir()
{
return Marshal.PtrToStringAnsi(Interop.PHYSFS_getBaseDir());
return Marshal.PtrToStringAnsi(interop.PHYSFS_getBaseDir());
}
/// <summary>
@ -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.
/// </para>
/// <returns>String of user dir in platform-dependent notation.</returns>
public static string GetUserDir()
public string GetUserDir()
{
return Marshal.PtrToStringAnsi(Interop.PHYSFS_getUserDir());
return Marshal.PtrToStringAnsi(interop.PHYSFS_getUserDir());
}
/// <summary>
@ -395,9 +302,9 @@ namespace SharpPhysFS
/// Get the current write dir. The default write dir is "".
/// </para>
/// <returns>String of write dir in platform-dependent notation, OR null IF NO WRITE PATH IS CURRENTLY SET</returns>
public static string GetWriteDir()
public string GetWriteDir()
{
return Marshal.PtrToStringAnsi(Interop.PHYSFS_getWriteDir());
return Marshal.PtrToStringAnsi(interop.PHYSFS_getWriteDir());
}
/// <summary>
@ -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.
/// </param>
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
/// <param name="newDir">Directory or archive to add to the path, in platform-dependent notation</param>
/// <param name="appendToPath">true to append to search path, false to prepend</param>
[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.
/// </para>
/// <param name="oldDir"> dir/archive to remove.</param>
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);
}
/// <summary>
/// Get the current search path.
/// </summary>
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.
/// </param>
/// <param name="archivesFirst">True to prepend the archives to the search path. False to append them. Ignored if !<paramref name="archiveExt"/>.</param>
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.
/// </para>
/// <param name="dirName">New dir to create.</param>
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. :)
/// </para>
/// <param name="filename">Filename to delete.</param>
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
/// </para>
/// <param name="filename">File to look for.</param>
/// <returns>String of element of search path containing the the file in question. null if not found.</returns>
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));
}
/// <summary>
@ -602,9 +509,9 @@ namespace SharpPhysFS
/// </para>
/// <param name="fname">Filename in platform-independent notation.</param>
/// <returns>True if filename exists. false otherwise.</returns>
public static bool Exists(string fname)
public bool Exists(string fname)
{
return Interop.PHYSFS_exists(fname) != 0;
return interop.PHYSFS_exists(fname) != 0;
}
/// <summary>
@ -614,9 +521,9 @@ namespace SharpPhysFS
/// <para>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.</para>
/// <param name="fname">Filename in platform-independent notation.</param>
/// <returns>True if filename exists and is a directory. False otherwise.</returns>
public static bool IsDirectory(string fname)
public bool IsDirectory(string fname)
{
return Interop.PHYSFS_isDirectory(fname) != 0;
return interop.PHYSFS_isDirectory(fname) != 0;
}
/// <summary>
@ -626,9 +533,9 @@ namespace SharpPhysFS
/// <para>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.</para>
/// <param name="fname">Filename in platform-independent notation.</param>
/// <returns>True if filename exists and is a symlink. False otherwise.</returns>
public static bool IsSymbolicLink(string fname)
public bool IsSymbolicLink(string fname)
{
return Interop.PHYSFS_isSymbolicLink(fname) != 0;
return interop.PHYSFS_isSymbolicLink(fname) != 0;
}
/// <summary>
@ -641,9 +548,9 @@ namespace SharpPhysFS
/// </para>
/// <param name="fname">Filename to check, in platform-independent notation.</param>
/// <returns>Last modified time of the file. -1 if it can't be determined.</returns>
public static long GetLastModTime(string fname)
public long GetLastModTime(string fname)
{
return Interop.PHYSFS_getLastModTime(fname);
return interop.PHYSFS_getLastModTime(fname);
}
/// <summary>
@ -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.
/// </para>
/// <returns>True if library is initialized, false if library is not.</returns>
public static bool IsInit()
public bool IsInit()
{
return Interop.PHYSFS_isInit() != 0;
return interop.PHYSFS_isInit() != 0;
}
/// <summary>
@ -667,14 +574,14 @@ namespace SharpPhysFS
/// If PhysFS.PermitSymbolicLinks() hasn't been called since the library was last initialized, symbolic links are implicitly disabled.
/// </para>
/// <returns>True if symlinks are permitted, false if not.</returns>
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.
/// </param>
/// <returns>String of mount point if added to path</returns>
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<T>(Action<T, string> c)
StringCallback WrapStringCallback<T>(Action<T, string> 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
/// <typeparam name="T">Type of data passed to callback</typeparam>
/// <param name="c">Callback function to notify about detected drives.</param>
/// <param name="data">Application-defined data passed to callback. Can be null.</param>
public static void GetCdRomDirsCallback<T>(Action<T, string> c, T data)
public void GetCdRomDirsCallback<T>(Action<T, string> 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
/// <typeparam name="T">Type of data passed to callback</typeparam>
/// <param name="c">Callback function to notify about search path elements.</param>
/// <param name="data">Application-defined data passed to callback. Can be null.</param>
public static void GetSearchPathCallback<T>(Action<T, string> c, T data)
public void GetSearchPathCallback<T>(Action<T, string> 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
/// <param name="dir">Directory, in platform-independent notation, to enumerate.</param>
/// <param name="c">Callback function to notify about search path elements.</param>
/// <param name="data">Application-defined data passed to callback. Can be null.</param>
public static void EnumerateFilesCallback<T>(string dir, Action<T, string, string> c, T data)
public void EnumerateFilesCallback<T>(string dir, Action<T, string, string> 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();
}
}
}

View File

@ -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);
}

View File

@ -37,6 +37,7 @@
<ItemGroup>
<Compile Include="PhysFS.cs" />
<Compile Include="Interop.cs" />
<Compile Include="PhysFS.LowLevel.cs" />
<Compile Include="PhysFSStream.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>

View File

@ -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 <dir>");
return false;
}
PhysFS.SetWriteDir(args[0]);
physFS.SetWriteDir(args[0]);
return true;
}
@ -193,7 +195,7 @@ namespace Test
{
Console.WriteLine("Usage: permitsymlinks <true/false>");
}
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 <dir>");
return false;
}
PhysFS.Mkdir(args[0]);
physFS.Mkdir(args[0]);
return true;
}
@ -234,7 +236,7 @@ namespace Test
Console.WriteLine("Usage: delete <dir>");
return false;
}
PhysFS.Delete(args[0]);
physFS.Delete(args[0]);
return true;
}
@ -245,7 +247,7 @@ namespace Test
Console.WriteLine("Usage: getrealdir <dir>");
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 <file>");
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 <path>");
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 <path>");
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 <file>");
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 <file>");
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();
}
}
}