//
// Authors
// Miguel de Icaza (miguel@novell.com)
+// Sebastien Pouliot <sebastien@ximian.com>
//
-// Copyright (C) 2007 Novell, Inc (http://www.novell.com)
+// Copyright (C) 2007, 2008 Novell, Inc (http://www.novell.com)
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
-#if NET_2_1
+#if MOONLIGHT
using System;
using System.IO;
namespace System.IO.IsolatedStorage {
+ // NOTES:
+ // * Silverlight allows extending to more than AvailableFreeSpace (by up to 1024 bytes).
+ // This looks like a safety buffer.
+
public class IsolatedStorageFileStream : FileStream {
+
IsolatedStorageFile container;
-
+
+ internal static string Verify (IsolatedStorageFile isf, string path)
+ {
+ if (path == null)
+ throw new ArgumentNullException ("path");
+ if (path.Length == 0)
+ throw new ArgumentException ("path");
+ if (isf == null)
+ throw new ArgumentNullException ("isf");
+
+ isf.PreCheck ();
+ return isf.Verify (path);
+ }
+
public IsolatedStorageFileStream (string path, FileMode mode, IsolatedStorageFile isf)
- : base (IsolatedStorageFile.Verify (path), mode)
+ : base (Verify (isf, path), mode, (mode == FileMode.Append ? FileAccess.Write : FileAccess.ReadWrite),
+ FileShare.Read, DefaultBufferSize, false, true)
{
container = isf;
}
public IsolatedStorageFileStream (string path, FileMode mode, FileAccess access, IsolatedStorageFile isf)
- : base (IsolatedStorageFile.Verify (path), mode, access)
+ : base (Verify (isf, path), mode, access, FileShare.Read, DefaultBufferSize, false, true)
{
container = isf;
}
public IsolatedStorageFileStream (string path, FileMode mode, FileAccess access, FileShare share, IsolatedStorageFile isf)
- : base (IsolatedStorageFile.Verify (path), mode, access, share)
+ : base (Verify (isf, path), mode, access, share, DefaultBufferSize, false, true)
{
container = isf;
}
protected override void Dispose (bool disposing)
{
+ // no PreCheck required
base.Dispose (disposing);
}
public override void Flush ()
{
+ container.PreCheck ();
base.Flush ();
}
public override int Read (byte [] buffer, int offset, int count)
{
+ container.PreCheck ();
return base.Read (buffer, offset, count);
}
public override int ReadByte ()
{
+ container.PreCheck ();
return base.ReadByte ();
}
public override long Seek (long offset, SeekOrigin origin)
{
+ container.PreCheck ();
return base.Seek (offset, origin);
}
public override void SetLength (long value)
{
+ container.PreCheck ();
+ // don't worry about quota if we can't write to the stream,
+ // the base class will throw the expected NotSupportedException
+ if (!base.CanWrite)
+ return;
+
+ // will that request put us in a position to grow *or shrink* the file ?
+ // note: this can be negative, e.g. calling SetLength(0), so we can't call EnsureQuotaLimits directly
+ if (!IsolatedStorage.CanExtend (value - Length))
+ throw new IsolatedStorageException ("Requested size is larger than remaining quota allowance.");
+
base.SetLength (value);
}
public override void Write (byte [] buffer, int offset, int count)
{
+ container.PreCheck ();
+ EnsureQuotaLimits (count);
base.Write (buffer, offset, count);
}
public override void WriteByte (byte value)
{
- WriteByte (value);
+ container.PreCheck ();
+ EnsureQuotaLimits (1);
+ base.WriteByte (value);
}
public override bool CanRead {
get {
+ // no PreCheck required
return base.CanRead;
}
}
public override bool CanSeek {
get {
+ // no PreCheck required
return base.CanSeek;
}
}
public override bool CanWrite {
get {
+ // no PreCheck required
return base.CanWrite;
}
}
- public override bool IsAsync {
- get {
- return base.IsAsync;
- }
- }
-
public override long Length {
get {
+ // FileStream ctor sometimes calls Length, i.e. before container is set
+ if (container != null)
+ container.PreCheck ();
return base.Length;
}
}
public override long Position {
get {
+ container.PreCheck ();
return base.Position;
}
-
set {
+ container.PreCheck ();
base.Position = value;
}
}
+
+ public override IAsyncResult BeginRead (byte[] buffer, int offset, int numBytes, AsyncCallback userCallback, object stateObject)
+ {
+ container.PreCheck ();
+ return base.BeginRead (buffer, offset, numBytes, userCallback, stateObject);
+ }
+
+ public override IAsyncResult BeginWrite (byte[] buffer, int offset, int numBytes, AsyncCallback userCallback, object stateObject)
+ {
+ container.PreCheck ();
+ EnsureQuotaLimits (numBytes);
+ return base.BeginWrite (buffer, offset, numBytes, userCallback, stateObject);
+ }
+
+ public override int EndRead (IAsyncResult asyncResult)
+ {
+ container.PreCheck ();
+ return base.EndRead (asyncResult);
+ }
+
+ public override void EndWrite (IAsyncResult asyncResult)
+ {
+ container.PreCheck ();
+ base.EndWrite (asyncResult);
+ }
+
+ private void EnsureQuotaLimits (long request)
+ {
+ // don't worry about quota if we can't write to the stream,
+ // the base class will throw the expected NotSupportedException
+ if (!base.CanWrite)
+ return;
+
+ // will that request put us in a position to grow the file ?
+ long grow = Position + request - Length;
+ if (grow < 0)
+ return;
+
+ if (!IsolatedStorage.CanExtend (grow))
+ throw new IsolatedStorageException ("Requested size is larger than remaining quota allowance.");
+ }
}
}
-#endif
\ No newline at end of file
+#endif