// Authors:
// Jonathan Pryor (jonpryor@vt.edu)
//
-// (C) 2005 Jonathan Pryor
+// (C) 2005-2006 Jonathan Pryor
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
public class StdioFileStream : Stream
{
public static readonly IntPtr InvalidFileStream = IntPtr.Zero;
- public static readonly IntPtr StandardInput = Stdlib.stdin;
- public static readonly IntPtr StandardOutput = Stdlib.stdout;
- public static readonly IntPtr StandardError = Stdlib.stderr;
+ public static readonly IntPtr StandardInput = Native.Stdlib.stdin;
+ public static readonly IntPtr StandardOutput = Native.Stdlib.stdout;
+ public static readonly IntPtr StandardError = Native.Stdlib.stderr;
public StdioFileStream (IntPtr fileStream)
: this (fileStream, true) {}
public StdioFileStream (string path)
{
- InitStream (Fopen (path, "r"), true);
+ InitStream (Fopen (path, "rb"), true);
}
public StdioFileStream (string path, string mode)
if (path.Length == 0)
throw new ArgumentException ("path");
if (mode == null)
- throw new ArgumentNullException ("path");
- IntPtr f = Stdlib.fopen (path, mode);
+ throw new ArgumentNullException ("mode");
+ IntPtr f = Native.Stdlib.fopen (path, mode);
if (f == IntPtr.Zero)
throw new DirectoryNotFoundException ("path",
UnixMarshal.CreateExceptionForLastError ());
this.owner = ownsHandle;
try {
- long offset = Stdlib.fseek (file, 0, SeekFlags.SEEK_CUR);
+ long offset = Native.Stdlib.fseek (file, 0, Native.SeekFlags.SEEK_CUR);
if (offset != -1)
canSeek = true;
- Stdlib.fread (IntPtr.Zero, 0, 0, file);
- if (Stdlib.ferror (file) == 0)
+ Native.Stdlib.fread (IntPtr.Zero, 0, 0, file);
+ if (Native.Stdlib.ferror (file) == 0)
canRead = true;
- Stdlib.fwrite (IntPtr.Zero, 0, 0, file);
- if (Stdlib.ferror (file) == 0)
+ Native.Stdlib.fwrite (IntPtr.Zero, 0, 0, file);
+ if (Native.Stdlib.ferror (file) == 0)
canWrite = true;
- Stdlib.clearerr (file);
+ Native.Stdlib.clearerr (file);
}
catch (Exception e) {
throw new ArgumentException (Locale.GetText ("Invalid file stream"), "fileStream");
}
+ GC.KeepAlive (this);
}
private void InitCanReadWrite (FileAccess access)
private static string ToFopenMode (string file, FileMode mode)
{
- string cmode = UnixConvert.ToFopenMode (mode);
+ string cmode = Native.NativeConvert.ToFopenMode (mode);
AssertFileMode (file, mode);
return cmode;
}
private static string ToFopenMode (string file, FileAccess access)
{
- return UnixConvert.ToFopenMode (access);
+ return Native.NativeConvert.ToFopenMode (access);
}
private static string ToFopenMode (string file, FileMode mode, FileAccess access)
{
- string cmode = UnixConvert.ToFopenMode (mode, access);
+ string cmode = Native.NativeConvert.ToFopenMode (mode, access);
bool exists = AssertFileMode (file, mode);
// HACK: for open-or-create & read, mode is "rb", which doesn't create
// files. If the file doesn't exist, we need to use "w+b" to ensure
private static bool FileExists (string file)
{
bool found = false;
- IntPtr f = Stdlib.fopen (file, "r");
+ IntPtr f = Native.Stdlib.fopen (file, "r");
found = f != IntPtr.Zero;
if (f != IntPtr.Zero)
- Stdlib.fclose (f);
+ Native.Stdlib.fclose (f);
return found;
}
{
if (file == InvalidFileStream)
throw new ObjectDisposedException ("Invalid File Stream");
+ GC.KeepAlive (this);
}
public IntPtr Handle {
- get {AssertNotDisposed (); return file;}
+ get {
+ AssertNotDisposed ();
+ GC.KeepAlive (this);
+ return file;
+ }
}
public override bool CanRead {
AssertNotDisposed ();
if (!CanSeek)
throw new NotSupportedException ("File Stream doesn't support seeking");
- long curPos = Stdlib.ftell (file);
+ long curPos = Native.Stdlib.ftell (file);
if (curPos == -1)
throw new NotSupportedException ("Unable to obtain current file position");
- int r = Stdlib.fseek (file, 0, SeekFlags.SEEK_END);
+ int r = Native.Stdlib.fseek (file, 0, Native.SeekFlags.SEEK_END);
UnixMarshal.ThrowExceptionForLastErrorIf (r);
- long endPos = Stdlib.ftell (file);
+ long endPos = Native.Stdlib.ftell (file);
if (endPos == -1)
UnixMarshal.ThrowExceptionForLastError ();
- r = Stdlib.fseek (file, curPos, SeekFlags.SEEK_SET);
+ r = Native.Stdlib.fseek (file, curPos, Native.SeekFlags.SEEK_SET);
UnixMarshal.ThrowExceptionForLastErrorIf (r);
+ GC.KeepAlive (this);
return endPos;
}
}
AssertNotDisposed ();
if (!CanSeek)
throw new NotSupportedException ("The stream does not support seeking");
- long pos = Stdlib.ftell (file);
+ long pos = Native.Stdlib.ftell (file);
if (pos == -1)
UnixMarshal.ThrowExceptionForLastError ();
+ GC.KeepAlive (this);
return (long) pos;
}
set {
}
}
- public FilePosition FilePosition {
- get {
- AssertNotDisposed ();
- FilePosition pos = new FilePosition ();
- int r = Stdlib.fgetpos (file, pos);
- UnixMarshal.ThrowExceptionForLastErrorIf (r);
- return pos;
- }
- set {
- AssertNotDisposed ();
- if (value == null)
- throw new ArgumentNullException ("value");
- int r = Stdlib.fsetpos (file, value);
- UnixMarshal.ThrowExceptionForLastErrorIf (r);
- }
+ public void SaveFilePosition (Native.FilePosition pos)
+ {
+ AssertNotDisposed ();
+ int r = Native.Stdlib.fgetpos (file, pos);
+ UnixMarshal.ThrowExceptionForLastErrorIf (r);
+ GC.KeepAlive (this);
+ }
+
+ public void RestoreFilePosition (Native.FilePosition pos)
+ {
+ AssertNotDisposed ();
+ if (pos == null)
+ throw new ArgumentNullException ("value");
+ int r = Native.Stdlib.fsetpos (file, pos);
+ UnixMarshal.ThrowExceptionForLastErrorIf (r);
+ GC.KeepAlive (this);
}
public override void Flush ()
{
AssertNotDisposed ();
- int r = Stdlib.fflush (file);
+ int r = Native.Stdlib.fflush (file);
if (r != 0)
UnixMarshal.ThrowExceptionForLastError ();
+ GC.KeepAlive (this);
}
public override unsafe int Read ([In, Out] byte[] buffer, int offset, int count)
ulong r = 0;
fixed (byte* buf = &buffer[offset]) {
- r = Stdlib.fread (buf, 1, (ulong) count, file);
+ r = Native.Stdlib.fread (buf, 1, (ulong) count, file);
}
if (r != (ulong) count) {
- if (Stdlib.ferror (file) != 0)
+ if (Native.Stdlib.ferror (file) != 0)
throw new IOException ();
}
+ GC.KeepAlive (this);
return (int) r;
}
public void Rewind ()
{
AssertNotDisposed ();
- Stdlib.rewind (file);
+ Native.Stdlib.rewind (file);
+ GC.KeepAlive (this);
}
public override long Seek (long offset, SeekOrigin origin)
if (!CanSeek)
throw new NotSupportedException ("The File Stream does not support seeking");
- SeekFlags sf = SeekFlags.SEEK_CUR;
+ Native.SeekFlags sf = Native.SeekFlags.SEEK_CUR;
switch (origin) {
- case SeekOrigin.Begin: sf = SeekFlags.SEEK_SET; break;
- case SeekOrigin.Current: sf = SeekFlags.SEEK_CUR; break;
- case SeekOrigin.End: sf = SeekFlags.SEEK_END; break;
+ case SeekOrigin.Begin: sf = Native.SeekFlags.SEEK_SET; break;
+ case SeekOrigin.Current: sf = Native.SeekFlags.SEEK_CUR; break;
+ case SeekOrigin.End: sf = Native.SeekFlags.SEEK_END; break;
default: throw new ArgumentException ("origin");
}
- int r = Stdlib.fseek (file, offset, sf);
+ int r = Native.Stdlib.fseek (file, offset, sf);
if (r != 0)
throw new IOException ("Unable to seek",
UnixMarshal.CreateExceptionForLastError ());
- long pos = Stdlib.ftell (file);
+ long pos = Native.Stdlib.ftell (file);
if (pos == -1)
throw new IOException ("Unable to get current file position",
UnixMarshal.CreateExceptionForLastError ());
+ GC.KeepAlive (this);
return pos;
}
ulong r = 0;
fixed (byte* buf = &buffer[offset]) {
- r = Stdlib.fwrite (buf, (ulong) 1, (ulong) count, file);
+ r = Native.Stdlib.fwrite (buf, (ulong) 1, (ulong) count, file);
}
if (r != (ulong) count)
UnixMarshal.ThrowExceptionForLastError ();
+ GC.KeepAlive (this);
}
~StdioFileStream ()
if (file == InvalidFileStream)
return;
- GC.SuppressFinalize (this);
-
- Flush ();
if (owner) {
- int r = Stdlib.fclose (file);
+ int r = Native.Stdlib.fclose (file);
if (r != 0)
UnixMarshal.ThrowExceptionForLastError ();
- }
+ } else
+ Flush ();
+
file = InvalidFileStream;
canRead = false;
canSeek = false;
canWrite = false;
+
+ GC.SuppressFinalize (this);
+ GC.KeepAlive (this);
}
private bool canSeek = false;