_FixedSizeReader.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / Net / System / Net / SecureProtocols / _FixedSizeReader.cs / 1305376 / _FixedSizeReader.cs

                            /*++ 
Copyright (c) 2000 Microsoft Corporation

Module Name:
 
    _FixedSizeReader.cs
 
Abstract: 
    The class is a simple wrapper on top of a read stream.
    It will read the exact number of bytes requested. 
    It operates either [....] or async.

Author:
 
    Alexei Vopilov  Aug 18 2003
 
Revision History: 

--*/ 

namespace System.Net {
    using System;
    using System.IO; 
    using System.Threading;
 
 
    //
    // Reads a fixed size packet from a stream, can disover EOF as 0 bytes read from stream 
    //
    internal class FixedSizeReader {
        private static readonly AsyncCallback _ReadCallback  = new AsyncCallback(ReadCallback);
 
        private readonly Stream      _Transport;
        private AsyncProtocolRequest _Request; 
        private int                  _TotalRead; 

        public FixedSizeReader(Stream transport) 
        {
            _Transport = transport;
        }
 
        //
        // Returns 0 on legitimate EOF or if 0 bytes was requested, otheriwse reads as directed or throws 
        // Returns count on success 
        //
        public int ReadPacket(byte[] buffer, int offset, int count) 
        {
            int tempCount = count;
            do {
                int bytes = _Transport.Read(buffer, offset, tempCount); 

                if (bytes == 0) 
                { 
                     if (tempCount != count)
                     { 
                         throw new IOException(SR.GetString(SR.net_io_eof));
                     }
                     return 0;
                } 

                tempCount -= bytes; 
                offset += bytes; 
            }while (tempCount != 0);
 
            return count;
        }

        // 
        // Completes "_Request" with 0 if 0 bytes was requested or legitimate EOF received
        // Otheriwse, reads as directed or completes "_Request" with an Exception or throws right here 
        // 
        public void AsyncReadPacket(AsyncProtocolRequest request)
        { 
            _Request = request;
            _TotalRead = 0;
            StartReading();
        } 
        //
        // Loops while subsequest completions are [....] 
        // 
        private void StartReading()
        { 
            while (true)
            {
                IAsyncResult ar = _Transport.BeginRead(_Request.Buffer, _Request.Offset+_TotalRead, _Request.Count-_TotalRead, _ReadCallback, this);
                if (!ar.CompletedSynchronously) 
                {
#if DEBUG 
                    _Request._DebugAsyncChain = ar; 
#endif
                    break; 
                }

                int bytes = _Transport.EndRead(ar);
 
                if (CheckCompletionBeforeNextRead(bytes))
                { 
                    break; 
                }
            } 
        }

        //
        // 
        //
        private bool CheckCompletionBeforeNextRead(int bytes) 
        { 
            if (bytes == 0)
            { 
                // 0 bytes was requested or EOF in the beginning of a frame, the caller should decide whether it's OK
                if(_TotalRead == 0)
                {
                    _Request.CompleteRequest(0); 
                    return true;
                } 
                // EOF in the middle of a frame, bummer! 
                throw new IOException(SR.GetString(SR.net_io_eof));
            } 

            GlobalLog.Assert(_TotalRead + bytes <= _Request.Count, "FixedSizeReader::CheckCompletion()|State got out of range. Total:{0} Count:{1}", _TotalRead + bytes, _Request.Count);

            if ((_TotalRead+=bytes) == _Request.Count) 
            {
                _Request.CompleteRequest(_Request.Count); 
                return true; 
            }
            return false; 
        }


        // 
        //
        // 
        private static void ReadCallback(IAsyncResult transportResult) 
        {
            GlobalLog.Assert(transportResult.AsyncState is FixedSizeReader, "ReadCallback|State type is wrong, expected FixedSizeReader."); 
            if (transportResult.CompletedSynchronously)
            {
                return;
            } 

            FixedSizeReader reader = (FixedSizeReader)transportResult.AsyncState; 
            AsyncProtocolRequest request = reader._Request; 

            // Async completion 
            try
            {
                int bytes = reader._Transport.EndRead(transportResult);
 
                if (reader.CheckCompletionBeforeNextRead(bytes))
                { 
                    return; 
                }
                reader.StartReading(); 
            }
            catch (Exception e)
            {
                if (request.IsUserCompleted) 
                    throw;
                request.CompleteWithError(e); 
            } 
        }
    } 

}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
/*++ 
Copyright (c) 2000 Microsoft Corporation

Module Name:
 
    _FixedSizeReader.cs
 
Abstract: 
    The class is a simple wrapper on top of a read stream.
    It will read the exact number of bytes requested. 
    It operates either [....] or async.

Author:
 
    Alexei Vopilov  Aug 18 2003
 
Revision History: 

--*/ 

