MoonIsolatedStorageFileStream.cs 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  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 int Read (byte [] buffer, int offset, int count)
  78. {
  79. container.PreCheck ();
  80. return base.Read (buffer, offset, count);
  81. }
  82. public override int ReadByte ()
  83. {
  84. container.PreCheck ();
  85. return base.ReadByte ();
  86. }
  87. public override long Seek (long offset, SeekOrigin origin)
  88. {
  89. container.PreCheck ();
  90. return base.Seek (offset, origin);
  91. }
  92. public override void SetLength (long value)
  93. {
  94. container.PreCheck ();
  95. // don't worry about quota if we can't write to the stream,
  96. // the base class will throw the expected NotSupportedException
  97. if (!base.CanWrite)
  98. return;
  99. // will that request put us in a position to grow *or shrink* the file ?
  100. // note: this can be negative, e.g. calling SetLength(0), so we can't call EnsureQuotaLimits directly
  101. if (!IsolatedStorage.CanExtend (value - Length))
  102. throw new IsolatedStorageException ("Requested size is larger than remaining quota allowance.");
  103. base.SetLength (value);
  104. }
  105. public override void Write (byte [] buffer, int offset, int count)
  106. {
  107. container.PreCheck ();
  108. EnsureQuotaLimits (count);
  109. base.Write (buffer, offset, count);
  110. }
  111. public override void WriteByte (byte value)
  112. {
  113. container.PreCheck ();
  114. EnsureQuotaLimits (1);
  115. base.WriteByte (value);
  116. }
  117. public override bool CanRead {
  118. get {
  119. // no PreCheck required
  120. return base.CanRead;
  121. }
  122. }
  123. public override bool CanSeek {
  124. get {
  125. // no PreCheck required
  126. return base.CanSeek;
  127. }
  128. }
  129. public override bool CanWrite {
  130. get {
  131. // no PreCheck required
  132. return base.CanWrite;
  133. }
  134. }
  135. public override long Length {
  136. get {
  137. // FileStream ctor sometimes calls Length, i.e. before container is set
  138. if (container != null)
  139. container.PreCheck ();
  140. return base.Length;
  141. }
  142. }
  143. public override long Position {
  144. get {
  145. container.PreCheck ();
  146. return base.Position;
  147. }
  148. set {
  149. container.PreCheck ();
  150. base.Position = value;
  151. }
  152. }
  153. public override IAsyncResult BeginRead (byte[] buffer, int offset, int numBytes, AsyncCallback userCallback, object stateObject)
  154. {
  155. container.PreCheck ();
  156. return base.BeginRead (buffer, offset, numBytes, userCallback, stateObject);
  157. }
  158. public override IAsyncResult BeginWrite (byte[] buffer, int offset, int numBytes, AsyncCallback userCallback, object stateObject)
  159. {
  160. container.PreCheck ();
  161. EnsureQuotaLimits (numBytes);
  162. return base.BeginWrite (buffer, offset, numBytes, userCallback, stateObject);
  163. }
  164. public override int EndRead (IAsyncResult asyncResult)
  165. {
  166. container.PreCheck ();
  167. return base.EndRead (asyncResult);
  168. }
  169. public override void EndWrite (IAsyncResult asyncResult)
  170. {
  171. container.PreCheck ();
  172. base.EndWrite (asyncResult);
  173. }
  174. private void EnsureQuotaLimits (long request)
  175. {
  176. // don't worry about quota if we can't write to the stream,
  177. // the base class will throw the expected NotSupportedException
  178. if (!base.CanWrite)
  179. return;
  180. // will that request put us in a position to grow the file ?
  181. long grow = Position + request - Length;
  182. if (grow < 0)
  183. return;
  184. if (!IsolatedStorage.CanExtend (grow))
  185. throw new IsolatedStorageException ("Requested size is larger than remaining quota allowance.");
  186. }
  187. }
  188. }
  189. #endif