Merge branch 'dllmap' into devel

pull/2/head
Francesco Bertolaccini 2017-05-26 13:15:22 +02:00
commit 9ae0d9d02d
7 changed files with 185 additions and 264 deletions

View File

@ -11,3 +11,6 @@
## Version 0.2.0 ## Version 0.2.0
- New dataless enumeration functions are available now, which do not cause GC havoc - New dataless enumeration functions are available now, which do not cause GC havoc
- Unsafe enumeration functions are now marked obsolete - Unsafe enumeration functions are now marked obsolete
## Version 1.0.0
- DLL configuration on platforms other than Windows is done via app.config now, as per http://www.mono-project.com/docs/advanced/pinvoke/dllmap/

View File

@ -4,19 +4,19 @@ using System.Runtime.InteropServices;
namespace SharpPhysFS namespace SharpPhysFS
{ {
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] [UnmanagedFunctionPointer(CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
public delegate int InitDelegate(); public delegate int InitDelegate();
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] [UnmanagedFunctionPointer(CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
public delegate void DeinitDelegate(); public delegate void DeinitDelegate();
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] [UnmanagedFunctionPointer(CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
public delegate IntPtr MallocDelegate(ulong size); public delegate IntPtr MallocDelegate(ulong size);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] [UnmanagedFunctionPointer(CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
public delegate IntPtr ReallocDelegate(IntPtr ptr, ulong size); public delegate IntPtr ReallocDelegate(IntPtr ptr, ulong size);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] [UnmanagedFunctionPointer(CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
public delegate void FreeDelegate(IntPtr ptr); public delegate void FreeDelegate(IntPtr ptr);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] [UnmanagedFunctionPointer(CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
public delegate void StringCallback(IntPtr data, string str); public delegate void StringCallback(IntPtr data, string str);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] [UnmanagedFunctionPointer(CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
public delegate void EnumFilesCallback(IntPtr data, string origdir, string fname); public delegate void EnumFilesCallback(IntPtr data, string origdir, string fname);
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Sequential)]
@ -62,225 +62,141 @@ namespace SharpPhysFS
public FreeDelegate Free; public FreeDelegate Free;
} }
static class DynamicLoader static class Interop
{ {
#region Windows [DllImport("physfs.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
[DllImport("kernel32.dll", SetLastError = true)] public static extern void PHYSFS_getLinkedVersion(ref Version v);
public static extern IntPtr LoadLibrary(string lpFileName);
[DllImport("kernel32.dll", CharSet = CharSet.Ansi, ExactSpelling = true, SetLastError = true)] [DllImport("physfs.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
public static extern IntPtr GetProcAddress(IntPtr hModule, string procName); public static extern int PHYSFS_init(string argv0);
[DllImport("kernel32.dll", CharSet = CharSet.Ansi, ExactSpelling = true, SetLastError = true)] [DllImport("physfs.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
public static extern bool FreeLibrary(IntPtr hModule); public static extern int PHYSFS_deinit();
#endregion
#region Unix [DllImport("physfs.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
[DllImport("libdl.so", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dlopen")] public static extern IntPtr PHYSFS_supportedArchiveTypes();
public static extern IntPtr unix_dlopen(string filename, int flags);
[DllImport("libdl.so", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dlsym")] [DllImport("physfs.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
public static extern IntPtr unix_dlsym(IntPtr handle, string symbol); public static extern void PHYSFS_freeList(IntPtr h);
[DllImport("libdl.so", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dlclose")] [DllImport("physfs.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
public static extern bool unix_dlclose(IntPtr handle); public static extern IntPtr PHYSFS_getLastError();
#endregion
#region OSX [DllImport("physfs.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
[DllImport("libdyld.dylib", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dlopen")] public static extern IntPtr PHYSFS_getDirSeparator();
public static extern IntPtr osx_dlopen(string filename, int flags);
[DllImport("libdyld.dylib", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dlsym")] [DllImport("physfs.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
public static extern IntPtr osx_dlsym(IntPtr handle, string symbol); public static extern void PHYSFS_permitSymbolicLinks(int permit);
[DllImport("libdyld.dylib", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dlclose")] [DllImport("physfs.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
public static extern bool osx_dlclose(IntPtr handle); public static extern IntPtr PHYSFS_getCdRomDirs();
#endregion
}
class Interop [DllImport("physfs.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
: IDisposable public static extern IntPtr PHYSFS_getBaseDir();
{
InvalidOperationException initException = new InvalidOperationException("Callbacks not initialized yet");
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void FnGetLinkedVersion(ref Version v);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate int FnInit(string argv0);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate int FnDeinit();
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate int FnClose(IntPtr ptr);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate IntPtr FnSupportedArchiveTypes();
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void FnFreeList(IntPtr h);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate IntPtr FnGetLastError();
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void FnPermitSymbolicLinks(int permit);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate int FnSetWriteDir(string s);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate int FnAddToSearchPath(string s, int i);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate int FnSetSaneConfig(string s1, string s2, string s3, int i1, int i2);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate IntPtr FnEnumerateFiles(string s);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate long FnGetLastModTime(string s);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate long FnRead(IntPtr ptr1, IntPtr ptr2, uint i1, uint i2);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate long FnTell(IntPtr ptr);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate int FnSeek(IntPtr ptr, ulong u);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate long FnFileLength(IntPtr ptr);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate int FnSetAllocator(Allocator alloc);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate int FnMount(string s1, string s2, int i);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void FnGetCdRomDirsCallback(StringCallback c, IntPtr ptr);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void FnEnumerateFilesCallback(string s, EnumFilesCallback c, IntPtr ptr);
// When the callbacks are not yet initialized, instead of throwing a [DllImport("physfs.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
// null reference exception we explain the problem. public static extern IntPtr PHYSFS_getUserDir();
// I think it makes for a more graceful failure.
public FnGetLinkedVersion PHYSFS_getLinkedVersion => throw initException;
public FnInit PHYSFS_init => throw initException;
public FnDeinit PHYSFS_deinit => throw initException;
public FnSupportedArchiveTypes PHYSFS_supportedArchiveTypes => throw initException;
public FnFreeList PHYSFS_freeList => throw initException;
public FnGetLastError PHYSFS_getLastError => throw initException;
public FnGetLastError PHYSFS_getDirSeparator => throw initException;
public FnPermitSymbolicLinks PHYSFS_permitSymbolicLinks => throw initException;
public FnSupportedArchiveTypes PHYSFS_getCdRomDirs => throw initException;
public FnGetLastError PHYSFS_getBaseDir => throw initException;
public FnGetLastError PHYSFS_getUserDir => throw initException;
public FnGetLastError PHYSFS_getWriteDir => throw initException;
public FnSetWriteDir PHYSFS_setWriteDir => throw initException;
public FnAddToSearchPath PHYSFS_addToSearchPath => throw initException;
public FnSetWriteDir PHYSFS_removeFromSearchPath => throw initException;
public FnSupportedArchiveTypes PHYSFS_getSearchPath => throw initException;
public FnSetSaneConfig PHYSFS_setSaneConfig => throw initException;
public FnSetWriteDir PHYSFS_mkdir => throw initException;
public FnSetWriteDir PHYSFS_delete => throw initException;
public FnEnumerateFiles PHYSFS_getRealDir => throw initException;
public FnEnumerateFiles PHYSFS_enumerateFiles => throw initException;
public FnSetWriteDir PHYSFS_exists => throw initException;
public FnSetWriteDir PHYSFS_isDirectory => throw initException;
public FnSetWriteDir PHYSFS_isSymbolicLink => throw initException;
public FnGetLastModTime PHYSFS_getLastModTime => throw initException;
public FnEnumerateFiles PHYSFS_openWrite => throw initException;
public FnEnumerateFiles PHYSFS_openAppend => throw initException;
public FnEnumerateFiles PHYSFS_openRead => throw initException;
public FnClose PHYSFS_close => throw initException;
public FnRead PHYSFS_read => throw initException;
public FnRead PHYSFS_write => throw initException;
public FnClose PHYSFS_eof => throw initException;
public FnTell PHYSFS_tell => throw initException;
public FnSeek PHYSFS_seek => throw initException;
public FnFileLength PHYSFS_fileLength => throw initException;
public FnSeek PHYSFS_setBuffer => throw initException;
public FnClose PHYSFS_flush => throw initException;
public FnDeinit PHYSFS_isInit => throw initException;
public FnDeinit PHYSFS_symbolicLinksPermitted => throw initException;
public FnSetAllocator PHYSFS_setAllocator => throw initException;
public FnMount PHYSFS_mount => throw initException;
public FnEnumerateFiles PHYSFS_getMountPoint => throw initException;
public FnGetCdRomDirsCallback PHYSFS_getCdRomDirsCallback => throw initException;
public FnGetCdRomDirsCallback PHYSFS_getSearchPathCallback => throw initException;
public FnEnumerateFilesCallback PHYSFS_enumerateFilesCallback => throw initException;
public Interop() [DllImport("physfs.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
: this("physfs.dll", "libphysfs.dylib", "libphysfs.so") public static extern IntPtr PHYSFS_getWriteDir();
{ }
public Interop(string libname) [DllImport("physfs.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
: this($"{libname}.dll", $"{libname}.dylib", $"{libname}.so") public static extern int PHYSFS_setWriteDir(string s);
{ }
Func<string, IntPtr> loadLibrary; [DllImport("physfs.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
Func<IntPtr, string, IntPtr> loadSymbol; public static extern int PHYSFS_addToSearchPath(string s, int i);
Func<IntPtr, bool> freeLibrary;
IntPtr library;
public Interop(string winlib, string maclib, string unixlib) [DllImport("physfs.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
{ public static extern int PHYSFS_removeFromSearchPath(string s);
/* This method is used to dynamically load the physfs
* library. It works by detecting the current platform
* and deciding whether to use LoadLibrary/GetProcAddr
* on Windows or dlopen/dlsym on Linux and OSX.
* The the class is then scanned using reflection
* to populate all the callbacks with the right function
* pointers from the loaded library
*/
string libraryName; [DllImport("physfs.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
public static extern IntPtr PHYSFS_getSearchPath();
if (Environment.OSVersion.Platform == PlatformID.Win32NT) [DllImport("physfs.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
{ public static extern int PHYSFS_setSaneConfig(string s1, string s2, string s3, int i1, int i2);
loadLibrary = DynamicLoader.LoadLibrary;
loadSymbol = DynamicLoader.GetProcAddress;
freeLibrary = DynamicLoader.FreeLibrary;
libraryName = winlib;
}
else if(Environment.OSVersion.Platform == PlatformID.MacOSX)
{
loadLibrary = n => DynamicLoader.osx_dlopen(n, 1);
loadSymbol = DynamicLoader.osx_dlsym;
freeLibrary = DynamicLoader.osx_dlclose;
libraryName = maclib;
}
else
{
loadLibrary = n => DynamicLoader.unix_dlopen(n, 1);
loadSymbol = DynamicLoader.unix_dlsym;
freeLibrary = DynamicLoader.unix_dlclose;
libraryName = unixlib;
}
library = loadLibrary(libraryName); [DllImport("physfs.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
if (library == IntPtr.Zero) public static extern int PHYSFS_mkdir(string s);
{
throw new PhysFSLibNotFound();
}
var fields = typeof(Interop).GetFields(); [DllImport("physfs.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
public static extern int PHYSFS_delete(string s);
foreach(var field in fields.Where(x => x.Name.StartsWith("PHYSFS_"))) [DllImport("physfs.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
{ public static extern IntPtr PHYSFS_getRealDir(string s);
var funcPtr = loadSymbol(library, field.Name);
var del = Marshal.GetDelegateForFunctionPointer(funcPtr, field.FieldType);
field.SetValue(this, del); [DllImport("physfs.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
} public static extern IntPtr PHYSFS_enumerateFiles(string s);
}
[DllImport("physfs.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
#region IDisposable Support public static extern int PHYSFS_exists(string s);
private bool disposedValue = false; // To detect redundant calls
[DllImport("physfs.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
protected virtual void Dispose(bool disposing) public static extern int PHYSFS_isDirectory(string s);
{
if (!disposedValue) [DllImport("physfs.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
{ public static extern int PHYSFS_isSymbolicLink(string s);
/*if (disposing)
{ [DllImport("physfs.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
// TODO: dispose managed state (managed objects). public static extern long PHYSFS_getLastModTime(string s);
}*/
[DllImport("physfs.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
freeLibrary(library); public static extern IntPtr PHYSFS_openWrite(string s);
disposedValue = true; [DllImport("physfs.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
} public static extern IntPtr PHYSFS_openAppend(string s);
}
[DllImport("physfs.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
public void Dispose() public static extern IntPtr PHYSFS_openRead(string s);
{
Dispose(true); [DllImport("physfs.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
} public static extern int PHYSFS_close(IntPtr ptr);
#endregion
[DllImport("physfs.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
public static extern long PHYSFS_read(IntPtr ptr1, IntPtr ptr2, uint i1, uint i2);
[DllImport("physfs.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
public static extern long PHYSFS_write(IntPtr ptr1, IntPtr ptr2, uint i1, uint i2);
[DllImport("physfs.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
public static extern int PHYSFS_eof(IntPtr ptr);
[DllImport("physfs.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
public static extern long PHYSFS_tell(IntPtr ptr);
[DllImport("physfs.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
public static extern int PHYSFS_seek(IntPtr ptr, ulong u);
[DllImport("physfs.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
public static extern long PHYSFS_fileLength(IntPtr ptr);
[DllImport("physfs.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
public static extern int PHYSFS_setBuffer(IntPtr ptr, ulong u);
[DllImport("physfs.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
public static extern int PHYSFS_flush(IntPtr ptr);
[DllImport("physfs.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
public static extern int PHYSFS_isInit();
[DllImport("physfs.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
public static extern int PHYSFS_symbolicLinksPermitted();
[DllImport("physfs.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
public static extern int PHYSFS_setAllocator(Allocator alloc);
[DllImport("physfs.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
public static extern int PHYSFS_mount(string s1, string s2, int i);
[DllImport("physfs.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
public static extern IntPtr PHYSFS_getMountPoint(string s);
[DllImport("physfs.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
public static extern void PHYSFS_getCdRomDirsCallback(StringCallback c, IntPtr p);
[DllImport("physfs.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
public static extern void PHYSFS_getSearchPathCallback(StringCallback c, IntPtr p);
[DllImport("physfs.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
public static extern void PHYSFS_enumerateFilesCallback(string s, EnumFilesCallback c, IntPtr p);
} }
} }

View File

@ -8,7 +8,7 @@ namespace SharpPhysFS
{ {
public static IntPtr OpenWrite(string filename, PhysFS physFS) public static IntPtr OpenWrite(string filename, PhysFS physFS)
{ {
var val = physFS.interop.PHYSFS_openWrite(filename); var val = Interop.PHYSFS_openWrite(filename);
if (val == null) if (val == null)
throw new PhysFSException(physFS); throw new PhysFSException(physFS);
return val; return val;
@ -16,7 +16,7 @@ namespace SharpPhysFS
public static IntPtr OpenAppend(string filename, PhysFS physFS) public static IntPtr OpenAppend(string filename, PhysFS physFS)
{ {
var val = physFS.interop.PHYSFS_openAppend(filename); var val = Interop.PHYSFS_openAppend(filename);
if (val == null) if (val == null)
throw new PhysFSException(physFS); throw new PhysFSException(physFS);
return val; return val;
@ -24,7 +24,7 @@ namespace SharpPhysFS
public static IntPtr OpenRead(string filename, PhysFS physFS) public static IntPtr OpenRead(string filename, PhysFS physFS)
{ {
var val = physFS.interop.PHYSFS_openRead(filename); var val = Interop.PHYSFS_openRead(filename);
if (val == null) if (val == null)
throw new PhysFSException(physFS); throw new PhysFSException(physFS);
return val; return val;
@ -32,62 +32,62 @@ namespace SharpPhysFS
public static void Close(IntPtr file, PhysFS physFS) public static void Close(IntPtr file, PhysFS physFS)
{ {
int err = physFS.interop.PHYSFS_close(file); int err = Interop.PHYSFS_close(file);
physFS.ThrowException(err); physFS.ThrowException(err);
} }
public static long Read(IntPtr file, byte[] buffer, uint objSize, uint objCount, PhysFS physFS) public static long Read(IntPtr file, byte[] buffer, uint objSize, uint objCount)
{ {
unsafe unsafe
{ {
fixed (void* ptr = buffer) fixed (void* ptr = buffer)
{ {
return physFS.interop.PHYSFS_read(file, (IntPtr)ptr, objSize, objCount); return Interop.PHYSFS_read(file, (IntPtr)ptr, objSize, objCount);
} }
} }
} }
public static long Write(IntPtr file, byte[] buffer, uint objSize, uint objCount, PhysFS physFS) public static long Write(IntPtr file, byte[] buffer, uint objSize, uint objCount)
{ {
unsafe unsafe
{ {
fixed (void* ptr = buffer) fixed (void* ptr = buffer)
{ {
return physFS.interop.PHYSFS_write(file, (IntPtr)ptr, objSize, objCount); return Interop.PHYSFS_write(file, (IntPtr)ptr, objSize, objCount);
} }
} }
} }
public static bool EOF(IntPtr file, PhysFS physFS) public static bool EOF(IntPtr file)
{ {
return physFS.interop.PHYSFS_eof(file) != 0; return Interop.PHYSFS_eof(file) != 0;
} }
public static long Tell(IntPtr file, PhysFS physFS) public static long Tell(IntPtr file)
{ {
return physFS.interop.PHYSFS_tell(file); return Interop.PHYSFS_tell(file);
} }
public static void Seek(IntPtr file, ulong pos, PhysFS physFS) public static void Seek(IntPtr file, ulong pos, PhysFS physFS)
{ {
int err = physFS.interop.PHYSFS_seek(file, pos); int err = Interop.PHYSFS_seek(file, pos);
physFS.ThrowException(err); physFS.ThrowException(err);
} }
public static long FileLength(IntPtr file, PhysFS physFS) public static long FileLength(IntPtr file)
{ {
return physFS.interop.PHYSFS_fileLength(file); return Interop.PHYSFS_fileLength(file);
} }
public static void SetBuffer(IntPtr file, ulong bufSize, PhysFS physFS) public static void SetBuffer(IntPtr file, ulong bufSize, PhysFS physFS)
{ {
int err = physFS.interop.PHYSFS_setBuffer(file, bufSize); int err = Interop.PHYSFS_setBuffer(file, bufSize);
physFS.ThrowException(err); physFS.ThrowException(err);
} }
public static void Flush(IntPtr file, PhysFS physFS) public static void Flush(IntPtr file, PhysFS physFS)
{ {
int err = physFS.interop.PHYSFS_flush(file); int err = Interop.PHYSFS_flush(file);
physFS.ThrowException(err); physFS.ThrowException(err);
} }
} }

View File

@ -24,11 +24,13 @@ namespace SharpPhysFS
{ } { }
} }
Interop interop;
public PhysFS(string argv0) public PhysFS(string argv0)
{ {
interop = new Interop(); Init(argv0);
}
public PhysFS(string argv0, string libname)
{
Init(argv0); Init(argv0);
} }
@ -52,7 +54,7 @@ namespace SharpPhysFS
public Version GetLinkedVersion() public Version GetLinkedVersion()
{ {
Version v = new Version(); Version v = new Version();
interop.PHYSFS_getLinkedVersion(ref v); Interop.PHYSFS_getLinkedVersion(ref v);
return v; return v;
} }
@ -67,7 +69,7 @@ namespace SharpPhysFS
/// <param name="argv0">This should be the path of the executable (first arguments passed to main function in C programs)</param> /// <param name="argv0">This should be the path of the executable (first arguments passed to main function in C programs)</param>
public void Init(string argv0) public void Init(string argv0)
{ {
int err = interop.PHYSFS_init(argv0); int err = Interop.PHYSFS_init(argv0);
ThrowException(err); ThrowException(err);
} }
@ -90,7 +92,7 @@ namespace SharpPhysFS
/// </remarks> /// </remarks>
public void Deinit() public void Deinit()
{ {
int err = interop.PHYSFS_deinit(); int err = Interop.PHYSFS_deinit();
ThrowException(err); ThrowException(err);
} }
@ -117,7 +119,7 @@ namespace SharpPhysFS
/// <param name="appendToPath">True to append to search path, false to prepend.</param> /// <param name="appendToPath">True to append to search path, false to prepend.</param>
public 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); ThrowException(err);
} }
@ -134,7 +136,7 @@ namespace SharpPhysFS
/// <returns>String of last error message.</returns> /// <returns>String of last error message.</returns>
public string GetLastError() public string GetLastError()
{ {
return Marshal.PtrToStringAnsi(interop.PHYSFS_getLastError()); return Marshal.PtrToStringAnsi(Interop.PHYSFS_getLastError());
} }
/// <summary> /// <summary>
@ -150,7 +152,7 @@ namespace SharpPhysFS
/// <returns>Platform-dependent dir separator string</returns> /// <returns>Platform-dependent dir separator string</returns>
public string GetDirSeparator() public string GetDirSeparator()
{ {
return Marshal.PtrToStringAnsi(interop.PHYSFS_getDirSeparator()); return Marshal.PtrToStringAnsi(Interop.PHYSFS_getDirSeparator());
} }
/// <summary> /// <summary>
@ -196,7 +198,7 @@ namespace SharpPhysFS
/// <returns>An enumeration of supported archive types</returns> /// <returns>An enumeration of supported archive types</returns>
public IEnumerable<ArchiveInfo> SupportedArchiveTypes() public IEnumerable<ArchiveInfo> SupportedArchiveTypes()
{ {
IntPtr archives = interop.PHYSFS_supportedArchiveTypes(); IntPtr archives = Interop.PHYSFS_supportedArchiveTypes();
IntPtr i = archives; IntPtr i = archives;
for (i = archives; Marshal.ReadIntPtr(i) != IntPtr.Zero; i = IntPtr.Add(i, IntPtr.Size)) for (i = archives; Marshal.ReadIntPtr(i) != IntPtr.Zero; i = IntPtr.Add(i, IntPtr.Size))
{ {
@ -231,7 +233,7 @@ namespace SharpPhysFS
/// <param name="permit">true to permit symlinks, false to deny linking.</param> /// <param name="permit">true to permit symlinks, false to deny linking.</param>
public void PermitSymbolicLinks(bool permit) public void PermitSymbolicLinks(bool permit)
{ {
interop.PHYSFS_permitSymbolicLinks(permit ? 1 : 0); Interop.PHYSFS_permitSymbolicLinks(permit ? 1 : 0);
} }
/// <summary> /// <summary>
@ -268,7 +270,7 @@ namespace SharpPhysFS
/// <returns></returns> /// <returns></returns>
public string GetBaseDir() public string GetBaseDir()
{ {
return Marshal.PtrToStringAnsi(interop.PHYSFS_getBaseDir()); return Marshal.PtrToStringAnsi(Interop.PHYSFS_getBaseDir());
} }
/// <summary> /// <summary>
@ -286,7 +288,7 @@ namespace SharpPhysFS
/// <returns>String of user dir in platform-dependent notation.</returns> /// <returns>String of user dir in platform-dependent notation.</returns>
public string GetUserDir() public string GetUserDir()
{ {
return Marshal.PtrToStringAnsi(interop.PHYSFS_getUserDir()); return Marshal.PtrToStringAnsi(Interop.PHYSFS_getUserDir());
} }
/// <summary> /// <summary>
@ -298,7 +300,7 @@ namespace SharpPhysFS
/// <returns>String of write dir in platform-dependent notation, OR null IF NO WRITE PATH IS CURRENTLY SET</returns> /// <returns>String of write dir in platform-dependent notation, OR null IF NO WRITE PATH IS CURRENTLY SET</returns>
public string GetWriteDir() public string GetWriteDir()
{ {
return Marshal.PtrToStringAnsi(interop.PHYSFS_getWriteDir()); return Marshal.PtrToStringAnsi(Interop.PHYSFS_getWriteDir());
} }
/// <summary> /// <summary>
@ -316,7 +318,7 @@ namespace SharpPhysFS
/// </param> /// </param>
public void SetWriteDir(string path) public void SetWriteDir(string path)
{ {
int err = interop.PHYSFS_setWriteDir(path); int err = Interop.PHYSFS_setWriteDir(path);
ThrowException(err); ThrowException(err);
} }
@ -328,7 +330,7 @@ namespace SharpPhysFS
[Obsolete("AddToSearchPath is deprecated, please use Mount instead")] [Obsolete("AddToSearchPath is deprecated, please use Mount instead")]
public 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); ThrowException(err);
} }
@ -344,7 +346,7 @@ namespace SharpPhysFS
/// <param name="oldDir"> dir/archive to remove.</param> /// <param name="oldDir"> dir/archive to remove.</param>
public void RemoveFromSearchPath(string oldDir) public void RemoveFromSearchPath(string oldDir)
{ {
int err = interop.PHYSFS_removeFromSearchPath(oldDir); int err = Interop.PHYSFS_removeFromSearchPath(oldDir);
ThrowException(err); ThrowException(err);
} }
@ -414,7 +416,7 @@ namespace SharpPhysFS
/// <param name="archivesFirst">True to prepend the archives to the search path. False to append them. Ignored if !<paramref name="archiveExt"/>.</param> /// <param name="archivesFirst">True to prepend the archives to the search path. False to append them. Ignored if !<paramref name="archiveExt"/>.</param>
public 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); ThrowException(err);
} }
@ -434,7 +436,7 @@ namespace SharpPhysFS
/// <param name="dirName">New dir to create.</param> /// <param name="dirName">New dir to create.</param>
public void Mkdir(string dirName) public void Mkdir(string dirName)
{ {
int err = interop.PHYSFS_mkdir(dirName); int err = Interop.PHYSFS_mkdir(dirName);
ThrowException(err); ThrowException(err);
} }
@ -461,7 +463,7 @@ namespace SharpPhysFS
/// <param name="filename">Filename to delete.</param> /// <param name="filename">Filename to delete.</param>
public void Delete(string filename) public void Delete(string filename)
{ {
int err = interop.PHYSFS_delete(filename); int err = Interop.PHYSFS_delete(filename);
ThrowException(err); ThrowException(err);
} }
@ -485,7 +487,7 @@ namespace SharpPhysFS
/// <returns>String of element of search path containing the the file in question. null if not found.</returns> /// <returns>String of element of search path containing the the file in question. null if not found.</returns>
public string GetRealDir(string filename) public string GetRealDir(string filename)
{ {
return Marshal.PtrToStringAnsi(interop.PHYSFS_getRealDir(filename)); return Marshal.PtrToStringAnsi(Interop.PHYSFS_getRealDir(filename));
} }
/// <summary> /// <summary>
@ -500,7 +502,7 @@ namespace SharpPhysFS
/// <returns>True if filename exists. false otherwise.</returns> /// <returns>True if filename exists. false otherwise.</returns>
public bool Exists(string fname) public bool Exists(string fname)
{ {
return interop.PHYSFS_exists(fname) != 0; return Interop.PHYSFS_exists(fname) != 0;
} }
/// <summary> /// <summary>
@ -512,7 +514,7 @@ namespace SharpPhysFS
/// <returns>True if filename exists and is a directory. False otherwise.</returns> /// <returns>True if filename exists and is a directory. False otherwise.</returns>
public bool IsDirectory(string fname) public bool IsDirectory(string fname)
{ {
return interop.PHYSFS_isDirectory(fname) != 0; return Interop.PHYSFS_isDirectory(fname) != 0;
} }
/// <summary> /// <summary>
@ -524,7 +526,7 @@ namespace SharpPhysFS
/// <returns>True if filename exists and is a symlink. False otherwise.</returns> /// <returns>True if filename exists and is a symlink. False otherwise.</returns>
public bool IsSymbolicLink(string fname) public bool IsSymbolicLink(string fname)
{ {
return interop.PHYSFS_isSymbolicLink(fname) != 0; return Interop.PHYSFS_isSymbolicLink(fname) != 0;
} }
/// <summary> /// <summary>
@ -539,7 +541,7 @@ namespace SharpPhysFS
/// <returns>Last modified time of the file. -1 if it can't be determined.</returns> /// <returns>Last modified time of the file. -1 if it can't be determined.</returns>
public long GetLastModTime(string fname) public long GetLastModTime(string fname)
{ {
return interop.PHYSFS_getLastModTime(fname); return Interop.PHYSFS_getLastModTime(fname);
} }
/// <summary> /// <summary>
@ -552,7 +554,7 @@ namespace SharpPhysFS
/// <returns>True if library is initialized, false if library is not.</returns> /// <returns>True if library is initialized, false if library is not.</returns>
public bool IsInit() public bool IsInit()
{ {
return interop.PHYSFS_isInit() != 0; return Interop.PHYSFS_isInit() != 0;
} }
/// <summary> /// <summary>
@ -565,12 +567,12 @@ namespace SharpPhysFS
/// <returns>True if symlinks are permitted, false if not.</returns> /// <returns>True if symlinks are permitted, false if not.</returns>
public bool SymbolicLinksPermitted() public bool SymbolicLinksPermitted()
{ {
return interop.PHYSFS_symbolicLinksPermitted() != 0; return Interop.PHYSFS_symbolicLinksPermitted() != 0;
} }
public void SetAllocator(Allocator allocator) public void SetAllocator(Allocator allocator)
{ {
int err = interop.PHYSFS_setAllocator(allocator); int err = Interop.PHYSFS_setAllocator(allocator);
ThrowException(err); ThrowException(err);
} }
@ -588,7 +590,7 @@ namespace SharpPhysFS
/// <returns>String of mount point if added to path</returns> /// <returns>String of mount point if added to path</returns>
public 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) if(s == null)
{ {
throw new PhysFSException(this); throw new PhysFSException(this);
@ -608,7 +610,7 @@ namespace SharpPhysFS
void GetCdRomDirsCallback(StringCallback c, object data) void GetCdRomDirsCallback(StringCallback c, object data)
{ {
GCHandle objHandle = GCHandle.Alloc(data); GCHandle objHandle = GCHandle.Alloc(data);
interop.PHYSFS_getCdRomDirsCallback(c, GCHandle.ToIntPtr(objHandle)); Interop.PHYSFS_getCdRomDirsCallback(c, GCHandle.ToIntPtr(objHandle));
objHandle.Free(); objHandle.Free();
} }
@ -633,13 +635,13 @@ namespace SharpPhysFS
/// <param name="c">Callback function to notify about detected drives.</param> /// <param name="c">Callback function to notify about detected drives.</param>
public void GetCdRomDirsCallback(Action<string> c) public void GetCdRomDirsCallback(Action<string> c)
{ {
interop.PHYSFS_getCdRomDirsCallback((p, s) => c(s), IntPtr.Zero); Interop.PHYSFS_getCdRomDirsCallback((p, s) => c(s), IntPtr.Zero);
} }
void GetSearchPathCallback(StringCallback c, object data) void GetSearchPathCallback(StringCallback c, object data)
{ {
GCHandle objHandle = GCHandle.Alloc(data); GCHandle objHandle = GCHandle.Alloc(data);
interop.PHYSFS_getSearchPathCallback(c, GCHandle.ToIntPtr(objHandle)); Interop.PHYSFS_getSearchPathCallback(c, GCHandle.ToIntPtr(objHandle));
objHandle.Free(); objHandle.Free();
} }
@ -664,13 +666,13 @@ namespace SharpPhysFS
/// <param name="c">Callback function to notify about search path elements.</param> /// <param name="c">Callback function to notify about search path elements.</param>
public void GetSearchPathCallback(Action<string> c) public void GetSearchPathCallback(Action<string> c)
{ {
interop.PHYSFS_getSearchPathCallback((p, s) => c(s), IntPtr.Zero); Interop.PHYSFS_getSearchPathCallback((p, s) => c(s), IntPtr.Zero);
} }
void EnumerateFilesCallback(string dir, EnumFilesCallback c, object data) void EnumerateFilesCallback(string dir, EnumFilesCallback c, object data)
{ {
GCHandle objHandle = GCHandle.Alloc(data); GCHandle objHandle = GCHandle.Alloc(data);
interop.PHYSFS_enumerateFilesCallback(dir, c, GCHandle.ToIntPtr(objHandle)); Interop.PHYSFS_enumerateFilesCallback(dir, c, GCHandle.ToIntPtr(objHandle));
objHandle.Free(); objHandle.Free();
} }
@ -701,7 +703,7 @@ namespace SharpPhysFS
/// <param name="c">Callback function to notify about search path elements.</param> /// <param name="c">Callback function to notify about search path elements.</param>
public void EnumerateFilesCallback(string dir, Action<string, string> c) public void EnumerateFilesCallback(string dir, Action<string, string> c)
{ {
interop.PHYSFS_enumerateFilesCallback(dir, (data, origdir, fname) => c(origdir, fname), IntPtr.Zero); Interop.PHYSFS_enumerateFilesCallback(dir, (data, origdir, fname) => c(origdir, fname), IntPtr.Zero);
} }
public PhysFSStream OpenAppend(string file) public PhysFSStream OpenAppend(string file)
@ -731,7 +733,6 @@ namespace SharpPhysFS
if (disposing) if (disposing)
{ {
Deinit(); Deinit();
interop.Dispose();
} }
disposed = true; disposed = true;

View File

@ -49,7 +49,7 @@ namespace SharpPhysFS
{ {
get get
{ {
return PhysFS.LowLevel.FileLength(handle, physFS); return PhysFS.LowLevel.FileLength(handle);
} }
} }
@ -57,7 +57,7 @@ namespace SharpPhysFS
{ {
get get
{ {
return PhysFS.LowLevel.Tell(handle, physFS); return PhysFS.LowLevel.Tell(handle);
} }
set set
{ {
@ -67,7 +67,7 @@ namespace SharpPhysFS
public long Read(byte[] buffer, uint offset, uint count) public long Read(byte[] buffer, uint offset, uint count)
{ {
return PhysFS.LowLevel.Read(handle, buffer, 1, count, physFS); return PhysFS.LowLevel.Read(handle, buffer, 1, count);
} }
public override int Read(byte[] buffer, int offset, int count) public override int Read(byte[] buffer, int offset, int count)
@ -81,9 +81,9 @@ namespace SharpPhysFS
if (origin == SeekOrigin.Begin) if (origin == SeekOrigin.Begin)
pos = 0; pos = 0;
else if (origin == SeekOrigin.Current) else if (origin == SeekOrigin.Current)
pos = PhysFS.LowLevel.Tell(handle, physFS); pos = PhysFS.LowLevel.Tell(handle);
else else
pos = PhysFS.LowLevel.FileLength(handle, physFS); pos = PhysFS.LowLevel.FileLength(handle);
PhysFS.LowLevel.Seek(handle, (ulong)(pos + offset), physFS); PhysFS.LowLevel.Seek(handle, (ulong)(pos + offset), physFS);
return pos + offset; return pos + offset;
@ -91,7 +91,7 @@ namespace SharpPhysFS
public long Write(byte[] buffer, uint offset, uint count) public long Write(byte[] buffer, uint offset, uint count)
{ {
return PhysFS.LowLevel.Write(handle, buffer, 1, count, physFS); return PhysFS.LowLevel.Write(handle, buffer, 1, count);
} }
public override void Write(byte[] buffer, int offset, int count) public override void Write(byte[] buffer, int offset, int count)

View File

@ -10,7 +10,7 @@ using System.Runtime.InteropServices;
[assembly: AssemblyConfiguration("")] [assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Francesco Bertolaccini")] [assembly: AssemblyCompany("Francesco Bertolaccini")]
[assembly: AssemblyProduct("SharpPhysFS")] [assembly: AssemblyProduct("SharpPhysFS")]
[assembly: AssemblyCopyright("Copyright © 2016 Francesco Bertolaccini")] [assembly: AssemblyCopyright("")]
[assembly: AssemblyTrademark("")] [assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")] [assembly: AssemblyCulture("")]
@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Build and Revision Numbers // You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below: // by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")] // [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("0.2.0.0")] [assembly: AssemblyVersion("0.1.0.0")]
[assembly: AssemblyFileVersion("0.2.0.0")] [assembly: AssemblyFileVersion("0.1.0.0")]

View File

@ -3,4 +3,5 @@
<startup> <startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" /> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
</startup> </startup>
<dllmap os="!windows" dll="physfs.dll" target="libphysfs.so" />
</configuration> </configuration>