Table of Contents

BencodeNode Class

Definition

Namespace
Bodu.Text.Bencode.Nodes
Assembly
Bodu.Text.Bencode.dll
Package
Bodu.Text.Bencode 1.0.0
Source
BencodeNode.cs

Represents a single node in a mutable Bencode (BEP 3) document object model, serving as the base for the three concrete node kinds - BencodeObject, BencodeArray, and BencodeValue.

public abstract class BencodeNode
Inheritance
BencodeNode
Derived
Inherited Members
Extension Methods

Remarks

A node tree is editable in place: containers expose the standard collection surfaces, scalar values can be replaced, and any node can be re-serialized to canonical Bencode through WriteTo(Utf8BencodeWriter) or ToByteArray(). Bencode has no boolean, null, or floating-point values, so the model defines only the four value kinds the format supports; in particular there is no null node, so a tree that still contains a null entry cannot be written.

Each node has at most one parent. Adding a node that already belongs to another container throws an InvalidOperationException.

// Parse, edit in place, and re-serialize to canonical Bencode.
BencodeNode? root = BencodeNode.Parse("d3:cowi42ee"u8);
BencodeObject dict = root!.AsObject();

long age = dict["cow"]!.AsValue().GetValue<long>();   // 42
dict["pig"] = BencodeValue.Create("oink");

byte[] bytes = dict.ToByteArray();   // "d3:cow i42e 3:pig 4:oink e" (sorted)

Properties

this[int]

Gets or sets the element at the specified index, treating this node as a BencodeArray.

public BencodeNode? this[int index] { get; set; }

Parameters

index int

The zero-based index of the element.

Property Value

BencodeNode

The element at index.

Exceptions

InvalidOperationException

Thrown when this node is not a BencodeArray.

ArgumentOutOfRangeException

Thrown when index is outside the bounds of the array.

this[string]

Gets or sets the value associated with the specified property name, treating this node as a BencodeObject.

public BencodeNode? this[string propertyName] { get; set; }

Parameters

propertyName string

The property name to look up.

Property Value

BencodeNode

The value associated with propertyName.

Exceptions

InvalidOperationException

Thrown when this node is not a BencodeObject.

ArgumentNullException

Thrown when propertyName is null.

Parent

Gets the node that contains this node, or null when this node is the root of its tree.

public BencodeNode? Parent { get; }

Property Value

BencodeNode

The containing node, or null for a root node.

Root

Gets the topmost node of the tree this node belongs to.

public BencodeNode Root { get; }

Property Value

BencodeNode

The root node reached by following Parent until it is null.

Methods

AsArray()

Returns this node as a BencodeArray.

public BencodeArray AsArray()

Returns

BencodeArray

This node cast to BencodeArray.

Exceptions

InvalidOperationException

Thrown when this node is not a BencodeArray.

AsObject()

Returns this node as a BencodeObject.

public BencodeObject AsObject()

Returns

BencodeObject

This node cast to BencodeObject.

Exceptions

InvalidOperationException

Thrown when this node is not a BencodeObject.

AsValue()

Returns this node as a BencodeValue.

public BencodeValue AsValue()

Returns

BencodeValue

This node cast to BencodeValue.

Exceptions

InvalidOperationException

Thrown when this node is not a BencodeValue.

DeepClone()

Creates a deep copy of this node and its entire subtree.

public abstract BencodeNode DeepClone()

Returns

BencodeNode

An independent clone with no parent.

DeepEquals(BencodeNode?, BencodeNode?)

Determines whether two node trees are structurally equal.

public static bool DeepEquals(BencodeNode? node1, BencodeNode? node2)

Parameters

node1 BencodeNode

The first node, which may be null.

node2 BencodeNode

The second node, which may be null.

Returns

bool

true when both nodes are null or represent the same value kind with equal content; otherwise false.

Remarks

Integers compare by value and byte strings by byte sequence. Arrays compare element-wise in order, and objects compare by key set with equal values, independently of in-memory key order.

GetPath()

Computes the path from the root of this node's tree to this node.

public string GetPath()

Returns

string

The JSONPath-style path: $ for a root node, with [n] segments for array indices and .name segments for object keys. A key containing characters other than ASCII letters, digits, and underscores is rendered as a quoted ['name'] segment.

Remarks

When the same node instance is stored under more than one key of the same object, the path reports the first matching key in enumeration order.

GetValueKind()

Gets the kind of value this node represents.

public abstract BencodeValueKind GetValueKind()

Returns

BencodeValueKind

The BencodeValueKind of this node.

GetValue<T>()

Returns the scalar value of this node converted to the requested type, treating this node as a BencodeValue.

public T GetValue<T>()

Returns

T

The converted scalar value.

Type Parameters

T

The type to convert the scalar value to.

Exceptions

InvalidOperationException

Thrown when this node is not a BencodeValue, or its stored value cannot be converted to T.

Parse(ReadOnlySpan<byte>)

Parses a single Bencode document into a node tree.

public static BencodeNode? Parse(ReadOnlySpan<byte> data)

Parameters

data ReadOnlySpan<byte>

The Bencode source bytes.

Returns

BencodeNode

The root node of the parsed tree.

Remarks

The underlying reader enforces the canonical grammar - a single root value, ascending unique dictionary keys, and no trailing bytes - so a successful parse round-trips byte-for-byte through ToByteArray().

Exceptions

BencodeFormatException

Thrown when data is empty or is not valid canonical Bencode.

Parse(ReadOnlySpan<byte>, BencodeNodeOptions)

Parses a single Bencode document into a node tree, using the supplied options for every object created while parsing.

public static BencodeNode? Parse(ReadOnlySpan<byte> data, BencodeNodeOptions options)

