public void WriteEntry_FromUnseekableStream_AdvanceDataStream_WriteFromThatPosition()
        {
            using MemoryStream source      = GetTarMemoryStream(CompressionMethod.Uncompressed, TestTarFormat.ustar, "file");
            using WrappedStream unseekable = new WrappedStream(source, canRead: true, canWrite: true, canSeek: false);

            using MemoryStream destination = new MemoryStream();

            using (TarReader reader = new TarReader(unseekable))
            {
                TarEntry entry = reader.GetNextEntry();
                Assert.NotNull(entry);
                Assert.NotNull(entry.DataStream);
                entry.DataStream.ReadByte(); // Advance one byte, now the expected string would be "ello file"

                using (TarWriter writer = new TarWriter(destination, TarEntryFormat.Ustar, leaveOpen: true))
                {
                    writer.WriteEntry(entry);
                }
            }

            destination.Seek(0, SeekOrigin.Begin);
            using (TarReader reader = new TarReader(destination))
            {
                TarEntry entry = reader.GetNextEntry();
                Assert.NotNull(entry);
                Assert.NotNull(entry.DataStream);

                using (StreamReader streamReader = new StreamReader(entry.DataStream, leaveOpen: true))
                {
                    string contents = streamReader.ReadLine();
                    Assert.Equal("ello file", contents);
                }
            }
        }
        public static void CreateNormal_VerifyDataDescriptor()
        {
            using var memoryStream = new MemoryStream();
            // We need an non-seekable stream so the data descriptor bit is turned on when saving
            var wrappedStream = new WrappedStream(memoryStream, true, true, false, null);

            // Creation will go through the path that sets the data descriptor bit when the stream is unseekable
            using (var archive = new ZipArchive(wrappedStream, ZipArchiveMode.Create))
            {
                CreateEntry(archive, "A", "xxx");
                CreateEntry(archive, "B", "yyy");
            }

            AssertDataDescriptor(memoryStream, true);

            // Update should flip the data descriptor bit to zero on save
            using (var archive = new ZipArchive(memoryStream, ZipArchiveMode.Update))
            {
                ZipArchiveEntry entry = archive.Entries[0];
                using Stream entryStream = entry.Open();
                StreamReader reader  = new StreamReader(entryStream);
                string       content = reader.ReadToEnd();

                // Append a string to this entry
                entryStream.Seek(0, SeekOrigin.End);
                StreamWriter writer = new StreamWriter(entryStream);
                writer.Write("zzz");
                writer.Flush();
            }

            AssertDataDescriptor(memoryStream, false);
        }
Exemple #3
0
 /// <summary>
 ///   Wraps a generic stream into a block stream using the specified transformer and blocksize.
 /// </summary>
 /// <remarks>The wrapped stream must be writable and seekable</remarks>
 /// <param name="wrappedStream">Stream to wrap</param>
 /// <param name="transformer">The block transformer to use</param>
 /// <param name="blockSize">Block size to use</param>
 public BlockWriteOnceStream(Stream wrappedStream, IBlockTransformer transformer, short blockSize = BLOCK_SIZE) :
     base(wrappedStream, transformer, blockSize)
 {
     currentBlock = new byte[BlockSize];
     WrappedStream.Seek(0, SeekOrigin.Begin);
     wrappedStream.SetLength(0);
 }
Exemple #4
0
        protected virtual void Dispose(bool disposing, CloseExState closeState)
        {
            // All calls below should already be idempotent.

            try
            {
                if (disposing)
                {
                    ICloseEx icloseEx = WrappedStream as ICloseEx;

                    if (icloseEx != null)
                    {
                        icloseEx.CloseEx(closeState);
                    }
                    else
                    {
                        WrappedStream.Close();
                    }
                }
            }
            finally
            {
                base.Dispose(disposing);
            }
        }
        public override int Read(byte[] buffer, int offset, int count)
        {
            int startOffset = (int)(_position % _blockSize);

            if (startOffset == 0 && (count % _blockSize == 0 || _position + count == Length))
            {
                // Aligned read - pass through to underlying stream.
                WrappedStream.Position = _position;
                int numRead = WrappedStream.Read(buffer, offset, count);
                _position += numRead;
                return(numRead);
            }

            long startPos = MathUtilities.RoundDown(_position, _blockSize);
            long endPos   = MathUtilities.RoundUp(_position + count, _blockSize);

            if (endPos - startPos > int.MaxValue)
            {
                throw new IOException("Oversized read, after alignment");
            }

            byte[] tempBuffer = new byte[endPos - startPos];

            WrappedStream.Position = startPos;
            int read      = WrappedStream.Read(tempBuffer, 0, tempBuffer.Length);
            int available = Math.Min(count, read - startOffset);

            Array.Copy(tempBuffer, startOffset, buffer, offset, available);

            _position += available;
            return(available);
        }
