//------------------------------------------------------
        //
        //  Public Methods
        //
        //------------------------------------------------------
        #region Stream Methods
        /// <summary>
        /// Return the bytes requested from the container
        /// </summary>
        /// <param name="buffer">destination buffer</param>
        /// <param name="offset">offset to write into that buffer</param>
        /// <param name="count">how many bytes requested</param>
        /// <returns>how many bytes were written into <paramref name="buffer" />.</returns>
        /// <remarks>
        /// The underlying stream, expected to be an IsolatedStorageFileStream,
        /// is trusted to leave the IO position unchanged in case of an exception.
        /// </remarks>
        public override int Read(byte[] buffer, int offset, int count)
        {
            CheckDisposed();

            PackagingUtilities.VerifyStreamReadArgs(this, buffer, offset, count);

            return(_tempStream.Read(buffer, offset, count));
        }
        //------------------------------------------------------
        //
        //  Public Methods
        //
        //------------------------------------------------------

        /// <summary>
        /// Return the bytes requested.
        /// </summary>
        /// <param name="buffer">Destination buffer.</param>
        /// <param name="offset">
        /// The zero-based byte offset in buffer at which to begin storing the data read
        /// from the current stream.
        /// </param>
        /// <param name="count">How many bytes requested.</param>
        /// <returns>How many bytes were written into buffer.</returns>
        public override int Read(byte[] buffer, int offset, int count)
        {
            CheckClosed();

            // Check arguments.
            PackagingUtilities.VerifyStreamReadArgs(this, buffer, offset, count);

            // Leave capability and FileAccess checks up to the underlying stream(s).

            // Reading 0 bytes is a no-op.
            if (count == 0)
            {
                return(0);
            }

            int pieceNumber    = GetCurrentPieceNumber();
            int totalBytesRead = 0;

            Stream pieceStream = _dir.GetStream(pieceNumber);

            checked
            {
                //Seek to the correct location in the underlying stream for the current piece
                pieceStream.Seek(_currentOffset - _dir.GetStartOffset(pieceNumber), SeekOrigin.Begin);

                while (totalBytesRead < count)
                {
                    int numBytesRead = pieceStream.Read(
                        buffer,
                        offset + totalBytesRead,
                        count - totalBytesRead);

                    // End of the current stream: try to move to the next stream.
                    if (numBytesRead == 0)
                    {
                        if (_dir.IsLastPiece(pieceNumber))
                        {
                            break;
                        }

                        ++pieceNumber;
                        Invariant.Assert(_dir.GetStartOffset(pieceNumber) == _currentOffset + totalBytesRead);

                        pieceStream = _dir.GetStream(pieceNumber);

                        //Seek inorder to set the correct pointer for the next piece stream
                        pieceStream.Seek(0, SeekOrigin.Begin);
                    }

                    totalBytesRead += numBytesRead;
                }

                // Advance current position now we know the operation completed successfully.
                _currentOffset += totalBytesRead;
            }

            return(totalBytesRead);
        }
