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