/// <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; } }