namespace System.Net {
    using System;
    using System.IO; 
    using System.Threading;
 
 
    //
    // Reads a fixed size packet from a stream, can disover EOF as 0 bytes read from stream 
    //
    internal class FixedSizeReader {
        private static readonly AsyncCallback _ReadCallback  = new AsyncCallback(ReadCallback);
 
        private readonly Stream      _Transport;
        private AsyncProtocolRequest _Request; 
        private int                  _TotalRead; 

        public FixedSizeReader(Stream transport) 
        {
            _Transport = transport;
        }
 
        //
        // Returns 0 on legitimate EOF or if 0 bytes was requested, otheriwse reads as directed or throws 
        // Returns count on success 
        //
        public int ReadPacket(byte[] buffer, int offset, int count) 
        {
            int tempCount = count;
            do {
                int bytes = _Transport.Read(buffer, offset, tempCount); 

                if (bytes == 0) 
                { 
                     if (tempCount != count)
                     { 
                         throw new IOException(SR.GetString(SR.net_io_eof));
                     }
                     return 0;
                } 

                tempCount -= bytes; 
                offset += bytes; 
            }while (tempCount != 0);
 
            return count;
        }

        // 
        // Completes "_Request" with 0 if 0 bytes was requested or legitimate EOF received
        // Otheriwse, reads as directed or completes "_Request" with an Exception or throws right here 
        // 
        public void AsyncReadPacket(AsyncProtocolRequest request)
        { 
            _Request = request;
            _TotalRead = 0;
            StartReading();
        } 
        //
        // Loops while subsequest completions are [....] 
        // 
        private void StartReading()
        { 
            while (true)
            {
                IAsyncResult ar = _Transport.BeginRead(_Request.Buffer, _Request.Offset+_TotalRead, _Request.Count-_TotalRead, _ReadCallback, this);
                if (!ar.CompletedSynchronously) 
                {
#if DEBUG 
                    _Request._DebugAsyncChain = ar; 
#endif
                    break; 
                }

                int bytes = _Transport.EndRead(ar);
 
                if (CheckCompletionBeforeNextRead(bytes))
                { 
                    break; 
                }
            } 
        }

        //
        // 
        //
        private bool CheckCompletionBeforeNextRead(int bytes) 
        { 
            if (bytes == 0)
            { 
                // 0 bytes was requested or EOF in the beginning of a frame, the caller should decide whether it's OK
                if(_TotalRead == 0)
                {
                    _Request.CompleteRequest(0); 
                    return true;
                } 
                // EOF in the middle of a frame, bummer! 
                throw new IOException(SR.GetString(SR.net_io_eof));
            } 

            GlobalLog.Assert(_TotalRead + bytes <= _Request.Count, "FixedSizeReader::CheckCompletion()|State got out of range. Total:{0} Count:{1}", _TotalRead + bytes, _Request.Count);

            if ((_TotalRead+=bytes) == _Request.Count) 
            {
                _Request.CompleteRequest(_Request.Count); 
                return true; 
            }
            return false; 
        }


        // 
        //
        // 
        private static void ReadCallback(IAsyncResult transportResult) 
        {
            GlobalLog.Assert(transportResult.AsyncState is FixedSizeReader, "ReadCallback|State type is wrong, expected FixedSizeReader."); 
            if (transportResult.CompletedSynchronously)
            {
                return;
            } 

            FixedSizeReader reader = (FixedSizeReader)transportResult.AsyncState; 
            AsyncProtocolRequest request = reader._Request; 

            // Async completion 
            try
            {
                int bytes = reader._Transport.EndRead(transportResult);
 
                if (reader.CheckCompletionBeforeNextRead(bytes))
                { 
                    return; 
                }
                reader.StartReading(); 
            }
            catch (Exception e)
            {
                if (request.IsUserCompleted) 
                    throw;
                request.CompleteWithError(e); 
            } 
        }
    } 

}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK