/// <summary> /// Reads a single line string. /// </summary> /// <param name="exceededAction">Specifies how line-reader behaves when maximum line size exceeded.</param> /// <returns> /// The total number of bytes read into the buffer. /// This can be less than the number of bytes requested if that many bytes are not currently available, /// or zero (0) if the end of the stream has been reached. /// </returns> public Task <int> ReadAsync(SizeExceededAction exceededAction) { return(Task.Factory.StartNew(() => { return Read(exceededAction); })); }
/// <summary> /// Reads and logs specified line from connected host. /// </summary> /// <param name="exceededAction">Specifies how line-reader behaves when maximum line size exceeded.</param> /// <returns>Returns readed line.</returns> /// <exception cref="ObjectDisposedException">Is raised when this object is disposed and this method is accessed.</exception> /// <exception cref="InvalidOperationException">Is raised when client is not connected.</exception> public string ReadLine(SizeExceededAction exceededAction) { ThrowIfObjectDisposed(); ThrowIfNotConnected(); if (m_pLineBuffer == null) { m_pLineBuffer = new byte[m_LineBufferSize]; } var reader = new LineReader(m_pTcpStream, m_pLineBuffer); reader.CRLFLines = m_pTcpStream.CRLFLines; reader.Read(exceededAction); var line = reader.ToLineString(m_pTcpStream.Encoding); if (reader.BytesInBuffer > 0) { LogAddRead(reader.BytesInBuffer, line); } else { LogAddText("Remote host closed connection."); } return(line); }
/// <summary> /// Default constructor. /// </summary> /// <param name="buffer">Line buffer.</param> /// <param name="exceededAction">Specifies how line-reader behaves when maximum line size exceeded.</param> /// <exception cref="ArgumentNullException">Is raised when <b>buffer</b> is null reference.</exception> public ReadLineEventArgs(byte[] buffer,SizeExceededAction exceededAction) { if(buffer == null){ throw new ArgumentNullException("buffer"); } m_pBuffer = buffer; m_ExceededAction = exceededAction; }
/// <summary> /// Default constructor. /// </summary> /// <param name="buffer">Line buffer.</param> /// <param name="exceededAction">Specifies how line-reader behaves when maximum line size exceeded.</param> /// <exception cref="ArgumentNullException">Is raised when <b>buffer</b> is null reference.</exception> public ReadLineEventArgs(byte[] buffer, SizeExceededAction exceededAction) { if (buffer == null) { throw new ArgumentNullException("buffer"); } m_pBuffer = buffer; m_ExceededAction = exceededAction; }
/// <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> /// Reads a single line string. /// </summary> /// <param name="exceededAction">Specifies how line-reader behaves when maximum line size exceeded.</param> /// <returns> /// The total number of bytes read into the buffer. /// This can be less than the number of bytes requested if that many bytes are not currently available, /// or zero (0) if the end of the stream has been reached. /// </returns> public int Read(SizeExceededAction exceededAction) { int lastByte = -1; int bytesReaded = 0; lock (this) { while (bytesReaded < this.Buffer.Length) { int b = m_pStream.ReadByte(); if (b == -1) { break; } // Line buffer full. if (bytesReaded >= this.Buffer.Length) { if (exceededAction == SizeExceededAction.ThrowException) { throw new LineSizeExceededException(); } } // Store byte. else { this.Buffer[bytesReaded++] = (byte)b; } // We have LF line. if (b == '\n') { if (!this.CRLFLines || (this.CRLFLines && lastByte == '\r')) { break; } } lastByte = b; } } if (bytesReaded > 0) { LinesReaded++; BytesReaded += bytesReaded; } BytesInBuffer = bytesReaded; return(bytesReaded); }
/// <summary> /// Reads a single line string. /// </summary> /// <param name="exceededAction">Specifies how line-reader behaves when maximum line size exceeded.</param> /// <exception cref="ObjectDisposedException">Is raised when this object is disposed and this method is accessed.</exception> public string ReadLine(SizeExceededAction exceededAction) { ThrowIfObjectDisposed(); if (m_pLineBuffer == null) { m_pLineBuffer = new byte[m_LineBufferSize]; } var lineReader = new LineReader(this, m_pLineBuffer); lineReader.CRLFLines = m_CRLFLines; lineReader.Read(exceededAction); return(lineReader.ToLineString(m_pEncoding)); }
/// <summary> /// Reads binary line and stores it to the specified buffer. /// </summary> /// <param name="buffer">Buffer where to store line data.</param> /// <param name="offset">Start offset in the buffer.</param> /// <param name="count">Maximum number of bytes store to the buffer.</param> /// <param name="exceededAction">Specifies how reader acts when line buffer too small.</param> /// <param name="rawBytesReaded">Gets raw number of bytes readed from source.</param> /// <returns>Returns number of bytes stored to <b>buffer</b> or -1 if end of stream reached.</returns> /// <exception cref="ObjectDisposedException">Is raised when this object is disposed and this method is accessed.</exception> /// <exception cref="ArgumentNullException">Is raised when <b>buffer</b> is null.</exception> /// <exception cref="ArgumentException">Is raised when any of the arguments has invalid value.</exception> /// <exception cref="LineSizeExceededException">Is raised when line is bigger than <b>buffer</b> can store.</exception> public override int ReadLine(byte[] buffer, int offset, int count, SizeExceededAction exceededAction, out int rawBytesReaded) { rawBytesReaded = 0; // We are at the end of body or "body part". if (m_State == State.Finished || m_State == State.NextWaited) { return(-1); } // Read next line. else { int readedCount = m_pReader.ReadLine(buffer, offset, count, exceededAction, out rawBytesReaded); // End of stream reached, no more data. if (readedCount == -1) { m_State = State.Finished; return(-1); } // For multipart we must check boundary tags. else if (!string.IsNullOrEmpty(m_Boundary) && readedCount > 2 && buffer[0] == '-') { string line = Encoding.Default.GetString(buffer, 0, readedCount); // Boundray end-tag reached, no more "body parts". if (line == "--" + m_Boundary + "--") { m_State = State.Finished; return(-1); } // Boundary start-tag reached, wait for this.Next() call. else if (line == "--" + m_Boundary) { m_State = State.NextWaited; return(-1); } } return(readedCount); } }
/// <summary> /// Begins reading period terminated data from source stream. Reads data while gets single period on line, /// what is data terminator. /// </summary> /// <param name="storeStream">Stream where to store data.</param> /// <param name="maxSize">Maximum muber of bytes to read.</param> /// <param name="exceededAction">Specifies how this method behaves when maximum size exceeded.</param> /// <param name="callback">Callback to be called if asynchronous reading completes.</param> /// <param name="tag">User data.</param> /// <exception cref="ArgumentNullException">Raised when <b>storeStream</b> is null.</exception> /// <exception cref="InvalidOperationException">Raised when there already is pending read operation.</exception> public void BeginReadPeriodTerminated(Stream storeStream,int maxSize,SizeExceededAction exceededAction,ReadToStreamCallback callback,object tag) { if(storeStream == null){ throw new ArgumentNullException("storeStream"); } lock(this){ if(m_IsReadActive){ throw new InvalidOperationException("There is pending read operation, multiple read operations not allowed !"); } m_IsReadActive = false; } _ToStreamReader reader = new _ToStreamReader(this,storeStream,maxSize,exceededAction,callback,tag); reader.BeginReadPeriodTerminated(); }
/// <summary> /// Reads binary line and stores it to the specified buffer. /// </summary> /// <param name="buffer">Buffer where to store line data.</param> /// <param name="offset">Start offset in the buffer.</param> /// <param name="count">Maximum number of bytes store to the buffer.</param> /// <param name="exceededAction">Specifies how reader acts when line buffer too small.</param> /// <returns>Returns number of bytes stored to <b>buffer</b> or -1 if end of stream reached.</returns> /// <exception cref="ObjectDisposedException">Is raised when this object is disposed and this method is accessed.</exception> /// <exception cref="ArgumentNullException">Is raised when <b>buffer</b> is null.</exception> /// <exception cref="ArgumentException">Is raised when any of the arguments has invalid value.</exception> /// <exception cref="LineSizeExceededException">Is raised when line is bigger than <b>buffer</b> can store.</exception> public int ReadLine(byte[] buffer,int offset,int count,SizeExceededAction exceededAction) { int rawBytesReaded = 0; return ReadLine(buffer,offset,count,exceededAction,out rawBytesReaded); }
/// <summary> /// Begins an asynchronous header reading from the source stream. /// </summary> /// <param name="storeStream">Stream where to store readed header.</param> /// <param name="maxCount">Maximum number of bytes to read. Value 0 means not limited.</param> /// <param name="exceededAction">Specifies action what is done if <b>maxCount</b> number of bytes has exceeded.</param> /// <param name="callback">The AsyncCallback delegate that is executed when asynchronous operation completes.</param> /// <param name="state">An object that contains any additional user-defined data.</param> /// <returns>An IAsyncResult that represents the asynchronous call.</returns> /// <exception cref="ObjectDisposedException">Is raised when this object is disposed and this method is accessed.</exception> /// <exception cref="ArgumentNullException">Is raised when <b>storeStream</b> is null reference.</exception> /// <exception cref="ArgumentException">Is raised when any of the arguments has invalid value.</exception> public IAsyncResult BeginReadHeader(Stream storeStream, int maxCount, SizeExceededAction exceededAction, AsyncCallback callback, object state) { if (m_IsDisposed) { throw new ObjectDisposedException(GetType().Name); } if (storeStream == null) { throw new ArgumentNullException("storeStream"); } if (maxCount < 0) { throw new ArgumentException("Argument 'maxCount' must be >= 0."); } return new ReadToTerminatorAsyncOperation(this, "", storeStream, maxCount, exceededAction, callback, state); }
/// <summary> /// Default constructor. /// </summary> /// <param name="owner">Owner stream.</param> /// <param name="terminator">Data terminator.</param> /// <param name="storeStream">Stream where to store readed header.</param> /// <param name="maxCount">Maximum number of bytes to read. Value 0 means not limited.</param> /// <param name="exceededAction">Specifies how this method behaves when maximum line size exceeded.</param> /// <param name="callback">The AsyncCallback delegate that is executed when asynchronous operation completes.</param> /// <param name="asyncState">User-defined object that qualifies or contains information about an asynchronous operation.</param> /// <exception cref="ArgumentNullException">Is raised when <b>owner</b>,<b>terminator</b> or <b>storeStream</b> is null reference.</exception> public ReadToTerminatorAsyncOperation(SmartStream owner, string terminator, Stream storeStream, long maxCount, SizeExceededAction exceededAction, AsyncCallback callback, object asyncState) { if (owner == null) { throw new ArgumentNullException("owner"); } if (terminator == null) { throw new ArgumentNullException("terminator"); } if (storeStream == null) { throw new ArgumentNullException("storeStream"); } if (maxCount < 0) { throw new ArgumentException("Argument 'maxCount' must be >= 0."); } m_pOwner = owner; m_Terminator = terminator; m_pTerminatorBytes = Encoding.ASCII.GetBytes(terminator); m_pStoreStream = storeStream; m_MaxCount = maxCount; m_SizeExceededAction = exceededAction; m_pAsyncCallback = callback; m_pAsyncState = asyncState; m_pAsyncWaitHandle = new AutoResetEvent(false); m_pLineBuffer = new byte[Workaround.Definitions.MaxStreamLineLength]; // Start reading data. m_pOwner.BeginReadLine(m_pLineBuffer, 0, m_pLineBuffer.Length - 2, m_SizeExceededAction, ReadLine_Completed, null); }
/// <summary> /// Default constructor. /// </summary> /// <param name="owner">Owner stream.</param> /// <param name="buffer">Buffer where to store data.</param> /// <param name="offset">The location in <b>buffer</b> to begin storing the data.</param> /// <param name="maxCount">Maximum number of bytes to read.</param> /// <param name="exceededAction">Specifies how this method behaves when maximum line size exceeded.</param> /// <param name="callback">The AsyncCallback delegate that is executed when asynchronous operation completes.</param> /// <param name="asyncState">User-defined object that qualifies or contains information about an asynchronous operation.</param> /// <exception cref="ArgumentNullException">Is raised when <b>owner</b>,<b>buffer</b> is null reference.</exception> /// <exception cref="ArgumentOutOfRangeException">Is raised when any of the arguments has out of valid range.</exception> public ReadLineAsyncOperation(SmartStream owner, byte[] buffer, int offset, int maxCount, SizeExceededAction exceededAction, AsyncCallback callback, object asyncState) { if (owner == null) { throw new ArgumentNullException("owner"); } if (buffer == null) { throw new ArgumentNullException("buffer"); } if (offset < 0) { throw new ArgumentOutOfRangeException("offset", "Argument 'offset' value must be >= 0."); } if (offset > buffer.Length) { throw new ArgumentOutOfRangeException("offset", "Argument 'offset' value must be < buffer.Length."); } if (maxCount < 0) { throw new ArgumentOutOfRangeException("maxCount", "Argument 'maxCount' value must be >= 0."); } if (offset + maxCount > buffer.Length) { throw new ArgumentOutOfRangeException("maxCount", "Argument 'maxCount' is bigger than than argument 'buffer' can store."); } m_pOwner = owner; m_pBuffer = buffer; m_OffsetInBuffer = offset; m_MaxCount = maxCount; m_SizeExceededAction = exceededAction; m_pAsyncCallback = callback; m_pAsyncState = asyncState; m_pAsyncWaitHandle = new AutoResetEvent(false); DoLineReading(); }
/// <summary> /// Reads line from source stream and stores to specified buffer. This method accepts LF or CRLF lines. /// </summary> /// <param name="buffer">Buffer where to store line data.</param> /// <param name="exceededAction">Specifies how this method behaves when maximum line size exceeded.</param> /// <param name="readedCount">Returns how many bytes this method actually readed form source stream.</param> /// <param name="log">Specifies if read line is logged.</param> /// <returns>Returns number of bytes stored to buffer, returns -1 if end of stream reached and no more data.</returns> /// <exception cref="InvalidOperationException">Raised when there already is pending read operation.</exception> /// <exception cref="LineSizeExceededException">Raised when maximum allowed line size has exceeded.</exception> public int ReadLineInternal(byte[] buffer,SizeExceededAction exceededAction,out int readedCount,bool log) { readedCount = 0; int bufferSize = buffer.Length; int posInBuffer = 0; int currentByte = 0; /* Because performance gain we need todo,2 while, buffered and non buffered read. Each if clause in this while adds about 5% cpu. */ #region Buffered if(m_IsReadBuffered){ while(true){ //--- Read byte ----------------------------------------------------- if(m_ReadBufferOffset >= m_ReadBufferEndPos){ m_ReadBufferEndPos = m_pStream.Read(m_pReadBuffer,0,32000); m_ReadBufferOffset = 0; // We reached end of stream. if(m_ReadBufferEndPos == 0){ break; } } currentByte = m_pReadBuffer[m_ReadBufferOffset]; m_ReadBufferOffset++; readedCount++; //------------------------------------------------------------------- // We have LF. if(currentByte == '\n'){ break; } // We just skip all CR. else if(currentByte == '\r'){ } // Maximum allowed line size exceeded. else if(readedCount > bufferSize){ if(exceededAction == SizeExceededAction.ThrowException){ throw new LineSizeExceededException(); } } // Store readed byte. else{ buffer[posInBuffer] = (byte)currentByte; posInBuffer++; } } } #endregion #region No-buffered else{ while(true){ // Read byte currentByte = m_pStream.ReadByte(); // We reached end of stream, no more data. if(currentByte == -1){ break; } readedCount++; // We have LF. if(currentByte == '\n'){ break; } // We just skip all CR. else if(currentByte == '\r'){ } // Maximum allowed line size exceeded. else if(readedCount > bufferSize){ if(exceededAction == SizeExceededAction.ThrowException){ throw new LineSizeExceededException(); } } // Store readed byte. else{ buffer[posInBuffer] = (byte)currentByte; posInBuffer++; } } } #endregion // We are end of stream, no more data. if(readedCount == 0){ return -1; } // Maximum allowed line size exceeded. if(readedCount > m_MaxLineSize){ throw new LineSizeExceededException(); } // Log if(log && this.Logger != null){ this.Logger.AddRead(readedCount,Encoding.Default.GetString(buffer,0,readedCount)); } return posInBuffer; }
/// <summary> /// Reads line from source stream and stores to specified buffer. This method accepts LF or CRLF lines. /// </summary> /// <param name="buffer">Buffer where to store line data.</param> /// <param name="exceededAction">Specifies how this method behaves when maximum line size exceeded.</param> /// <returns>Returns number of bytes stored to buffer, returns -1 if end of stream reached and no more data.</returns> /// <exception cref="ArgumentNullException">Raised when <b>buffer</b> is null.</exception> /// <exception cref="InvalidOperationException">Raised when there already is pending read operation.</exception> /// <exception cref="LineSizeExceededException">Raised when maximum allowed line size has exceeded.</exception> public int ReadLine(byte[] buffer,SizeExceededAction exceededAction) { if(buffer == null){ throw new ArgumentNullException("buffer"); } lock(this){ if(m_IsReadActive){ throw new InvalidOperationException("There is pending read operation, multiple read operations not allowed !"); } else{ m_IsReadActive = true; } } try{ int readedCount = 0; return ReadLineInternal(buffer,exceededAction,out readedCount,true); } finally{ m_IsReadActive = false; } }
public static Task <StreamWriteResult> WriteAsync(LineReader fromReader, Stream toStream, long maxCount, SizeExceededAction exceededAction) { if (fromReader == null) { throw new ArgumentNullException(nameof(fromReader)); } if (toStream == null) { throw new ArgumentNullException(nameof(toStream)); } if (!toStream.CanWrite) { throw new ArgumentException($"Argument '{nameof(toStream)}' cannot be written.", nameof(toStream)); } return(Task.Factory.StartNew(() => { return Write(fromReader, toStream, maxCount, exceededAction); })); }
/// <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]; }
/// <summary> /// Reads binary line and stores it to the specified buffer. /// </summary> /// <param name="buffer">Buffer where to store line data.</param> /// <param name="offset">Start offset in the buffer.</param> /// <param name="count">Maximum number of bytes store to the buffer.</param> /// <param name="exceededAction">Specifies how reader acts when line buffer too small.</param> /// <param name="rawBytesReaded">Gets raw number of bytes readed from source.</param> /// <returns>Returns number of bytes stored to <b>buffer</b> or -1 if end of stream reached.</returns> /// <exception cref="ObjectDisposedException">Is raised when this object is disposed and this method is accessed.</exception> /// <exception cref="ArgumentNullException">Is raised when <b>buffer</b> is null.</exception> /// <exception cref="ArgumentException">Is raised when any of the arguments has invalid value.</exception> /// <exception cref="LineSizeExceededException">Is raised when line is bigger than <b>buffer</b> can store.</exception> public override int ReadLine(byte[] buffer,int offset,int count,SizeExceededAction exceededAction,out int rawBytesReaded) { rawBytesReaded = 0; // We are at the end of body or "body part". if(m_State == State.Finished || m_State == State.NextWaited){ return -1; } // Read next line. else{ int readedCount = m_pReader.ReadLine(buffer,offset,count,exceededAction,out rawBytesReaded); // End of stream reached, no more data. if(readedCount == -1){ m_State = State.Finished; return -1; } // For multipart we must check boundary tags. else if(!string.IsNullOrEmpty(m_Boundary) && readedCount > 2 && buffer[0] == '-'){ string line = Encoding.Default.GetString(buffer,0,readedCount); // Boundray end-tag reached, no more "body parts". if(line == "--" + m_Boundary + "--"){ m_State = State.Finished; return -1; } // Boundary start-tag reached, wait for this.Next() call. else if(line == "--" + m_Boundary){ m_State = State.NextWaited; return -1; } } return readedCount; } }
public static StreamReadResult Read(LineReader fromReader, Stream toStream, long maxCount, SizeExceededAction exceededAction) { if (fromReader == null) { throw new ArgumentNullException(nameof(fromReader)); } if (toStream == null) { throw new ArgumentNullException(nameof(toStream)); } if (!toStream.CanWrite) { throw new ArgumentException($"Argument '{nameof(toStream)}' cannot be written.", nameof(toStream)); } var hasReadExceeded = false; var result = new StreamReadResult(); while (true) { fromReader.Read(); if (fromReader.BytesInBuffer == 0) { throw new IncompleteDataException("Data is not period-terminated."); } // We have period terminator. else if (fromReader.LineBytesInBuffer == 1 && fromReader.Buffer[0] == '.') { break; } // Normal line. else { if (hasReadExceeded == true) { continue; } // Period handling: If line starts with '.', it must be removed. if (fromReader.Buffer[0] == '.') { if (maxCount > 0 && (result.BytesReaded + fromReader.BytesInBuffer - 1) > maxCount) { hasReadExceeded = true; // Maximum allowed to read bytes exceeded. if (exceededAction == SizeExceededAction.ThrowException) { throw new DataSizeExceededException(); } continue; } result.LinesReaded++; result.BytesReaded += fromReader.BytesInBuffer - 1; toStream.Write(fromReader.Buffer, 1, fromReader.BytesInBuffer - 1); continue; } // Nomrmal line. if (maxCount > 0 && (result.BytesReaded + fromReader.BytesInBuffer) > maxCount) { hasReadExceeded = true; // Maximum allowed to read bytes exceeded. if (exceededAction == SizeExceededAction.ThrowException) { throw new DataSizeExceededException(); } continue; } result.LinesReaded++; result.BytesReaded += fromReader.BytesInBuffer; toStream.Write(fromReader.Buffer, 0, fromReader.BytesInBuffer); } } toStream.Flush(); return(result); }
/// <summary> /// Reads binary line and stores it to the specified buffer. /// </summary> /// <param name="buffer">Buffer where to store line data.</param> /// <param name="offset">Start offset in the buffer.</param> /// <param name="count">Maximum number of bytes store to the buffer.</param> /// <param name="exceededAction">Specifies how reader acts when line buffer too small.</param> /// <param name="rawBytesReaded">Gets raw number of bytes readed from source.</param> /// <returns>Returns number of bytes stored to <b>buffer</b> or -1 if end of stream reached.</returns> /// <exception cref="ObjectDisposedException">Is raised when this object is disposed and this method is accessed.</exception> /// <exception cref="ArgumentNullException">Is raised when <b>buffer</b> is null.</exception> /// <exception cref="ArgumentException">Is raised when any of the arguments has invalid value.</exception> /// <exception cref="LineSizeExceededException">Is raised when line is bigger than <b>buffer</b> can store.</exception> public virtual int ReadLine(byte[] buffer,int offset,int count,SizeExceededAction exceededAction,out int rawBytesReaded) { if(m_IsDisposed){ throw new ObjectDisposedException(this.GetType().Name); } if(buffer == null){ throw new ArgumentNullException("buffer"); } if(offset < 0){ throw new ArgumentException("Argument 'offset' value must be >= 0."); } if(count < 0){ throw new ArgumentException("Argument 'count' value must be >= 0."); } if(buffer.Length < (count + offset)){ throw new ArgumentException("Argument 'count' value is bigger than specified 'buffer' can store."); } int maxStoreCount = buffer.Length - offset; int storedCount = 0; rawBytesReaded = 0; bool sizeExceeded = false; while(true){ // No data in buffer, buffer next block. if(m_StoredInBuffer == m_OffsetInBuffer){ m_OffsetInBuffer = 0; m_StoredInBuffer = m_pSource.Read(m_pReadBuffer,0,m_BufferSize); // We reached end of stream, no more data. if(m_StoredInBuffer == 0){ break; } } byte currentByte = m_pReadBuffer[m_OffsetInBuffer++]; rawBytesReaded++; // We have LF, we got a line. if(currentByte == '\n'){ break; } // We just skip CR, because CR must be with LF, otherwise it's invalid CR. else if(currentByte == '\r'){ } // Normal byte. else{ // Line buffer full. if(storedCount == maxStoreCount){ sizeExceeded = true; if(exceededAction == SizeExceededAction.ThrowException){ throw new LineSizeExceededException(); } } else{ buffer[offset + storedCount] = currentByte; storedCount++; } } } // Line buffer is not big enough to store whole line data. if(sizeExceeded){ throw new LineSizeExceededException(); } // We haven't readed nothing, we are end of stream. else if(rawBytesReaded == 0){ return -1; } else{ return storedCount; } }
/// <summary> /// Reads all source stream data and stores to the specified store stream. /// </summary> /// <param name="storeStream">Stream where to store readed data.</param> /// <param name="maxSize">Maximum muber of bytes to read.</param> /// <param name="exceededAction">Specifies how this method behaves when maximum size exceeded.</param> /// <returns>Returns number of bytes written to <b>storeStream</b>.</returns> /// <exception cref="ArgumentNullException">Raised when <b>storeStream</b> is null.</exception> /// <exception cref="ArgumentException">Raised when <b>maxSize</b> less than 1.</exception> /// <exception cref="InvalidOperationException">Raised when there already is pending read operation.</exception> /// <exception cref="DataSizeExceededException">Raised when maximum allowed data size has exceeded.</exception> public int ReadAll(Stream storeStream,int maxSize,SizeExceededAction exceededAction) { if(storeStream == null){ throw new ArgumentNullException("storeStream"); } if(maxSize < 1){ throw new ArgumentException("Parameter maxSize value must be >= 1 !"); } lock(this){ if(m_IsReadActive){ throw new InvalidOperationException("There is pending read operation, multiple read operations not allowed !"); } m_IsReadActive = true; } try{ byte[] buffer = new byte[32000]; int totalReadedCount = 0; int readedCount = 0; while(true){ // We have data in read buffer, we must consume it first ! if(m_ReadBufferOffset < m_ReadBufferEndPos){ Array.Copy(m_pLineBuffer,m_ReadBufferOffset,buffer,0,m_ReadBufferEndPos - m_ReadBufferOffset); m_ReadBufferOffset = 0; m_ReadBufferEndPos = 0; } // Just get read next data block. else{ readedCount = m_pStream.Read(buffer,0,buffer.Length); } // End of stream reached, no more data. if(readedCount == 0){ break; } totalReadedCount += readedCount; // Maximum allowed data size exceeded. if(totalReadedCount > maxSize){ if(exceededAction == SizeExceededAction.ThrowException){ throw new DataSizeExceededException(); } } else{ storeStream.Write(buffer,0,readedCount); } } // Maximum allowed data size exceeded, some data junked. if(totalReadedCount > maxSize){ throw new DataSizeExceededException(); } // Log if(this.Logger != null){ this.Logger.AddRead(totalReadedCount,null); } return totalReadedCount; } finally{ m_IsReadActive = false; } }
/// <summary> /// Reads header from source stream and stores to the specified stream. Reads header data while /// gets blank line, what is header terminator. For example this method can be used for reading /// mail,http,sip, ... headers. /// </summary> /// <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 line or data size exceeded.</param> /// <returns>Returns number of bytes written to <b>storeStream</b>.</returns> /// <exception cref="ArgumentNullException">Raised when <b>storeStream</b> is null.</exception> /// <exception cref="ArgumentException">Raised when <b>maxSize</b> less than 1.</exception> /// <exception cref="InvalidOperationException">Raised when there already is pending read operation.</exception> /// <exception cref="LineSizeExceededException">Raised when maximum allowed line size has exceeded.</exception> /// <exception cref="DataSizeExceededException">Raised when maximum allowed data size has exceeded.</exception> public int ReadHeader(Stream storeStream,int maxSize,SizeExceededAction exceededAction) { if(storeStream == null){ throw new ArgumentNullException("storeStream"); } lock(this){ if(m_IsReadActive){ throw new InvalidOperationException("There is pending read operation, multiple read operations not allowed !"); } else{ m_IsReadActive = true; } } try{ BufferedStream bufferedStoreStream = new BufferedStream(storeStream,32000); bool lineSizeExceeded = false; int totalReadedCount = 0; int readedCount = 0; int rawReadedCount = 0; while(true){ // Read line. readedCount = this.ReadLineInternal(m_pLineBuffer,SizeExceededAction.ThrowException,out rawReadedCount,false); // We have reached end of stream, no more data. if(rawReadedCount == 0){ break; } totalReadedCount += rawReadedCount; // We got header terminator. if(readedCount == 0){ break; } else{ // Maximum allowed data size exceeded. if(totalReadedCount > maxSize){ if(exceededAction == SizeExceededAction.ThrowException){ throw new DataSizeExceededException(); } } // Write readed bytes to store stream. else{ bufferedStoreStream.Write(m_pLineBuffer,0,readedCount); bufferedStoreStream.Write(m_LineBreak,0,m_LineBreak.Length); } } } bufferedStoreStream.Flush(); // Maximum allowed line size exceeded, some data is junked. if(lineSizeExceeded){ throw new LineSizeExceededException(); } // Maximum allowed data size exceeded, some data is junked. if(totalReadedCount > maxSize){ throw new DataSizeExceededException(); } // Log if(this.Logger != null){ this.Logger.AddRead(totalReadedCount,null); } return totalReadedCount; } finally{ m_IsReadActive = false; } }
/// <summary> /// Reads binary line and stores it to the specified buffer. /// </summary> /// <param name="buffer">Buffer where to store line data.</param> /// <param name="offset">Start offset in the buffer.</param> /// <param name="count">Maximum number of bytes store to the buffer.</param> /// <param name="exceededAction">Specifies how reader acts when line buffer too small.</param> /// <returns>Returns number of bytes stored to <b>buffer</b> or -1 if end of stream reached.</returns> /// <exception cref="ObjectDisposedException">Is raised when this object is disposed and this method is accessed.</exception> /// <exception cref="ArgumentNullException">Is raised when <b>buffer</b> is null.</exception> /// <exception cref="ArgumentException">Is raised when any of the arguments has invalid value.</exception> /// <exception cref="LineSizeExceededException">Is raised when line is bigger than <b>buffer</b> can store.</exception> public int ReadLine(byte[] buffer, int offset, int count, SizeExceededAction exceededAction) { int rawBytesReaded = 0; return(ReadLine(buffer, offset, count, exceededAction, out rawBytesReaded)); }
/// <summary> /// Reads line from source stream. /// </summary> /// <param name="encoding">Encoding to use to decode line.</param> /// <param name="exceededAction">Specifies how this method behaves when maximum line size exceeded.</param> /// <returns>Returns readed line with specified encoding or null if end of stream reached and no more data.</returns> /// <exception cref="ArgumentNullException">Raised when <b>encoding</b> is null.</exception> /// <exception cref="InvalidOperationException">Raised when there already is pending read operation.</exception> /// <exception cref="LineSizeExceededException">Raised when maximum allowed line size has exceeded.</exception> public string ReadLine(Encoding encoding,SizeExceededAction exceededAction) { if(encoding == null){ throw new ArgumentNullException("encoding"); } int readedCount = ReadLine(m_pLineBuffer,exceededAction); if(readedCount == -1){ return null; } else{ return encoding.GetString(m_pLineBuffer,0,readedCount); } }
/// <summary> /// Reads binary line and stores it to the specified buffer. /// </summary> /// <param name="buffer">Buffer where to store line data.</param> /// <param name="offset">Start offset in the buffer.</param> /// <param name="count">Maximum number of bytes store to the buffer.</param> /// <param name="exceededAction">Specifies how reader acts when line buffer too small.</param> /// <param name="rawBytesReaded">Gets raw number of bytes readed from source.</param> /// <returns>Returns number of bytes stored to <b>buffer</b> or -1 if end of stream reached.</returns> /// <exception cref="ObjectDisposedException">Is raised when this object is disposed and this method is accessed.</exception> /// <exception cref="ArgumentNullException">Is raised when <b>buffer</b> is null.</exception> /// <exception cref="ArgumentException">Is raised when any of the arguments has invalid value.</exception> /// <exception cref="LineSizeExceededException">Is raised when line is bigger than <b>buffer</b> can store.</exception> public virtual int ReadLine(byte[] buffer, int offset, int count, SizeExceededAction exceededAction, out int rawBytesReaded) { if (m_IsDisposed) { throw new ObjectDisposedException(GetType().Name); } if (buffer == null) { throw new ArgumentNullException("buffer"); } if (offset < 0) { throw new ArgumentException("Argument 'offset' value must be >= 0."); } if (count < 0) { throw new ArgumentException("Argument 'count' value must be >= 0."); } if (buffer.Length < (count + offset)) { throw new ArgumentException( "Argument 'count' value is bigger than specified 'buffer' can store."); } int maxStoreCount = buffer.Length - offset; int storedCount = 0; rawBytesReaded = 0; bool sizeExceeded = false; while (true) { // No data in buffer, buffer next block. if (m_StoredInBuffer == m_OffsetInBuffer) { m_OffsetInBuffer = 0; m_StoredInBuffer = m_pSource.Read(m_pReadBuffer, 0, m_BufferSize); // We reached end of stream, no more data. if (m_StoredInBuffer == 0) { break; } } byte currentByte = m_pReadBuffer[m_OffsetInBuffer++]; rawBytesReaded++; // We have LF, we got a line. if (currentByte == '\n') { break; } // We just skip CR, because CR must be with LF, otherwise it's invalid CR. else if (currentByte == '\r') { } // Normal byte. else { // Line buffer full. if (storedCount == maxStoreCount) { sizeExceeded = true; if (exceededAction == SizeExceededAction.ThrowException) { throw new LineSizeExceededException(); } } else { buffer[offset + storedCount] = currentByte; storedCount++; } } } // Line buffer is not big enough to store whole line data. if (sizeExceeded) { throw new LineSizeExceededException(); } // We haven't readed nothing, we are end of stream. else if (rawBytesReaded == 0) { return(-1); } else { return(storedCount); } }
/// <summary> /// Reads period terminated data from source stream. Reads data while gets single period on line, /// what is data terminator. /// </summary> /// <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> /// <returns>Returns number of bytes written to <b>storeStream</b>.</returns> /// <exception cref="ArgumentNullException">Raised when <b>storeStream</b> is null.</exception> /// <exception cref="ArgumentException">Raised when <b>maxSize</b> less than 1.</exception> /// <exception cref="InvalidOperationException">Raised when there already is pending read operation.</exception> /// <exception cref="LineSizeExceededException">Raised when maximum allowed line size has exceeded.</exception> /// <exception cref="DataSizeExceededException">Raised when maximum allowed data size has exceeded.</exception> /// <exception cref="IncompleteDataException">Raised when source stream was reached end of stream and data is not period terminated.</exception> public int ReadPeriodTerminated(Stream storeStream,int maxSize,SizeExceededAction exceededAction) { if(storeStream == null){ throw new ArgumentNullException("storeStream"); } lock(this){ if(m_IsReadActive){ throw new InvalidOperationException("There is pending read operation, multiple read operations not allowed !"); } else{ m_IsReadActive = true; } } try{ BufferedStream bufferedStoreStream = new BufferedStream(storeStream,32000); bool lineSizeExceeded = false; bool isPeriodTerminated = false; int totalReadedCount = 0; int readedCount = 0; int rawReadedCount = 0; // Just break reading at once if maximum allowed line or data size exceeded. if(exceededAction == SizeExceededAction.ThrowException){ try{ // Read first line. readedCount = this.ReadLineInternal(m_pLineBuffer,SizeExceededAction.JunkAndThrowException,out rawReadedCount,false); } catch(LineSizeExceededException x){ string dummy = x.Message; lineSizeExceeded = true; } while(rawReadedCount != 0){ totalReadedCount += rawReadedCount; // We have data terminator "<CRLF>.<CRLF>". if(readedCount == 1 && m_pLineBuffer[0] == '.'){ isPeriodTerminated = true; break; } // If line starts with period(.), first period is removed. else if(m_pLineBuffer[0] == '.'){ // Maximum allowed line or data size exceeded. if(lineSizeExceeded || totalReadedCount > maxSize){ // Junk data } // Write readed line to store stream. else{ bufferedStoreStream.Write(m_pLineBuffer,1,readedCount - 1); bufferedStoreStream.Write(m_LineBreak,0,m_LineBreak.Length); } } // Normal line. else{ // Maximum allowed line or data size exceeded. if(lineSizeExceeded || totalReadedCount > maxSize){ // Junk data } // Write readed line to store stream. else{ bufferedStoreStream.Write(m_pLineBuffer,0,readedCount); bufferedStoreStream.Write(m_LineBreak,0,m_LineBreak.Length); } } try{ // Read next line. readedCount = this.ReadLineInternal(m_pLineBuffer,SizeExceededAction.JunkAndThrowException,out rawReadedCount,false); } catch(LineSizeExceededException x){ string dummy = x.Message; lineSizeExceeded = true; } } } // Read and junk all data if maximum allowed line or data size exceeded. else{ // Read first line. readedCount = this.ReadLineInternal(m_pLineBuffer,SizeExceededAction.JunkAndThrowException,out rawReadedCount,false); while(rawReadedCount != 0){ totalReadedCount += rawReadedCount; // We have data terminator "<CRLF>.<CRLF>". if(readedCount == 1 && m_pLineBuffer[0] == '.'){ isPeriodTerminated = true; break; } // If line starts with period(.), first period is removed. else if(m_pLineBuffer[0] == '.'){ // Maximum allowed size exceeded. if(totalReadedCount > maxSize){ throw new DataSizeExceededException(); } // Write readed line to store stream. bufferedStoreStream.Write(m_pLineBuffer,1,readedCount - 1); bufferedStoreStream.Write(m_LineBreak,0,m_LineBreak.Length); } // Normal line. else{ // Maximum allowed size exceeded. if(totalReadedCount > maxSize){ throw new DataSizeExceededException(); } // Write readed line to store stream. bufferedStoreStream.Write(m_pLineBuffer,0,readedCount); bufferedStoreStream.Write(m_LineBreak,0,m_LineBreak.Length); } // Read next line. readedCount = this.ReadLineInternal(m_pLineBuffer,SizeExceededAction.JunkAndThrowException,out rawReadedCount,false); } } bufferedStoreStream.Flush(); // Log if(this.Logger != null){ this.Logger.AddRead(totalReadedCount,null); } if(lineSizeExceeded){ throw new LineSizeExceededException(); } if(!isPeriodTerminated){ throw new IncompleteDataException("Source stream was reached end of stream and data is not period terminated !"); } if(totalReadedCount > maxSize){ throw new DataSizeExceededException(); } return totalReadedCount; } finally{ m_IsReadActive = false; } }
public static StreamWriteResult Write(LineReader fromReader, Stream toStream, long maxCount, SizeExceededAction exceededAction) { if (fromReader == null) { throw new ArgumentNullException(nameof(fromReader)); } if (toStream == null) { throw new ArgumentNullException(nameof(toStream)); } if (!toStream.CanWrite) { throw new ArgumentException($"Argument '{nameof(toStream)}' cannot be written.", nameof(toStream)); } var hasWriteExceeded = false; var lastLineEndsWithCRLF = false; var result = new StreamWriteResult(); while (true) { fromReader.Read(); // We have readed all source stream data, we are done. if (fromReader.BytesInBuffer == 0) { if (hasWriteExceeded == true) { break; } var lastEndBytes = new byte[] { (byte)'.', (byte)'\r', (byte)'\n' }; // if last line isnot end with CRLF. if (!lastLineEndsWithCRLF) { lastEndBytes = new byte[] { (byte)'\r', (byte)'\n', (byte)'.', (byte)'\r', (byte)'\n' }; } if (maxCount > 0 && (result.BytesWritten + lastEndBytes.Length) > maxCount) { hasWriteExceeded = true; // Maximum allowed to write bytes exceeded. if (exceededAction == SizeExceededAction.ThrowException) { throw new DataSizeExceededException(); } break; } result.LinesWritten++; result.BytesWritten += lastEndBytes.Length; toStream.Write(lastEndBytes, 0, lastEndBytes.Length); break; } // Write readed line. else { if (hasWriteExceeded == true) { continue; } // Check if line ends CRLF. if (fromReader.BytesInBuffer >= 2 && fromReader.Buffer[fromReader.BytesInBuffer - 2] == '\r' && fromReader.Buffer[fromReader.BytesInBuffer - 1] == '\n') { lastLineEndsWithCRLF = true; } else { lastLineEndsWithCRLF = false; } // Period handling. If line starts with period(.), additional period is added. if (fromReader.Buffer[0] == '.') { if (maxCount > 0 && (result.BytesWritten + fromReader.BytesInBuffer + 1) > maxCount) { hasWriteExceeded = true; // Maximum allowed to write bytes exceeded. if (exceededAction == SizeExceededAction.ThrowException) { throw new DataSizeExceededException(); } continue; } result.LinesWritten++; result.BytesWritten += fromReader.BytesInBuffer + 1; toStream.Write(new byte[] { (byte)'.' }, 0, 1); toStream.Write(fromReader.Buffer, 0, fromReader.BytesInBuffer); continue; } // Normal line. if (maxCount > 0 && (result.BytesWritten + fromReader.BytesInBuffer) > maxCount) { hasWriteExceeded = true; // Maximum allowed to write bytes exceeded. if (exceededAction == SizeExceededAction.ThrowException) { throw new DataSizeExceededException(); } continue; } result.LinesWritten++; result.BytesWritten += fromReader.BytesInBuffer; toStream.Write(fromReader.Buffer, 0, fromReader.BytesInBuffer); } } toStream.Flush(); return(result); }
/// <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; }
/// <summary> /// Starts reading line from source stream. This method does not do any checks and read locks. /// </summary> /// <param name="buffer">Buffer where to store line data.</param> /// <param name="exceededAction">Specifies how this method behaves when maximum line size exceeded.</param> /// <param name="tag">User data.</param> /// <param name="callback">Callback to be called whan asynchronous operation completes.</param> /// <param name="unlockRead">Specifies if read lock is released.</param> /// <param name="log">User data.</param> private void BeginReadLineInternal(byte[] buffer,SizeExceededAction exceededAction,object tag,ReadLineCallback callback,bool unlockRead,bool log) { m_pRLine_LineBuffer = buffer; m_RLine_ExceedAction = exceededAction; m_pRLine_Tag = tag; m_pRLine_Callback = callback; m_RLine_LineBufferOffset = 0; m_RLine_TotalReadedCount = 0; m_RLine_LineBufferSize = buffer.Length; m_RLine_UnlockRead = unlockRead; m_RLine_Log = log; if(this.IsReadBuffered){ DoReadLine_Buffered(); } else{ m_pStream.BeginRead(m_pRLine_ByteBuffer,0,1,new AsyncCallback(this.OnReadByte_Completed),null); } }
// TODO: // *) timeout support for sync versions // *) WriteHeader SmartStream buffers !!! we may not do this if stream wont support seeking. /// <summary> /// Begins an asynchronous line reading from the source stream. /// </summary> /// <param name="buffer">Buffer where to store readed line data.</param> /// <param name="offset">The location in <b>buffer</b> to begin storing the data.</param> /// <param name="maxCount">Maximum number of bytes to read.</param> /// <param name="exceededAction">Specifies how this method behaves when maximum line size exceeded.</param> /// <param name="callback">The AsyncCallback delegate that is executed when asynchronous operation completes.</param> /// <param name="state">An object that contains any additional user-defined data.</param> /// <returns>An IAsyncResult that represents the asynchronous call.</returns> /// <exception cref="ObjectDisposedException">Is raised when this object is disposed and this method is accessed.</exception> /// <exception cref="ArgumentNullException">Is raised when <b>buffer</b> is null reference.</exception> /// <exception cref="ArgumentOutOfRangeException">is raised when any of the arguments has invalid value.</exception> public IAsyncResult BeginReadLine(byte[] buffer, int offset, int maxCount, SizeExceededAction exceededAction, AsyncCallback callback, object state) { if (m_IsDisposed) { throw new ObjectDisposedException(GetType().Name); } if (buffer == null) { throw new ArgumentNullException("buffer"); } if (offset < 0) { throw new ArgumentOutOfRangeException("offset", "Argument 'offset' value must be >= 0."); } if (offset > buffer.Length) { throw new ArgumentOutOfRangeException("offset", "Argument 'offset' value must be < buffer.Length."); } if (maxCount < 0) { throw new ArgumentOutOfRangeException("maxCount", "Argument 'maxCount' value must be >= 0."); } if (offset + maxCount > buffer.Length) { throw new ArgumentOutOfRangeException("maxCount", "Argument 'maxCount' is bigger than than argument 'buffer' can store."); } return new ReadLineAsyncOperation(this, buffer, offset, maxCount, exceededAction, callback, state); }
/// <summary> /// Starts reading line from source stream. /// </summary> /// <param name="buffer">Buffer where to store line data.</param> /// <param name="exceededAction">Specifies how this method behaves when maximum line size exceeded.</param> /// <param name="tag">User data.</param> /// <param name="callback">Callback to be called whan asynchronous operation completes.</param> /// <exception cref="ArgumentNullException">Raised when <b>buffer</b> is null.</exception> /// <exception cref="InvalidOperationException">Raised when there already is pending read operation.</exception> public void BeginReadLine(byte[] buffer,SizeExceededAction exceededAction,object tag,ReadLineCallback callback) { if(buffer == null){ throw new ArgumentNullException("buffer"); } lock(this){ if(m_IsReadActive){ throw new InvalidOperationException("There is pending read operation, multiple read operations not allowed !"); } m_IsReadActive = false; } BeginReadLineInternal(buffer,exceededAction,tag,callback,true,true); }
/// <summary> /// Reads header from stream and stores to the specified <b>storeStream</b>. /// </summary> /// <param name="storeStream">Stream where to store readed header.</param> /// <param name="maxCount">Maximum number of bytes to read. Value 0 means not limited.</param> /// <param name="exceededAction">Specifies action what is done if <b>maxCount</b> number of bytes has exceeded.</param> /// <returns>Returns how many bytes readed from 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>storeStream</b> is null.</exception> /// <exception cref="ArgumentException">Is raised when any of the arguments has invalid value.</exception> /// <exception cref="LineSizeExceededException">Is raised when source stream has too big line.</exception> /// <exception cref="DataSizeExceededException">Is raised when reading exceeds <b>maxCount</b> specified value.</exception> /// <exception cref="IncompleteDataException">Is raised when source stream closed before header-terminator reached.</exception> public int ReadHeader(Stream storeStream, int maxCount, SizeExceededAction exceededAction) { if (m_IsDisposed) { throw new ObjectDisposedException(GetType().Name); } if (storeStream == null) { throw new ArgumentNullException("storeStream"); } if (maxCount < 0) { throw new ArgumentException("Argument 'maxCount' must be >= 0."); } IAsyncResult ar = BeginReadHeader(storeStream, maxCount, exceededAction, null, null); return EndReadHeader(ar); }
/// <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); }