Example #1
0
        public void TestStreamCanI()
        {
            Stream stream;

            using (StreamCache cache = new StreamCache(new SharedMemoryStream(), 1))
            {
                using (stream = cache.Open())
                {
                    Assert.IsTrue(stream.CanRead);
                    Assert.IsTrue(stream.CanWrite);
                    Assert.IsTrue(stream.CanSeek);
                }
                using (stream = ((IFactory <Stream>)cache).Create())
                {
                    Assert.IsTrue(stream.CanRead);
                    Assert.IsTrue(stream.CanWrite);
                    Assert.IsTrue(stream.CanSeek);
                }
                using (stream = cache.Open(FileAccess.Read))
                {
                    Assert.IsTrue(stream.CanRead);
                    Assert.IsFalse(stream.CanWrite);
                    Assert.IsTrue(stream.CanSeek);
                }
                using (stream = cache.Open(FileAccess.Write))
                {
                    Assert.IsFalse(stream.CanRead);
                    Assert.IsTrue(stream.CanWrite);
                    Assert.IsTrue(stream.CanSeek);
                }
            }
        }
Example #2
0
        public void TestCacheRecoverAbandondStream()
        {
            Stream stream;

            using (StreamCache cache = new StreamCache(new SharedMemoryStream(), 1))
            {
                if (true)
                {
                    stream = cache.Open();
                    stream.Write(new byte[100], 25, 55);
                    stream = null;//simulated "accidental" object abandonment... i.e. someone does something stupid.
                }

                GC.Collect(0, GCCollectionMode.Forced);
                GC.WaitForPendingFinalizers();

                Thread t = new Thread(
                    delegate()
                {
                    using (stream = cache.Open(FileAccess.Read))
                    {
                        Assert.AreEqual(new byte[55], IOStream.ReadAllBytes(stream));
                    }
                }
                    );
                t.IsBackground = true;
                t.Start();
                Assert.IsTrue(t.Join(1000));
            }
        }
            private void ReadByteRange(Guid transferId, Salt sessionKey, string location, StreamCache streams, long offset, int count)
            {
                using (Message req = new Message(TransferState.DownloadBytesRequest, transferId, _publicKey, s => sessionKey))
                {
                    req.Write(location);
                    req.Write(offset);
                    req.Write(count);

                    Stream response = SendPayload(req, location, req.ToStream(_privateKey));
                    using (Message rsp = new Message(response, _privateKey, s => sessionKey))
                    {
                        Check.Assert <InvalidOperationException>(rsp.State == TransferState.DownloadBytesResponse);
                        byte[] bytes = rsp.ReadBytes(100 * 1000 * 1024);
                        Check.Assert <InvalidOperationException>(bytes.Length == count);

                        rsp.VerifySignature(_publicKey);

                        using (Stream io = streams.Open(FileAccess.Write))
                        {
                            io.Seek(offset, SeekOrigin.Begin);
                            io.Write(bytes, 0, count);
                        }
                    }
                }
            }
Example #4
0
        public void TestStreamCacheDisposes()
        {
            Stream stream;

            using (StreamCache cache = new StreamCache(new SharedMemoryStream(), 1))
            {
                stream = cache.Open();
                Assert.IsTrue(stream.CanRead && stream.CanWrite);
            }

            Assert.IsFalse(stream.CanRead || stream.CanWrite);
            try
            {
                stream.ReadByte();
                Assert.Fail();
            }/* why InvalidOperation?, the underlying stream was disposed, not the stream itself */
            catch (InvalidOperationException) { }

            stream.Dispose();
            try
            {
                stream.WriteByte(1);
                Assert.Fail();
            }/* Now it's been disposed */
            catch (ObjectDisposedException) { }
        }
        public void TestStreamCacheDisposes()
        {
            Stream stream;
            using (StreamCache cache = new StreamCache(new SharedMemoryStream(), 1))
            {
                stream = cache.Open();
                Assert.IsTrue(stream.CanRead && stream.CanWrite);
            }

            Assert.IsFalse(stream.CanRead || stream.CanWrite);
            try
            {
                stream.ReadByte();
                Assert.Fail();
            }/* why InvalidOperation?, the underlying stream was disposed, not the stream itself */
            catch (InvalidOperationException) { }

            stream.Dispose();
            try
            {
                stream.WriteByte(1);
                Assert.Fail();
            }/* Now it's been disposed */
            catch (ObjectDisposedException) { }
        }
 public void TestStreamCanI()
 {
     Stream stream;
     using (StreamCache cache = new StreamCache(new SharedMemoryStream(), 1))
     {
         using (stream = cache.Open())
         {
             Assert.IsTrue(stream.CanRead);
             Assert.IsTrue(stream.CanWrite);
             Assert.IsTrue(stream.CanSeek);
         }
         using (stream = ((IFactory<Stream>)cache).Create())
         {
             Assert.IsTrue(stream.CanRead);
             Assert.IsTrue(stream.CanWrite);
             Assert.IsTrue(stream.CanSeek);
         }
         using (stream = cache.Open(FileAccess.Read))
         {
             Assert.IsTrue(stream.CanRead);
             Assert.IsFalse(stream.CanWrite);
             Assert.IsTrue(stream.CanSeek);
         }
         using (stream = cache.Open(FileAccess.Write))
         {
             Assert.IsFalse(stream.CanRead);
             Assert.IsTrue(stream.CanWrite);
             Assert.IsTrue(stream.CanSeek);
         }
     }
 }
