Utf8BencodeWriter Struct
Definition
Provides a forward-only writer that emits canonical Bencode (BEP 3) bytes to an IBufferWriter<T>. Because the grammar requires dictionary keys in ascending bytewise order, the writer buffers each dictionary's entries and sorts them when the dictionary is closed; values at the root and inside lists stream directly to the destination.
public ref struct Utf8BencodeWriter
- Inherited Members
Remarks
The writer is a ref struct whose mutable state lives in shared managed buffers, so a copy taken
by value continues to write to the same output. Booleans, floating-point values, and date-times have no Bencode
representation and must be reduced to an integer or byte string by a converter before they are written.
The writer validates the call sequence against the canonical grammar: a property name may only be written inside an open dictionary, every dictionary value must follow a property name, container ends must match the open container kind, a dictionary containing duplicate keys is rejected when it is closed, and a second root value is rejected unless AllowMultipleRootValues is set.
Scalars and lists written outside any dictionary are emitted to the destination as they are written; bytes that belong to an open dictionary are held in that dictionary's buffer until it closes, because the canonical key order is only known at that point. A consequence of streaming is that a write failing partway through a document leaves the bytes already emitted in the destination - discard the destination when any write throws, and assert CurrentDepth is zero before consuming it.
var output = new ArrayBufferWriter<byte>();
var writer = new Utf8BencodeWriter(output);
writer.WriteStartDictionary();
writer.WriteString("cow", "moo"); // keys are sorted on close
writer.WriteInteger("age", 42);
writer.WriteEndDictionary();
// output.WrittenSpan now holds canonical "d3:agei42e3:cow3:mooe".
Constructors
Utf8BencodeWriter(IBufferWriter<byte>)
Initializes a new instance of the Utf8BencodeWriter struct.
public Utf8BencodeWriter(IBufferWriter<byte> output)
Parameters
outputIBufferWriter<byte>The destination buffer writer.
Exceptions
- ArgumentNullException
Thrown when
outputis null.
Utf8BencodeWriter(IBufferWriter<byte>, BencodeWriterOptions)
Initializes a new instance of the Utf8BencodeWriter struct using the supplied options.
public Utf8BencodeWriter(IBufferWriter<byte> output, BencodeWriterOptions options)
Parameters
outputIBufferWriter<byte>The destination buffer writer.
optionsBencodeWriterOptionsThe writer options controlling the maximum nesting depth and root-value policy.
Remarks
A MaxDepth of zero or less selects the default maximum depth of 64, and a larger value is clamped to Bodu.Text.Bencode.BencodeLimits.AbsoluteMaxDepth so that an unbounded configured value cannot drive the writer into a StackOverflowException. Opening a list or dictionary past that depth throws BencodeSerializationException.
Exceptions
- ArgumentNullException
Thrown when
outputis null.
Properties
CurrentDepth
Gets the current container nesting depth.
public readonly int CurrentDepth { get; }
Property Value
- int
The number of open containers, where zero means the writer is at the document root.
Remarks
A document is complete only when the depth has returned to zero: an unclosed dictionary's bytes never reach the
destination, and an unclosed list leaves the output without its terminating e. Callers driving the writer
manually can assert this property is zero before consuming the destination.
Options
Gets the customizations the writer was created with.
public readonly BencodeWriterOptions Options { get; }
Property Value
- BencodeWriterOptions
The effective options, with MaxDepth carrying the resolved value rather than a zero placeholder.
Methods
WriteByteString(ReadOnlySpan<byte>)
Writes a byte-string value.
public readonly void WriteByteString(ReadOnlySpan<byte> value)
Parameters
valueReadOnlySpan<byte>The byte-string content.
Exceptions
- InvalidOperationException
Thrown when the value is written directly inside a dictionary before a property name has been written, or when a complete root value has already been written and AllowMultipleRootValues is not set.
WriteByteString(ReadOnlySpan<byte>, ReadOnlySpan<byte>)
Writes a property name and a byte-string value in one call.
public readonly void WriteByteString(ReadOnlySpan<byte> name, ReadOnlySpan<byte> value)
Parameters
nameReadOnlySpan<byte>The key bytes.
valueReadOnlySpan<byte>The byte-string content.
Exceptions
- InvalidOperationException
Thrown when the currently open container is not a dictionary, or when a previously written property name is still awaiting its value.
WriteByteString(string, ReadOnlySpan<byte>)
Writes a property name and a byte-string value in one call.
public readonly void WriteByteString(string name, ReadOnlySpan<byte> value)
Parameters
namestringThe key text.
valueReadOnlySpan<byte>The byte-string content.
Exceptions
- ArgumentNullException
Thrown when
nameis null.- InvalidOperationException
Thrown when the currently open container is not a dictionary, or when a previously written property name is still awaiting its value.
WriteEndDictionary()
Writes the end of the current dictionary, emitting its entries in ascending bytewise key order.
public readonly void WriteEndDictionary()
Exceptions
- InvalidOperationException
Thrown when no container is open, when the currently open container is not a dictionary, or when a property name is still awaiting its value.
- BencodeSerializationException
Thrown when the dictionary contains more than one entry for the same key, which canonical Bencode forbids.
WriteEndList()
Writes the end of the current list.
public readonly void WriteEndList()
Exceptions
- InvalidOperationException
Thrown when no container is open, or when the currently open container is not a list.
WriteInteger(long)
Writes an integer value.
public readonly void WriteInteger(long value)
Parameters
valuelongThe integer value.
Exceptions
- InvalidOperationException
Thrown when the value is written directly inside a dictionary before a property name has been written, or when a complete root value has already been written and AllowMultipleRootValues is not set.
WriteInteger(ReadOnlySpan<byte>, long)
Writes a property name and an integer value in one call.
public readonly void WriteInteger(ReadOnlySpan<byte> name, long value)
Parameters
nameReadOnlySpan<byte>The key bytes.
valuelongThe integer value.
Exceptions
- InvalidOperationException
Thrown when the currently open container is not a dictionary, or when a previously written property name is still awaiting its value.
WriteInteger(ReadOnlySpan<byte>, ulong)
Writes a property name and an unsigned integer value in one call, permitting the full ulong range.
public readonly void WriteInteger(ReadOnlySpan<byte> name, ulong value)
Parameters
nameReadOnlySpan<byte>The key bytes.
valueulongThe unsigned integer value.
Exceptions
- InvalidOperationException
Thrown when the currently open container is not a dictionary, or when a previously written property name is still awaiting its value.
WriteInteger(string, long)
Writes a property name and an integer value in one call.
public readonly void WriteInteger(string name, long value)
Parameters
Exceptions
- ArgumentNullException
Thrown when
nameis null.- InvalidOperationException
Thrown when the currently open container is not a dictionary, or when a previously written property name is still awaiting its value.
WriteInteger(string, ulong)
Writes a property name and an unsigned integer value in one call, permitting the full ulong range.
public readonly void WriteInteger(string name, ulong value)
Parameters
Exceptions
- ArgumentNullException
Thrown when
nameis null.- InvalidOperationException
Thrown when the currently open container is not a dictionary, or when a previously written property name is still awaiting its value.
WriteInteger(ulong)
Writes an unsigned integer value, permitting the full ulong range.
public readonly void WriteInteger(ulong value)
Parameters
valueulongThe unsigned integer value.
Remarks
Bencode integers are arbitrary-precision in BEP 3, so values between MaxValue and MaxValue are valid documents even though they exceed the writer's signed 64-bit overload. A reader consuming such a value must use GetUInt64() rather than GetInt64().
Exceptions
- InvalidOperationException
Thrown when the value is written directly inside a dictionary before a property name has been written, or when a complete root value has already been written and AllowMultipleRootValues is not set.
WritePropertyName(ReadOnlySpan<byte>)
Writes the name of the dictionary key whose value follows.
public readonly void WritePropertyName(ReadOnlySpan<byte> name)
Parameters
nameReadOnlySpan<byte>The key bytes.
Exceptions
- InvalidOperationException
Thrown when the currently open container is not a dictionary, or when a previously written property name is still awaiting its value.
WritePropertyName(ReadOnlySpan<char>)
Writes the name of the dictionary key whose value follows, encoding the characters as UTF-8.
public readonly void WritePropertyName(ReadOnlySpan<char> name)
Parameters
nameReadOnlySpan<char>The key text.
Exceptions
- InvalidOperationException
Thrown when the currently open container is not a dictionary, or when a previously written property name is still awaiting its value.
WritePropertyName(string)
Writes the name of the dictionary key whose value follows, encoding the name as UTF-8.
public readonly void WritePropertyName(string name)
Parameters
namestringThe key text.
Exceptions
- ArgumentNullException
Thrown when
nameis null.- InvalidOperationException
Thrown when the currently open container is not a dictionary, or when a previously written property name is still awaiting its value.
WriteRawValue(ReadOnlySpan<byte>, bool)
Writes a pre-encoded Bencode value verbatim. Supports round-tripping verified slices such as a torrent's
info dictionary without re-encoding.
public readonly void WriteRawValue(ReadOnlySpan<byte> value, bool skipInputValidation = false)
Parameters
valueReadOnlySpan<byte>The complete, already-encoded Bencode value bytes.
skipInputValidationbooltrue to write the bytes without verifying they form a single complete Bencode value.
Remarks
Validation parses value with a standalone Utf8BencodeReader using the
default maximum depth; the payload's nesting is not counted against this writer's configured
MaxDepth. When validation is skipped the caller is responsible for the bytes
being canonical - non-canonical bytes produce a document this library's reader rejects.
Exceptions
- BencodeFormatException
Thrown when validation is enabled and
valueis not exactly one complete, canonical Bencode value.- InvalidOperationException
Thrown when the value is written directly inside a dictionary before a property name has been written, or when a complete root value has already been written and AllowMultipleRootValues is not set.
WriteStartDictionary()
Writes the start of a dictionary.
public readonly void WriteStartDictionary()
Remarks
No bytes are emitted until the dictionary closes: entries must be reordered into ascending bytewise key order, so the dictionary's content accumulates in a private buffer that WriteEndDictionary() flushes.
Exceptions
- InvalidOperationException
Thrown when the dictionary is opened directly inside a dictionary before a property name has been written, or when a complete root value has already been written and AllowMultipleRootValues is not set.
- BencodeSerializationException
Thrown when opening the dictionary would exceed the configured maximum nesting depth.
WriteStartDictionary(ReadOnlySpan<byte>)
Writes a property name and the start of a dictionary as its value.
public readonly void WriteStartDictionary(ReadOnlySpan<byte> name)
Parameters
nameReadOnlySpan<byte>The key bytes.
Exceptions
- InvalidOperationException
Thrown when the currently open container is not a dictionary, or when a previously written property name is still awaiting its value.
- BencodeSerializationException
Thrown when opening the dictionary would exceed the configured maximum nesting depth.
WriteStartDictionary(string)
Writes a property name and the start of a dictionary as its value, combining WritePropertyName(string) and WriteStartDictionary().
public readonly void WriteStartDictionary(string name)
Parameters
namestringThe key text.
Exceptions
- ArgumentNullException
Thrown when
nameis null.- InvalidOperationException
Thrown when the currently open container is not a dictionary, or when a previously written property name is still awaiting its value.
- BencodeSerializationException
Thrown when opening the dictionary would exceed the configured maximum nesting depth.
WriteStartList()
Writes the start of a list.
public readonly void WriteStartList()
Exceptions
- InvalidOperationException
Thrown when the list is opened directly inside a dictionary before a property name has been written, or when a complete root value has already been written and AllowMultipleRootValues is not set.
- BencodeSerializationException
Thrown when opening the list would exceed the configured maximum nesting depth.
WriteStartList(ReadOnlySpan<byte>)
Writes a property name and the start of a list as its value.
public readonly void WriteStartList(ReadOnlySpan<byte> name)
Parameters
nameReadOnlySpan<byte>The key bytes.
Exceptions
- InvalidOperationException
Thrown when the currently open container is not a dictionary, or when a previously written property name is still awaiting its value.
- BencodeSerializationException
Thrown when opening the list would exceed the configured maximum nesting depth.
WriteStartList(string)
Writes a property name and the start of a list as its value, combining WritePropertyName(string) and WriteStartList().
public readonly void WriteStartList(string name)
Parameters
namestringThe key text.
Exceptions
- ArgumentNullException
Thrown when
nameis null.- InvalidOperationException
Thrown when the currently open container is not a dictionary, or when a previously written property name is still awaiting its value.
- BencodeSerializationException
Thrown when opening the list would exceed the configured maximum nesting depth.
WriteString(ReadOnlySpan<byte>, string)
Writes a property name and a string value in one call, encoding the value as UTF-8.
public readonly void WriteString(ReadOnlySpan<byte> name, string value)
Parameters
nameReadOnlySpan<byte>The key bytes.
valuestringThe string value.
Exceptions
- ArgumentNullException
Thrown when
valueis null.- InvalidOperationException
Thrown when the currently open container is not a dictionary, or when a previously written property name is still awaiting its value.
WriteString(string)
Writes a string value, encoding it as a UTF-8 byte string.
public readonly void WriteString(string value)
Parameters
valuestringThe string value.
Exceptions
- ArgumentNullException
Thrown when
valueis null.- InvalidOperationException
Thrown when the value is written directly inside a dictionary before a property name has been written, or when a complete root value has already been written and AllowMultipleRootValues is not set.
WriteString(string, string)
Writes a property name and a string value in one call, encoding both as UTF-8.
public readonly void WriteString(string name, string value)
Parameters
Exceptions
- ArgumentNullException
Thrown when
nameorvalueis null.- InvalidOperationException
Thrown when the currently open container is not a dictionary, or when a previously written property name is still awaiting its value.
Applies to
| Product | Versions |
|---|---|
| .NET | 8, 10 |