Example #1
0
        private void FlushCharBuffer(bool flushEncoder)
        {
            int charCount = this._charBufferLength - this._charBufferFree;

            if (!this._responseEncodingUpdated)
            {
                this.UpdateResponseEncoding();
            }
            this._responseEncodingUsed = true;
            int maxByteCount = this._responseEncoding.GetMaxByteCount(charCount);

            if ((maxByteCount <= 0x80) || !this._responseBufferingOn)
            {
                byte[] bytes = new byte[maxByteCount];
                int    size  = this._responseEncoder.GetBytes(this._charBuffer, 0, charCount, bytes, 0, flushEncoder);
                this.BufferData(bytes, 0, size, false);
            }
            else
            {
                int freeBytes = (this._lastBuffer != null) ? this._lastBuffer.FreeBytes : 0;
                if (freeBytes < maxByteCount)
                {
                    this._lastBuffer = this.CreateNewMemoryBufferElement();
                    this._buffers.Add(this._lastBuffer);
                    freeBytes = this._lastBuffer.FreeBytes;
                }
                this._lastBuffer.AppendEncodedChars(this._charBuffer, 0, charCount, this._responseEncoder, flushEncoder);
            }
            this._charBufferFree = this._charBufferLength;
        }
Example #2
0
 internal void FilterIntegrated(bool finalFiltering, IIS7WorkerRequest wr)
 {
     if (this._installedFilter != null)
     {
         if (this._charBufferLength != this._charBufferFree)
         {
             this.FlushCharBuffer(true);
         }
         this._lastBuffer = null;
         ArrayList list = this._buffers;
         this._buffers = new ArrayList();
         ArrayList list2          = null;
         bool      hasSubstBlocks = false;
         list2 = wr.GetBufferedResponseChunks(false, null, ref hasSubstBlocks);
         this._filterSink.Filtering = true;
         try
         {
             if (list2 != null)
             {
                 for (int i = 0; i < list2.Count; i++)
                 {
                     IHttpResponseElement element = (IHttpResponseElement)list2[i];
                     long size = element.GetSize();
                     if (size > 0L)
                     {
                         this._installedFilter.Write(element.GetBytes(), 0, Convert.ToInt32(size));
                     }
                 }
                 wr.ClearResponse(true, false);
             }
             if (list != null)
             {
                 for (int j = 0; j < list.Count; j++)
                 {
                     IHttpResponseElement element2 = (IHttpResponseElement)list[j];
                     long num4 = element2.GetSize();
                     if (num4 > 0L)
                     {
                         this._installedFilter.Write(element2.GetBytes(), 0, Convert.ToInt32(num4));
                     }
                 }
             }
             this._installedFilter.Flush();
         }
         finally
         {
             try
             {
                 if (finalFiltering)
                 {
                     this._installedFilter.Close();
                 }
             }
             finally
             {
                 this._filterSink.Filtering = false;
             }
         }
     }
 }
Example #3
0
        internal ArrayList GetSnapshot(out bool hasSubstBlocks)
        {
            if (this._charBufferLength != this._charBufferFree)
            {
                this.FlushCharBuffer(true);
            }
            this._lastBuffer = null;
            hasSubstBlocks   = false;
            ArrayList list  = new ArrayList();
            int       count = this._buffers.Count;

            for (int i = 0; i < count; i++)
            {
                object obj2 = this._buffers[i];
                HttpBaseMemoryResponseBufferElement element = obj2 as HttpBaseMemoryResponseBufferElement;
                if (element != null)
                {
                    if (element.FreeBytes > 0x1000)
                    {
                        obj2 = element.Clone();
                    }
                    else
                    {
                        element.DisableRecycling();
                    }
                }
                else if (obj2 is HttpSubstBlockResponseElement)
                {
                    hasSubstBlocks = true;
                }
                list.Add(obj2);
            }
            return(list);
        }
