Upload 2.0.2
[physicsfs] / extras / PhysFS.NET / PhysFSFileStream.cs
diff --git a/extras/PhysFS.NET/PhysFSFileStream.cs b/extras/PhysFS.NET/PhysFSFileStream.cs
new file mode 100755 (executable)
index 0000000..c0f6b05
--- /dev/null
@@ -0,0 +1,194 @@
+/* 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