Table of Contents

BiffReader Struct

Definition

Namespace
Bodu.IO.Biff
Assembly
Bodu.IO.Biff.dll
Package
Bodu.IO.Biff 1.0.0
Source
BiffReader.Records.cs

Provides a forward-only, allocation-free reader over a BIFF5 or BIFF8 record stream. The reader is a ref struct over the supplied bytes: each call to Read() advances to the next physical record and exposes its identifier, length, and payload slice, and typed accessors decode the records the codec names.

public ref struct BiffReader
Inherited Members

Remarks

The reader walks physical records only. A CONTINUE record is reported as a record like any other; the one structure whose logical value routinely spans continuation records, the BIFF8 shared string table, is decoded by BiffSstReader, and TryReadContinuation(out ReadOnlySpan<byte>) lets a caller consume a following CONTINUE record for any other structure.

The BIFF version is established from the first BOF record (or supplied through Version) and the code page for byte strings from the CODEPAGE record (or CodePage); the reader keeps no other state, and in particular no workbook, sheet, or cell model. A record whose identifier the codec does not name is never an error - it remains readable through RecordId and ValueSpan.

To read incrementally, capture CurrentState and BytesConsumed after a pass, then construct the next reader over the remaining bytes with that state. With isFinalBlock set to false, an incomplete trailing record makes Read() return false without consuming it so the caller can supply more data; with true, the same condition is a format error.

var reader = new BiffReader(workbookStreamBytes);
while (reader.Read())
{
    switch (reader.RecordType)
    {
        case BiffRecordType.Bof:
            Console.WriteLine($"{reader.Version} {reader.GetBof().SubstreamType}");
            break;
        case BiffRecordType.Number:
            BiffNumberRecord number = reader.GetNumber();
            Console.WriteLine($"R{number.Row}C{number.Column} = {number.Value}");
            break;
        default:
            // Unknown records stay accessible: reader.RecordId, reader.ValueSpan.
            break;
    }
}

Constructors

BiffReader(ReadOnlySpan<byte>)

Initializes a new instance of the BiffReader struct over the supplied bytes, which hold the complete stream.

public BiffReader(ReadOnlySpan<byte> data)

Parameters

data ReadOnlySpan<byte>

The BIFF record bytes.

BiffReader(ReadOnlySpan<byte>, BiffReaderOptions)

Initializes a new instance of the BiffReader struct over the supplied bytes using the supplied options.

public BiffReader(ReadOnlySpan<byte> data, BiffReaderOptions options)

Parameters

data ReadOnlySpan<byte>

The BIFF record bytes.

options BiffReaderOptions

The options seeding the version and code page.

BiffReader(ReadOnlySpan<byte>, bool, BiffReaderState)

Initializes a new instance of the BiffReader struct over a block of a stream, continuing from a previously captured state.

public BiffReader(ReadOnlySpan<byte> data, bool isFinalBlock, BiffReaderState state)

Parameters

data ReadOnlySpan<byte>

The BIFF record bytes, beginning at a record header.

isFinalBlock bool

Whether data holds the end of the stream. When false, an incomplete trailing record is left unconsumed rather than rejected.

state BiffReaderState

The state captured from the reader that processed the preceding bytes.

Properties

BytesConsumed

Gets the number of bytes consumed so far: the offset of the next record header.

public readonly int BytesConsumed { get; }

Property Value

int

The read position within the supplied bytes.

CodePage

Gets the code page in effect for byte strings.

public readonly int CodePage { get; }

Property Value

int

The code page from the most recent CODEPAGE record or the options, or DefaultCodePage.

CurrentState

Gets the state needed to continue the stream in a new reader.

public readonly BiffReaderState CurrentState { get; }

Property Value

BiffReaderState

The established version and code page.

HasRecord

Gets a value indicating whether a record is current.

public readonly bool HasRecord { get; }

Property Value

bool

true after a successful Read() until the stream ends.

Header

Gets the header of the current record.

public readonly BiffRecordHeader Header { get; }

Property Value

BiffRecordHeader

The identifier and declared payload length.

IsContinuation

Gets a value indicating whether the current record is a CONTINUE record carrying the overflow of the record before it.

public readonly bool IsContinuation { get; }

Property Value

bool

true when the current record is Continue.

IsFinalBlock

Gets a value indicating whether the supplied bytes hold the end of the stream.

public readonly bool IsFinalBlock { get; }

Property Value

bool

true when an incomplete trailing record is a format error.

RecordId

Gets the 16-bit identifier of the current record.

public readonly ushort RecordId { get; }

Property Value

ushort