Exemple #6
0
 public void Constructors_UnwritableStream_Throws()
 {
     using MemoryStream archiveStream  = new MemoryStream();
     using WrappedStream wrappedStream = new WrappedStream(archiveStream, canRead: true, canWrite: false, canSeek: false);
     Assert.Throws <IOException>(() => new TarWriter(wrappedStream));
     Assert.Throws <IOException>(() => new TarWriter(wrappedStream, TarEntryFormat.V7));
 }
Exemple #7
0
        public override int EndRead(IAsyncResult asyncResult)
        {
            int result = WrappedStream.EndRead(asyncResult);

            m_Position += result;
            return(result);
        }
Exemple #8
0
        public async void Write_To_UnseekableStream_Async()
        {
            await using (MemoryStream inner = new MemoryStream())
            {
                await using (WrappedStream wrapped = new WrappedStream(inner, canRead: true, canWrite: true, canSeek: false))
                {
                    await using (TarWriter writer = new TarWriter(wrapped, TarEntryFormat.Pax, leaveOpen: true))
                    {
                        PaxTarEntry paxEntry = new PaxTarEntry(TarEntryType.RegularFile, "file.txt");
                        await writer.WriteEntryAsync(paxEntry);
                    } // The final records should get written, and the length should not be set because position cannot be read

                    inner.Seek(0, SeekOrigin.Begin); // Rewind the base stream (wrapped cannot be rewound)

                    await using (TarReader reader = new TarReader(wrapped))
                    {
                        TarEntry entry = await reader.GetNextEntryAsync();

                        Assert.Equal(TarEntryFormat.Pax, entry.Format);
                        Assert.Equal(TarEntryType.RegularFile, entry.EntryType);
                        Assert.Null(await reader.GetNextEntryAsync());
                    }
                }
            }
        }
Exemple #9
0
        public override int Read(byte[] buffer, int offset, int count)
        {
            try {
                if (Interlocked.Increment(ref m_ReadNesting) != 1)
                {
                    throw new NotSupportedException(SR.GetString(SR.net_io_invalidnestedcall, "Read", "read"));
                }

                if (m_HeadEOF)
                {
                    return(WrappedStream.Read(buffer, offset, count));
                }
                else
                {
                    int result = m_HeadStream.Read(buffer, offset, count);
                    m_HeadLength += result;
                    if (result == 0 && count != 0)
                    {
                        m_HeadEOF = true;
                        m_HeadStream.Close();
                        result = WrappedStream.Read(buffer, offset, count);
                    }
                    return(result);
                }
            }
            finally {
                Interlocked.Decrement(ref m_ReadNesting);
            }
        }
Exemple #10
0
        private byte[] LoadData(int blockIndex)
        {
            ThrowIfDisposed();

            if (m_blocks !.Count <= blockIndex)
            {
                m_blocks.AddRange(new byte[blockIndex - m_blocks.Count + 1][]);
            }

            var blockData = m_blocks[blockIndex];

            if (blockData is null)
            {
                WrappedStream.Position = blockIndex * c_blockSize;
                blockData = new byte[c_blockSize];
                var bytesRead = WrappedStream.ReadBlock(blockData, 0, blockData.Length);
                if (bytesRead != c_blockSize)
                {
                    Array.Resize(ref blockData, bytesRead);
                }
                m_blocks[blockIndex] = blockData;
            }

            return(blockData);
        }