Example #4
0
        internal void MoveResponseBufferRangeForward(int srcIndex, int srcCount, int dstIndex)
        {
            if (srcCount > 0)
            {
                object[] array = new object[srcIndex - dstIndex];
                this._buffers.CopyTo(dstIndex, array, 0, array.Length);
                for (int i = 0; i < srcCount; i++)
                {
                    this._buffers[dstIndex + i] = this._buffers[srcIndex + i];
                }
                for (int j = 0; j < array.Length; j++)
                {
                    this._buffers[(dstIndex + srcCount) + j] = array[j];
                }
            }
            HttpBaseMemoryResponseBufferElement element = this._buffers[this._buffers.Count - 1] as HttpBaseMemoryResponseBufferElement;

            if ((element != null) && (element.FreeBytes > 0))
            {
                this._lastBuffer = element;
            }
            else
            {
                this._lastBuffer = null;
            }
        }
 private void BufferResource(IntPtr data, int offset, int size)
 {
     if ((size > 0x1000) || !this._responseBufferingOn)
     {
         this._lastBuffer = null;
         this._buffers.Add(new HttpResourceResponseElement(data, offset, size));
     }
     else
     {
         int num;
         if (this._lastBuffer != null)
         {
             num = this._lastBuffer.Append(data, offset, size);
             size -= num;
             offset += num;
         }
         while (size > 0)
         {
             this._lastBuffer = this.CreateNewMemoryBufferElement();
             this._buffers.Add(this._lastBuffer);
             num = this._lastBuffer.Append(data, offset, size);
             offset += num;
             size -= num;
         }
     }
 }
Example #6
0
 private void BufferResource(IntPtr data, int offset, int size)
 {
     if ((size > 0x1000) || !this._responseBufferingOn)
     {
         this._lastBuffer = null;
         this._buffers.Add(new HttpResourceResponseElement(data, offset, size));
     }
     else
     {
         int num;
         if (this._lastBuffer != null)
         {
             num     = this._lastBuffer.Append(data, offset, size);
             size   -= num;
             offset += num;
         }
         while (size > 0)
         {
             this._lastBuffer = this.CreateNewMemoryBufferElement();
             this._buffers.Add(this._lastBuffer);
             num     = this._lastBuffer.Append(data, offset, size);
             offset += num;
             size   -= num;
         }
     }
 }
Example #7
0
 internal int GetResponseBufferCountAfterFlush()
 {
     if (this._charBufferLength != this._charBufferFree)
     {
         this.FlushCharBuffer(true);
     }
     this._lastBuffer = null;
     return(this._buffers.Count);
 }
Example #8
0
 internal HttpWriter(HttpResponse response) : base(null)
 {
     this._response         = response;
     this._stream           = new HttpResponseStream(this);
     this._buffers          = new ArrayList();
     this._lastBuffer       = null;
     this._charBuffer       = (char[])s_Allocator.GetBuffer();
     this._charBufferLength = this._charBuffer.Length;
     this._charBufferFree   = this._charBufferLength;
     this.UpdateResponseBuffering();
 }
 internal HttpWriter(HttpResponse response) : base(null)
 {
     this._response = response;
     this._stream = new HttpResponseStream(this);
     this._buffers = new ArrayList();
     this._lastBuffer = null;
     this._charBuffer = (char[]) s_Allocator.GetBuffer();
     this._charBufferLength = this._charBuffer.Length;
     this._charBufferFree = this._charBufferLength;
     this.UpdateResponseBuffering();
 }
Example #10
0
 internal void ClearBuffers()
 {
     this.ClearCharBuffer();
     if (this._substElements != null)
     {
         this._response.Context.Request.SetDynamicCompression(true);
     }
     this.RecycleBufferElements();
     this._buffers                = new ArrayList();
     this._lastBuffer             = null;
     this._hasBeenClearedRecently = true;
 }
Example #11
0
 internal void WriteFile(string filename, long offset, long size)
 {
     if (this._charBufferLength != this._charBufferFree)
     {
         this.FlushCharBuffer(true);
     }
     this._lastBuffer = null;
     this._buffers.Add(new HttpFileResponseElement(filename, offset, size));
     if (!this._responseBufferingOn)
     {
         this._response.Flush();
     }
 }
