Table of Contents

Supply a runtime array count

Advanced · C#. The application supplies COUNT through an integer dictionary. A prior field does not automatically become a variable. This dictionary is a C# API feature.

Run this example

Prerequisites: the repository's .NET 10 SDK and a checkout of this source. Run from the repository root:

dotnet run --project docs/examples/CStructSharp.Docs.Examples.csproj -c Release -- runtime-payload

The runner checks three payload values; second is 32; length lookup preserves position. Success includes PASS runtime-payload.

This example uses the C# API. Browser capabilities and result shapes are described in the browser guide.

Complete program

The layout, options, input bytes, helper methods, and required types are all included. To adapt it outside the repository, create a .NET 10 console project, add CStructSharp, and replace Program.cs with this complete file. These examples follow the source version; use a matching package when testing a release.

Download the complete C# source.

// Generated from executable documentation examples. Edit the source region, then regenerate.
using System;
using System.IO;
using System.IO.Pipelines;
using System.Linq;
using System.Buffers;
using System.Collections.Generic;
using System.Dynamic;
using System.Globalization;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
using CStructSharp;
using CStructSharp.Codecs;
using CStructSharp.Diagnostics;
using CStructSharp.Introspection;
using CStructSharp.Values;

internal static partial class Program
{
    public static void Main()
    {
        RuntimePayload();
        Console.WriteLine("PASS runtime-payload");
    }

    private static void RuntimePayload()
    {
        var layout = new CStruct("struct packet { uint8 kind; uint8 payload[COUNT]; };");
        var variables = new Dictionary<string, int> { ["COUNT"] = 3 };
        byte[] bytes = [0x7F, 0x10, 0x20, 0x30];
        StructValue packet = layout.Parse(bytes, "packet", variables);
        Equal((byte)0x7F, packet.Get<byte>("kind"));
        Equal(3, packet.Get<byte[]>("payload").Length);
        object? secondPayload = layout.ReadValue(bytes, "packet.payload[1]", variables);
        Equal((byte)0x20, (byte)secondPayload!);

        using var stream = new MemoryStream(bytes);
        stream.Position = 1;
        Equal(3, layout.GetArrayLength(stream, "packet.payload", variables));
        Equal(1L, stream.Position);
    }

    private static void Equal<T>(T expected, T actual)
    {
        if (!EqualityComparer<T>.Default.Equals(expected, actual))
        {
            throw new InvalidOperationException($"Expected '{expected}', received '{actual}'.");
        }
    }
}

Try it and diagnose mistakes

Set COUNT to 4 without adding input bytes.

Answer: Reading fails because the fourth payload byte is missing. Validate external counts before parsing. The program contains assertions for its original inputs. When changing an input intentionally, update the expected assertion too; an unchanged assertion is not evidence that the new value is wrong.

Continue with the related guide or choose another recipe.