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

https://github.com/ccflo/mono · C# · 479 lines · 374 code · 77 blank · 28 comment · 131 complexity · 6ce593d65020685370daa5a3661cd481 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
  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. #pragma warning disable 414
  39. long offset;
  40. #pragma warning restore
  41. long capacity;
  42. bool canwrite, canread;
  43. protected UnmanagedMemoryAccessor ()
  44. {
  45. }
  46. public UnmanagedMemoryAccessor (SafeBuffer buffer, long offset, long capacity)
  47. {
  48. Initialize (buffer, offset, capacity, FileAccess.ReadWrite);
  49. }
  50. public UnmanagedMemoryAccessor (SafeBuffer buffer, long offset, long capacity, FileAccess access)
  51. {
  52. Initialize (buffer, offset, capacity, access);
  53. }
  54. [SecurityPermissionAttribute(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)]
  55. protected void Initialize(SafeBuffer buffer, long offset, long capacity, FileAccess access)
  56. {
  57. if (buffer == null)
  58. throw new ArgumentNullException ("buffer");
  59. if (offset < 0)
  60. throw new ArgumentOutOfRangeException ("offset");
  61. if (capacity < 0)
  62. throw new ArgumentOutOfRangeException ("capacity");
  63. if (access == FileAccess.Read || access == FileAccess.ReadWrite)
  64. canread = true;
  65. if (access == FileAccess.Write || access == FileAccess.ReadWrite)
  66. canwrite = true;
  67. if (this.buffer != null)
  68. Dispose (true);
  69. this.buffer = buffer;
  70. this.offset = offset;
  71. this.capacity = capacity;
  72. }
  73. public void Dispose ()
  74. {
  75. Dispose (true);
  76. GC.SuppressFinalize (this);
  77. }
  78. protected virtual void Dispose (bool disposing)
  79. {
  80. if (buffer != null){
  81. if (disposing){
  82. buffer.Dispose ();
  83. }
  84. }
  85. buffer = null;
  86. }
  87. public byte ReadByte (long position)
  88. {
  89. if (!canread)
  90. throw new NotSupportedException ();
  91. if (buffer == null)
  92. throw new ObjectDisposedException ("buffer");
  93. if (position < 0)
  94. throw new ArgumentOutOfRangeException ();
  95. return buffer.Read<byte> ((ulong) position);
  96. }
  97. public bool ReadBoolean (long position)
  98. {
  99. if (!canread)
  100. throw new NotSupportedException ();
  101. if (buffer == null)
  102. throw new ObjectDisposedException ("buffer");
  103. if (position < 0)
  104. throw new ArgumentOutOfRangeException ();
  105. return buffer.Read<bool> ((ulong) position);
  106. }
  107. public char ReadChar (long position)
  108. {
  109. if (!canread)
  110. throw new NotSupportedException ();
  111. if (buffer == null)
  112. throw new ObjectDisposedException ("buffer");
  113. if (position < 0)
  114. throw new ArgumentOutOfRangeException ();
  115. return buffer.Read<char> ((ulong) position);
  116. }
  117. public decimal ReadDecimal (long position)
  118. {
  119. if (!canread)
  120. throw new NotSupportedException ();
  121. if (buffer == null)
  122. throw new ObjectDisposedException ("buffer");
  123. if (position < 0)
  124. throw new ArgumentOutOfRangeException ();
  125. return buffer.Read<decimal> ((ulong) position);
  126. }
  127. public double ReadDouble (long position)
  128. {
  129. if (!canread)
  130. throw new NotSupportedException ();
  131. if (buffer == null)
  132. throw new ObjectDisposedException ("buffer");
  133. if (position < 0)
  134. throw new ArgumentOutOfRangeException ();
  135. return buffer.Read<double> ((ulong) position);
  136. }
  137. public short ReadInt16 (long position)
  138. {
  139. if (!canread)
  140. throw new NotSupportedException ();
  141. if (buffer == null)
  142. throw new ObjectDisposedException ("buffer");
  143. if (position < 0)
  144. throw new ArgumentOutOfRangeException ();
  145. return buffer.Read<short> ((ulong) position);
  146. }
  147. public int ReadInt32 (long position)
  148. {
  149. if (!canread)
  150. throw new NotSupportedException ();
  151. if (buffer == null)
  152. throw new ObjectDisposedException ("buffer");
  153. if (position < 0)
  154. throw new ArgumentOutOfRangeException ();
  155. return buffer.Read<int> ((ulong) position);
  156. }
  157. public long ReadInt64 (long position)
  158. {
  159. if (!canread)
  160. throw new NotSupportedException ();
  161. if (buffer == null)
  162. throw new ObjectDisposedException ("buffer");
  163. if (position < 0)
  164. throw new ArgumentOutOfRangeException ();
  165. return buffer.Read<long> ((ulong) position);
  166. }
  167. [CLSCompliant (false)]
  168. public sbyte ReadSByte (long position)
  169. {
  170. if (!canread)
  171. throw new NotSupportedException ();
  172. if (buffer == null)
  173. throw new ObjectDisposedException ("buffer");
  174. if (position < 0)
  175. throw new ArgumentOutOfRangeException ();
  176. return buffer.Read<sbyte> ((ulong) position);
  177. }
  178. public float ReadSingle (long position)
  179. {
  180. if (!canread)
  181. throw new NotSupportedException ();
  182. if (buffer == null)
  183. throw new ObjectDisposedException ("buffer");
  184. if (position < 0)
  185. throw new ArgumentOutOfRangeException ();
  186. return buffer.Read<float> ((ulong) position);
  187. }
  188. [CLSCompliant (false)]
  189. public ushort ReadUInt16 (long position)
  190. {
  191. if (!canread)
  192. throw new NotSupportedException ();
  193. if (buffer == null)
  194. throw new ObjectDisposedException ("buffer");
  195. if (position < 0)
  196. throw new ArgumentOutOfRangeException ();
  197. return buffer.Read<ushort> ((ulong) position);
  198. }
  199. [CLSCompliant (false)]
  200. public uint ReadUInt32 (long position)
  201. {
  202. if (!canread)
  203. throw new NotSupportedException ();
  204. if (buffer == null)
  205. throw new ObjectDisposedException ("buffer");
  206. if (position < 0)
  207. throw new ArgumentOutOfRangeException ();
  208. return buffer.Read<uint> ((ulong) position);
  209. }
  210. [CLSCompliant (false)]
  211. public ulong ReadUInt64 (long position)
  212. {
  213. if (!canread)
  214. throw new NotSupportedException ();
  215. if (buffer == null)
  216. throw new ObjectDisposedException ("buffer");
  217. if (position < 0)
  218. throw new ArgumentOutOfRangeException ();
  219. return buffer.Read<ulong> ((ulong) position);
  220. }
  221. public void Read<T> (long position, out T structure) where T : struct
  222. {
  223. if (!canread)
  224. throw new NotSupportedException ();
  225. if (buffer == null)
  226. throw new ObjectDisposedException ("buffer");
  227. if (position < 0)
  228. throw new ArgumentOutOfRangeException ();
  229. structure = buffer.Read<T> ((ulong) position);
  230. }
  231. public int ReadArray<T> (long position, T [] array, int offset, int count) where T : struct
  232. {
  233. if (position < 0)
  234. throw new ArgumentOutOfRangeException ();
  235. long left = capacity - position;
  236. var slots = (int)(left / Marshal.SizeOf (typeof (T)));
  237. buffer.ReadArray ((ulong) position, array, offset, slots);
  238. return slots;
  239. }
  240. public void Write (long position, bool value)
  241. {
  242. if (!canwrite)
  243. throw new NotSupportedException ();
  244. if (buffer == null)
  245. throw new ObjectDisposedException ("buffer");
  246. if (position < 0)
  247. throw new ArgumentOutOfRangeException ();
  248. buffer.Write ((ulong)position, value);
  249. }
  250. public void Write (long position, byte value)
  251. {
  252. if (!canwrite)
  253. throw new NotSupportedException ();
  254. if (buffer == null)
  255. throw new ObjectDisposedException ("buffer");
  256. if (position < 0)
  257. throw new ArgumentOutOfRangeException ();
  258. buffer.Write ((ulong)position, value);
  259. }
  260. public void Write (long position, char value)
  261. {
  262. if (!canwrite)
  263. throw new NotSupportedException ();
  264. if (buffer == null)
  265. throw new ObjectDisposedException ("buffer");
  266. if (position < 0)
  267. throw new ArgumentOutOfRangeException ();
  268. buffer.Write ((ulong)position, value);
  269. }
  270. public void Write (long position, decimal value)
  271. {
  272. if (!canwrite)
  273. throw new NotSupportedException ();
  274. if (buffer == null)
  275. throw new ObjectDisposedException ("buffer");
  276. if (position < 0)
  277. throw new ArgumentOutOfRangeException ();
  278. buffer.Write ((ulong)position, value);
  279. }
  280. public void Write (long position, double value)
  281. {
  282. if (!canwrite)
  283. throw new NotSupportedException ();
  284. if (buffer == null)
  285. throw new ObjectDisposedException ("buffer");
  286. if (position < 0)
  287. throw new ArgumentOutOfRangeException ();
  288. buffer.Write ((ulong)position, value);
  289. }
  290. public void Write (long position, short value)
  291. {
  292. if (!canwrite)
  293. throw new NotSupportedException ();
  294. if (buffer == null)
  295. throw new ObjectDisposedException ("buffer");
  296. if (position < 0)
  297. throw new ArgumentOutOfRangeException ();
  298. buffer.Write ((ulong)position, value);
  299. }
  300. public void Write (long position, int value)
  301. {
  302. if (!canwrite)
  303. throw new NotSupportedException ();
  304. if (buffer == null)
  305. throw new ObjectDisposedException ("buffer");
  306. if (position < 0)
  307. throw new ArgumentOutOfRangeException ();
  308. buffer.Write ((ulong)position, value);
  309. }
  310. public void Write (long position, long value)
  311. {
  312. if (!canwrite)
  313. throw new NotSupportedException ();
  314. if (buffer == null)
  315. throw new ObjectDisposedException ("buffer");
  316. if (position < 0)
  317. throw new ArgumentOutOfRangeException ();
  318. buffer.Write ((ulong)position, value);
  319. }
  320. [CLSCompliant (false)]
  321. public void Write (long position, sbyte value)
  322. {
  323. if (!canwrite)
  324. throw new NotSupportedException ();
  325. if (buffer == null)
  326. throw new ObjectDisposedException ("buffer");
  327. if (position < 0)
  328. throw new ArgumentOutOfRangeException ();
  329. buffer.Write ((ulong)position, value);
  330. }
  331. public void Write (long position, float value)
  332. {
  333. if (!canwrite)
  334. throw new NotSupportedException ();
  335. if (buffer == null)
  336. throw new ObjectDisposedException ("buffer");
  337. if (position < 0)
  338. throw new ArgumentOutOfRangeException ();
  339. buffer.Write ((ulong)position, value);
  340. }
  341. [CLSCompliant (false)]
  342. public void Write (long position, ushort value)
  343. {
  344. if (!canwrite)
  345. throw new NotSupportedException ();
  346. if (buffer == null)
  347. throw new ObjectDisposedException ("buffer");
  348. if (position < 0)
  349. throw new ArgumentOutOfRangeException ();
  350. buffer.Write ((ulong)position, value);
  351. }
  352. [CLSCompliant (false)]
  353. public void Write (long position, uint value)
  354. {
  355. if (!canwrite)
  356. throw new NotSupportedException ();
  357. if (buffer == null)
  358. throw new ObjectDisposedException ("buffer");
  359. if (position < 0)
  360. throw new ArgumentOutOfRangeException ();
  361. buffer.Write ((ulong)position, value);
  362. }
  363. [CLSCompliant (false)]
  364. public void Write (long position, ulong value)
  365. {
  366. if (!canwrite)
  367. throw new NotSupportedException ();
  368. if (buffer == null)
  369. throw new ObjectDisposedException ("buffer");
  370. if (position < 0)
  371. throw new ArgumentOutOfRangeException ();
  372. buffer.Write ((ulong)position, value);
  373. }
  374. public void Write<T> (long position, ref T structure) where T : struct
  375. {
  376. if (!canwrite)
  377. throw new NotSupportedException ();
  378. if (buffer == null)
  379. throw new ObjectDisposedException ("buffer");
  380. if (position < 0)
  381. throw new ArgumentOutOfRangeException ();
  382. buffer.Write<T> ((ulong)position, structure);
  383. }
  384. public void WriteArray<T> (long position, T [] array, int offset, int count) where T : struct
  385. {
  386. buffer.WriteArray ((ulong)position, array, offset, count);
  387. }
  388. public bool CanRead {
  389. get { return canread; }
  390. }
  391. public bool CanWrite {
  392. get { return canwrite; }
  393. }
  394. public long Capacity {
  395. get { return capacity; }
  396. }
  397. protected bool IsOpen {
  398. get { return buffer != null; }
  399. }
  400. }
  401. }
  402. #endif