Example #3
0
        //------------------------------------------------------
        //
        //  Public Methods
        //
        //------------------------------------------------------

        /// <summary>
        /// Return the bytes requested.
        /// </summary>
        /// <param name="buffer">Destination buffer.</param>
        /// <param name="offset">The zero-based byte offset in buffer at which to begin storing the data read from the current stream.</param>
        /// <param name="count">How many bytes requested.</param>
        /// <returns>How many bytes were written into buffer.</returns>
        public unsafe override int Read(byte[] buffer, int offset, int count)
        {
            ThrowIfStreamDisposed();

            // Check arguments.
            PackagingUtilities.VerifyStreamReadArgs(this, buffer, offset, count);

            // Reading 0 bytes is a no-op.
            if (count == 0)
            {
                return(0);
            }

            // Prepare location of return value and call the COM object.
            int    bytesRead;
            IntPtr pBytesRead = new IntPtr(&bytesRead);

            // Prepare to restore position in case the read fails.
            long positionBeforeReadAttempt = this.Position;

            try
            {
                // Pin the array wrt GC while using an address in it.
                fixed(byte *bufferPointer = &buffer[offset])
                {
                    _oleStream.Read(new IntPtr(bufferPointer), count, pBytesRead);
                }
            }
            catch (COMException comException)
            {
                this.Position = positionBeforeReadAttempt;
                throw new IOException("Read", comException);
            }
            catch (IOException ioException)
            {
                this.Position = positionBeforeReadAttempt;
                throw new IOException("Read", ioException);
            }
            return(bytesRead);
        }
        // Token: 0x06006C85 RID: 27781 RVA: 0x001F3B74 File Offset: 0x001F1D74
        public unsafe override int Read(byte[] buffer, int offset, int count)
        {
            this.ThrowIfStreamDisposed();
            PackagingUtilities.VerifyStreamReadArgs(this, buffer, offset, count);
            if (count == 0)
            {
                return(0);
            }
            int    result;
            IntPtr refToNumBytesRead = new IntPtr((void *)(&result));
            long   position          = this.Position;

            try
            {
                try
                {
                    fixed(byte *ptr = &buffer[offset])
                    {
                        this._oleStream.Read(new IntPtr((void *)ptr), count, refToNumBytesRead);
                    }
                }
                finally
                {
                    byte *ptr = null;
                }
            }
            catch (COMException innerException)
            {
                this.Position = position;
                throw new IOException("Read", innerException);
            }
            catch (IOException innerException2)
            {
                this.Position = position;
                throw new IOException("Read", innerException2);
            }
            return(result);
        }
        override public int Read(byte[] buffer, int offset, int count)
        {
            CheckDisposed();

            PackagingUtilities.VerifyStreamReadArgs(this, buffer, offset, count);

            Debug.Assert(_currentStreamPosition >= 0);

            if (count == 0)
            {
                return(0);
            }

            if (_currentStreamLength <= _currentStreamPosition)
            {
                // we are past the end of the stream so let's just return 0
                return(0);
            }

            // No need to use checked{} since _currentStreamLength > _currentStreamPosition
            int bytesToRead = (int)Math.Min((long)count, _currentStreamLength - _currentStreamPosition);

            checked
            {
                Debug.Assert(bytesToRead > 0);

                int bytesRead;  // how much data we actually were able to read
                if (_isolatedStorageMode)
                {
                    lock (PackagingUtilities.IsolatedStorageFileLock)
                    {
                        _isolatedStorageStream.Seek(_currentStreamPosition, SeekOrigin.Begin);
                        bytesRead = _isolatedStorageStream.Read(buffer, offset, bytesToRead);
                    }
                }
                else
                {
                    // let's reset data to 0 first, so that gaps will be filled with 0s
                    // this is required for consistent behavior between the read calls used by the CRC Calculator
                    // and the WriteToStream calls used by the Flush/Save routines
                    Array.Clear(buffer, offset, bytesToRead);

                    int index = _memoryStreamList.BinarySearch(GetSearchBlockForOffset(_currentStreamPosition));
                    if (index < 0) // the head of new write block does not overlap with any existing blocks
                    // ~startIndex represents the insertion position
                    {
                        index = ~index;
                    }

                    for ( ; index < _memoryStreamList.Count; ++index)
                    {
                        MemoryStreamBlock memStreamBlock = _memoryStreamList[index];
                        long overlapBlockOffset;
                        long overlapBlockSize;
                        // let's check for overlap and fill up appropriate data
                        PackagingUtilities.CalculateOverlap(memStreamBlock.Offset, (int)memStreamBlock.Stream.Length,
                                                            _currentStreamPosition, bytesToRead,
                                                            out overlapBlockOffset, out overlapBlockSize);
                        if (overlapBlockSize > 0)
                        {
                            // we got an overlap let's copy data over to the target buffer
                            // _currentStreamPosition is not updated in this foreach loop; it will be updated later
                            Array.Copy(memStreamBlock.Stream.GetBuffer(), (int)(overlapBlockOffset - memStreamBlock.Offset),
                                       buffer, (int)(offset + overlapBlockOffset - _currentStreamPosition),
                                       (int)overlapBlockSize);
                        }
                        else
                        {
                            break;
                        }
                    }
                    // for memory stream case we get as much as we asked for
                    bytesRead = bytesToRead;
                }

                _currentStreamPosition += bytesRead;

                return(bytesRead);
            }
        }
Example #6
0
        //------------------------------------------------------
        //
        //  Public Methods
        //
        //------------------------------------------------------
        #region Stream Methods
        /// <summary>
        /// Return the bytes requested from the container
        /// </summary>
        /// <param name="buffer">destination buffer</param>
        /// <param name="offset">offset to write into that buffer</param>
        /// <param name="count">how many bytes requested</param>
        /// <returns>how many bytes were written into <paramref name="buffer" />.</returns>
        /// <remarks>
        /// The underlying stream, expected to be a DeflateStream or a CompressEmulationStream,
        /// is in charge of leaving the IO position unchanged in case of an exception.
        /// </remarks>
        public override int Read(byte[] buffer, int offset, int count)
        {
            CheckDisposed();

            PackagingUtilities.VerifyStreamReadArgs(this, buffer, offset, count);

            // no-op
            if (count == 0)
            {
                return(0);
            }

            checked     // catch any integer overflows
            {
                switch (_mode)
                {
                case Mode.Start:
                {
                    // skip to the correct logical position if necessary (DeflateStream starts at position zero)
                    if (_position == 0)
                    {
                        // enter ReadPassThrough mode if it is efficient
                        ChangeMode(Mode.ReadPassThrough);
                    }
                    else
                    {
                        ChangeMode(Mode.Emulation);
                    }

                    break;
                }

                case Mode.ReadPassThrough:      // continue in ReadPassThrough mode
                case Mode.Emulation:            // continue to read from existing emulation stream
                {
                    break;
                }

                case Mode.WritePassThrough:     // enter Emulation mode
                {
                    // optimization - if they are trying to jump back to the start to read, simply jump to ReadPassThrough mode
                    if (_position == 0)
                    {
                        ChangeMode(Mode.ReadPassThrough);
                    }
                    else
                    {
                        ChangeMode(Mode.Emulation);
                    }
                    break;
                }

                default: Debug.Assert(false, "Illegal state for CompressStream - logic error"); break;
                }

                // we might be in Start mode now if we are beyond the end of stream - just return zero
                if (_current == null)
                {
                    return(0);
                }

                int bytesRead = _current.Read(buffer, offset, count);

                // optimization for ReadPassThrough mode - we actually know the length because we ran out of bytes
                if (_mode == Mode.ReadPassThrough && bytesRead == 0)
                {
                    // possible first chance to set and verify length from header against real data length
                    UpdateUncompressedDataLength(_position);

                    // since we've exhausted the deflateStream, discard it to reduce working set
                    ChangeMode(Mode.Start);
                }

                // Stream contract - don't update position until we are certain that no exceptions have occurred
                _position += bytesRead;

                return(bytesRead);
            }
        }