Parameters

data ReadOnlySpan<byte>

The Bencode source bytes.

options BencodeNodeOptions

The node options controlling property-name case sensitivity.

Returns

BencodeNode

The root node of the parsed tree.

Remarks

Every BencodeObject materialized while parsing adopts the comparison selected by options, so a case-insensitive parse yields a tree whose dictionary lookups ignore case.

Exceptions

BencodeFormatException

Thrown when data is empty or is not valid canonical Bencode.

Parse(ReadOnlySpan<byte>, BencodeNodeOptions, BencodeDocumentOptions)

Parses a single Bencode document into a node tree, using the supplied node options for every object created while parsing and the supplied document options for the parse itself.

public static BencodeNode? Parse(ReadOnlySpan<byte> data, BencodeNodeOptions options, BencodeDocumentOptions documentOptions)

Parameters

data ReadOnlySpan<byte>

The Bencode source bytes.

options BencodeNodeOptions

The node options controlling property-name case sensitivity.

documentOptions BencodeDocumentOptions

The document options controlling depth and dictionary-key leniency.

Returns

BencodeNode

The root node of the parsed tree.

Remarks

When AllowDuplicateKeys is set, repeated keys collapse into the dictionary-backed BencodeObject with the last occurrence winning.

Exceptions

BencodeFormatException

Thrown when data is empty or is not a single Bencode value acceptable under documentOptions.

ReplaceWith(BencodeNode?)

Replaces this node within its parent container with the supplied value, detaching this node. The implicit conversions from string, integers, and byte arrays let scalars be passed directly.

public void ReplaceWith(BencodeNode? value)

Parameters

value BencodeNode

The replacement node, or null to clear the slot this node occupies.

Remarks

When this node has no parent the call does nothing. After a successful replacement this node's Parent is null and it can be added to another container.

Exceptions

InvalidOperationException

Thrown when value already belongs to another container.

ToByteArray()

Serializes this node to a new canonical Bencode byte array.

public byte[] ToByteArray()

Returns

byte[]

The Bencode encoding of this node.

Exceptions

BencodeSerializationException

Thrown when the subtree rooted at this node contains a null entry, which has no Bencode representation.

ToString()

Returns a string representation of this node.

public override abstract string ToString()

Returns

string

A textual rendering of this node.

WriteTo(Utf8BencodeWriter)

Writes the canonical Bencode encoding of this node to the supplied writer.

public abstract void WriteTo(Utf8BencodeWriter writer)

Parameters

writer Utf8BencodeWriter

The destination writer.

Exceptions

BencodeSerializationException

Thrown when the subtree rooted at this node contains a null entry, which has no Bencode representation.

Operators

explicit operator byte[](BencodeNode)

Reads the scalar value of the supplied node as a byte array.

public static explicit operator byte[](BencodeNode node)

Parameters

node BencodeNode

The node to read.

Returns

byte[]

Exceptions

ArgumentNullException

Thrown when node is null.

InvalidOperationException

Thrown when node is not a byte-string BencodeValue.

explicit operator int(BencodeNode)

Reads the scalar value of the supplied node as a 32-bit integer.

public static explicit operator int(BencodeNode node)

Parameters

node BencodeNode

The node to read.

Returns

int

Exceptions

ArgumentNullException

Thrown when node is null.

InvalidOperationException

Thrown when node is not an integer-valued BencodeValue.

explicit operator long(BencodeNode)

Reads the scalar value of the supplied node as a 64-bit integer.

public static explicit operator long(BencodeNode node)

Parameters

node BencodeNode

The node to read.

Returns

long

Exceptions

ArgumentNullException

Thrown when node is null.

InvalidOperationException

Thrown when node is not an integer-valued BencodeValue.

explicit operator string(BencodeNode)

Reads the scalar value of the supplied node as a string, decoding the byte string as UTF-8.

public static explicit operator string(BencodeNode node)

Parameters

node BencodeNode

The node to read.

Returns

string

Exceptions

ArgumentNullException

Thrown when node is null.

InvalidOperationException

Thrown when node is not a byte-string BencodeValue.

explicit operator ulong(BencodeNode)

Reads the scalar value of the supplied node as an unsigned 64-bit integer.

public static explicit operator ulong(BencodeNode node)

Parameters

node BencodeNode

The node to read.

Returns

ulong

Exceptions

ArgumentNullException

Thrown when node is null.

InvalidOperationException

Thrown when node is not a non-negative integer-valued BencodeValue.

implicit operator BencodeNode(byte[])

Creates a BencodeValue that wraps the supplied byte array as a byte string.

public static implicit operator BencodeNode(byte[] value)

Parameters

value byte[]

The byte array to wrap.

Returns

BencodeNode

implicit operator BencodeNode(int)

Creates a BencodeValue that wraps the supplied 32-bit integer.

public static implicit operator BencodeNode(int value)

Parameters

value int

The integer to wrap.

Returns

BencodeNode

implicit operator BencodeNode(long)

Creates a BencodeValue that wraps the supplied 64-bit integer.

public static implicit operator BencodeNode(long value)

Parameters

value long

The integer to wrap.

Returns

BencodeNode

implicit operator BencodeNode(string)

Creates a BencodeValue that wraps the supplied string as a byte string.

public static implicit operator BencodeNode(string value)

Parameters

value string

The string to wrap.

Returns

BencodeNode

implicit operator BencodeNode(ulong)

Creates a BencodeValue that wraps the supplied unsigned 64-bit integer, permitting the full ulong range.

public static implicit operator BencodeNode(ulong value)

Parameters

value ulong

The unsigned integer to wrap.

Returns

BencodeNode

Applies to

ProductVersions
.NET8, 10