Example #7
0
        public void TestCacheLimit()
        {
            bool finished = false;

            using (SharedMemoryStream shared = new SharedMemoryStream())
                using (StreamCache cache = new StreamCache(shared, 1))
                {
                    ManualResetEvent ready   = new ManualResetEvent(false);
                    ManualResetEvent release = new ManualResetEvent(false);
                    Thread           t       = new Thread(
                        delegate()
                    {
                        using (Stream stream = cache.Open(FileAccess.ReadWrite))
                        {
                            stream.Write(new byte[50], 0, 50);
                            ready.Set();
                            release.WaitOne();
                            stream.Write(new byte[50], 0, 50);
                            GC.KeepAlive(stream);
                            finished = true;
                        }
                    }
                        );
                    t.IsBackground = true;
                    t.Start();

                    Assert.IsTrue(ready.WaitOne());
                    Assert.AreEqual(50, shared.Length);

                    new Thread(
                        delegate()
                    {
                        Thread.Sleep(10);
                        release.Set();
                    }
                        ).Start();

                    Assert.IsFalse(finished);
                    using (Stream stream = cache.Open())
                    {
                        Assert.IsTrue(finished);
                        Assert.IsTrue(release.WaitOne(0, false));
                        Assert.AreEqual(100, stream.Read(new byte[100], 0, 100));
                    }
                    Assert.IsTrue(t.Join(1000));
                }
        }
Example #8
0
        public void TestStreamReadWrite()
        {
            Stream stream;

            using (StreamCache cache = new StreamCache(new SharedMemoryStream(), 1))
            {
                using (stream = cache.Open())
                {
                    stream.Write(new byte[100], 25, 55);
                    stream.Close();
                }
                using (stream = cache.Open(FileAccess.Read))
                {
                    Assert.AreEqual(new byte[55], IOStream.ReadAllBytes(stream));
                }
            }
        }
 public void ChangeLogFile()
 {
     lock (this) {
         if (file != null)
         {
             logFiles.Close(file);
         }
         file = logFiles.Open(LogPath(pathFormat), true);
     }
 }
 public void ChangeLogFile()
 {
     lock (this) {
         if (file != null)
         {
             logFiles.Close(file);
         }
         var path = LogPath(pathFormat);
         file = logFiles.Open(path, WillAppend(path));
     }
 }
Example #11
0
        public void TestCacheRecoverAbandondMutex()
        {
            Stream stream = null;

            using (StreamCache cache = new StreamCache(new SharedMemoryStream(), 1))
            {
                Thread t = new Thread(delegate() { stream = cache.Open(FileAccess.Read); });
                t.Start();
                t.Join(); //The exit of this thread releases the stream...

                using (Stream another = cache.Open())
                {
                    Assert.AreEqual(0, another.Position);
                    // Another thread can then objtain the same underlying stream... we can demonstrate
                    // this by the fact that the Position property affects both streams.
                    stream.Position = 100;
                    Assert.AreEqual(100, another.Position);
                }
            }
        }
        public void TestFileStreamCache()
        {
            Stream stream;
            using (TempFile tempFile = new TempFile())
            {
                using (StreamCache cache = new StreamCache(new FileStreamFactory(tempFile.TempPath, FileMode.Open)))
                {
                    using (stream = cache.Open())
                    {
                        stream.SetLength(100);
                        stream.WriteByte(1);
                    }
                }

                Assert.AreEqual(100, tempFile.Length);
                using (stream = tempFile.Open())
                    Assert.AreEqual(1, stream.ReadByte());
            }
        }