Example #12
0
 internal void TransmitFile(string filename, long offset, long size, bool isImpersonating, bool supportsLongTransmitFile)
 {
     if (this._charBufferLength != this._charBufferFree)
     {
         this.FlushCharBuffer(true);
     }
     this._lastBuffer = null;
     this._buffers.Add(new HttpFileResponseElement(filename, offset, size, isImpersonating, supportsLongTransmitFile));
     if (!this._responseBufferingOn)
     {
         this._response.Flush();
     }
 }
Example #13
0
 private void RecycleBufferElements()
 {
     if (this._buffers != null)
     {
         int count = this._buffers.Count;
         for (int i = 0; i < count; i++)
         {
             HttpBaseMemoryResponseBufferElement element = this._buffers[i] as HttpBaseMemoryResponseBufferElement;
             if (element != null)
             {
                 element.Recycle();
             }
         }
         this._buffers = null;
     }
 }
Example #14
0
 internal void DisposeIntegratedBuffers()
 {
     if (this._buffers != null)
     {
         int count = this._buffers.Count;
         for (int i = 0; i < count; i++)
         {
             HttpBaseMemoryResponseBufferElement element = this._buffers[i] as HttpBaseMemoryResponseBufferElement;
             if (element != null)
             {
                 element.Recycle();
             }
         }
         this._buffers = null;
     }
     this.ClearBuffers();
 }
Example #15
0
 internal void Filter(bool finalFiltering)
 {
     if (this._installedFilter != null)
     {
         if (this._charBufferLength != this._charBufferFree)
         {
             this.FlushCharBuffer(true);
         }
         this._lastBuffer = null;
         if ((this._buffers.Count != 0) || finalFiltering)
         {
             ArrayList list = this._buffers;
             this._buffers = new ArrayList();
             this._filterSink.Filtering = true;
             try
             {
                 int count = list.Count;
                 for (int i = 0; i < count; i++)
                 {
                     IHttpResponseElement element = (IHttpResponseElement)list[i];
                     long size = element.GetSize();
                     if (size > 0L)
                     {
                         this._installedFilter.Write(element.GetBytes(), 0, Convert.ToInt32(size));
                     }
                 }
                 this._installedFilter.Flush();
             }
             finally
             {
                 try
                 {
                     if (finalFiltering)
                     {
                         this._installedFilter.Close();
                     }
                 }
                 finally
                 {
                     this._filterSink.Filtering = false;
                 }
             }
         }
     }
 }
Example #16
0
        internal void WriteSubstBlock(HttpResponseSubstitutionCallback callback, IIS7WorkerRequest iis7WorkerRequest)
        {
            if (this._charBufferLength != this._charBufferFree)
            {
                this.FlushCharBuffer(true);
            }
            this._lastBuffer = null;
            IHttpResponseElement element = new HttpSubstBlockResponseElement(callback, this.Encoding, this.Encoder, iis7WorkerRequest);

            this._buffers.Add(element);
            if (iis7WorkerRequest != null)
            {
                this.SubstElements.Add(element);
            }
            if (!this._responseBufferingOn)
            {
                this._response.Flush();
            }
        }
 private void BufferData(byte[] data, int offset, int size, bool needToCopyData)
 {
     int num;
     if (this._lastBuffer != null)
     {
         num = this._lastBuffer.Append(data, offset, size);
         size -= num;
         offset += num;
     }
     else if ((!needToCopyData && (offset == 0)) && !this._responseBufferingOn)
     {
         this._buffers.Add(new HttpResponseBufferElement(data, size));
         return;
     }
     while (size > 0)
     {
         this._lastBuffer = this.CreateNewMemoryBufferElement();
         this._buffers.Add(this._lastBuffer);
         num = this._lastBuffer.Append(data, offset, size);
         offset += num;
         size -= num;
     }
 }
