TableDefinition instances. Provides a readable, type-safe API for defining PSEM table structures." /> TableDefinition instances. Provides a readable, type-safe API for defining PSEM table structures." /> TableDefinition instances. Provides a readable, type-safe API for defining PSEM table structures." />
Class Sealed
public sealed class TableDefinitionBuilder

Namespace: SharpMeter.Core.Tables

Fluent builder for constructing TableDefinition instances. Provides a readable, type-safe API for defining PSEM table structures.

Remarks

Example usage:


var definition = TableDefinitionBuilder.Create(1, "Manufacturer ID")
    .WithDescription("General Manufacturer Identification Table")
    .WithSize(32)
    .Ascii("MANUFACTURER", 4, "Manufacturer code")
    .Ascii("ED_MODEL", 8, "End device model")
    .UInt8("HW_VERSION_NUMBER", "Hardware version")
    .UInt8("HW_REVISION_NUMBER", "Hardware revision")
    .UInt8("FW_VERSION_NUMBER", "Firmware version")
    .UInt8("FW_REVISION_NUMBER", "Firmware revision")
    .Ascii("MFG_SERIAL_NUMBER", 16, "Serial number")
    .Build();

Methods

NameDescription
Ascii(…) Adds an ASCII string field.
AtOffset(int offset) Advances the current offset to a specific position (for gaps/padding).
Bcd(…) Adds a BCD field.
BitArray(…) Adds a bit array field (each bit maps to a table/procedure ID).
BitField(…) Adds a bit field with sub-field definitions using a nested builder.
Bool(string name, string description) Adds a boolean field (1 byte).
Build() Builds the immutable TableDefinition.
Create(ushort tableId, string name) static Creates a new builder for a table definition.
DateTime(…) Adds a date/time field (6+ bytes).
Enum(…) Adds an enum field with value-to-name mappings.
Hex(…) Adds a raw hex field.
Int16(string name, string description) Adds a signed 16-bit integer field (big-endian).
Int32(string name, string description) Adds a signed 32-bit integer field (big-endian).
Int8(string name, string description) Adds a signed 8-bit integer field.
Manufacturing(ushort tableNumber, string name) static Creates a builder for a manufacturing table (MT). Adds 2048 offset automatically.
Skip(int bytes) Skips the specified number of bytes (padding/reserved).
Standard(ushort tableId, string name) static Creates a builder for a standard table (ST). The tableId is used directly.
String(…) Adds a UTF-8 string field.
UInt16(string name, string description) Adds an unsigned 16-bit integer field (big-endian).
UInt32(string name, string description) Adds an unsigned 32-bit integer field (big-endian).
UInt8(string name, string description) Adds an unsigned 8-bit integer field.
WithDescription(string description) Sets the table description.
WithSize(int size) Sets the expected total size in bytes.

Ascii(string name, int size, string description)

TableDefinitionBuilder TableDefinitionBuilder.Ascii(string name, int size, string description = "")

Adds an ASCII string field.

AtOffset(int offset)

TableDefinitionBuilder TableDefinitionBuilder.AtOffset(int offset)

Advances the current offset to a specific position (for gaps/padding).

Bcd(string name, int size, string description)

TableDefinitionBuilder TableDefinitionBuilder.Bcd(string name, int size, string description = "")

Adds a BCD field.

BitArray(string name, int size, string description)

TableDefinitionBuilder TableDefinitionBuilder.BitArray(string name, int size, string description = "")

Adds a bit array field (each bit maps to a table/procedure ID).

BitField(string name, int size, string description, BitFieldBuilder> configure)

TableDefinitionBuilder TableDefinitionBuilder.BitField(string name, int size, string description, Action<BitFieldBuilder> configure)

Adds a bit field with sub-field definitions using a nested builder.

Parameters

NameTypeDescription
namestringThe field name.
sizeintSize in bytes (1, 2, or 4).
descriptionstringHuman-readable description.
configureAction<SharpMeter.Core.Tables.BitFieldBuilder>Action to configure bit sub-fields.

