/// <summary> /// Default constructor. /// </summary> /// <param name="streamHelper">Reference to StreamHelper.</param> /// <param name="storeStream">Stream where to store readed data.</param> /// <param name="maxSize">Maximum number of bytes to read.</param> /// <param name="exceededAction">Specifies how this method behaves when maximum size exceeded.</param> /// <param name="callback">Callback what will be called if asynchronous reading compltes.</param> /// <param name="tag">User data.</param> public _ToStreamReader(StreamHelper streamHelper,Stream storeStream,int maxSize,SizeExceededAction exceededAction,ReadToStreamCallback callback,object tag) { m_pStreamHelper = streamHelper; m_pStoreStream = storeStream; m_pBufferedStream = new BufferedStream(m_pStoreStream,32000); m_MaxSize = maxSize; m_ExceededAction = exceededAction; m_pCallback = callback; m_pTag = tag; m_pBuffer = new byte[32000]; m_pLineBuffer = new byte[4096]; }
/// <summary> /// Reades all data from the specified stream and writes it to source stream. Period handlign and period terminator is added as required. /// </summary> /// <param name="stream">Stream which data to write to source stream.</param> /// <param name="maxSize">Maximum muber of bytes to read from <b>stream</b> and write source stream.</param> /// <returns>Returns number of bytes written to source stream. Note this value differs from /// <b>stream</b> readed bytes count because of period handling and period terminator. /// </returns> /// <exception cref="ArgumentNullException">Raised when <b>stream</b> is null.</exception> /// <exception cref="InvalidOperationException">Raised when there already is pending write operation.</exception> /// <exception cref="LineSizeExceededException">Raised when <b>stream</b> contains line with bigger line size than allowed.</exception> /// <exception cref="DataSizeExceededException">Raised when <b>stream</b> has more data than <b>maxSize</b> allows..</exception> public int WritePeriodTerminated(Stream stream,int maxSize) { if(stream == null){ throw new ArgumentNullException("stream"); } lock(this){ if(m_IsWriteActive){ throw new InvalidOperationException("There is pending write operation, multiple write operations not allowed !"); } m_IsWriteActive = true; } try{ BufferedStream bufferedStoreStream = new BufferedStream(m_pStream,32000); StreamHelper reader = new StreamHelper(stream); int totalWrittenCount = 0; int readedCount = 0; int rawReadedCount = 0; while(true){ // Read data block. readedCount = this.ReadLineInternal(m_pLineBuffer,SizeExceededAction.ThrowException,out rawReadedCount,false); // We reached end of stream, no more data. if(readedCount == 0){ break; } // Maximum allowed data size exceeded. if((totalWrittenCount + rawReadedCount) > maxSize){ throw new DataSizeExceededException(); } // If line starts with period(.), additional period is added. if(m_pLineBuffer[0] == '.'){ bufferedStoreStream.WriteByte((byte)'.'); totalWrittenCount++; } // Write readed line to buffered stream. bufferedStoreStream.Write(m_pLineBuffer,0,readedCount); bufferedStoreStream.Write(m_LineBreak,0,m_LineBreak.Length); totalWrittenCount += (readedCount + m_LineBreak.Length); } // Write terminator ".<CRLF>". We have start <CRLF> already in stream. bufferedStoreStream.Write(new byte[]{(byte)'.',(byte)'\r',(byte)'\n'},0,3); bufferedStoreStream.Flush(); m_pStream.Flush(); // Log if(this.Logger != null){ this.Logger.AddWrite(totalWrittenCount,null); } return totalWrittenCount; } finally{ m_IsWriteActive = false; } }