Exemple #11
0
        private async Task <byte[]> LoadDataAsync(int blockIndex)
        {
            ThrowIfDisposed();

            if (m_blocks !.Count <= blockIndex)
            {
                m_blocks.AddRange(new byte[blockIndex - m_blocks.Count + 1][]);
            }

            var blockData = m_blocks[blockIndex];

            if (blockData is null)
            {
                WrappedStream.Position = blockIndex * c_blockSize;
                blockData = new byte[c_blockSize];
                var bytesRead = await WrappedStream.ReadBlockAsync(blockData, 0, blockData.Length).ConfigureAwait(false);

                if (bytesRead != c_blockSize)
                {
                    Array.Resize(ref blockData, bytesRead);
                }
                m_blocks[blockIndex] = blockData;
            }

            return(blockData);
        }
        public void Constructor_ConversionFromUstar_From_UnseekableTarReader(TarEntryFormat writerFormat)
        {
            using MemoryStream source         = GetTarMemoryStream(CompressionMethod.Uncompressed, TestTarFormat.ustar, "file");
            using WrappedStream wrappedSource = new WrappedStream(source, canRead: true, canWrite: false, canSeek: false);

            using TarReader sourceReader = new TarReader(wrappedSource, leaveOpen: true);
            UstarTarEntry ustarEntry = sourceReader.GetNextEntry(copyData: false) as UstarTarEntry;
            V7TarEntry    v7Entry    = new V7TarEntry(other: ustarEntry); // Convert, and avoid advancing wrappedSource position

            using MemoryStream destination = new MemoryStream();
            using (TarWriter writer = new TarWriter(destination, writerFormat, leaveOpen: true))
            {
                writer.WriteEntry(v7Entry); // Write DataStream exactly where the wrappedSource position was left
            }

            destination.Position = 0; // Rewind
            using (TarReader destinationReader = new TarReader(destination, leaveOpen: false))
            {
                V7TarEntry resultEntry = destinationReader.GetNextEntry() as V7TarEntry;
                Assert.NotNull(resultEntry);
                using (StreamReader streamReader = new StreamReader(resultEntry.DataStream))
                {
                    Assert.Equal("Hello file", streamReader.ReadToEnd());
                }
            }
        }
Exemple #13
0
        public override int EndRead(IAsyncResult asyncResult)
        {
            if (Interlocked.Decrement(ref m_ReadNesting) != 0)
            {
                Interlocked.Increment(ref m_ReadNesting);
                throw new InvalidOperationException(SR.GetString(SR.net_io_invalidendcall, "EndRead"));
            }

            if (asyncResult == null)
            {
                throw new ArgumentNullException("asyncResult");
            }

            InnerAsyncResult myResult = asyncResult as InnerAsyncResult;

            if (myResult == null)
            {
                // We are just passing IO down, although m_HeadEOF should be always true here.
                GlobalLog.Assert(m_HeadEOF, "CombinedReadStream::EndRead|m_HeadEOF is false and asyncResult is not of InnerAsyncResult type {0).", asyncResult.GetType().FullName);
                return(m_HeadEOF? WrappedStream.EndRead(asyncResult): m_HeadStream.EndRead(asyncResult));
            }

            // this is our wrapped AsyncResult
            myResult.InternalWaitForCompletion();

            // Exception?
            if (myResult.Result is Exception)
            {
                throw (Exception)(myResult.Result);
            }

            // Report the count read
            return((int)myResult.Result);
        }
Exemple #14
0
 public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, Object state)
 {
     if (m_Position + offset > m_Offset + m_Size)
     {
         throw new NotSupportedException(SR.GetString(SR.net_cache_unsupported_partial_stream));
     }
     return(WrappedStream.BeginWrite(buffer, offset, count, callback, state));
 }
        private void DoOperation(ModifyStream modifyStream, ModifyBuffer modifyBuffer, int count)
        {
            int startOffset = (int)(_position % _blockSize);

            if (startOffset == 0 && (count % _blockSize == 0 || _position + count == Length))
            {
                WrappedStream.Position = _position;
                modifyStream(WrappedStream, 0, count);
                _position += count;
                return;
            }

            long unalignedEnd = _position + count;
            long alignedPos   = MathUtilities.RoundDown(_position, _blockSize);

            if (startOffset != 0)
            {
                WrappedStream.Position = alignedPos;
                WrappedStream.Read(_alignmentBuffer, 0, _blockSize);

                modifyBuffer(_alignmentBuffer, startOffset, 0, Math.Min(count, _blockSize - startOffset));

                WrappedStream.Position = alignedPos;
                WrappedStream.Write(_alignmentBuffer, 0, _blockSize);
            }

            alignedPos = MathUtilities.RoundUp(_position, _blockSize);
            if (alignedPos >= unalignedEnd)
            {
                _position = unalignedEnd;
                return;
            }

            int passthroughLength = (int)MathUtilities.RoundDown(_position + count - alignedPos, _blockSize);

            if (passthroughLength > 0)
            {
                WrappedStream.Position = alignedPos;
                modifyStream(WrappedStream, (int)(alignedPos - _position), passthroughLength);
            }

            alignedPos += passthroughLength;
            if (alignedPos >= unalignedEnd)
            {
                _position = unalignedEnd;
                return;
            }

            WrappedStream.Position = alignedPos;
            WrappedStream.Read(_alignmentBuffer, 0, _blockSize);

            modifyBuffer(_alignmentBuffer, 0, (int)(alignedPos - _position), (int)Math.Min(count - (alignedPos - _position), unalignedEnd - alignedPos));

            WrappedStream.Position = alignedPos;
            WrappedStream.Write(_alignmentBuffer, 0, _blockSize);

            _position = unalignedEnd;
        }
