Example #1
0
        /// <summary>
        /// Begins line reading.
        /// </summary>
        /// <param name="op">Read line opeartion.</param>
        /// <param name="async">If true then this method can complete asynchronously. If false, this method completed always syncronously.</param>
        /// <returns>Returns true if read line completed synchronously, false if asynchronous operation pending.</returns>
        /// <exception cref="ArgumentNullException">Is raised when <b>op</b> is null reference.</exception>
        public bool ReadLine(ReadLineAsyncOP op, bool async)
        {
            if (op == null)
            {
                throw new ArgumentNullException("op");
            }

            if (!op.Start(async, this))
            {
                /* REMOVE ME:
                if(!async){
                    // Wait while async operation completes.
                    while(!op.IsCompleted){
                        Thread.Sleep(1);
                    }

                    return true;
                }
                else{
                    return false;
                }*/

                return false;
            }
                // Completed synchronously.
            else
            {
                return true;
            }
        }
Example #2
0
        /// <summary>
        /// Reads all data from the source <b>stream</b> and writes it to stream. Period handling and period terminator is added as required.
        /// </summary>
        /// <param name="stream">Source stream which data to write to stream.</param>
        /// <returns>Returns number of bytes written to source stream.</returns>
        /// <exception cref="ObjectDisposedException">Is raised when this object is disposed and this method is accessed.</exception>
        /// <exception cref="ArgumentNullException">Is raised when <b>stream</b> is null.</exception>
        /// <exception cref="LineSizeExceededException">Is raised when <b>stream</b> has too big line.</exception>        
        public long WritePeriodTerminated(Stream stream)
        {
            if (m_IsDisposed)
            {
                throw new ObjectDisposedException(GetType().Name);
            }
            if (stream == null)
            {
                throw new ArgumentNullException("stream");
            }

            // We need to read lines, do period handling and write them to stream.
            long totalWritten = 0;
            byte[] buffer = new byte[m_BufferSize];
            ReadLineAsyncOP readLineOP = new ReadLineAsyncOP(buffer, SizeExceededAction.ThrowException);
            SmartStream reader = new SmartStream(stream, false);
            while (true)
            {
                reader.ReadLine(readLineOP, false);
                if (readLineOP.Error != null)
                {
                    throw readLineOP.Error;
                }
                // We reached end of stream, no more data.
                if (readLineOP.BytesInBuffer == 0)
                {
                    break;
                }

                // Period handling. If line starts with period(.), additional period is added.
                if (readLineOP.LineBytesInBuffer > 0 && buffer[0] == '.')
                {
                    // Add additional period.
                    Write(new[] {(byte) '.'}, 0, 1);
                    totalWritten++;
                }

                // Write line to source stream.
                Write(buffer, 0, readLineOP.BytesInBuffer);
                totalWritten += readLineOP.BytesInBuffer;
            }

            // Write period terminator.
            WriteLine(".");

            Flush();

            return totalWritten;
        }
Example #3
0
            /// <summary>
            /// Default constructor.
            /// </summary>
            /// <param name="stream">Stream wehre to sore readed data.</param>
            /// <param name="maxCount">Maximum number of bytes to read. Value 0 means not limited.</param>
            /// <param name="exceededAction">Specifies how period-terminated reader behaves when <b>maxCount</b> exceeded.</param>
            /// <exception cref="ArgumentNullException">Is raised when <b>stream</b> is null reference.</exception>
            public ReadPeriodTerminatedAsyncOP(Stream stream, long maxCount, SizeExceededAction exceededAction)
            {
                if (stream == null)
                {
                    throw new ArgumentNullException("stream");
                }

                m_pStream = stream;
                m_MaxCount = maxCount;
                m_ExceededAction = exceededAction;

                m_pReadLineOP = new ReadLineAsyncOP(new byte[Workaround.Definitions.MaxStreamLineLength], exceededAction);
                m_pReadLineOP.Completed += m_pReadLineOP_Completed;
            }
