/mcs/class/corlib/System.IO/UnmanagedMemoryAccessor.cs

https://github.com/sdether/mono · C# · 477 lines · 372 code · 77 blank · 28 comment · 132 complexity · 22fb7c6f1ae12efe863604e0d029f9f9 MD5 · raw file

  1. //
  2. // System.IO.UnmanagedMemoryAccessor.cs
  3. //
  4. // Author:
  5. // Zoltan Varga (vargaz@gmail.com)
  6. // Marek Safar (marek.safar@gmail.com)
  7. //
  8. // Copyright (C) 2009 Novell, Inc (http://www.novell.com)
  9. //
  10. // Permission is hereby granted, free of charge, to any person obtaining
  11. // a copy of this software and associated documentation files (the
  12. // "Software"), to deal in the Software without restriction, including
  13. // without limitation the rights to use, copy, modify, merge, publish,
  14. // distribute, sublicense, and/or sell copies of the Software, and to
  15. // permit persons to whom the Software is furnished to do so, subject to
  16. // the following conditions:
  17. //
  18. // The above copyright notice and this permission notice shall be
  19. // included in all copies or substantial portions of the Software.
  20. //
  21. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  22. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  23. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  24. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  25. // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  26. // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  27. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  28. //
  29. #if NET_4_0 || BOOTSTRAP_NET_4_0
  30. using System;
  31. using System.Runtime.InteropServices;
  32. using System.Security.Permissions;
  33. namespace System.IO
  34. {
  35. [MonoTODO ("Offset is ignored")]
  36. public class UnmanagedMemoryAccessor : IDisposable {
  37. SafeBuffer buffer;
  38. long offset;
  39. long capacity;
  40. bool canwrite, canread;
  41. protected UnmanagedMemoryAccessor ()
  42. {
  43. }
  44. public UnmanagedMemoryAccessor (SafeBuffer buffer, long offset, long capacity)
  45. {
  46. Initialize (buffer, offset, capacity, FileAccess.ReadWrite);
  47. }
  48. public UnmanagedMemoryAccessor (SafeBuffer buffer, long offset, long capacity, FileAccess access)
  49. {
  50. Initialize (buffer, offset, capacity, access);
  51. }
  52. [SecurityPermissionAttribute(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)]
  53. protected void Initialize(SafeBuffer buffer, long offset, long capacity, FileAccess access)
  54. {
  55. if (buffer == null)
  56. throw new ArgumentNullException ("buffer");
  57. if (offset < 0)
  58. throw new ArgumentOutOfRangeException ("offset");
  59. if (capacity < 0)
  60. throw new ArgumentOutOfRangeException ("capacity");
  61. if (access == FileAccess.Read || access == FileAccess.ReadWrite)
  62. canread = true;
  63. if (access == FileAccess.Write || access == FileAccess.ReadWrite)
  64. canwrite = true;
  65. if (this.buffer != null)
  66. Dispose (true);
  67. this.buffer = buffer;
  68. this.offset = offset;
  69. this.capacity = capacity;
  70. }
  71. public void Dispose ()
  72. {
  73. Dispose (true);
  74. GC.SuppressFinalize (this);
  75. }
  76. protected virtual void Dispose (bool disposing)
  77. {
  78. if (buffer != null){
  79. if (disposing){
  80. buffer.Dispose ();
  81. }
  82. }
  83. buffer = null;
  84. }
  85. public byte ReadByte (long position)
  86. {
  87. if (!canread)
  88. throw new NotSupportedException ();
  89. if (buffer == null)
  90. throw new ObjectDisposedException ("buffer");
  91. if (position < 0)
  92. throw new ArgumentOutOfRangeException ();
  93. return buffer.Read<byte> ((ulong) position);
  94. }
  95. public bool ReadBoolean (long position)
  96. {
  97. if (!canread)
  98. throw new NotSupportedException ();
  99. if (buffer == null)
  100. throw new ObjectDisposedException ("buffer");
  101. if (position < 0)
  102. throw new ArgumentOutOfRangeException ();
  103. return buffer.Read<bool> ((ulong) position);
  104. }
  105. public char ReadChar (long position)
  106. {
  107. if (!canread)
  108. throw new NotSupportedException ();
  109. if (buffer == null)
  110. throw new ObjectDisposedException ("buffer");
  111. if (position < 0)
  112. throw new ArgumentOutOfRangeException ();
  113. return buffer.Read<char> ((ulong) position);
  114. }
  115. public decimal ReadDecimal (long position)
  116. {
  117. if (!canread)
  118. throw new NotSupportedException ();
  119. if (buffer == null)
  120. throw new ObjectDisposedException ("buffer");
  121. if (position < 0)
  122. throw new ArgumentOutOfRangeException ();
  123. return buffer.Read<decimal> ((ulong) position);
  124. }
  125. public double ReadDouble (long position)
  126. {
  127. if (!canread)
  128. throw new NotSupportedException ();
  129. if (buffer == null)
  130. throw new ObjectDisposedException ("buffer");
  131. if (position < 0)
  132. throw new ArgumentOutOfRangeException ();
  133. return buffer.Read<double> ((ulong) position);
  134. }
  135. public short ReadInt16 (long position)
  136. {
  137. if (!canread)
  138. throw new NotSupportedException ();
  139. if (buffer == null)
  140. throw new ObjectDisposedException ("buffer");
  141. if (position < 0)
  142. throw new ArgumentOutOfRangeException ();
  143. return buffer.Read<short> ((ulong) position);
  144. }
  145. public int ReadInt32 (long position)
  146. {
  147. if (!canread)
  148. throw new NotSupportedException ();
  149. if (buffer == null)
  150. throw new ObjectDisposedException ("buffer");
  151. if (position < 0)
  152. throw new ArgumentOutOfRangeException ();
  153. return buffer.Read<int> ((ulong) position);
  154. }
  155. public long ReadInt64 (long position)
  156. {
  157. if (!canread)
  158. throw new NotSupportedException ();
  159. if (buffer == null)
  160. throw new ObjectDisposedException ("buffer");
  161. if (position < 0)
  162. throw new ArgumentOutOfRangeException ();
  163. return buffer.Read<long> ((ulong) position);
  164. }
  165. [CLSCompliant (false)]
  166. public sbyte ReadSByte (long position)
  167. {
  168. if (!canread)
  169. throw new NotSupportedException ();
  170. if (buffer == null)
  171. throw new ObjectDisposedException ("buffer");
  172. if (position < 0)
  173. throw new ArgumentOutOfRangeException ();
  174. return buffer.Read<sbyte> ((ulong) position);
  175. }
  176. public float ReadSingle (long position)
  177. {
  178. if (!canread)
  179. throw new NotSupportedException ();
  180. if (buffer == null)
  181. throw new ObjectDisposedException ("buffer");
  182. if (position < 0)
  183. throw new ArgumentOutOfRangeException ();
  184. return buffer.Read<float> ((ulong) position);
  185. }
  186. [CLSCompliant (false)]
  187. public ushort ReadUInt16 (long position)
  188. {
  189. if (!canread)
  190. throw new NotSupportedException ();
  191. if (buffer == null)
  192. throw new ObjectDisposedException ("buffer");
  193. if (position < 0)
  194. throw new ArgumentOutOfRangeException ();
  195. return buffer.Read<ushort> ((ulong) position);
  196. }
  197. [CLSCompliant (false)]
  198. public uint ReadUInt32 (long position)
  199. {
  200. if (!canread)
  201. throw new NotSupportedException ();
  202. if (buffer == null)
  203. throw new ObjectDisposedException ("buffer");
  204. if (position < 0)
  205. throw new ArgumentOutOfRangeException ();
  206. return buffer.Read<uint> ((ulong) position);
  207. }
  208. [CLSCompliant (false)]
  209. public ulong ReadUInt64 (long position)
  210. {
  211. if (!canread)
  212. throw new NotSupportedException ();
  213. if (buffer == null)
  214. throw new ObjectDisposedException ("buffer");
  215. if (position < 0)
  216. throw new ArgumentOutOfRangeException ();
  217. return buffer.Read<ulong> ((ulong) position);
  218. }
  219. public void Read<T> (long position, out T structure) where T : struct
  220. {
  221. if (!canread)
  222. throw new NotSupportedException ();
  223. if (buffer == null)
  224. throw new ObjectDisposedException ("buffer");
  225. if (position < 0)
  226. throw new ArgumentOutOfRangeException ();
  227. structure = buffer.Read<T> ((ulong) position);
  228. }
  229. public int ReadArray<T> (long position, T [] array, int offset, int count) where T : struct
  230. {
  231. if (position < 0)
  232. throw new ArgumentOutOfRangeException ();
  233. long left = capacity - position;
  234. var slots = (int)(left / Marshal.SizeOf (typeof (T)));
  235. buffer.ReadArray ((ulong) position, array, offset, slots);
  236. return slots;
  237. }
  238. public void Write (long position, bool value)
  239. {
  240. if (!canwrite)
  241. throw new NotSupportedException ();
  242. if (buffer == null)
  243. throw new ObjectDisposedException ("buffer");
  244. if (position < 0)
  245. throw new ArgumentOutOfRangeException ();
  246. buffer.Write ((ulong)position, value);
  247. }
  248. public void Write (long position, byte value)
  249. {
  250. if (!canwrite)
  251. throw new NotSupportedException ();
  252. if (buffer == null)
  253. throw new ObjectDisposedException ("buffer");
  254. if (position < 0)
  255. throw new ArgumentOutOfRangeException ();
  256. buffer.Write ((ulong)position, value);
  257. }
  258. public void Write (long position, char value)
  259. {
  260. if (!canwrite)
  261. throw new NotSupportedException ();
  262. if (buffer == null)
  263. throw new ObjectDisposedException ("buffer");
  264. if (position < 0)
  265. throw new ArgumentOutOfRangeException ();
  266. buffer.Write ((ulong)position, value);
  267. }
  268. public void Write (long position, decimal value)
  269. {
  270. if (!canwrite)
  271. throw new NotSupportedException ();
  272. if (buffer == null)
  273. throw new ObjectDisposedException ("buffer");
  274. if (position < 0)
  275. throw new ArgumentOutOfRangeException ();
  276. buffer.Write ((ulong)position, value);
  277. }
  278. public void Write (long position, double value)
  279. {
  280. if (!canwrite)
  281. throw new NotSupportedException ();
  282. if (buffer == null)
  283. throw new ObjectDisposedException ("buffer");
  284. if (position < 0)
  285. throw new ArgumentOutOfRangeException ();
  286. buffer.Write ((ulong)position, value);
  287. }
  288. public void Write (long position, short value)
  289. {
  290. if (!canwrite)
  291. throw new NotSupportedException ();
  292. if (buffer == null)
  293. throw new ObjectDisposedException ("buffer");
  294. if (position < 0)
  295. throw new ArgumentOutOfRangeException ();
  296. buffer.Write ((ulong)position, value);
  297. }
  298. public void Write (long position, int value)
  299. {
  300. if (!canwrite)
  301. throw new NotSupportedException ();
  302. if (buffer == null)
  303. throw new ObjectDisposedException ("buffer");
  304. if (position < 0)
  305. throw new ArgumentOutOfRangeException ();
  306. buffer.Write ((ulong)position, value);
  307. }
  308. public void Write (long position, long value)
  309. {
  310. if (!canwrite)
  311. throw new NotSupportedException ();
  312. if (buffer == null)
  313. throw new ObjectDisposedException ("buffer");
  314. if (position < 0)
  315. throw new ArgumentOutOfRangeException ();
  316. buffer.Write ((ulong)position, value);
  317. }
  318. [CLSCompliant (false)]
  319. public void Write (long position, sbyte value)
  320. {
  321. if (!canwrite)
  322. throw new NotSupportedException ();
  323. if (buffer == null)
  324. throw new ObjectDisposedException ("buffer");
  325. if (position < 0)
  326. throw new ArgumentOutOfRangeException ();
  327. buffer.Write ((ulong)position, value);
  328. }
  329. public void Write (long position, float value)
  330. {
  331. if (!canwrite)
  332. throw new NotSupportedException ();
  333. if (buffer == null)
  334. throw new ObjectDisposedException ("buffer");
  335. if (position < 0)
  336. throw new ArgumentOutOfRangeException ();
  337. buffer.Write ((ulong)position, value);
  338. }
  339. [CLSCompliant (false)]
  340. public void Write (long position, ushort value)
  341. {
  342. if (!canwrite)
  343. throw new NotSupportedException ();
  344. if (buffer == null)
  345. throw new ObjectDisposedException ("buffer");
  346. if (position < 0)
  347. throw new ArgumentOutOfRangeException ();
  348. buffer.Write ((ulong)position, value);
  349. }
  350. [CLSCompliant (false)]
  351. public void Write (long position, uint value)
  352. {
  353. if (!canwrite)
  354. throw new NotSupportedException ();
  355. if (buffer == null)
  356. throw new ObjectDisposedException ("buffer");
  357. if (position < 0)
  358. throw new ArgumentOutOfRangeException ();
  359. buffer.Write ((ulong)position, value);
  360. }
  361. [CLSCompliant (false)]
  362. public void Write (long position, ulong value)
  363. {
  364. if (!canwrite)
  365. throw new NotSupportedException ();
  366. if (buffer == null)
  367. throw new ObjectDisposedException ("buffer");
  368. if (position < 0)
  369. throw new ArgumentOutOfRangeException ();
  370. buffer.Write ((ulong)position, value);
  371. }
  372. public void Write<T> (long position, ref T structure) where T : struct
  373. {
  374. if (!canwrite)
  375. throw new NotSupportedException ();
  376. if (buffer == null)
  377. throw new ObjectDisposedException ("buffer");
  378. if (position < 0)
  379. throw new ArgumentOutOfRangeException ();
  380. buffer.Write<T> ((ulong)position, structure);
  381. }
  382. public void WriteArray<T> (long position, T [] array, int offset, int count) where T : struct
  383. {
  384. buffer.WriteArray ((ulong)position, array, offset, count);
  385. }
  386. public bool CanRead {
  387. get { return canread; }
  388. }
  389. public bool CanWrite {
  390. get { return canwrite; }
  391. }
  392. public long Capacity {
  393. get { return capacity; }
  394. }
  395. protected bool IsOpen {
  396. get { return buffer != null; }
  397. }
  398. }
  399. }
  400. #endif