The raw identifier, or zero when no record is current.

RecordLength

Gets the length of the current record's payload, in bytes.

public readonly int RecordLength { get; }

Property Value

int

The payload length, or zero when no record is current.

RecordStartIndex

Gets the byte offset of the current record's header within the supplied bytes.

public readonly int RecordStartIndex { get; }

Property Value

int

The header offset.

RecordType

Gets the identifier of the current record as a BiffRecordType.

public readonly BiffRecordType RecordType { get; }

Property Value

BiffRecordType

The typed identifier, None when no record is current. The value may not correspond to a defined member when the record is one the codec does not name.

ValueSpan

Gets the payload of the current record as a slice of the supplied bytes.

public readonly ReadOnlySpan<byte> ValueSpan { get; }

Property Value

ReadOnlySpan<byte>

The payload, excluding the four-byte header; empty when no record is current.

Version

Gets the BIFF version of the stream.

public readonly BiffVersion Version { get; }

Property Value

BiffVersion

The version established from the first BOF record or the options, or Unknown before either.

Methods

GetBlank()

Decodes the current BLANK record.

public readonly BiffBlankRecord GetBlank()

Returns

BiffBlankRecord

The decoded record.

Exceptions

InvalidOperationException

Thrown when the current record is not a BLANK record.

BiffFormatException

Thrown when the payload is malformed.

GetBof()

Decodes the current BOF record.

public readonly BiffBofRecord GetBof()

Returns

BiffBofRecord

The decoded record.

Exceptions

InvalidOperationException

Thrown when the current record is not a BOF record.

BiffFormatException

Thrown when the payload is malformed.

GetBoolErr()

Decodes the current BOOLERR record.

public readonly BiffBoolErrRecord GetBoolErr()

Returns

BiffBoolErrRecord

The decoded record.

Exceptions

InvalidOperationException

Thrown when the current record is not a BOOLERR record.

BiffFormatException

Thrown when the payload is malformed.

GetBoundSheet()

Decodes the current BOUNDSHEET record.

public readonly BiffBoundSheetRecord GetBoundSheet()

Returns

BiffBoundSheetRecord

The decoded record.

Exceptions

InvalidOperationException

Thrown when the current record is not a BOUNDSHEET record, or the version is unknown.

BiffFormatException

Thrown when the payload is malformed.

GetCodePage()

Decodes the current CODEPAGE record.

public readonly BiffCodePageRecord GetCodePage()

Returns

BiffCodePageRecord

The decoded record.

Exceptions

InvalidOperationException

Thrown when the current record is not a CODEPAGE record.

BiffFormatException

Thrown when the payload is malformed.

GetDateMode()

Decodes the current DATEMODE record.

public readonly BiffDateModeRecord GetDateMode()

Returns

BiffDateModeRecord

The decoded record.

Exceptions

InvalidOperationException

Thrown when the current record is not a DATEMODE record.

BiffFormatException

Thrown when the payload is malformed.

GetDimensions()

Decodes the current DIMENSIONS record.

public readonly BiffDimensionsRecord GetDimensions()

Returns

BiffDimensionsRecord

The decoded record.

Exceptions

InvalidOperationException

Thrown when the current record is not a DIMENSIONS record, or the version is unknown.

BiffFormatException

Thrown when the payload is malformed.

GetFilePass()

Decodes the current FILEPASS record.

public readonly BiffFilePassRecord GetFilePass()

Returns

BiffFilePassRecord

The decoded record.

Exceptions

InvalidOperationException

Thrown when the current record is not a FILEPASS record, or the version is unknown.

BiffFormatException

Thrown when the payload is malformed.

GetFont()

Decodes the current FONT record.

public readonly BiffFontRecord GetFont()

Returns

BiffFontRecord

The decoded record.

Exceptions

InvalidOperationException

Thrown when the current record is not a FONT record, or the version is unknown.

BiffFormatException

Thrown when the payload is malformed.

GetFormat()

Decodes the current FORMAT record.

public readonly BiffFormatRecord GetFormat()

Returns

BiffFormatRecord

The decoded record.

Exceptions

InvalidOperationException

Thrown when the current record is not a FORMAT record, or the version is unknown.

BiffFormatException

Thrown when the payload is malformed.

GetFormula()

Decodes the current FORMULA record.

public readonly BiffFormulaRecord GetFormula()

Returns

BiffFormulaRecord

The decoded record.

Exceptions

InvalidOperationException

Thrown when the current record is not a FORMULA record.

BiffFormatException

Thrown when the payload is malformed.

GetLabel()

Decodes the current LABEL record.

