New tests.
[mono.git] / mcs / class / corlib / System.IO.IsolatedStorage / MoonIsolatedStorageFileStream.cs
1 //
2 // System.IO.IsolatedStorage.MoonIsolatedStorageFileStream
3 //
4 // Moonlight's implementation for the IsolatedStorageFileStream
5 // 
6 // Authors
7 //      Miguel de Icaza (miguel@novell.com)
8 //      Sebastien Pouliot  <sebastien@ximian.com>
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
35 namespace System.IO.IsolatedStorage {
36
37         // NOTES: 
38         // * Silverlight allows extending to more than AvailableFreeSpace (by up to 1024 bytes).
39         //   This looks like a safety buffer.
40
41         public class IsolatedStorageFileStream : FileStream {
42
43                 IsolatedStorageFile container;
44
45                 internal static string Verify (IsolatedStorageFile isf, string path)
46                 {
47                         if (path == null)
48                                 throw new ArgumentNullException ("path");
49                         if (path.Length == 0)
50                                 throw new ArgumentException ("path");
51                         if (isf == null)
52                                 throw new ArgumentNullException ("isf");
53
54                         isf.PreCheck ();
55                         return isf.Verify (path);
56                 }
57
58                 public IsolatedStorageFileStream (string path, FileMode mode, IsolatedStorageFile isf)
59                         : base (Verify (isf, path), mode, (mode == FileMode.Append ? FileAccess.Write : FileAccess.ReadWrite), 
60                                 FileShare.Read, DefaultBufferSize, false, true)
61                 {
62                         container = isf;
63                 }
64
65                 public IsolatedStorageFileStream (string path, FileMode mode, FileAccess access, IsolatedStorageFile isf)
66                         : base (Verify (isf, path), mode, access, FileShare.Read, DefaultBufferSize, false, true)
67                 {
68                         container = isf;
69                 }
70
71                 public IsolatedStorageFileStream (string path, FileMode mode, FileAccess access, FileShare share, IsolatedStorageFile isf)
72                         : base (Verify (isf, path), mode, access, share, DefaultBufferSize, false, true)
73                 {
74                         container = isf;
75                 }
76
77                 protected override void Dispose (bool disposing)
78                 {
79                         // no PreCheck required
80                         base.Dispose (disposing);
81                 }
82
83                 public override void Flush ()
84                 {
85                         container.PreCheck ();
86                         base.Flush ();
87                 }
88
89                 public override int Read (byte [] buffer, int offset, int count)
90                 {
91                         container.PreCheck ();
92                         return base.Read (buffer, offset, count);
93                 }
94
95                 public override int ReadByte ()
96                 {
97                         container.PreCheck ();
98                         return base.ReadByte ();
99                 }
100
101                 public override long Seek (long offset, SeekOrigin origin)
102                 {
103                         container.PreCheck ();
104                         return base.Seek (offset, origin);
105                 }
106
107                 public override void SetLength (long value)
108                 {
109                         container.PreCheck ();
110                         // don't worry about quota if we can't write to the stream, 
111                         // the base class will throw the expected NotSupportedException
112                         if (!base.CanWrite)
113                                 return;
114
115                         // will that request put us in a position to grow *or shrink* the file ?
116                         // note: this can be negative, e.g. calling SetLength(0), so we can't call EnsureQuotaLimits directly
117                         if (!IsolatedStorage.CanExtend (value - Length))
118                                 throw new IsolatedStorageException ("Requested size is larger than remaining quota allowance.");
119
120                         base.SetLength (value);
121                 }
122
123                 public override void Write (byte [] buffer, int offset, int count)
124                 {
125                         container.PreCheck ();
126                         EnsureQuotaLimits (count);
127                         base.Write (buffer, offset, count);
128                 }
129
130                 public override void WriteByte (byte value)
131                 {
132                         container.PreCheck ();
133                         EnsureQuotaLimits (1);
134                         base.WriteByte (value);
135                 }
136
137                 public override bool CanRead {
138                         get {
139                                 // no PreCheck required
140                                 return base.CanRead;
141                         }
142                 }
143
144                 public override bool CanSeek {
145                         get {
146                                 // no PreCheck required
147                                 return base.CanSeek;
148                         }
149                 }
150
151                 public override bool CanWrite {
152                         get {
153                                 // no PreCheck required
154                                 return base.CanWrite;
155                         }
156                 }
157
158                 public override long Length {
159                         get {
160                                 // FileStream ctor sometimes calls Length, i.e. before container is set
161                                 if (container != null)
162                                         container.PreCheck ();
163                                 return base.Length;
164                         }
165                 }
166
167                 public override long Position {
168                         get {
169                                 container.PreCheck ();
170                                 return base.Position;
171                         }
172                         set {
173                                 container.PreCheck ();
174                                 base.Position = value;
175                         }
176                 }
177
178                 public override IAsyncResult BeginRead (byte[] buffer, int offset, int numBytes, AsyncCallback userCallback, object stateObject)
179                 {
180                         container.PreCheck ();
181                         return base.BeginRead (buffer, offset, numBytes, userCallback, stateObject);
182                 }
183
184                 public override IAsyncResult BeginWrite (byte[] buffer, int offset, int numBytes, AsyncCallback userCallback, object stateObject)
185                 {
186                         container.PreCheck ();
187                         EnsureQuotaLimits (numBytes);
188                         return base.BeginWrite (buffer, offset, numBytes, userCallback, stateObject);
189                 }
190
191                 public override int EndRead (IAsyncResult asyncResult)
192                 {
193                         container.PreCheck ();
194                         return base.EndRead (asyncResult);
195                 }
196
197                 public override void EndWrite (IAsyncResult asyncResult)
198                 {
199                         container.PreCheck ();
200                         base.EndWrite (asyncResult);
201                 }
202
203                 private void EnsureQuotaLimits (long request)
204                 {
205                         // don't worry about quota if we can't write to the stream, 
206                         // the base class will throw the expected NotSupportedException
207                         if (!base.CanWrite)
208                                 return;
209
210                         // will that request put us in a position to grow the file ?
211                         long grow = Position + request - Length;
212                         if (grow < 0)
213                                 return;
214
215                         if (!IsolatedStorage.CanExtend (grow))
216                                 throw new IsolatedStorageException ("Requested size is larger than remaining quota allowance.");
217                 }
218         }
219 }
220 #endif