MoonIsolatedStorageFileStream.cs 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. //
  2. // System.IO.IsolatedStorage.MoonIsolatedStorageFileStream
  3. //
  4. // Moonlight's implementation for the IsolatedStorageFileStream
  5. //
  6. // Authors
  7. // Miguel de Icaza ([email protected])
  8. // Sebastien Pouliot <[email protected]>
  9. //
  10. // Copyright (C) 2007, 2008 Novell, Inc (http://www.novell.com)
  11. //
  12. // Permission is hereby granted, free of charge, to any person obtaining
  13. // a copy of this software and associated documentation files (the
  14. // "Software"), to deal in the Software without restriction, including
  15. // without limitation the rights to use, copy, modify, merge, publish,
  16. // distribute, sublicense, and/or sell copies of the Software, and to
  17. // permit persons to whom the Software is furnished to do so, subject to
  18. // the following conditions:
  19. //
  20. // The above copyright notice and this permission notice shall be
  21. // included in all copies or substantial portions of the Software.
  22. //
  23. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  24. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  25. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  26. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  27. // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  28. // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  29. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  30. //
  31. #if MOONLIGHT
  32. using System;
  33. using System.IO;
  34. namespace System.IO.IsolatedStorage {
  35. // NOTES:
  36. // * Silverlight allows extending to more than AvailableFreeSpace (by up to 1024 bytes).
  37. // This looks like a safety buffer.
  38. public class IsolatedStorageFileStream : FileStream {
  39. IsolatedStorageFile container;
  40. internal static string Verify (IsolatedStorageFile isf, string path)
  41. {
  42. if (path == null)
  43. throw new ArgumentNullException ("path");
  44. if (path.Length == 0)
  45. throw new ArgumentException ("path");
  46. if (isf == null)
  47. throw new ArgumentNullException ("isf");
  48. isf.PreCheck ();
  49. return isf.Verify (path);
  50. }
  51. public IsolatedStorageFileStream (string path, FileMode mode, IsolatedStorageFile isf)
  52. : base (Verify (isf, path), mode, (mode == FileMode.Append ? FileAccess.Write : FileAccess.ReadWrite),
  53. FileShare.Read, DefaultBufferSize, false, true)
  54. {
  55. container = isf;
  56. }
  57. public IsolatedStorageFileStream (string path, FileMode mode, FileAccess access, IsolatedStorageFile isf)
  58. : base (Verify (isf, path), mode, access, FileShare.Read, DefaultBufferSize, false, true)
  59. {
  60. container = isf;
  61. }
  62. public IsolatedStorageFileStream (string path, FileMode mode, FileAccess access, FileShare share, IsolatedStorageFile isf)
  63. : base (Verify (isf, path), mode, access, share, DefaultBufferSize, false, true)
  64. {
  65. container = isf;
  66. }
  67. protected override void Dispose (bool disposing)
  68. {
  69. // no PreCheck required
  70. base.Dispose (disposing);
  71. }
  72. public override void Flush ()
  73. {
  74. container.PreCheck ();
  75. base.Flush ();
  76. }
  77. public override void Flush (bool flushToDisk)
  78. {
  79. container.PreCheck ();
  80. base.Flush (flushToDisk);
  81. }
  82. public override int Read (byte [] buffer, int offset, int count)
  83. {
  84. container.PreCheck ();
  85. return base.Read (buffer, offset, count);
  86. }
  87. public override int ReadByte ()
  88. {
  89. container.PreCheck ();
  90. return base.ReadByte ();
  91. }
  92. public override long Seek (long offset, SeekOrigin origin)
  93. {
  94. container.PreCheck ();
  95. return base.Seek (offset, origin);
  96. }
  97. public override void SetLength (long value)
  98. {
  99. container.PreCheck ();
  100. // don't worry about quota if we can't write to the stream,
  101. // the base class will throw the expected NotSupportedException
  102. if (!base.CanWrite)
  103. return;
  104. // will that request put us in a position to grow *or shrink* the file ?
  105. // note: this can be negative, e.g. calling SetLength(0), so we can't call EnsureQuotaLimits directly
  106. if (!IsolatedStorage.CanExtend (value - Length))
  107. throw new IsolatedStorageException ("Requested size is larger than remaining quota allowance.");
  108. base.SetLength (value);
  109. }
  110. public override void Write (byte [] buffer, int offset, int count)
  111. {
  112. container.PreCheck ();
  113. EnsureQuotaLimits (count);
  114. base.Write (buffer, offset, count);
  115. }
  116. public override void WriteByte (byte value)
  117. {
  118. container.PreCheck ();
  119. EnsureQuotaLimits (1);
  120. base.WriteByte (value);
  121. }
  122. public override bool CanRead {
  123. get {
  124. // no PreCheck required
  125. return base.CanRead;
  126. }
  127. }
  128. public override bool CanSeek {
  129. get {
  130. // no PreCheck required
  131. return base.CanSeek;
  132. }
  133. }
  134. public override bool CanWrite {
  135. get {
  136. // no PreCheck required
  137. return base.CanWrite;
  138. }
  139. }
  140. public override long Length {
  141. get {
  142. // FileStream ctor sometimes calls Length, i.e. before container is set
  143. if (container != null)
  144. container.PreCheck ();
  145. return base.Length;
  146. }
  147. }
  148. public override long Position {
  149. get {
  150. container.PreCheck ();
  151. return base.Position;
  152. }
  153. set {
  154. container.PreCheck ();
  155. base.Position = value;
  156. }
  157. }
  158. public override IAsyncResult BeginRead (byte[] buffer, int offset, int numBytes, AsyncCallback userCallback, object stateObject)
  159. {
  160. container.PreCheck ();
  161. return base.BeginRead (buffer, offset, numBytes, userCallback, stateObject);
  162. }
  163. public override IAsyncResult BeginWrite (byte[] buffer, int offset, int numBytes, AsyncCallback userCallback, object stateObject)
  164. {
  165. container.PreCheck ();
  166. EnsureQuotaLimits (numBytes);
  167. return base.BeginWrite (buffer, offset, numBytes, userCallback, stateObject);
  168. }
  169. public override int EndRead (IAsyncResult asyncResult)
  170. {
  171. container.PreCheck ();
  172. return base.EndRead (asyncResult);
  173. }
  174. public override void EndWrite (IAsyncResult asyncResult)
  175. {
  176. container.PreCheck ();
  177. base.EndWrite (asyncResult);
  178. }
  179. private void EnsureQuotaLimits (long request)
  180. {
  181. // don't worry about quota if we can't write to the stream,
  182. // the base class will throw the expected NotSupportedException
  183. if (!base.CanWrite)
  184. return;
  185. // will that request put us in a position to grow the file ?
  186. long grow = Position + request - Length;
  187. if (grow < 0)
  188. return;
  189. if (!IsolatedStorage.CanExtend (grow))
  190. throw new IsolatedStorageException ("Requested size is larger than remaining quota allowance.");
  191. }
  192. }
  193. }
  194. #endif