public readonly BiffLabelRecord GetLabel()

Returns

BiffLabelRecord

The decoded record.

Exceptions

InvalidOperationException

Thrown when the current record is not a LABEL record, or the version is unknown.

BiffFormatException

Thrown when the payload is malformed.

GetLabelSst()

Decodes the current LABELSST record.

public readonly BiffLabelSstRecord GetLabelSst()

Returns

BiffLabelSstRecord

The decoded record.

Exceptions

InvalidOperationException

Thrown when the current record is not a LABELSST record.

BiffFormatException

Thrown when the payload is malformed.

GetMulBlank()

Decodes the current MULBLANK record.

public readonly BiffMulBlankRecord GetMulBlank()

Returns

BiffMulBlankRecord

The decoded record.

Exceptions

InvalidOperationException

Thrown when the current record is not a MULBLANK record.

BiffFormatException

Thrown when the payload is malformed.

GetMulRk()

Decodes the current MULRK record.

public readonly BiffMulRkRecord GetMulRk()

Returns

BiffMulRkRecord

The decoded record.

Exceptions

InvalidOperationException

Thrown when the current record is not a MULRK record.

BiffFormatException

Thrown when the payload is malformed.

GetNumber()

Decodes the current NUMBER record.

public readonly BiffNumberRecord GetNumber()

Returns

BiffNumberRecord

The decoded record.

Exceptions

InvalidOperationException

Thrown when the current record is not a NUMBER record.

BiffFormatException

Thrown when the payload is malformed.

GetRString()

Decodes the current RSTRING record, the BIFF5 rich-text label cell.

public readonly BiffRStringRecord GetRString()

Returns

BiffRStringRecord

The decoded record.

Exceptions

InvalidOperationException

Thrown when the current record is not an RSTRING record.

BiffFormatException

Thrown when the payload is malformed.

GetRk()

Decodes the current RK record.

public readonly BiffRkRecord GetRk()

Returns

BiffRkRecord

The decoded record.

Exceptions

InvalidOperationException

Thrown when the current record is not an RK record.

BiffFormatException

Thrown when the payload is malformed.

GetRow()

Decodes the current ROW record.

public readonly BiffRowRecord GetRow()

Returns

BiffRowRecord

The decoded record.

Exceptions

InvalidOperationException

Thrown when the current record is not a ROW record.

BiffFormatException

Thrown when the payload is malformed.

GetSstHeader()

Decodes the counts at the head of the current SST record. The strings themselves are read through BiffSstReader.

public readonly BiffSstHeader GetSstHeader()

Returns

BiffSstHeader

The decoded header.

Exceptions

InvalidOperationException

Thrown when the current record is not an SST record.

BiffFormatException

Thrown when the payload is malformed.

GetString()

Decodes the current STRING record, the cached text result of the preceding formula.

public readonly BiffStringRecord GetString()

Returns

BiffStringRecord

The decoded record.

Exceptions

InvalidOperationException

Thrown when the current record is not a STRING record, or the version is unknown.

BiffFormatException

Thrown when the payload is malformed.

GetXf()

Decodes the current XF record.

public readonly BiffXfRecord GetXf()

Returns

BiffXfRecord

The decoded record.

Exceptions

InvalidOperationException

Thrown when the current record is not an XF record.

BiffFormatException

Thrown when the payload is malformed.

Read()

Advances to the next physical record.

public bool Read()

Returns

bool

true when a record was read; false at the clean end of the supplied bytes, or - when IsFinalBlock is false - when the next record is incomplete and more data is needed.

Exceptions

BiffFormatException

Thrown when the stream holds the end of the data and a trailing fragment is too short to form a record header, a record's declared payload runs past the end of the data, or a BOF record disagrees with the established version.

BiffUnsupportedVersionException

Thrown when the first BOF record declares a version other than BIFF5 or BIFF8, or the stream opens with a BIFF2, BIFF3, or BIFF4 beginning-of-file record.

TryReadContinuation(out ReadOnlySpan<byte>)

Consumes the record that follows the current one when, and only when, it is a CONTINUE record, making it current and exposing its payload.

public bool TryReadContinuation(out ReadOnlySpan<byte> payload)

Parameters

payload ReadOnlySpan<byte>

When this method returns, the continuation payload when one was consumed.

Returns

bool

true when a CONTINUE record was consumed; false when the next record is any other kind, the stream has ended, or more data is needed.

Exceptions

BiffFormatException

Thrown when the stream holds the end of the data and the continuation record's declared payload runs past it.

Applies to

ProductVersions
.NET8, 10