/// <summary> /// Loads a header from the specified stream. /// </summary> /// <param name="stream">The input stream.</param> /// <returns>A header loaded from the specified stream.</returns> /// <exception cref="ArgumentNullException"><paramref name="stream"/> is <c>null</c>.</exception> public virtual async Task <Header> LoadAsync(Stream stream) { if (stream == null) { throw new ArgumentNullException(nameof(stream)); } // optimization: be one byte ahead when loading columns => only one I/O read per column var buffer = new byte[HEADER_SIZE + 1]; int totalReadBytes = await stream.ReadAsync(buffer, 0, buffer.Length).ConfigureAwait(false); BasicProperties headerProperties = ParseBasicProperties(buffer); LoadColumnsResult loadColumnsResult = await LoadColumnsAsync(stream, buffer.Last()).ConfigureAwait(false); totalReadBytes += loadColumnsResult.ReadBytes; int bytesToSkip = headerProperties.HeaderSize - totalReadBytes; if (bytesToSkip > 0) { // move to the end of the header if (stream.CanSeek) { stream.Seek(bytesToSkip, SeekOrigin.Current); } else { // async read is more expensive then sync read so we use bigger buffer to reduce the number of I/O reads const int MAX_SKIP_BUFFER_SIZE = 512; byte[] skipBuffer = buffer; if (bytesToSkip > buffer.Length) { skipBuffer = new byte[Math.Min(bytesToSkip, MAX_SKIP_BUFFER_SIZE)]; } while (bytesToSkip > 0) { bytesToSkip -= await stream.ReadAsync(skipBuffer, 0, Math.Min(skipBuffer.Length, bytesToSkip)).ConfigureAwait(false); } } } return(CreateHeader(headerProperties, loadColumnsResult.Columns)); }
/// <summary> /// Loads a header from the specified stream. /// </summary> /// <param name="stream">The input stream.</param> /// <returns>A header loaded from the specified stream.</returns> /// <exception cref="ArgumentNullException"><paramref name="stream"/> is <c>null</c>.</exception> public virtual Header Load(Stream stream) { if (stream == null) { throw new ArgumentNullException(nameof(stream)); } // optimization: be one byte ahead when loading columns => only one I/O read per column var buffer = new byte[HEADER_SIZE + 1]; int totalReadBytes = stream.Read(buffer, 0, buffer.Length); BasicProperties headerProperties = ParseBasicProperties(buffer); LoadColumnsResult loadColumnsResult = LoadColumns(stream, buffer.Last()); totalReadBytes += loadColumnsResult.ReadBytes; int bytesToSkip = headerProperties.HeaderSize - totalReadBytes; if (bytesToSkip > 0) { // move to the end of the header if (stream.CanSeek) { stream.Seek(bytesToSkip, SeekOrigin.Current); } else { while (bytesToSkip > 0) { bytesToSkip -= stream.Read(buffer, 0, Math.Min(buffer.Length, bytesToSkip)); } } } return(CreateHeader(headerProperties, loadColumnsResult.Columns)); }