/// <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, Workaround.Definitions.MaxStreamLineLength); StreamHelper reader = new StreamHelper(stream); int totalWrittenCount = 0; int readedCount = 0; int rawReadedCount = 0; while (true) { // Read data block. readedCount = 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) '\r', (byte) '\n'}, 0, 3); bufferedStoreStream.Flush(); m_pStream.Flush(); // Log if (Logger != null) { Logger.AddWrite(totalWrittenCount, null); } return totalWrittenCount; } finally { m_IsWriteActive = false; } }
/// <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, Workaround.Definitions.MaxStreamLineLength); m_MaxSize = maxSize; m_ExceededAction = exceededAction; m_pCallback = callback; m_pTag = tag; m_pBuffer = new byte[Workaround.Definitions.MaxStreamLineLength]; m_pLineBuffer = new byte[4096]; }