/// <summary> /// Is called when BeginWritePeriodTerminated stream.BeginReadLine has completed. /// </summary> /// <param name="e">Callback data.</param> private void InternalBeginWritePeriodTerminatedReadLineCompleted(ReadLine_EventArgs e) { try{ // Error happened during read. if(e.Exception != null){ InternalBeginWritePeriodTerminatedCompleted(e.Exception); } // We reached end of stream, no more data. else if(e.ReadedCount == 0){ InternalBeginWritePeriodTerminatedCompleted(null); } else{ m_BeginWritePeriodTerminated_Readed += e.ReadedCount; // Maximum allowed data size exceeded. if(m_BeginWritePeriodTerminated_Readed > m_BeginWritePeriodTerminated_MaxSize){ throw new DataSizeExceededException(); } // If line starts with period, addtional period is added. if(e.LineBuffer[0] == '.'){ m_pBeginWritePeriodTerminated_BufferedStream.WriteByte((int)'.'); m_BeginWritePeriodTerminated_Written++; } // Write readed line to buffered stream. m_pBeginWritePeriodTerminated_BufferedStream.Write(e.LineBuffer,0,e.Count); m_pBeginWritePeriodTerminated_BufferedStream.Write(m_LineBreak,0,m_LineBreak.Length); m_BeginWritePeriodTerminated_Written += e.Count + m_LineBreak.Length; } } catch(Exception x){ InternalBeginWritePeriodTerminatedCompleted(x); } }
/// <summary> /// Is called when asynchrounous line reading has completed. /// </summary> /// <param name="e">Callback data.</param> private void OnReadPeriodTerminated_ReadLine_Completed(ReadLine_EventArgs e) { try{ m_TotalReadedCount += e.ReadedCount; // We got error. if(e.Exception != null){ try{ m_pBufferedStream.Flush(); m_pStoreStream.Flush(); } catch{ // Just skip excpetions here, otherwise we may hide original exception, // if exceptions is thrown by flush. } // Maximum line size exceeded, but junk data wanted. if(m_ExceededAction == SizeExceededAction.JunkAndThrowException && e.Exception is LineSizeExceededException){ m_IsLineSizeExceeded = true; // Start reading next data buffer block. m_pStreamHelper.BeginReadLineInternal(m_pLineBuffer,m_ExceededAction,null,new ReadLineCallback(this.OnReadPeriodTerminated_ReadLine_Completed),false,false); } // Unknown exception or ThrowException, so we are done. else{ ReadPeriodTerminatedCompleted(e.Exception); } } // We reached end of stream before got period terminator. else if(e.ReadedCount == 0){ ReadPeriodTerminatedCompleted(new IncompleteDataException("Source stream was reached end of stream and data is not period terminated !")); } // We got terminator, so we are done now. else if(e.Count == 1 && e.LineBuffer[0] == '.'){ m_pBufferedStream.Flush(); m_pStoreStream.Flush(); // LineSizeExceeded. if(m_IsLineSizeExceeded){ ReadPeriodTerminatedCompleted(new LineSizeExceededException()); } // DataSizeExceeded. else if(m_TotalReadedCount > m_MaxSize){ ReadPeriodTerminatedCompleted(new DataSizeExceededException()); } // Completed successfuly. else{ ReadPeriodTerminatedCompleted(null); } } // Just append line to store stream and get next line. else{ // Maximum allowed data size exceeded. if(m_TotalReadedCount > m_MaxSize){ if(m_ExceededAction == SizeExceededAction.ThrowException){ ReadPeriodTerminatedCompleted(new DataSizeExceededException()); return; } // Junk data. //else{ //} } else{ // If line starts with period, first period is removed. if(e.LineBuffer[0] == '.'){ m_pBufferedStream.Write(e.LineBuffer,1,e.Count - 1); } // Normal line. else{ m_pBufferedStream.Write(e.LineBuffer,0,e.Count); } // Add line break. m_pBufferedStream.Write(m_pStreamHelper.m_LineBreak,0,m_pStreamHelper.m_LineBreak.Length); } // Start getting new data buffer block. m_pStreamHelper.BeginReadLineInternal(m_pLineBuffer,m_ExceededAction,null,new ReadLineCallback(this.OnReadPeriodTerminated_ReadLine_Completed),false,false); } } catch(Exception x){ ReadPeriodTerminatedCompleted(x); } }
/// <summary> /// Default constructor. /// </summary> /// <param name="stream">Source stream.</param> /// <param name="maxLineSize">Specifies maximum line size in bytes.</param> /// <param name="bufferRead">Specifies if source stream reads are buffered..</param> public StreamHelper(Stream stream,int maxLineSize,bool bufferRead) { if(stream == null){ throw new ArgumentNullException("stream"); } if(maxLineSize < 1 || maxLineSize > 32000){ throw new ArgumentException("Parameter maxLineSize value must be >= 1 and <= 32000 !"); } m_IsReadBuffered = bufferRead; if(m_IsReadBuffered){ m_pReadBuffer = new byte[32000]; } m_pStream = stream; m_pLineBuffer = new byte[maxLineSize]; m_MaxLineSize = maxLineSize; m_pRLine_EventArgs = new ReadLine_EventArgs(); m_pRLine_ByteBuffer = new byte[1]; }