namespace WatsonTcp { using System; using System.Collections.Generic; using System.IO; /// /// Event arguments for when a stream is received. /// public class StreamReceivedEventArgs : EventArgs { #region Public-Members /// /// Client metadata. /// public ClientMetadata Client { get; } = null; /// /// The metadata received from the endpoint. /// public Dictionary Metadata { get { return _Metadata; } set { if (value == null) _Metadata = new Dictionary(); else _Metadata = value; } } /// /// The number of data bytes that should be read from DataStream. /// public long ContentLength { get; } /// /// The stream containing the message data. /// public Stream DataStream { get; } /// /// The data from DataStream. /// Using Data will fully read the contents of DataStream. /// public byte[] Data { get { if (_Data != null) return _Data; if (ContentLength <= 0) return null; _Data = ReadFromStream(DataStream, ContentLength); return _Data; } } #endregion #region Private-Members private Dictionary _Metadata = new Dictionary(); private byte[] _Data = null; private int _BufferSize = 65536; #endregion #region Constructors-and-Factories internal StreamReceivedEventArgs(ClientMetadata client, Dictionary metadata, long contentLength, Stream stream) { Client = client; Metadata = metadata; ContentLength = contentLength; DataStream = stream; } #endregion #region Public-Methods #endregion #region Private-Methods private byte[] ReadFromStream(Stream stream, long count) { if (count <= 0) return Array.Empty(); byte[] buffer = new byte[_BufferSize]; int read = 0; long bytesRemaining = count; MemoryStream ms = new MemoryStream(); while (bytesRemaining > 0) { if (_BufferSize > bytesRemaining) buffer = new byte[bytesRemaining]; read = stream.Read(buffer, 0, buffer.Length); if (read > 0) { ms.Write(buffer, 0, read); bytesRemaining -= read; } else { throw new IOException("Could not read from supplied stream."); } } byte[] data = ms.ToArray(); return data; } #endregion } }