FileStream.cs 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. //
  2. // System.IO/FileStream.cs
  3. //
  4. // Author:
  5. // Dietmar Maurer ([email protected])
  6. //
  7. // (C) 2001 Ximian, Inc. http://www.ximian.com
  8. //
  9. using System;
  10. using System.Runtime.InteropServices;
  11. using System.Private;
  12. // fixme: I do not know how to handle errno when calling PInvoke functions
  13. // fixme: emit the correct exceptions everywhere
  14. namespace System.IO
  15. {
  16. public class FileStream : Stream
  17. {
  18. private IntPtr fd;
  19. private FileAccess acc;
  20. private bool owner;
  21. private int getUnixFlags (FileMode mode, FileAccess access)
  22. {
  23. int flags = 0;
  24. switch (access) {
  25. case FileAccess.Read:
  26. flags = Wrapper.O_RDONLY;
  27. break;
  28. case FileAccess.Write:
  29. flags = Wrapper.O_WRONLY;
  30. break;
  31. case FileAccess.ReadWrite:
  32. flags = Wrapper.O_RDWR;
  33. break;
  34. }
  35. switch (mode) {
  36. case FileMode.Append:
  37. flags |= Wrapper.O_APPEND;
  38. break;
  39. case FileMode.Create:
  40. flags |= Wrapper.O_CREAT;
  41. break;
  42. case FileMode.CreateNew:
  43. flags |= Wrapper.O_CREAT | Wrapper.O_EXCL;
  44. break;
  45. case FileMode.Open:
  46. break;
  47. case FileMode.OpenOrCreate:
  48. flags |= Wrapper.O_CREAT;
  49. break;
  50. case FileMode.Truncate:
  51. flags |= Wrapper.O_TRUNC;
  52. break;
  53. }
  54. return flags;
  55. }
  56. public FileStream (IntPtr fd, FileAccess access)
  57. : this (fd, access, true, 0, false) {}
  58. public FileStream (IntPtr fd, FileAccess access, bool ownsHandle)
  59. : this (fd, access, ownsHandle, 0, false) {}
  60. public FileStream (IntPtr fd, FileAccess access, bool ownsHandle, int bufferSize)
  61. : this (fd, access, ownsHandle, bufferSize, false) {}
  62. public FileStream (IntPtr fd, FileAccess access, bool ownsHandle,
  63. int bufferSize, bool isAsync)
  64. {
  65. fd = fd;
  66. acc = access;
  67. owner = ownsHandle;
  68. }
  69. public FileStream (string name, FileMode mode)
  70. : this (name, mode, FileAccess.ReadWrite, FileShare.ReadWrite, 0, false) {}
  71. public FileStream (string name, FileMode mode, FileAccess access)
  72. : this (name, mode, access, FileShare.ReadWrite, 0, false) {}
  73. public FileStream (string name, FileMode mode, FileAccess access, FileShare share)
  74. : this (name, mode, access, share, 0, false) {}
  75. public FileStream (string name, FileMode mode, FileAccess access,
  76. FileShare share, int buferSize)
  77. : this (name, mode, access, share, 0, false) {}
  78. // fixme: implement all share, buffer, async
  79. public FileStream (string name, FileMode mode, FileAccess access, FileShare share,
  80. int buferSize, bool useAsync)
  81. {
  82. int flags = getUnixFlags (mode, access);
  83. if ((int)(fd = Wrapper.open (name, flags, 0x1a4)) == -1)
  84. throw new IOException();
  85. acc = access;
  86. owner = true;
  87. }
  88. public override bool CanRead
  89. {
  90. get {
  91. switch (acc) {
  92. case FileAccess.Read:
  93. case FileAccess.ReadWrite:
  94. return true;
  95. case FileAccess.Write:
  96. default:
  97. return false;
  98. }
  99. }
  100. }
  101. public override bool CanSeek
  102. {
  103. get {
  104. // fixme: not alway true
  105. return true;
  106. }
  107. }
  108. public override bool CanWrite
  109. {
  110. get {
  111. switch (acc) {
  112. case FileAccess.Write:
  113. case FileAccess.ReadWrite:
  114. return true;
  115. default:
  116. return false;
  117. }
  118. }
  119. }
  120. unsafe public override long Length
  121. {
  122. get {
  123. stat fs;
  124. Wrapper.fstat (fd, &fs);
  125. return fs.st_size;
  126. }
  127. }
  128. public override long Position
  129. {
  130. get {
  131. return Wrapper.seek (fd, 0, Wrapper.SEEK_CUR);
  132. }
  133. set {
  134. Wrapper.seek (fd, value, Wrapper.SEEK_SET);
  135. }
  136. }
  137. public override void Flush ()
  138. {
  139. }
  140. public override void Close ()
  141. {
  142. if (owner && Wrapper.close (fd) != 0)
  143. throw new IOException();
  144. }
  145. public unsafe override int Read (byte[] buffer,
  146. int offset,
  147. int count)
  148. {
  149. int res;
  150. fixed (void *p = &buffer [offset]) {
  151. res = Wrapper.read (fd, p, count);
  152. }
  153. return res;
  154. }
  155. public unsafe override int ReadByte ()
  156. {
  157. byte val;
  158. if (Wrapper.read (fd, &val, 1) != 1)
  159. throw new IOException();
  160. return val;
  161. }
  162. public override long Seek (long offset,
  163. SeekOrigin origin)
  164. {
  165. int off = (int)offset;
  166. switch (origin) {
  167. case SeekOrigin.End:
  168. return Wrapper.seek (fd, Wrapper.SEEK_END, off);
  169. case SeekOrigin.Current:
  170. return Wrapper.seek (fd, Wrapper.SEEK_CUR, off);
  171. default:
  172. return Wrapper.seek (fd, Wrapper.SEEK_SET, off);
  173. }
  174. }
  175. public override void SetLength (long value)
  176. {
  177. int res;
  178. if ((res = Wrapper.ftruncate (fd, value)) == -1)
  179. throw new IOException();
  180. }
  181. public unsafe override void Write (byte[] buffer,
  182. int offset,
  183. int count)
  184. {
  185. int res;
  186. fixed (void *p = &buffer [offset]) {
  187. res = Wrapper.write (fd, p, count);
  188. }
  189. if (res != count)
  190. throw new IOException();
  191. }
  192. public unsafe override void WriteByte (byte value)
  193. {
  194. if (Wrapper.write (fd, &value, 1) != 1)
  195. throw new IOException();
  196. }
  197. }
  198. }