Example #18
0
        private void BufferData(byte[] data, int offset, int size, bool needToCopyData)
        {
            int num;

            if (this._lastBuffer != null)
            {
                num     = this._lastBuffer.Append(data, offset, size);
                size   -= num;
                offset += num;
            }
            else if ((!needToCopyData && (offset == 0)) && !this._responseBufferingOn)
            {
                this._buffers.Add(new HttpResponseBufferElement(data, size));
                return;
            }
            while (size > 0)
            {
                this._lastBuffer = this.CreateNewMemoryBufferElement();
                this._buffers.Add(this._lastBuffer);
                num     = this._lastBuffer.Append(data, offset, size);
                offset += num;
                size   -= num;
            }
        }
 internal void WriteFile(string filename, long offset, long size)
 {
     if (this._charBufferLength != this._charBufferFree)
     {
         this.FlushCharBuffer(true);
     }
     this._lastBuffer = null;
     this._buffers.Add(new HttpFileResponseElement(filename, offset, size));
     if (!this._responseBufferingOn)
     {
         this._response.Flush();
     }
 }
        private void FlushCharBuffer(bool flushEncoder) {
            int numChars = _charBufferLength - _charBufferFree;

            Debug.Assert(numChars > 0);

            // remember that response required encoding (to indicate the charset= is needed)
            if (!_responseEncodingUpdated) {
                UpdateResponseEncoding();
            }

            _responseEncodingUsed = true;

            // estimate conversion size
            int estByteSize = _responseEncoding.GetMaxByteCount(numChars);

            if (estByteSize <= BufferingParams.MAX_BYTES_TO_COPY || !_responseBufferingOn) {
                // small size -- allocate intermediate buffer and copy into the output buffer
                byte[] byteBuffer = new byte[estByteSize];
                int realByteSize = _responseEncoder.GetBytes(_charBuffer, 0, numChars,
                                                             byteBuffer, 0, flushEncoder);
                BufferData(byteBuffer, 0, realByteSize, false);
            }
            else {
                // convert right into the output buffer

                int free = (_lastBuffer != null) ? _lastBuffer.FreeBytes : 0;

                if (free < estByteSize) {
                    // need new buffer -- last one doesn't have enough space
                    _lastBuffer = CreateNewMemoryBufferElement();
                    _buffers.Add(_lastBuffer);
                    free = _lastBuffer.FreeBytes;
                }

                // byte buffers must be long enough to keep everything in char buffer
                Debug.Assert(free >= estByteSize);
                _lastBuffer.AppendEncodedChars(_charBuffer, 0, numChars, _responseEncoder, flushEncoder);
            }

            _charBufferFree = _charBufferLength;
        }
        private void BufferResource(IntPtr data, int offset, int size) {
            if (size > BufferingParams.MAX_RESOURCE_BYTES_TO_COPY || !_responseBufferingOn) {
                // for long response strings create its own buffer element to avoid copy cost
                // also, when not buffering, no need for an extra copy (nothing will get accumulated anyway)
                _lastBuffer = null;
                _buffers.Add(new HttpResourceResponseElement(data, offset, size));
                return;
            }

            int n;

            // try last buffer
            if (_lastBuffer != null) {
                n = _lastBuffer.Append(data, offset, size);
                size -= n;
                offset += n;
            }

            // do other buffers if needed
            while (size > 0) {
                _lastBuffer = CreateNewMemoryBufferElement();
                _buffers.Add(_lastBuffer);
                n = _lastBuffer.Append(data, offset, size);
                offset += n;
                size -= n;
            }
        }
 private void FlushCharBuffer(bool flushEncoder)
 {
     int charCount = this._charBufferLength - this._charBufferFree;
     if (!this._responseEncodingUpdated)
     {
         this.UpdateResponseEncoding();
     }
     this._responseEncodingUsed = true;
     int maxByteCount = this._responseEncoding.GetMaxByteCount(charCount);
     if ((maxByteCount <= 0x80) || !this._responseBufferingOn)
     {
         byte[] bytes = new byte[maxByteCount];
         int size = this._responseEncoder.GetBytes(this._charBuffer, 0, charCount, bytes, 0, flushEncoder);
         this.BufferData(bytes, 0, size, false);
     }
     else
     {
         int freeBytes = (this._lastBuffer != null) ? this._lastBuffer.FreeBytes : 0;
         if (freeBytes < maxByteCount)
         {
             this._lastBuffer = this.CreateNewMemoryBufferElement();
             this._buffers.Add(this._lastBuffer);
             freeBytes = this._lastBuffer.FreeBytes;
         }
         this._lastBuffer.AppendEncodedChars(this._charBuffer, 0, charCount, this._responseEncoder, flushEncoder);
     }
     this._charBufferFree = this._charBufferLength;
 }
 internal ArrayList GetSnapshot(out bool hasSubstBlocks)
 {
     if (this._charBufferLength != this._charBufferFree)
     {
         this.FlushCharBuffer(true);
     }
     this._lastBuffer = null;
     hasSubstBlocks = false;
     ArrayList list = new ArrayList();
     int count = this._buffers.Count;
     for (int i = 0; i < count; i++)
     {
         object obj2 = this._buffers[i];
         HttpBaseMemoryResponseBufferElement element = obj2 as HttpBaseMemoryResponseBufferElement;
         if (element != null)
         {
             if (element.FreeBytes > 0x1000)
             {
                 obj2 = element.Clone();
             }
             else
             {
                 element.DisableRecycling();
             }
         }
         else if (obj2 is HttpSubstBlockResponseElement)
         {
             hasSubstBlocks = true;
         }
         list.Add(obj2);
     }
     return list;
 }
        //
        //  Snapshot for caching
        //        

        internal ArrayList GetSnapshot(out bool hasSubstBlocks) {
            if (_charBufferLength != _charBufferFree)
                FlushCharBuffer(true);

            _lastBuffer = null; // to make sure nothing gets appended after

            hasSubstBlocks = false;

            ArrayList buffers = new ArrayList();

            // copy buffer references to the returned list, make non-recyclable
            int n = _buffers.Count;
            for (int i = 0; i < n; i++) {
                Object responseElement = _buffers[i];

                HttpBaseMemoryResponseBufferElement buffer = responseElement as HttpBaseMemoryResponseBufferElement;

                if (buffer != null) {
                    if (buffer.FreeBytes > BufferingParams.MAX_FREE_BYTES_TO_CACHE) {
                        // copy data if too much is free
                        responseElement = buffer.Clone();
                    }
                    else {
                        // cache the buffer as is with free bytes
                        buffer.DisableRecycling();
                    }
                }
                else if (responseElement is HttpSubstBlockResponseElement) {
                    hasSubstBlocks = true;
                }

                buffers.Add(responseElement);
            }
            return buffers;
        }
 internal void FilterIntegrated(bool finalFiltering, IIS7WorkerRequest wr)
 {
     if (this._installedFilter != null)
     {
         if (this._charBufferLength != this._charBufferFree)
         {
             this.FlushCharBuffer(true);
         }
         this._lastBuffer = null;
         ArrayList list = this._buffers;
         this._buffers = new ArrayList();
         ArrayList list2 = null;
         bool hasSubstBlocks = false;
         list2 = wr.GetBufferedResponseChunks(false, null, ref hasSubstBlocks);
         this._filterSink.Filtering = true;
         try
         {
             if (list2 != null)
             {
                 for (int i = 0; i < list2.Count; i++)
                 {
                     IHttpResponseElement element = (IHttpResponseElement) list2[i];
                     long size = element.GetSize();
                     if (size > 0L)
                     {
                         this._installedFilter.Write(element.GetBytes(), 0, Convert.ToInt32(size));
                     }
                 }
                 wr.ClearResponse(true, false);
             }
             if (list != null)
             {
                 for (int j = 0; j < list.Count; j++)
                 {
                     IHttpResponseElement element2 = (IHttpResponseElement) list[j];
                     long num4 = element2.GetSize();
                     if (num4 > 0L)
                     {
                         this._installedFilter.Write(element2.GetBytes(), 0, Convert.ToInt32(num4));
                     }
                 }
             }
             this._installedFilter.Flush();
         }
         finally
         {
             try
             {
                 if (finalFiltering)
                 {
                     this._installedFilter.Close();
                 }
             }
             finally
             {
                 this._filterSink.Filtering = false;
             }
         }
     }
 }
        // Gets the response buffer count after flushing the char buffer.  Note that _lastBuffer is cleared,
        // and therefore may not be filled, so calling this can lead to inefficient use of response buffers.
        internal int GetResponseBufferCountAfterFlush() {
            if (_charBufferLength != _charBufferFree) {
                FlushCharBuffer(true);
            }

            // set _lastBuffer to null to prevent more data from being added to it
            _lastBuffer = null;

            return _buffers.Count;
        }
        //
        // Support for substitution blocks
        //

        internal void WriteSubstBlock(HttpResponseSubstitutionCallback callback, IIS7WorkerRequest iis7WorkerRequest) {
            if (_charBufferLength != _charBufferFree)
                FlushCharBuffer(true);
            _lastBuffer = null;

            // add new substitution block to the buffer list
            IHttpResponseElement element = new HttpSubstBlockResponseElement(callback, Encoding, Encoder, iis7WorkerRequest);
            _buffers.Add(element);

            if (iis7WorkerRequest != null) {
                SubstElements.Add(element);
            }

            if (!_responseBufferingOn)
                _response.Flush();
        }
        internal void WriteFile(String filename, long offset, long size) {
            if (_charBufferLength != _charBufferFree)
                FlushCharBuffer(true);

            _lastBuffer = null;
            _buffers.Add(new HttpFileResponseElement(filename, offset, size));

            if (!_responseBufferingOn)
                _response.Flush();
        }
 internal void TransmitFile(string filename, long offset, long size, bool isImpersonating, bool supportsLongTransmitFile) {
     if (_charBufferLength != _charBufferFree)
         FlushCharBuffer(true);
     
     _lastBuffer = null;
     _buffers.Add(new HttpFileResponseElement(filename, offset, size, isImpersonating, supportsLongTransmitFile));
     
     if (!_responseBufferingOn)
         _response.Flush();
 }
 internal void MoveResponseBufferRangeForward(int srcIndex, int srcCount, int dstIndex)
 {
     if (srcCount > 0)
     {
         object[] array = new object[srcIndex - dstIndex];
         this._buffers.CopyTo(dstIndex, array, 0, array.Length);
         for (int i = 0; i < srcCount; i++)
         {
             this._buffers[dstIndex + i] = this._buffers[srcIndex + i];
         }
         for (int j = 0; j < array.Length; j++)
         {
             this._buffers[(dstIndex + srcCount) + j] = array[j];
         }
     }
     HttpBaseMemoryResponseBufferElement element = this._buffers[this._buffers.Count - 1] as HttpBaseMemoryResponseBufferElement;
     if ((element != null) && (element.FreeBytes > 0))
     {
         this._lastBuffer = element;
     }
     else
     {
         this._lastBuffer = null;
     }
 }