Exemple #16
0
 public static async Task TestStreamingRead(string zipFile, string zipFolder)
 {
     using (var stream = await StreamHelpers.CreateTempCopyStream(zfile(zipFile)))
     {
         Stream wrapped = new WrappedStream(stream, true, false, false, null);
         IsZipSameAsDir(wrapped, zfolder(zipFolder), ZipArchiveMode.Read, false, false);
         Assert.False(wrapped.CanRead, "Wrapped stream should be closed at this point"); //check that it was closed
     }
 }
Exemple #17
0
 private static async Task TestStreamingRead(String zipFile, String directory)
 {
     using (var stream = await StreamHelpers.CreateTempCopyStream(zipFile))
     {
         Stream wrapped = new WrappedStream(stream, true, false, false, null);
         ZipTest.IsZipSameAsDir(wrapped, directory, ZipArchiveMode.Read, false, false);
         Assert.False(wrapped.CanRead, "Wrapped stream should be closed at this point"); //check that it was closed
     }
 }
Exemple #18
0
 public static async Task TestStreamingRead(string zipFile, string zipFolder)
 {
     using (var stream = await StreamHelpers.CreateTempCopyStream(zfile(zipFile)))
     {
         Stream wrapped = new WrappedStream(stream, true, false, false, null);
         IsZipSameAsDir(wrapped, zfolder(zipFolder), ZipArchiveMode.Read, false, false);
         Assert.False(wrapped.CanRead, "Wrapped stream should be closed at this point"); //check that it was closed
     }
 }
Exemple #19
0
 public override void Write(byte[] buffer, int offset, int count)
 {
     if (m_Position + count > m_Offset + m_Size)
     {
         throw new NotSupportedException(SR.GetString(SR.net_cache_unsupported_partial_stream));
     }
     WrappedStream.Write(buffer, offset, count);
     m_Position += count;
 }
Exemple #20
0
 private static async Task TestStreamingRead(String zipFile, String directory)
 {
     using (var stream = await StreamHelpers.CreateTempCopyStream(zipFile))
     {
         Stream wrapped = new WrappedStream(stream, true, false, false, null);
         ZipTest.IsZipSameAsDir(wrapped, directory, ZipArchiveMode.Read, false, false);
         Assert.False(wrapped.CanRead, "Wrapped stream should be closed at this point"); //check that it was closed
     }
 }