Example #13
0
        public void TestFileStreamCache()
        {
            Stream stream;

            using (TempFile tempFile = new TempFile())
            {
                using (StreamCache cache = new StreamCache(new FileStreamFactory(tempFile.TempPath, FileMode.Open)))
                {
                    using (stream = cache.Open())
                    {
                        stream.SetLength(100);
                        stream.WriteByte(1);
                    }
                }

                Assert.AreEqual(100, tempFile.Length);
                using (stream = tempFile.Open())
                    Assert.AreEqual(1, stream.ReadByte());
            }
        }
            private bool Download(string location, StreamCache output)
            {
                int maxMessageLength;
                long fileLength, bytesReceived = 0;
                Guid transferId = Guid.NewGuid();
                byte[] serverKeyBits;
                byte[] nonce = GetNonce(transferId, location, out serverKeyBits);
                Hash hnonce = Hash.SHA256(nonce);

                //STEP 2: Create and send session key
                Salt clientKeyBits = new Salt(Salt.Size.b256);
                Salt sessionKey = SessionSecret(clientKeyBits, serverKeyBits);

                using (Message req = new Message(TransferState.DownloadRequest, transferId, _publicKey, NoSession))
                {
                    req.Write(hnonce.ToArray());
                    req.Write(location);
                    req.Write(clientKeyBits.ToArray());

                    Stream response = SendPayload(req, location, req.ToStream(_privateKey));
                    using (Message rsp = new Message(response, _privateKey, s=>sessionKey))
                    {
                        Check.Assert<InvalidOperationException>(rsp.State == TransferState.DownloadResponse);
                        maxMessageLength = Check.InRange(rsp.ReadInt32(), 0, int.MaxValue);
                        fileLength = Check.InRange(rsp.ReadInt64(), 0, 0x00FFFFFFFFFFFFFFL);
                        byte[] bytes = rsp.ReadBytes(100 * 1000 * 1024);
                        rsp.VerifySignature(_publicKey);

                        using(Stream io = output.Open(FileAccess.Write))
                        {
                            io.SetLength(fileLength);
                            if (bytes.Length > 0)
                            {
                                io.Seek(0, SeekOrigin.Begin);
                                io.Write(bytes, 0, bytes.Length);
                                bytesReceived += bytes.Length;
                            }
                        }
                    }
                }
                //STEP 3...n: Continue downloading other chunks of the file
                if (bytesReceived < fileLength)
                {
                    bool[] failed = new bool[1];
                    using (WorkQueue queue = new WorkQueue(LimitThreads))
                    {
                        queue.OnError += (o, e) => { failed[0] = true; };
                        while (bytesReceived < fileLength && !failed[0] && !_abort.WaitOne(0, false))
                        {
                            int len = (int) Math.Min(fileLength - bytesReceived, maxMessageLength);
                            BytesToRead task = new BytesToRead(
                                this, LimitThreads, transferId, sessionKey, location, output, bytesReceived, len);
                            queue.Enqueue(task.Send);
                            OnProgressChanged(location, bytesReceived, fileLength);
                            bytesReceived += len;
                        }

                        queue.Complete(true, failed[0] ? 5000 : 7200000);
                    }

                    if (_abort.WaitOne(0, false))
                        return false;
                    Check.Assert<InvalidDataException>(failed[0] == false);

                    // STEP 4: Complete the transfer
                    using (Message req = new Message(TransferState.DownloadCompleteRequest, transferId, _publicKey, s => sessionKey))
                    {
                        SendPayload(req, location, req.ToStream(_privateKey)).Dispose();
                    }
                }
                OnProgressChanged(location, fileLength, fileLength);
                return true;
            }
        public void TestCacheLimit()
        {
            bool finished = false;
            using (SharedMemoryStream shared = new SharedMemoryStream())
            using (StreamCache cache = new StreamCache(shared, 1))
            {
                ManualResetEvent ready = new ManualResetEvent(false);
                ManualResetEvent release = new ManualResetEvent(false);
                Thread t = new Thread(
                    delegate()
                    {
                        using (Stream stream = cache.Open(FileAccess.ReadWrite))
                        {
                            stream.Write(new byte[50], 0, 50);
                            ready.Set();
                            release.WaitOne();
                            stream.Write(new byte[50], 0, 50);
                            GC.KeepAlive(stream);
                            finished = true;
                        }
                    }
                );
                t.IsBackground = true;
                t.Start();

                Assert.IsTrue(ready.WaitOne());
                Assert.AreEqual(50, shared.Length);

                new Thread(
                    delegate()
                    {
                        Thread.Sleep(10);
                        release.Set();
                    }
                ).Start();

                Assert.IsFalse(finished);
                using (Stream stream = cache.Open())
                {
                    Assert.IsTrue(finished);
                    Assert.IsTrue(release.WaitOne(0, false));
                    Assert.AreEqual(100, stream.Read(new byte[100], 0, 100));
                }
                Assert.IsTrue(t.Join(1000));
            }
        }
        public void TestCacheRecoverAbandondStream()
        {
            Stream stream;
            using (StreamCache cache = new StreamCache(new SharedMemoryStream(), 1))
            {
                if(true)
                {
                    stream = cache.Open();
                    stream.Write(new byte[100], 25, 55);
                    stream = null;//simulated "accidental" object abandonment... i.e. someone does something stupid.
                }

                GC.Collect(0, GCCollectionMode.Forced);
                GC.WaitForPendingFinalizers();

                Thread t = new Thread(
                    delegate()
                    {
                        using (stream = cache.Open(FileAccess.Read))
                        {
                            Assert.AreEqual(new byte[55], IOStream.ReadAllBytes(stream));
                        }
                    }
                );
                t.IsBackground = true;
                t.Start();
                Assert.IsTrue(t.Join(1000));
            }
        }
        public void TestCacheRecoverAbandondMutex()
        {
            Stream stream = null;
            using (StreamCache cache = new StreamCache(new SharedMemoryStream(), 1))
            {
                Thread t = new Thread( delegate() { stream = cache.Open(FileAccess.Read); } );
                t.Start();
                t.Join(); //The exit of this thread releases the stream...

                using (Stream another = cache.Open())
                {
                    Assert.AreEqual(0, another.Position);
                    // Another thread can then objtain the same underlying stream... we can demonstrate
                    // this by the fact that the Position property affects both streams.
                    stream.Position = 100;
                    Assert.AreEqual(100, another.Position);
                }
            }
        }
 public void TestStreamReadWrite()
 {
     Stream stream;
     using (StreamCache cache = new StreamCache(new SharedMemoryStream(), 1))
     {
         using (stream = cache.Open())
         {
             stream.Write(new byte[100], 25, 55);
             stream.Close();
         }
         using (stream = cache.Open(FileAccess.Read))
         {
             Assert.AreEqual(new byte[55], IOStream.ReadAllBytes(stream));
         }
     }
 }
        /// <summary> Internal use to specify aligned IO when using NoBuffering file option </summary>
        protected FragmentedFile(IFactory<Stream> streamFactory, int blockSize, int growthRate, int cacheLimit, FileOptions options)
        {
            _useAlignedIo = (options & NoBuffering) == NoBuffering;
            _streamCache = new StreamCache(streamFactory, cacheLimit);
            _header = new FileBlock(blockSize, _useAlignedIo);
            _syncFreeBlock = new object();
            try
            {
                long fallocated;
                bool canWrite;

                using (Stream s = _streamCache.Open(FileAccess.ReadWrite))
                {
                    canWrite = s.CanWrite;
                    if (!s.CanRead)
                        throw new InvalidOperationException("The stream does not support Read access.");

                    _header.Read(s, blockSize);

                    if ((_header.Flags & ~BlockFlags.HeaderFilter) != BlockFlags.HeaderFlags)
                        throw new InvalidDataException();

                    _nextFree = _header.NextBlockId;
                    SetBlockSize(_header.Length, out _blockSize, out _maskVersion, out _maskOffset);
                    if (blockSize != _blockSize) throw new ArgumentOutOfRangeException("blockSize");
                    fallocated = LastAllocated(s);
                    _reallocSize = growthRate * _blockSize;

                    if (canWrite)
                    {
                        s.Position = 0;
                        _header.NextBlockId = long.MinValue;
                        _header.Write(s, FileBlock.HeaderSize);
                    }
                }

                if (canWrite)
                {
                    if ((_header.Flags & BlockFlags.ResizingFile) == BlockFlags.ResizingFile && _nextFree > 0)
                        ResizeFile(_nextFree, Math.Max(fallocated, _nextFree + _reallocSize));

                    if (_nextFree == long.MinValue)
                        _nextFree = RecoverFreeBlocks();
                }
            }
            catch
            {
                _streamCache.Dispose();
                throw;
            }
        }
            private bool Download(string location, StreamCache output)
            {
                int  maxMessageLength;
                long fileLength, bytesReceived = 0;
                Guid transferId = Guid.NewGuid();

                byte[] serverKeyBits;
                byte[] nonce  = GetNonce(transferId, location, out serverKeyBits);
                Hash   hnonce = Hash.SHA256(nonce);

                //STEP 2: Create and send session key
                Salt clientKeyBits = new Salt(Salt.Size.b256);
                Salt sessionKey    = SessionSecret(clientKeyBits, serverKeyBits);

                using (Message req = new Message(TransferState.DownloadRequest, transferId, _publicKey, NoSession))
                {
                    req.Write(hnonce.ToArray());
                    req.Write(location);
                    req.Write(clientKeyBits.ToArray());

                    Stream response = SendPayload(req, location, req.ToStream(_privateKey));
                    using (Message rsp = new Message(response, _privateKey, s => sessionKey))
                    {
                        Check.Assert <InvalidOperationException>(rsp.State == TransferState.DownloadResponse);
                        maxMessageLength = Check.InRange(rsp.ReadInt32(), 0, int.MaxValue);
                        fileLength       = Check.InRange(rsp.ReadInt64(), 0, 0x00FFFFFFFFFFFFFFL);
                        byte[] bytes = rsp.ReadBytes(100 * 1000 * 1024);
                        rsp.VerifySignature(_publicKey);

                        using (Stream io = output.Open(FileAccess.Write))
                        {
                            io.SetLength(fileLength);
                            if (bytes.Length > 0)
                            {
                                io.Seek(0, SeekOrigin.Begin);
                                io.Write(bytes, 0, bytes.Length);
                                bytesReceived += bytes.Length;
                            }
                        }
                    }
                }
                //STEP 3...n: Continue downloading other chunks of the file
                if (bytesReceived < fileLength)
                {
                    bool[] failed = new bool[1];
                    using (WorkQueue queue = new WorkQueue(LimitThreads))
                    {
                        queue.OnError += (o, e) => { failed[0] = true; };
                        while (bytesReceived < fileLength && !failed[0] && !_abort.WaitOne(0, false))
                        {
                            int         len  = (int)Math.Min(fileLength - bytesReceived, maxMessageLength);
                            BytesToRead task = new BytesToRead(
                                this, LimitThreads, transferId, sessionKey, location, output, bytesReceived, len);
                            queue.Enqueue(task.Send);
                            OnProgressChanged(location, bytesReceived, fileLength);
                            bytesReceived += len;
                        }

                        queue.Complete(true, failed[0] ? 5000 : 7200000);
                    }

                    if (_abort.WaitOne(0, false))
                    {
                        return(false);
                    }
                    Check.Assert <InvalidDataException>(failed[0] == false);

                    // STEP 4: Complete the transfer
                    using (Message req = new Message(TransferState.DownloadCompleteRequest, transferId, _publicKey, s => sessionKey))
                    {
                        SendPayload(req, location, req.ToStream(_privateKey)).Dispose();
                    }
                }
                OnProgressChanged(location, fileLength, fileLength);
                return(true);
            }
            private void ReadByteRange(Guid transferId, Salt sessionKey, string location, StreamCache streams, long offset, int count)
            {
                using (Message req = new Message(TransferState.DownloadBytesRequest, transferId, _publicKey, s=>sessionKey))
                {
                    req.Write(location);
                    req.Write(offset);
                    req.Write(count);

                    Stream response = SendPayload(req, location, req.ToStream(_privateKey));
                    using (Message rsp = new Message(response, _privateKey, s=>sessionKey))
                    {
                        Check.Assert<InvalidOperationException>(rsp.State == TransferState.DownloadBytesResponse);
                        byte[] bytes = rsp.ReadBytes(100 * 1000 * 1024);
                        Check.Assert<InvalidOperationException>(bytes.Length == count);
                        
                        rsp.VerifySignature(_publicKey);

                        using(Stream io = streams.Open(FileAccess.Write))
                        {
                            io.Seek(offset, SeekOrigin.Begin);
                            io.Write(bytes, 0, count);
                        }
                    }
                }
            }