123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194 |
- /* 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;
- }
- }
|