Exemple #21
0
        public override int EndRead(IAsyncResult asyncResult)
        {
            if (Interlocked.Decrement(ref m_ReadNesting) != 0)
            {
                Interlocked.Increment(ref m_ReadNesting);
                throw new InvalidOperationException(SR.GetString(SR.net_io_invalidendcall, "EndRead"));
            }

            if (asyncResult == null)
            {
                throw new ArgumentNullException("asyncResult");
            }

            InnerAsyncResult myResult = asyncResult as InnerAsyncResult;

            if (myResult == null)
            {
                // We are just passing IO down, although the shadow stream should be dead for now.
                GlobalLog.Assert(m_ShadowStreamIsDead, "ForwardingReadStream::EndRead|m_ShadowStreamIsDead is false and asyncResult is not of InnerAsyncResult type {0}.", asyncResult.GetType().FullName);
                int bytes = WrappedStream.EndRead(asyncResult);
                if (bytes == 0)
                {
                    m_SeenReadEOF = true;
                }
            }

            // this is our wrapped AsyncResult
            bool suceess = false;

            try {
                myResult.InternalWaitForCompletion();
                // Exception?
                if (myResult.Result is Exception)
                {
                    throw (Exception)(myResult.Result);
                }
                suceess = true;
            }
            finally {
                if (!suceess && !m_ShadowStreamIsDead)
                {
                    m_ShadowStreamIsDead = true;
                    if (m_ShadowStream is ICloseEx)
                    {
                        ((ICloseEx)m_ShadowStream).CloseEx(CloseExState.Abort | CloseExState.Silent);
                    }
                    else
                    {
                        m_ShadowStream.Close();
                    }
                }
            }

            // Report the read count
            return((int)myResult.Result);
        }
 public async Task UnreadableStream_Throws_Async()
 {
     using (MemoryStream archive = new MemoryStream())
     {
         using (WrappedStream unreadable = new WrappedStream(archive, canRead: false, canWrite: true, canSeek: true))
         {
             await Assert.ThrowsAsync <IOException>(() => TarFile.ExtractToDirectoryAsync(unreadable, destinationDirectoryName: "path", overwriteFiles: false));
         }
     }
 }
Exemple #23
0
        [Trait(XunitConstants.Category, XunitConstants.IgnoreForCI)] // Jenkins fails with unicode characters [JENKINS-12610]
        public static async Task CreateNormal_Unicode(string folder, bool seekable)
        {
            using (var s = new MemoryStream())
            {
                var testStream = new WrappedStream(s, false, true, seekable, null);
                await CreateFromDir(zfolder(folder), testStream, ZipArchiveMode.Create);

                IsZipSameAsDir(s, zfolder(folder), ZipArchiveMode.Read, requireExplicit: true, checkTimes: true);
            }
        }
        public static async Task testCreate(String folder, bool seekable)
        {
            using (var s = new MemoryStream())
            {
                var testStream = new WrappedStream(s, false, true, seekable, null);
                await ZipTest.CreateFromDir(ZipTest.zfolder(folder), testStream, ZipArchiveMode.Create);

                ZipTest.IsZipSameAsDir(s, ZipTest.zfolder(folder), ZipArchiveMode.Read, false, false);
            }
        }
        public static async Task CreateNormal_Unicode_Seekable()
        {
            using (var s = new MemoryStream())
            {
                var testStream = new WrappedStream(s, false, true, true, null);
                await CreateFromDir(zfolder("unicode"), testStream, ZipArchiveMode.Create);

                IsZipSameAsDir(s, zfolder("unicode"), ZipArchiveMode.Read, requireExplicit: true, checkTimes: true);
            }
        }
        public static async Task CreateNormal_Seekable(string folder, bool useSpansForWriting, bool writeInChunks)
        {
            using (var s = new MemoryStream())
            {
                var testStream = new WrappedStream(s, false, true, true, null);
                await CreateFromDir(zfolder(folder), testStream, ZipArchiveMode.Create, useSpansForWriting, writeInChunks);

                IsZipSameAsDir(s, zfolder(folder), ZipArchiveMode.Read, requireExplicit: true, checkTimes: true);
            }
        }
Exemple #27
0
        [Trait(XunitConstants.Category, XunitConstants.IgnoreForCI)] // Jenkins fails with unicode characters [JENKINS-12610]
        public static async Task CreateNormal_Unicode(string folder, bool seekable)
        {
            using (var s = new MemoryStream())
            {
                var testStream = new WrappedStream(s, false, true, seekable, null);
                await ZipTest.CreateFromDir(ZipTest.zfolder(folder), testStream, ZipArchiveMode.Create);

                ZipTest.IsZipSameAsDir(s, ZipTest.zfolder(folder), ZipArchiveMode.Read, false, false);
            }
        }
Exemple #28
0
 public async Task UnwritableStream_Throws_Async()
 {
     await using (MemoryStream archiveStream = new MemoryStream())
     {
         await using (WrappedStream unwritable = new WrappedStream(archiveStream, canRead: true, canWrite: false, canSeek: true))
         {
             await Assert.ThrowsAsync <IOException>(() => TarFile.CreateFromDirectoryAsync(sourceDirectoryName: "path", destination: unwritable, includeBaseDirectory: false));
         }
     }
 }
