TableDefinition instances for looking up table structures by ID. Pre-loaded with standard ANSI C12.19 tables. Users can register custom/manufacturing table definitions." /> TableDefinition instances for looking up table structures by ID. Pre-loaded with standard ANSI C12.19 tables. Users can register custom/manufacturing table definitions." /> TableDefinition instances for looking up table structures by ID. Pre-loaded with standard ANSI C12.19 tables. Users can register custom/manufacturing table definitions." />
Class Sealed
public sealed class TableRegistry

Namespace: SharpMeter.Core.Tables

Registry of TableDefinition instances for looking up table structures by ID. Pre-loaded with standard ANSI C12.19 tables. Users can register custom/manufacturing table definitions.

Constructors

NameDescription
TableRegistry() Creates a new registry pre-loaded with built-in standard table definitions.

TableRegistry()

TableRegistry.TableRegistry()

Creates a new registry pre-loaded with built-in standard table definitions.

Properties

NameDescription
All Gets all registered table definitions.
Count Gets the count of registered definitions.

All

IEnumerable<TableDefinition> TableRegistry.All { get; }

Gets all registered table definitions.

Count

int TableRegistry.Count { get; }

Gets the count of registered definitions.

Methods

NameDescription
CreateEmpty() static Creates an empty registry with no pre-loaded definitions.
Deserialize(ushort tableId, ReadOnlyMemory<byte> data) Deserializes raw table bytes using the registered definition for the given table ID.
GetDefinition(ushort tableId) Gets a table definition by ID, or null if not registered.
HasDefinition(ushort tableId) Checks whether a definition exists for the given table ID.
LoadFromJson(string json) Loads and registers table definition(s) from a JSON string. Supports a single object or an array.
LoadFromJsonFile(string filePath) Loads and registers table definition(s) from a JSON file.
Register(TableDefinition definition) Registers a table definition. Overwrites any existing definition for the same table ID.
Register(TableDefinition> configure) Registers a table definition built with the fluent builder API.
RegisterFromAttributes() Registers a table definition by scanning attributes on a type decorated with PsemTableAttribute and TableFieldAttribute.
Unregister(ushort tableId) Removes a table definition by ID.

CreateEmpty()

TableRegistry TableRegistry.CreateEmpty()

Creates an empty registry with no pre-loaded definitions.

Returns: An empty registry.

Deserialize(ushort tableId, ReadOnlyMemory data)

Result<ParsedTable> TableRegistry.Deserialize(ushort tableId, ReadOnlyMemory<byte> data)

Deserializes raw table bytes using the registered definition for the given table ID.

Parameters

NameTypeDescription
tableIdushortThe table ID.
dataReadOnlyMemory<byte>The raw table bytes.

Returns: A parsed table, or an error if no definition exists or parsing fails.

GetDefinition(ushort tableId)

TableDefinition? TableRegistry.GetDefinition(ushort tableId)

Gets a table definition by ID, or null if not registered.

Parameters

NameTypeDescription
tableIdushortThe table ID.

Returns: The definition, or null.

HasDefinition(ushort tableId)

bool TableRegistry.HasDefinition(ushort tableId)

Checks whether a definition exists for the given table ID.

LoadFromJson(string json)

TableRegistry TableRegistry.LoadFromJson(string json)

Loads and registers table definition(s) from a JSON string. Supports a single object or an array.

Parameters

NameTypeDescription
jsonstringThe JSON string.

Returns: This registry for chaining.

LoadFromJsonFile(string filePath)

TableRegistry TableRegistry.LoadFromJsonFile(string filePath)

Loads and registers table definition(s) from a JSON file.

Parameters

NameTypeDescription
filePathstringThe path to the JSON file.

Returns: This registry for chaining.

Register(TableDefinition definition)

TableRegistry TableRegistry.Register(TableDefinition definition)

Registers a table definition. Overwrites any existing definition for the same table ID.

Parameters

NameTypeDescription
definitionSharpMeter.Core.Tables.TableDefinitionThe table definition to register.

Returns: This registry for chaining.

Register(TableDefinition> configure)

TableRegistry TableRegistry.Register(Func<TableDefinitionBuilder, TableDefinition> configure)

Registers a table definition built with the fluent builder API.

Parameters

NameTypeDescription
configureFunc<SharpMeter.Core.Tables.TableDefinitionBuilder, SharpMeter.Core.Tables.TableDefinition>Action to build the definition.

Returns: This registry for chaining.

RegisterFromAttributes()

TableRegistry TableRegistry.RegisterFromAttributes<T>()

Registers a table definition by scanning attributes on a type decorated with PsemTableAttribute and TableFieldAttribute.

Returns: This registry for chaining.

Unregister(ushort tableId)

TableRegistry TableRegistry.Unregister(ushort tableId)

Removes a table definition by ID.

Parameters

NameTypeDescription
tableIdushortThe table ID to remove.

Returns: This registry for chaining.

