/// <summary>
        /// Write
        /// </summary>
        public override void Write(byte[] buffer, int offset, int count)
        {
            CheckDisposed();

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

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

            _tempStream.Write(buffer, offset, count);
            _dirty = true;
        }
        override public void Write(byte[] buffer, int offset, int count)
        {
            CheckDisposed();
#if DEBUG
            DebugAssertConsistentArrayStructure();
#endif

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

            Debug.Assert(_currentStreamPosition >= 0);

            if (count == 0)
            {
                return;
            }

            checked
            {
                if (_isolatedStorageMode)
                {
                    lock (PackagingUtilities.IsolatedStorageFileLock)
                    {
                        _isolatedStorageStream.Seek(_currentStreamPosition, SeekOrigin.Begin);
                        _isolatedStorageStream.Write(buffer, offset, count);
                    }
                    _currentStreamPosition += count;
                }
                else
                {
                    WriteAndCollapseBlocks(buffer, offset, count);
                }
                _currentStreamLength = Math.Max(_currentStreamLength, _currentStreamPosition);
            }

            // this can potentially affect memory consumption
            SwitchModeIfNecessary();
#if DEBUG
            DebugAssertConsistentArrayStructure();
#endif
        }
Beispiel #3
0
        /// <summary>
        /// Write
        /// </summary>
        /// <remarks>Note that zero length write to deflate stream actually results in a stream containing 2 bytes.  This is
        /// required to maintain compatibility with the standard.</remarks>
        public override void Write(byte[] buffer, int offset, int count)
        {
            CheckDisposed();

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

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

            checked
            {
                switch (_mode)
                {
                case Mode.Start:                 // enter WritePassThrough mode if possible
                {
                    // Special case: If stream has existing content, we need to go straight
                    // to Emulation mode otherwise we'll potentially destroy existing data.
                    // Don't bother entering WritePassThroughMode if position is non-zero because
                    // we'll just enter emulation later.
                    if (_position == 0 && IsDeflateStreamEmpty(_baseStream))
                    {
                        ChangeMode(Mode.WritePassThrough);
                    }
                    else
                    {
                        ChangeMode(Mode.Emulation);
                    }
                    break;
                }

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

                case Mode.ReadPassThrough:      // enter Emulation mode
                {
                    ChangeMode(Mode.Emulation); break;
                }

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

                _current.Write(buffer, offset, count);

                _position += count;
            }

            // keep track of the current length in case someone asks for it
            if (_mode == Mode.WritePassThrough)
            {
                CachedLength = _position;
            }

            _dirtyForFlushing = true;
            _dirtyForClosing  = true;
        }
        /// <summary>
        /// Write. Distribute the bytes to write across several contiguous streams if needed.
        /// </summary>
        /// <remarks>
        /// Zip streams can be assumed seekable so the length will be available for chaining
        /// pieces.
        /// </remarks>
        public override void Write(byte[] buffer, int offset, int count)
        {
            CheckClosed();

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

            // No check for FileAccess and stream capability (CanWrite). This is the responsibility
            // of the underlying stream(s).

            // A no-op if zero bytes to write.
            if (count == 0)
            {
                return;
            }

            // Write into piece streams, preserving all lengths in non-terminal pieces.
            int    totalBytesWritten = 0;
            int    pieceNumber       = GetCurrentPieceNumber();
            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 (totalBytesWritten < count)
                {
                    // Compute the number of bytes to write into pieceStream.
                    int numBytesToWriteInCurrentPiece = count - totalBytesWritten;
                    if (!_dir.IsLastPiece(pieceNumber))
                    {
                        // The write should not change the length of an intermediate piece.
                        long currentPosition = _currentOffset + totalBytesWritten;
                        long maxPosition     = _dir.GetStartOffset(pieceNumber + 1) - 1;
                        if (numBytesToWriteInCurrentPiece > (maxPosition - currentPosition + 1))
                        {
                            // Cast from long to cast is safe in so far as *count*, which is the
                            // absolute max for all byte counts, is a positive int.
                            numBytesToWriteInCurrentPiece = checked ((int)(maxPosition - currentPosition + 1));
                        }
                    }

                    // Do the write.
                    pieceStream.Write(buffer, offset + totalBytesWritten, numBytesToWriteInCurrentPiece);

                    // Update the tally.
                    totalBytesWritten += numBytesToWriteInCurrentPiece;

                    // If there is more data to write, get the next piece stream
                    if (!_dir.IsLastPiece(pieceNumber) && totalBytesWritten < count)
                    {
                        // The next write, should involve the next piece.
                        ++pieceNumber;

                        pieceStream = _dir.GetStream(pieceNumber);

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

                // Now we know the operation has completed, the current position can be updated.
                Invariant.Assert(totalBytesWritten == count);
                _currentOffset += totalBytesWritten;
            }
        }