Exemple #29
0
        [Trait(XunitConstants.Category, XunitConstants.IgnoreForCI)] // Jenkins fails with unicode characters [JENKINS-12610]
        public static async Task CreateNormal_Unicode(string folder, bool seekable)
        {
            using (var s = new MemoryStream())
            {
                var testStream = new WrappedStream(s, false, true, seekable, null);
                await CreateFromDir(zfolder(folder), testStream, ZipArchiveMode.Create);

                IsZipSameAsDir(s, zfolder(folder), ZipArchiveMode.Read, false, false);
            }
        }
Exemple #30
0
 public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, Object state)
 {
     if (m_Position >= m_Offset + m_Size)
     {
         count = 0;
     }
     else if (m_Position + count > m_Offset + m_Size)
     {
         count = (int)(m_Offset + m_Size - m_Position);
     }
     return(WrappedStream.BeginRead(buffer, offset, count, callback, state));
 }
    public async Task JsonRpcClosesStreamAfterDisconnectedEvent()
    {
        var server = new Server();

        var streams = Nerdbank.FullDuplexStream.CreateStreams();

        var clientStream = streams.Item2;

        // Use wrapped stream to see when the stream is closed and disposed.
        var serverStream = new WrappedStream(streams.Item1);

        // Subscribe to disconnected event on the server stream
        var serverStreamDisconnected = new TaskCompletionSource <object?>();

        serverStream.Disconnected += (sender, args) => serverStreamDisconnected.SetResult(null);

        using (JsonRpc serverRpc = JsonRpc.Attach(serverStream, server))
        {
            // Subscribe to disconnected event on json rpc
            var    disconnectedEventFired  = new TaskCompletionSource <JsonRpcDisconnectedEventArgs>();
            object?disconnectedEventSender = null;
            serverRpc.Disconnected += (object?sender, JsonRpcDisconnectedEventArgs e) =>
            {
                // The stream must not be disposed when the Disconnected even fires
                Assert.True(serverStream.IsConnected);

                disconnectedEventSender = sender;
                disconnectedEventFired.SetResult(e);
            };

            // Send a bad json to the server
            byte[] badJson = Encoding.UTF8.GetBytes("Content-Length: 1\r\n\r\n{");
            await clientStream.WriteAsync(badJson, 0, badJson.Length);

            // The server must fire disonnected event because bad json must make it disconnect
            JsonRpcDisconnectedEventArgs args = await disconnectedEventFired.Task.WithCancellation(this.TimeoutToken);

            Assert.Same(serverRpc, disconnectedEventSender);
            Assert.NotNull(args);
            Assert.NotNull(args.Description);
            Assert.Equal(DisconnectedReason.ParseError, args.Reason);
#pragma warning disable CS0618 // Type or member is obsolete
            Assert.Null(args.LastMessage);
#pragma warning restore CS0618 // Type or member is obsolete
            Assert.NotNull(args.Exception);

            // Server must dispose the stream now
            await serverStreamDisconnected.Task.WithCancellation(this.TimeoutToken);

            Assert.True(serverStream.Disposed);
            Assert.False(serverStream.IsEndReached);
        }
    }
Exemple #32
0
        public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, Object state)
        {
            try {
                if (Interlocked.Increment(ref m_ReadNesting) != 1)
                {
                    throw new NotSupportedException(SR.GetString(SR.net_io_invalidnestedcall, "BeginRead", "read"));
                }

                if (m_ReadCallback == null)
                {
                    m_ReadCallback = new AsyncCallback(ReadCallback);
                }

                if (m_HeadEOF)
                {
                    return(WrappedStream.BeginRead(buffer, offset, count, callback, state));
                }
                else
                {
                    InnerAsyncResult userResult = new InnerAsyncResult(state, callback, buffer, offset, count);
                    IAsyncResult     ar         = m_HeadStream.BeginRead(buffer, offset, count, m_ReadCallback, userResult);

                    if (!ar.CompletedSynchronously)
                    {
                        return(userResult);
                    }

                    int bytes = m_HeadStream.EndRead(ar);
                    m_HeadLength += bytes;

                    //check on EOF condition
                    if (bytes == 0 && userResult.Count != 0)
                    {
                        //Got a first stream EOF
                        m_HeadEOF = true;
                        m_HeadStream.Close();
                        return(WrappedStream.BeginRead(buffer, offset, count, callback, state));
                    }
                    else
                    {
                        // just complete user IO
                        userResult.Buffer = null;
                        userResult.InvokeCallback(count);
                        return(userResult);
                    }
                }
            }
            catch {
                Interlocked.Decrement(ref m_ReadNesting);
                throw;
            }
        }
