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

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