View Source
/// <summary>
///     Registry of <see cref = "TableDefinition"/> instances for looking up table structures by ID.
///     Pre-loaded with standard ANSI C12.19 tables. Users can register custom/manufacturing table definitions.
/// </summary>
public sealed class TableRegistry
{
#region Fields
    private readonly ConcurrentDictionary<ushort, TableDefinition> _definitions = new();
#endregion
#region Deserialization
    /// <summary>
    ///     Deserializes raw table bytes using the registered definition for the given table ID.
    /// </summary>
    /// <param name = "tableId">The table ID.</param>
    /// <param name = "data">The raw table bytes.</param>
    /// <returns>A parsed table, or an error if no definition exists or parsing fails.</returns>
    public Result<ParsedTable> Deserialize(ushort tableId, ReadOnlyMemory<byte> data)
    {
        TableDefinition? definition = GetDefinition(tableId);
        if (definition is null)
            return PsemError.Framing($"No table definition registered for table ID {tableId}");
        return TableDeserializer.Deserialize(definition, data);
    }

#endregion
#region Constructor
    /// <summary>
    ///     Creates a new registry pre-loaded with built-in standard table definitions.
    /// </summary>
    public TableRegistry()
    {
        foreach (TableDefinition def in StandardTableDefinitions.All)
            _definitions[def.TableId] = def;
    }

    /// <summary>
    ///     Creates an empty registry with no pre-loaded definitions.
    /// </summary>
    /// <returns>An empty registry.</returns>
    public static TableRegistry CreateEmpty()
    {
        var registry = new TableRegistry();
        registry._definitions.Clear();
        return registry;
    }

#endregion
#region Registration
    /// <summary>
    ///     Registers a table definition. Overwrites any existing definition for the same table ID.
    /// </summary>
    /// <param name = "definition">The table definition to register.</param>
    /// <returns>This registry for chaining.</returns>
    public TableRegistry Register(TableDefinition definition)
    {
        ArgumentNullException.ThrowIfNull(definition);
        _definitions[definition.TableId] = definition;
        return this;
    }

    /// <summary>
    ///     Registers a table definition built with the fluent builder API.
    /// </summary>
    /// <param name = "configure">Action to build the definition.</param>
    /// <returns>This registry for chaining.</returns>
    public TableRegistry Register(Func<TableDefinitionBuilder, TableDefinition> configure)
    {
        ArgumentNullException.ThrowIfNull(configure);
        TableDefinition definition = configure(null!); // Builder is created inside the Func
        _definitions[definition.TableId] = definition;
        return this;
    }

    /// <summary>
    ///     Registers a table definition by scanning attributes on a type decorated with
    ///     <see cref = "Attributes.PsemTableAttribute"/> and <see cref = "Attributes.TableFieldAttribute"/>.
    /// </summary>
    /// <typeparam name = "T">The attribute-decorated table type.</typeparam>
    /// <returns>This registry for chaining.</returns>
    public TableRegistry RegisterFromAttributes<T>()
    {
        Result<TableDefinition> result = TableMapper.BuildDefinition<T>();
        if (result.IsSuccess)
            _definitions[result.Value.TableId] = result.Value;
        return this;
    }

    /// <summary>
    ///     Loads and registers table definition(s) from a JSON string.
    ///     Supports a single object or an array.
    /// </summary>
    /// <param name = "json">The JSON string.</param>
    /// <returns>This registry for chaining.</returns>
    public TableRegistry LoadFromJson(string json)
    {
        ArgumentNullException.ThrowIfNull(json);
        var trimmed = json.TrimStart();
        if (trimmed.StartsWith('['))
        {
            Result<IReadOnlyList<TableDefinition>> result = TableDefinitionLoader.FromJsonArray(json);
            if (result.IsSuccess)
                foreach (TableDefinition def in result.Value)
                    _definitions[def.TableId] = def;
        }
        else
        {
            Result<TableDefinition> result = TableDefinitionLoader.FromJson(json);
            if (result.IsSuccess)
                _definitions[result.Value.TableId] = result.Value;
        }

        return this;
    }

    /// <summary>
    ///     Loads and registers table definition(s) from a JSON file.
    /// </summary>
    /// <param name = "filePath">The path to the JSON file.</param>
    /// <returns>This registry for chaining.</returns>
    public TableRegistry LoadFromJsonFile(string filePath)
    {
        Result<IReadOnlyList<TableDefinition>> result = TableDefinitionLoader.FromFile(filePath);
        if (result.IsSuccess)
            foreach (TableDefinition def in result.Value)
                _definitions[def.TableId] = def;
        return this;
    }

    /// <summary>
    ///     Removes a table definition by ID.
    /// </summary>
    /// <param name = "tableId">The table ID to remove.</param>
    /// <returns>This registry for chaining.</returns>
    public TableRegistry Unregister(ushort tableId)
    {
        _definitions.TryRemove(tableId, out _);
        return this;
    }

#endregion
#region Lookup
    /// <summary>
    ///     Gets a table definition by ID, or null if not registered.
    /// </summary>
    /// <param name = "tableId">The table ID.</param>
    /// <returns>The definition, or null.</returns>
    public TableDefinition? GetDefinition(ushort tableId) => _definitions.TryGetValue(tableId, out TableDefinition? def) ? def : null;
    /// <summary>
    ///     Checks whether a definition exists for the given table ID.
    /// </summary>
    public bool HasDefinition(ushort tableId) => _definitions.ContainsKey(tableId);
    /// <summary>
    ///     Gets all registered table definitions.
    /// </summary>
    public IEnumerable<TableDefinition> All => _definitions.Values;
    /// <summary>
    ///     Gets the count of registered definitions.
    /// </summary>
    public int Count => _definitions.Count;
#endregion
}
Was this page helpful?