Exemple #33
0
        private void ReadCallback(IAsyncResult transportResult)
        {
            GlobalLog.Assert(transportResult.AsyncState is InnerAsyncResult, "InnerAsyncResult::ReadCallback|The state expected to be of type InnerAsyncResult, received {0}.", transportResult.GetType().FullName);
            if (transportResult.CompletedSynchronously)
            {
                return;
            }

            InnerAsyncResult userResult = transportResult.AsyncState as InnerAsyncResult;

            try {
                // Complete transport IO, in this callback that is always the head stream
                int count;
                if (!m_HeadEOF)
                {
                    count         = m_HeadStream.EndRead(transportResult);
                    m_HeadLength += count;
                }
                else
                {
                    count = WrappedStream.EndRead(transportResult);
                }


                //check on EOF condition
                if (!m_HeadEOF && count == 0 && userResult.Count != 0)
                {
                    //Got a first stream EOF
                    m_HeadEOF = true;
                    m_HeadStream.Close();
                    IAsyncResult ar = WrappedStream.BeginRead(userResult.Buffer, userResult.Offset, userResult.Count, m_ReadCallback, userResult);
                    if (!ar.CompletedSynchronously)
                    {
                        return;
                    }
                    count = WrappedStream.EndRead(ar);
                }
                // just complete user IO
                userResult.Buffer = null;
                userResult.InvokeCallback(count);
            }
            catch (Exception e) {
                //ASYNC: try to ignore even serious exceptions (nothing to loose?)
                if (userResult.InternalPeekCompleted)
                {
                    throw;
                }

                userResult.InvokeCallback(e);
            }
        }
        public async Task GetNextEntry_UnseekableArchive_ReplaceDataStream_ExcludeFromDisposing_Async(bool copyData)
        {
            await using (MemoryStream archive = new MemoryStream())
            {
                await using (TarWriter writer = new TarWriter(archive, TarEntryFormat.Ustar, leaveOpen: true))
                {
                    UstarTarEntry entry1 = new UstarTarEntry(TarEntryType.RegularFile, "file.txt");
                    entry1.DataStream = new MemoryStream();
                    using (StreamWriter streamWriter = new StreamWriter(entry1.DataStream, leaveOpen: true))
                    {
                        streamWriter.WriteLine("Hello world!");
                    }
                    entry1.DataStream.Seek(0, SeekOrigin.Begin); // Rewind to ensure it gets written from the beginning
                    await writer.WriteEntryAsync(entry1);

                    UstarTarEntry entry2 = new UstarTarEntry(TarEntryType.Directory, "dir");
                    await writer.WriteEntryAsync(entry2);
                }

                archive.Seek(0, SeekOrigin.Begin);
                await using (WrappedStream wrapped = new WrappedStream(archive, canRead: true, canWrite: false, canSeek: false))
                {
                    UstarTarEntry entry;
                    Stream        oldStream;
                    await using (TarReader reader = new TarReader(wrapped)) // Unseekable
                    {
                        entry = await reader.GetNextEntryAsync(copyData) as UstarTarEntry;

                        Assert.NotNull(entry);
                        Assert.Equal(TarEntryType.RegularFile, entry.EntryType);

                        oldStream = entry.DataStream;

                        entry.DataStream = new MemoryStream(); // Substitution, setter should dispose the previous stream
                        using (StreamWriter streamWriter = new StreamWriter(entry.DataStream, leaveOpen: true))
                        {
                            streamWriter.WriteLine("Substituted");
                        }
                    } // Disposing reader should not dispose the substituted DataStream

                    Assert.Throws <ObjectDisposedException>(() => oldStream.Read(new byte[1]));

                    entry.DataStream.Seek(0, SeekOrigin.Begin);
                    using (StreamReader streamReader = new StreamReader(entry.DataStream))
                    {
                        Assert.Equal("Substituted", streamReader.ReadLine());
                    }
                }
            }
        }
Exemple #35
0
 public void SetUp()
 {
     source = new MemoryStream(30);
     for (int i = 0; i < source.Capacity; i++) { source.WriteByte(0x55); }
     source.Position = wrappedStartPosition;
     ws = new WrappedStream(source, wrappedSize);
 }