Example #4
0
            /// <summary>
            /// Cleans up any resources being used.
            /// </summary>
            public void Dispose()
            {
                if (m_IsDisposed)
                {
                    return;
                }
                m_IsDisposed = true;

                m_pOwner = null;
                m_pStream = null;
                m_pReadLineOP.Dispose();
                m_pReadLineOP = null;
                m_pException = null;
                Completed = null;
            }
            /// <summary>
            /// Default constructor.
            /// </summary>
            /// <param name="stream">Stream wehre to sore readed data.</param>
            /// <param name="maxCount">Maximum number of bytes to read. Value 0 means not limited.</param>
            /// <param name="exceededAction">Specifies how period-terminated reader behaves when <b>maxCount</b> exceeded.</param>
            /// <exception cref="ArgumentNullException">Is raised when <b>stream</b> is null reference.</exception>
            public ReadPeriodTerminatedAsyncOP(Stream stream,long maxCount,SizeExceededAction exceededAction)
            {
                if(stream == null){
                    throw new ArgumentNullException("stream");
                }

                m_pStream        = stream;
                m_MaxCount       = maxCount;
                m_ExceededAction = exceededAction;

                m_pReadLineOP = new ReadLineAsyncOP(new byte[32000],exceededAction);
                m_pReadLineOP.Completed += new EventHandler<EventArgs<ReadLineAsyncOP>>(m_pReadLineOP_Completed);
            }
            /// <summary>
            /// Is called when source stream read line reading has completed.
            /// </summary>
            /// <param name="op">Asynchronous operation.</param>
            private void ReadLineCompleted(ReadLineAsyncOP op)
            {
                try{
                    if(op.Error != null){
                        m_pException = op.Error;
                        SetState(AsyncOP_State.Completed);
                    }
                    else{
                        // We have readed all source stream data, we are done.
                        if(op.BytesInBuffer == 0){
                            // Line ends CRLF.
                            if(m_EndsCRLF){
                                m_BytesWritten += 3;
                                m_pOwner.BeginWrite(new byte[]{(byte)'.',(byte)'\r',(byte)'\n'},0,3,this.SendTerminatorCompleted,null);
                            }
                            // Line doesn't end CRLF, we need to add it.
                            else{
                                m_BytesWritten += 5;
                                m_pOwner.BeginWrite(new byte[]{(byte)'\r',(byte)'\n',(byte)'.',(byte)'\r',(byte)'\n'},0,5,this.SendTerminatorCompleted,null);
                            }

                            op.Dispose();
                        }
                        // Write readed line.
                        else{
                            m_BytesWritten += op.BytesInBuffer;

                            // Check if line ends CRLF.
                            if(op.BytesInBuffer >= 2 && op.Buffer[op.BytesInBuffer - 2] == '\r' && op.Buffer[op.BytesInBuffer - 1] == '\n'){
                                m_EndsCRLF = true;
                            }
                            else{
                                m_EndsCRLF = false;
                            }

                            // Period handling. If line starts with period(.), additional period is added.
                            if(op.Buffer[0] == '.'){
                                byte[] buffer = new byte[op.BytesInBuffer + 1];
                                buffer[0] = (byte)'.';
                                Array.Copy(op.Buffer,0,buffer,1,op.BytesInBuffer);

                                m_pOwner.BeginWrite(buffer,0,buffer.Length,this.SendLineCompleted,null);
                            }
                            // Normal line.
                            else{
                                m_pOwner.BeginWrite(op.Buffer,0,op.BytesInBuffer,this.SendLineCompleted,null);
                            }
                        }
                    }
                }
                catch(Exception x){
                    m_pException = x;
                    SetState(AsyncOP_State.Completed);
                    op.Dispose();
                }
            }
            /// <summary>
            /// Starts operation processing.
            /// </summary>
            /// <param name="owner">Owner SmartStream.</param>
            /// <returns>Returns true if asynchronous operation in progress or false if operation completed synchronously.</returns>
            /// <exception cref="ArgumentNullException">Is raised when <b>owner</b> is null reference.</exception>
            internal bool Start(SmartStream owner)
            {
                if(owner == null){
                    throw new ArgumentNullException("owner");
                }

                m_pOwner = owner;

                SetState(AsyncOP_State.Active);

                try{
                    // Read line.
                    m_pReadLineOP = new ReadLineAsyncOP(new byte[32000],SizeExceededAction.ThrowException);
                    m_pReadLineOP.Completed += delegate(object s,EventArgs<ReadLineAsyncOP> e){
                        ReadLineCompleted(m_pReadLineOP);
                    };
                    if(m_pStream.ReadLine(m_pReadLineOP,true)){
                        ReadLineCompleted(m_pReadLineOP);
                    }
                }
                catch(Exception x){
                    m_pException = x;
                    SetState(AsyncOP_State.Completed);
                    m_pReadLineOP.Dispose();
                }

                // Set flag rise CompletedAsync event flag. The event is raised when async op completes.
                // If already completed sync, that flag has no effect.
                lock(m_pLock){
                    m_RiseCompleted = true;

                    return m_State == AsyncOP_State.Active;
                }
            }
            /// <summary>
            /// Cleans up any resources being used.
            /// </summary>
            public void Dispose()
            {
                if(m_State == AsyncOP_State.Disposed){
                    return;
                }
                SetState(AsyncOP_State.Disposed);
                
                m_pException  = null;
                m_pStream     = null;
                m_pOwner      = null;
                m_pReadLineOP = null;

                this.CompletedAsync = null;
            }
        /// <summary>
        /// Begins line reading.
        /// </summary>
        /// <param name="op">Read line opeartion.</param>
        /// <param name="async">If true then this method can complete asynchronously. If false, this method completed always syncronously.</param>
        /// <returns>Returns true if read line completed synchronously, false if asynchronous operation pending.</returns>
        /// <exception cref="ArgumentNullException">Is raised when <b>op</b> is null reference.</exception>
        public bool ReadLine(ReadLineAsyncOP op,bool async)
        {
            if(op == null){
                throw new ArgumentNullException("op");
            }

            #region async

            if(async){
                return op.Start(async,this);
            }

            #endregion

            #region sync

            else{
                byte[]             buffer         = op.Buffer;
                int                bytesInBuffer  = 0;
                int                lastByte       = -1;
                bool               CRLFLinesOnly  = true;
                int                lineBuffSize   = buffer.Length;
                SizeExceededAction exceededAction = op.SizeExceededAction;
                Exception          exception      = null;

                try{
                    while(true){                        
                        // Read buffer empty, buff next data block.
                        if(m_ReadBufferOffset >= m_ReadBufferCount){                        
                            this.BufferRead(false,null);
                        
                            // We reached end of stream, no more data.
                            if(m_ReadBufferCount == 0){                                    
                                break;
                            }                        
                        }

                        byte b = m_pReadBuffer[m_ReadBufferOffset++];
                        
                        // Line buffer full.
                        if(bytesInBuffer >= lineBuffSize){
                            if(exception == null){
                                exception = new LineSizeExceededException();
                            }

                            if(exceededAction == SizeExceededAction.ThrowException){                                
                                break;
                            }
                        }
                        // Store byte.
                        else{
                            buffer[bytesInBuffer++] = b;
                        }

                        // We have LF line.
                        if(b == '\n'){
                            if(!CRLFLinesOnly || CRLFLinesOnly && lastByte == '\r'){
                                break;
                            }
                        }

                        lastByte = b;
                    }
                }
                catch(Exception x){
                    exception = x;
                }

                // Set read line operation result data.
                op.SetInfo(bytesInBuffer,exception);

                return true;
            }

            #endregion
        }