Bool(string name, string description)

TableDefinitionBuilder TableDefinitionBuilder.Bool(string name, string description = "")

Adds a boolean field (1 byte).

Build()

TableDefinition TableDefinitionBuilder.Build()

Builds the immutable TableDefinition.

Create(ushort tableId, string name)

TableDefinitionBuilder TableDefinitionBuilder.Create(ushort tableId, string name)

Creates a new builder for a table definition.

Parameters

NameTypeDescription
tableIdushortThe table ID (0-4095). IDs 0-2047 are standard tables, 2048-4095 are manufacturing.
namestringThe table name.

Returns: A new builder instance.

DateTime(string name, int size, string description)

TableDefinitionBuilder TableDefinitionBuilder.DateTime(string name, int size = 6, string description = "")

Adds a date/time field (6+ bytes).

Enum(string name, string description, (int Value, string Label)[] values)

TableDefinitionBuilder TableDefinitionBuilder.Enum(string name, string description, params (int Value, string Label)[] values)

Adds an enum field with value-to-name mappings.

Hex(string name, int size, string description)

TableDefinitionBuilder TableDefinitionBuilder.Hex(string name, int size, string description = "")

Adds a raw hex field.

Int16(string name, string description)

TableDefinitionBuilder TableDefinitionBuilder.Int16(string name, string description = "")

Adds a signed 16-bit integer field (big-endian).

Int32(string name, string description)

TableDefinitionBuilder TableDefinitionBuilder.Int32(string name, string description = "")

Adds a signed 32-bit integer field (big-endian).

Int8(string name, string description)

TableDefinitionBuilder TableDefinitionBuilder.Int8(string name, string description = "")

Adds a signed 8-bit integer field.

Manufacturing(ushort tableNumber, string name)

TableDefinitionBuilder TableDefinitionBuilder.Manufacturing(ushort tableNumber, string name)

Creates a builder for a manufacturing table (MT). Adds 2048 offset automatically.

Skip(int bytes)

TableDefinitionBuilder TableDefinitionBuilder.Skip(int bytes)

Skips the specified number of bytes (padding/reserved).

Standard(ushort tableId, string name)

TableDefinitionBuilder TableDefinitionBuilder.Standard(ushort tableId, string name)

Creates a builder for a standard table (ST). The tableId is used directly.

String(string name, int size, string description)

TableDefinitionBuilder TableDefinitionBuilder.String(string name, int size, string description = "")

Adds a UTF-8 string field.

UInt16(string name, string description)

TableDefinitionBuilder TableDefinitionBuilder.UInt16(string name, string description = "")

Adds an unsigned 16-bit integer field (big-endian).

UInt32(string name, string description)

TableDefinitionBuilder TableDefinitionBuilder.UInt32(string name, string description = "")

Adds an unsigned 32-bit integer field (big-endian).

UInt8(string name, string description)

TableDefinitionBuilder TableDefinitionBuilder.UInt8(string name, string description = "")

Adds an unsigned 8-bit integer field.

WithDescription(string description)

TableDefinitionBuilder TableDefinitionBuilder.WithDescription(string description)

Sets the table description.

WithSize(int size)

TableDefinitionBuilder TableDefinitionBuilder.WithSize(int size)

Sets the expected total size in bytes.