Example #31
0
        internal HttpWriter(HttpResponse response): base(null) {
            _response = response;
            _stream = new HttpResponseStream(this);

            _buffers = new ArrayList();
            _lastBuffer = null;

            // Setup the buffer on demand using CharBuffer property
            _charBuffer = null;
            _charBufferLength = 0;
            _charBufferFree = 0;

            UpdateResponseBuffering();
            
            // delay getting response encoding until it is really needed
            // UpdateResponseEncoding();
        }
 internal int GetResponseBufferCountAfterFlush()
 {
     if (this._charBufferLength != this._charBufferFree)
     {
         this.FlushCharBuffer(true);
     }
     this._lastBuffer = null;
     return this._buffers.Count;
 }
 internal void ClearBuffers()
 {
     this.ClearCharBuffer();
     if (this._substElements != null)
     {
         this._response.Context.Request.SetDynamicCompression(true);
     }
     this.RecycleBufferElements();
     this._buffers = new ArrayList();
     this._lastBuffer = null;
     this._hasBeenClearedRecently = true;
 }
        internal void Filter(bool finalFiltering) {
            // no filter?
            if (_installedFilter == null)
                return;

            // flush char buffer and remember old buffers
            if (_charBufferLength != _charBufferFree)
                FlushCharBuffer(true);

            _lastBuffer = null;

            // no content to filter
            // Allow the filter to be closed (Dev10 Bug 550168).
            if (_buffers.Count == 0 && !finalFiltering)
                return;

            // remember old buffers
            ArrayList oldBuffers = _buffers;
            _buffers = new ArrayList();

            // push old buffer list through the filter

            Debug.Assert(_filterSink != null);

            _filterSink.Filtering = true;

            try {
                int n = oldBuffers.Count;
                for (int i = 0; i < n; i++) {
                    IHttpResponseElement buf = (IHttpResponseElement)oldBuffers[i];

                    long len = buf.GetSize();

                    if (len > 0) {
                        // Convert.ToInt32 will throw for sizes larger than Int32.MaxValue.
                        // Filtering large response sizes is not supported
                        _installedFilter.Write(buf.GetBytes(), 0, Convert.ToInt32(len));
                    }
                }

                _installedFilter.Flush();

            }
            finally {
                try {
                    if (finalFiltering)
                        _installedFilter.Close();
                }
                finally {
                    _filterSink.Filtering = false;
                }
            }
        }
        private void BufferData(byte[] data, int offset, int size, bool needToCopyData) {
            int n;

            // try last buffer
            if (_lastBuffer != null) {
                n = _lastBuffer.Append(data, offset, size);
                size -= n;
                offset += n;
            }
            else if (!needToCopyData && offset == 0 && !_responseBufferingOn) {
                // when not buffering, there is no need for big buffer accumulating multiple writes
                // the byte[] data can be sent as is

                _buffers.Add(new HttpResponseBufferElement(data, size));
                return;
            }

            // do other buffers if needed
            while (size > 0) {
                _lastBuffer = CreateNewMemoryBufferElement();
                _buffers.Add(_lastBuffer);
                n = _lastBuffer.Append(data, offset, size);
                offset += n;
                size -= n;
            }
        }
        internal void FilterIntegrated(bool finalFiltering, IIS7WorkerRequest wr) {
            // no filter?
            if (_installedFilter == null)
                return;

            // flush char buffer and remember old buffers
            if (_charBufferLength != _charBufferFree)
                FlushCharBuffer(true);

            _lastBuffer = null;

            // ISAPI mode bails if it has no buffers
            // to filter, in integrated mode we need
            // to check the unified response buffers
            // maintained by IIS for content, as well

            // remember current buffers (if any) that might be
            // response entity from this transition 
            // (not yet pushed through to IIS response buffers)
            ArrayList oldBuffers = _buffers;
            _buffers = new ArrayList();
            
            // now, get what's in the IIS buffers
            ArrayList nativeBuffers = null;            
            bool fDummy = false;
            nativeBuffers = wr.GetBufferedResponseChunks(false, null, ref fDummy);
            
            Debug.Assert(_filterSink != null);
            _filterSink.Filtering = true;
           
            try {
                // push buffers through installed filters
                // push the IIS ones through first since we need to maintain order
                if (null != nativeBuffers) {
                    for (int i = 0; i < nativeBuffers.Count; i++) {
                        IHttpResponseElement buf = (IHttpResponseElement)nativeBuffers[i];

                        long len = buf.GetSize();

                        if (len > 0)
                            _installedFilter.Write(buf.GetBytes(), 0, Convert.ToInt32(len));

                    }

                    // if we had stuff there, we now need to clear it since we may have
                    // transformed it
                    wr.ClearResponse(true /* entity */, false /* headers */);
                }

                // current buffers, if any
                if (null != oldBuffers) {
                    for (int i = 0; i < oldBuffers.Count; i++) {
                        IHttpResponseElement buf = (IHttpResponseElement)oldBuffers[i];

                        long len = buf.GetSize();

                        if (len > 0)
                            _installedFilter.Write(buf.GetBytes(), 0, Convert.ToInt32(len));

                    }
                }

                _installedFilter.Flush();
            }
            finally {
                try {
                    if (finalFiltering)
                        _installedFilter.Close();
                }
                finally {
                    _filterSink.Filtering = false;
                }
            }
        }
        internal HttpWriter(HttpResponse response): base(null) {
            _response = response;
            _stream = new HttpResponseStream(this);

            _buffers = new ArrayList();
            _lastBuffer = null;

            _charBuffer = (char[])s_Allocator.GetBuffer();
            _charBufferLength = _charBuffer.Length;
            _charBufferFree = _charBufferLength;

            UpdateResponseBuffering();
            
            // delay getting response encoding until it is really needed
            // UpdateResponseEncoding();
        }
        // Move the specified range of buffers forward in the buffer list.
        internal void MoveResponseBufferRangeForward(int srcIndex, int srcCount, int dstIndex) {
            Debug.Assert(dstIndex <= srcIndex);

            // DevDiv Bugs 154630: No need to copy the form between temporary array and the buffer list when
            // no hidden fields are written.
            if (srcCount > 0) {
                // create temporary storage for buffers that will be moved backwards
                object[] temp = new object[srcIndex - dstIndex];

                // copy buffers that will be moved backwards
                _buffers.CopyTo(dstIndex, temp, 0, temp.Length);

                // move the range forward from srcIndex to dstIndex
                for (int i = 0; i < srcCount; i++) {
                    _buffers[dstIndex + i] = _buffers[srcIndex + i];
                }

                // insert buffers that were placed in temporary storage
                for (int i = 0; i < temp.Length; i++) {
                    _buffers[dstIndex + srcCount + i] = temp[i];
                }
            }

            // set _lastBuffer
            HttpBaseMemoryResponseBufferElement buf = _buffers[_buffers.Count-1] as HttpBaseMemoryResponseBufferElement;
            if (buf != null && buf.FreeBytes > 0) {
                _lastBuffer = buf;
            }
            else {
                _lastBuffer = null;
            }
        }
 internal void WriteSubstBlock(HttpResponseSubstitutionCallback callback, IIS7WorkerRequest iis7WorkerRequest)
 {
     if (this._charBufferLength != this._charBufferFree)
     {
         this.FlushCharBuffer(true);
     }
     this._lastBuffer = null;
     IHttpResponseElement element = new HttpSubstBlockResponseElement(callback, this.Encoding, this.Encoder, iis7WorkerRequest);
     this._buffers.Add(element);
     if (iis7WorkerRequest != null)
     {
         this.SubstElements.Add(element);
     }
     if (!this._responseBufferingOn)
     {
         this._response.Flush();
     }
 }
        //
        // Buffer management
        //

        internal void ClearBuffers() {
            ClearCharBuffer();

            // re-enable dynamic compression if we are about to clear substitution blocks
            if (_substElements != null) {
                _response.Context.Request.SetDynamicCompression(true /*enable*/);
            }

            //VSWhidbey 559434: Private Bytes goes thru roof because unmanaged buffers are not recycled when Response.Flush is called
            RecycleBufferElements();

            _buffers = new ArrayList();
            _lastBuffer = null;
            _hasBeenClearedRecently = true;
        }
 internal void Filter(bool finalFiltering)
 {
     if (this._installedFilter != null)
     {
         if (this._charBufferLength != this._charBufferFree)
         {
             this.FlushCharBuffer(true);
         }
         this._lastBuffer = null;
         if ((this._buffers.Count != 0) || finalFiltering)
         {
             ArrayList list = this._buffers;
             this._buffers = new ArrayList();
             this._filterSink.Filtering = true;
             try
             {
                 int count = list.Count;
                 for (int i = 0; i < count; i++)
                 {
                     IHttpResponseElement element = (IHttpResponseElement) list[i];
                     long size = element.GetSize();
                     if (size > 0L)
                     {
                         this._installedFilter.Write(element.GetBytes(), 0, Convert.ToInt32(size));
                     }
                 }
                 this._installedFilter.Flush();
             }
             finally
             {
                 try
                 {
                     if (finalFiltering)
                     {
                         this._installedFilter.Close();
                     }
                 }
                 finally
                 {
                     this._filterSink.Filtering = false;
                 }
             }
         }
     }
 }