System.Net.ConnectStream.ReadChunkedCallback C# (CSharp) Method

ReadChunkedCallback() private static method

private static ReadChunkedCallback ( object state ) : void
state object
return void
        private static void ReadChunkedCallback(object state) {
#if DEBUG
            GlobalLog.SetThreadSource(ThreadKinds.Worker);
            using (GlobalLog.SetThreadKind(ThreadKinds.System | ThreadKinds.Sync)) {
#endif

// ********** WARNING - updating logic below should also be updated in ReadChunkedSync *****************

            NestedSingleAsyncResult castedAsyncResult = state as NestedSingleAsyncResult;
            ConnectStream thisConnectStream = castedAsyncResult.AsyncObject as ConnectStream;

            GlobalLog.Enter("ConnectStream#" + ValidationHelper.HashString(thisConnectStream) + "::ReadChunkedCallback", ValidationHelper.HashString(castedAsyncResult));

            try {
                if (!thisConnectStream.m_Draining && thisConnectStream.IsClosed) {
                    // throw on shutdown only if we're not draining the socket.
                    Exception exception =
                        new WebException(
                            NetRes.GetWebStatusString("net_requestaborted", WebExceptionStatus.ConnectionClosed),
                            WebExceptionStatus.ConnectionClosed);

                    castedAsyncResult.InvokeCallback(exception);
                    GlobalLog.LeaveException("ReadChunkedCallback", exception);
                    return;
                }
                else if (thisConnectStream.m_ErrorException!=null) {
                    // throw on IO error even if we're draining the socket.
                    castedAsyncResult.InvokeCallback(thisConnectStream.m_ErrorException);
                    GlobalLog.LeaveException("ReadChunkedCallback", thisConnectStream.m_ErrorException);
                    return;
                }
                if (thisConnectStream.m_ChunkedNeedCRLFRead) {
                    thisConnectStream.ReadCRLF(thisConnectStream.m_TempBuffer);
                    thisConnectStream.m_ChunkedNeedCRLFRead = false;
                }

                StreamChunkBytes ReadByteBuffer = new StreamChunkBytes(thisConnectStream);

                // We need to determine size of next chunk,
                // by carefully reading, byte by byte

                thisConnectStream.m_ChunkSize = thisConnectStream.ProcessReadChunkedSize(ReadByteBuffer);

                // If this isn't a zero length chunk, read it.
                if (thisConnectStream.m_ChunkSize != 0) {
                    thisConnectStream.m_ChunkedNeedCRLFRead = true;

                    int bytesToRead = Math.Min(castedAsyncResult.Size, thisConnectStream.m_ChunkSize);

                    //
                    // Attempt to fill in our entired read from,
                    //  data previously buffered, if this completely
                    //  satisfies us, then we are done, complete sync
                    //
                    int bytesAlreadyRead = 0;
                    if (thisConnectStream.m_ReadBufferSize > 0)
                    {
                        bytesAlreadyRead = thisConnectStream.FillFromBufferedData(castedAsyncResult.Buffer, ref castedAsyncResult.Offset, ref bytesToRead);
                        if (bytesToRead == 0)
                        {
                            castedAsyncResult.InvokeCallback(bytesAlreadyRead);
                            GlobalLog.Leave("ConnectStream::ReadChunkedCallback");
                            return;
                        }
                    }

                    //
                    // otherwise, we need to read more data from the connection.
                    //
                    if (thisConnectStream.ErrorInStream)
                    {
                        GlobalLog.LeaveException("ConnectStream::ReadChunkedCallback", thisConnectStream.m_ErrorException);
                        throw thisConnectStream.m_ErrorException;
                    }

                    GlobalLog.Assert(thisConnectStream.m_DoneCalled == 0 || thisConnectStream.m_ReadBytes != -1, "ConnectStream::ReadChunkedCallback|Calling BeginRead after ReadDone.");

                    // Keep track of this during the read so it can be added back at the end.
                    thisConnectStream.m_BytesAlreadyTransferred = bytesAlreadyRead;

                    IAsyncResult asyncResult = thisConnectStream.m_Connection.BeginRead(castedAsyncResult.Buffer, castedAsyncResult.Offset, bytesToRead, m_ReadCallbackDelegate, castedAsyncResult);

                    // a null return indicates that the connection was closed underneath us.
                    if (asyncResult == null)
                    {
                        thisConnectStream.m_BytesAlreadyTransferred = 0;
                        thisConnectStream.m_ErrorException = new WebException(
                            NetRes.GetWebStatusString("net_requestaborted", WebExceptionStatus.RequestCanceled),
                            WebExceptionStatus.RequestCanceled);

                        GlobalLog.LeaveException("ConnectStream::ReadChunkedCallback", thisConnectStream.m_ErrorException);
                        throw thisConnectStream.m_ErrorException;
                    }
                }
                else {
                    // We've found the terminating 0 length chunk. We may be very well looking
                    // at an extension footer or the very final CRLF.

                    thisConnectStream.ReadCRLF(thisConnectStream.m_TempBuffer);
                    thisConnectStream.RemoveTrailers(ReadByteBuffer);

                    // Remember that we've found this, so we don't try and dechunk
                    // more.

                    thisConnectStream.m_ReadBytes = 0;
                    thisConnectStream.m_ChunkEofRecvd = true;

                    thisConnectStream.CallDone();

                    // we're done reading, return 0 bytes
                    castedAsyncResult.InvokeCallback(0);
                }
                GlobalLog.Leave("ReadChunkedCallback");
            }
            catch (Exception exception)
            {
                if (NclUtilities.IsFatal(exception)) throw;

                castedAsyncResult.InvokeCallback(exception);
                GlobalLog.LeaveException("ConnectStream::ReadChunkedCallback", exception);
            }

// ********** WARNING - updating logic above should also be updated in ReadChunkedSync *****************
#if DEBUG
            }
#endif
        }