View Source
/// <summary>
///     Fluent builder for constructing <see cref = "TableDefinition"/> instances.
///     Provides a readable, type-safe API for defining PSEM table structures.
/// </summary>
/// <remarks>
///     <para>Example usage:</para>
///     <code>
/// var definition = TableDefinitionBuilder.Create(1, "Manufacturer ID")
///     .WithDescription("General Manufacturer Identification Table")
///     .WithSize(32)
///     .Ascii("MANUFACTURER", 4, "Manufacturer code")
///     .Ascii("ED_MODEL", 8, "End device model")
///     .UInt8("HW_VERSION_NUMBER", "Hardware version")
///     .UInt8("HW_REVISION_NUMBER", "Hardware revision")
///     .UInt8("FW_VERSION_NUMBER", "Firmware version")
///     .UInt8("FW_REVISION_NUMBER", "Firmware revision")
///     .Ascii("MFG_SERIAL_NUMBER", 16, "Serial number")
///     .Build();
/// </code>
/// </remarks>
public sealed class TableDefinitionBuilder
{
#region Enum Fields
    /// <summary>Adds an enum field with value-to-name mappings.</summary>
    public TableDefinitionBuilder Enum(string name, string description, params (int Value, string Label)[] values)
    {
        var enumValues = ImmutableDictionary.CreateRange(values.Select(v => KeyValuePair.Create(v.Value, v.Label)));
        _fields.Add(new TableFieldDefinition { Name = name, Offset = _currentOffset, Size = 1, Type = FieldType.Enum, Description = description, EnumValues = enumValues });
        _currentOffset += 1;
        return this;
    }

#endregion
#region Bit Fields
    /// <summary>
    ///     Adds a bit field with sub-field definitions using a nested builder.
    /// </summary>
    /// <param name = "name">The field name.</param>
    /// <param name = "size">Size in bytes (1, 2, or 4).</param>
    /// <param name = "description">Human-readable description.</param>
    /// <param name = "configure">Action to configure bit sub-fields.</param>
    public TableDefinitionBuilder BitField(string name, int size, string description, Action<BitFieldBuilder> configure)
    {
        ArgumentNullException.ThrowIfNull(configure);
        var bitBuilder = new BitFieldBuilder();
        configure(bitBuilder);
        _fields.Add(new TableFieldDefinition { Name = name, Offset = _currentOffset, Size = size, Type = FieldType.BitField, Description = description, BitFields = bitBuilder.Build() });
        _currentOffset += size;
        return this;
    }

#endregion
#region Build
    /// <summary>Builds the immutable <see cref = "TableDefinition"/>.</summary>
    public TableDefinition Build() => new()
    {
        TableId = _tableId,
        Name = _name,
        Description = _description,
        ExpectedSize = _expectedSize,
        Fields = [.._fields]
    };
#endregion
#region Private Helpers
    private TableDefinitionBuilder AddField(string name, int size, FieldType type, string description)
    {
        _fields.Add(new TableFieldDefinition { Name = name, Offset = _currentOffset, Size = size, Type = type, Description = description });
        _currentOffset += size;
        return this;
    }

#endregion
#region Fields
    private readonly ushort _tableId;
    private readonly string _name;
    private string _description = string.Empty;
    private int _expectedSize;
    private int _currentOffset;
    private readonly List<TableFieldDefinition> _fields = [];
#endregion
#region Constructor
    private TableDefinitionBuilder(ushort tableId, string name)
    {
        _tableId = tableId;
        _name = name;
    }

    /// <summary>
    ///     Creates a new builder for a table definition.
    /// </summary>
    /// <param name = "tableId">The table ID (0-4095). IDs 0-2047 are standard tables, 2048-4095 are manufacturing.</param>
    /// <param name = "name">The table name.</param>
    /// <returns>A new builder instance.</returns>
    public static TableDefinitionBuilder Create(ushort tableId, string name) => new(tableId, name);
    /// <summary>Creates a builder for a standard table (ST). The tableId is used directly.</summary>
    public static TableDefinitionBuilder Standard(ushort tableId, string name) => new(tableId, name);
    /// <summary>Creates a builder for a manufacturing table (MT). Adds 2048 offset automatically.</summary>
    public static TableDefinitionBuilder Manufacturing(ushort tableNumber, string name) => new((ushort)(tableNumber + 2048), name);
#endregion
#region Configuration
    /// <summary>Sets the table description.</summary>
    public TableDefinitionBuilder WithDescription(string description)
    {
        _description = description;
        return this;
    }

