--- /dev/null
+/* PhysFSFileStream.cs - (c)2003 Gregory S. Read */\r
+using System;\r
+using System.Collections;\r
+using System.IO;\r
+\r
+namespace PhysFS_NET\r
+{\r
+ public enum PhysFSFileMode {Read, Write, Append};\r
+\r
+ // Our exception class we'll use for throwing all PhysFS API related exception\r
+ public class PhysFSException : IOException\r
+ {\r
+ public PhysFSException(string Message) : base(Message) {}\r
+ public PhysFSException() : base(PhysFS_DLL.PHYSFS_getLastError()) {}\r
+ }\r
+\r
+ public unsafe class PhysFSFileStream : Stream\r
+ {\r
+ // ***Public properties***\r
+ public override bool CanRead\r
+ {\r
+ get\r
+ {\r
+ // Reading is supported\r
+ return true;\r
+ }\r
+ }\r
+ \r
+ public override bool CanSeek\r
+ {\r
+ get\r
+ {\r
+ // Seek is supported\r
+ return true;\r
+ }\r
+ }\r
+\r
+ public override bool CanWrite\r
+ {\r
+ get\r
+ {\r
+ // Writing is supported\r
+ return true;\r
+ }\r
+ }\r
+\r
+ public override long Length\r
+ {\r
+ get\r
+ {\r
+ long TempLength;\r
+ TempLength = PhysFS_DLL.PHYSFS_fileLength(pHandle);\r
+\r
+ // If call returned an error, throw an exception\r
+ if(TempLength == -1)\r
+ throw new PhysFSException();\r
+\r
+ return TempLength;\r
+ }\r
+ }\r
+\r
+ public override long Position\r
+ {\r
+ get\r
+ {\r
+ long TempPosition;\r
+ TempPosition = PhysFS_DLL.PHYSFS_tell(pHandle);\r
+\r
+ // If call returned an error, throw an exception\r
+ if(TempPosition == -1)\r
+ throw new PhysFSException();\r
+\r
+ return TempPosition;\r
+ }\r
+ set\r
+ {\r
+ // Seek from beginning of file using the position value\r
+ Seek(value, SeekOrigin.Begin);\r
+ }\r
+ }\r
+ \r
+ // ***Public methods***\r
+ public PhysFSFileStream(string FileName, PhysFSFileMode FileMode, ulong BufferSize)\r
+ {\r
+ // Open the specified file with the appropriate file access\r
+ switch(FileMode)\r
+ {\r
+ case PhysFSFileMode.Read:\r
+ pHandle = PhysFS_DLL.PHYSFS_openRead(FileName);\r
+ break;\r
+ case PhysFSFileMode.Write:\r
+ pHandle = PhysFS_DLL.PHYSFS_openWrite(FileName);\r
+ break;\r
+ case PhysFSFileMode.Append:\r
+ pHandle = PhysFS_DLL.PHYSFS_openAppend(FileName);\r
+ break;\r
+ default:\r
+ throw new PhysFSException("Invalid FileMode specified");\r
+ }\r
+\r
+ // If handle is null, an error occured, so raise an exception\r
+ //!!! Does object get created if exception is thrown?\r
+ if(pHandle == null)\r
+ throw new PhysFSException();\r
+\r
+ // Set buffer size, raise an exception if an error occured\r
+ if(PhysFS_DLL.PHYSFS_setBuffer(pHandle, BufferSize) == 0)\r
+ throw new PhysFSException();\r
+ }\r
+\r
+ // This constructor sets the buffer size to 0 if not specified\r
+ public PhysFSFileStream(string FileName, PhysFSFileMode FileMode) : this(FileName, FileMode, 0) {}\r
+ \r
+ ~PhysFSFileStream()\r
+ {\r
+ // Don't close the handle if they've specifically closed it already\r
+ if(!Closed)\r
+ Close();\r
+ }\r
+\r
+ public override void Flush()\r
+ {\r
+ if(PhysFS_DLL.PHYSFS_flush(pHandle) == 0)\r
+ throw new PhysFSException();\r
+ }\r
+\r
+ public override int Read(byte[] buffer, int offset, int count)\r
+ {\r
+ long RetValue;\r
+ \r
+ fixed(byte *pbytes = &buffer[offset])\r
+ {\r
+ // Read into our allocated pointer\r
+ RetValue = PhysFS_DLL.PHYSFS_read(pHandle, pbytes, sizeof(byte), (uint)count);\r
+ }\r
+\r
+ if(RetValue == -1)\r
+ throw new PhysFSException();\r
+\r
+ // Return number of bytes read\r
+ // Note: This cast should be safe since we are only reading 'count' items, which\r
+ // is of type 'int'.\r
+ return (int)RetValue;\r
+ }\r
+\r
+ public override void Write(byte[] buffer, int offset, int count)\r
+ {\r
+ long RetValue;\r
+\r
+ fixed(byte* pbytes = &buffer[offset])\r
+ {\r
+ // Write buffer\r
+ RetValue = PhysFS_DLL.PHYSFS_write(pHandle, pbytes, sizeof(byte), (uint)count);\r
+ }\r
+\r
+ if(RetValue == -1)\r
+ throw new PhysFSException();\r
+ }\r
+\r
+ public override long Seek(long offset, SeekOrigin origin)\r
+ {\r
+ // Only seeking from beginning is supported by PhysFS API\r
+ if(origin != SeekOrigin.Begin)\r
+ throw new PhysFSException("Only seek origin of \"Begin\" is supported");\r
+ \r
+ // Seek to specified offset, raise an exception if error occured\r
+ if(PhysFS_DLL.PHYSFS_seek(pHandle, (ulong)offset) == 0)\r
+ throw new PhysFSException();\r
+\r
+ // Since we always seek from beginning, the offset is always\r
+ // the absolute position.\r
+ return offset;\r
+ }\r
+\r
+ public override void SetLength(long value)\r
+ {\r
+ throw new NotSupportedException("SetLength method not supported in PhysFSFileStream objects.");\r
+ }\r
+\r
+ public override void Close()\r
+ {\r
+ // Close the handle\r
+ if(PhysFS_DLL.PHYSFS_close(pHandle) == 0)\r
+ throw new PhysFSException();\r
+\r
+ // File has been closed. Rock.\r
+ Closed = true;\r
+ }\r
+\r
+ // ***Private variables***\r
+ private void *pHandle;\r
+ private bool Closed = false;\r
+ }\r
+}
\ No newline at end of file