    /// <summary>Sets the expected total size in bytes.</summary>
    public TableDefinitionBuilder WithSize(int size)
    {
        _expectedSize = size;
        return this;
    }

    /// <summary>Advances the current offset to a specific position (for gaps/padding).</summary>
    public TableDefinitionBuilder AtOffset(int offset)
    {
        _currentOffset = offset;
        return this;
    }

    /// <summary>Skips the specified number of bytes (padding/reserved).</summary>
    public TableDefinitionBuilder Skip(int bytes)
    {
        _currentOffset += bytes;
        return this;
    }

#endregion
#region Simple Field Types
    /// <summary>Adds an ASCII string field.</summary>
    public TableDefinitionBuilder Ascii(string name, int size, string description = "") => AddField(name, size, FieldType.Ascii, description);
    /// <summary>Adds a UTF-8 string field.</summary>
    [SuppressMessage("Naming", "CA1720", Justification = "Fluent API method name matching FieldType.String")]
    public TableDefinitionBuilder String(string name, int size, string description = "") => AddField(name, size, FieldType.String, description);
    /// <summary>Adds a raw hex field.</summary>
    public TableDefinitionBuilder Hex(string name, int size, string description = "") => AddField(name, size, FieldType.Hex, description);
    /// <summary>Adds an unsigned 8-bit integer field.</summary>
    [SuppressMessage("Naming", "CA1720", Justification = "Fluent API method name matching FieldType.UInt8")]
    public TableDefinitionBuilder UInt8(string name, string description = "") => AddField(name, 1, FieldType.UInt8, description);
    /// <summary>Adds an unsigned 16-bit integer field (big-endian).</summary>
    [SuppressMessage("Naming", "CA1720", Justification = "Fluent API method name matching FieldType.UInt16")]
    public TableDefinitionBuilder UInt16(string name, string description = "") => AddField(name, 2, FieldType.UInt16, description);
    /// <summary>Adds an unsigned 32-bit integer field (big-endian).</summary>
    [SuppressMessage("Naming", "CA1720", Justification = "Fluent API method name matching FieldType.UInt32")]
    public TableDefinitionBuilder UInt32(string name, string description = "") => AddField(name, 4, FieldType.UInt32, description);
    /// <summary>Adds a signed 8-bit integer field.</summary>
    [SuppressMessage("Naming", "CA1720", Justification = "Fluent API method name matching FieldType.Int8")]
    public TableDefinitionBuilder Int8(string name, string description = "") => AddField(name, 1, FieldType.Int8, description);
    /// <summary>Adds a signed 16-bit integer field (big-endian).</summary>
    [SuppressMessage("Naming", "CA1720", Justification = "Fluent API method name matching FieldType.Int16")]
    public TableDefinitionBuilder Int16(string name, string description = "") => AddField(name, 2, FieldType.Int16, description);
    /// <summary>Adds a signed 32-bit integer field (big-endian).</summary>
    [SuppressMessage("Naming", "CA1720", Justification = "Fluent API method name matching FieldType.Int32")]
    public TableDefinitionBuilder Int32(string name, string description = "") => AddField(name, 4, FieldType.Int32, description);
    /// <summary>Adds a boolean field (1 byte).</summary>
    public TableDefinitionBuilder Bool(string name, string description = "") => AddField(name, 1, FieldType.Boolean, description);
    /// <summary>Adds a BCD field.</summary>
    public TableDefinitionBuilder Bcd(string name, int size, string description = "") => AddField(name, size, FieldType.Bcd, description);
    /// <summary>Adds a date/time field (6+ bytes).</summary>
    public TableDefinitionBuilder DateTime(string name, int size = 6, string description = "") => AddField(name, size, FieldType.DateTime, description);
    /// <summary>Adds a bit array field (each bit maps to a table/procedure ID).</summary>
    public TableDefinitionBuilder BitArray(string name, int size, string description = "") => AddField(name, size, FieldType.BitArray, description);
#endregion
}
Was this page helpful?