StreamStruct 0.2.0

There is a newer version of this package available.
See the version list below for details.
dotnet add package StreamStruct --version 0.2.0
                    
NuGet\Install-Package StreamStruct -Version 0.2.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="StreamStruct" Version="0.2.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="StreamStruct" Version="0.2.0" />
                    
Directory.Packages.props
<PackageReference Include="StreamStruct" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add StreamStruct --version 0.2.0
                    
#r "nuget: StreamStruct, 0.2.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package StreamStruct@0.2.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=StreamStruct&version=0.2.0
                    
Install as a Cake Addin
#tool nuget:?package=StreamStruct&version=0.2.0
                    
Install as a Cake Tool

StreamStruct

.NET

A .NET library for parsing and processing structured binary data from streams using field definition syntax.

Features

  • Type-safe parsing of binary streams using intuitive field definitions
  • Automatic type casting for flexible data input with type safety
  • Bidirectional communication support for client-server scenarios
  • Variable-length fields with dynamic sizing based on previously parsed values
  • Field validation including duplicate field name detection and reserved name checking
  • Comprehensive error handling with detailed error codes and messages
  • Async/await support throughout the API

Installation

Install the StreamStruct NuGet package:

Package Manager Console

Install-Package StreamStruct

.NET CLI

dotnet add package StreamStruct

PackageReference

<PackageReference Include="StreamStruct" />

NuGet Package: https://www.nuget.org/packages/StreamStruct/

Quick Start

Basic Usage

using StreamStruct;

// Create a processor with your stream
var stream = new EchoMemoryStream();
var processor = new StreamFieldProcessor(stream);

// Define the structure: [fieldName:type]
var definition = "[id:int][name_length:byte][name:name_length][flags:int:4]";

// Write structured data
var data = "Alice"u8.ToArray();
var flagIds = new[] { 1,2,3,4 };
await processor.WriteAsync(definition, [42, (byte)data.Length, data, flagIds]);

// Read it back
var result = await processor.ReadAsync(definition);
if (result.Success)
{
    result.TryRead<int>("id", out var id); // 42
    result.TryRead<byte>("name_length", out var nameLength); // 5
    result.TryRead<byte[]>("name", out var nameBytes); // 5
    result.TryReadUtf8("name", out var nameData); // Alice
    result.TryRead<int[]>("flags", out var flagIdData); // [1,2,3,4]
}

Supported Types

  • Fixed-size types: byte, sbyte, short, ushort, int, uint, long, ulong, float, double, char, bool
  • Variable-length fields: Reference previously parsed fields for dynamic sizing

Variable-Length Fields Example

// The 'message' field size is determined by the 'length' field
var definition = "[length:ushort][message:length]";

await processor.WriteAsync(definition, [(ushort)messageBytes.Length, "Hello, World!"u8.ToArray()]);

Type-Safe Reading

var result = await processor.ReadAsync("[value:int]");
if (result.TryRead<int>(0, out var value))
    Console.WriteLine($"Read integer: {value}");

Automatic Type Casting

StreamStruct automatically casts data to the appropriate field types when writing, providing flexibility while maintaining type safety:

Flexible Data Input

var definition = "[id:int][score:float][active:bool][grade:char]";

// All of these work - values are automatically cast to field types
await processor.WriteAsync(definition, [
    42,         // int -> stays int
    "85.5",     // string -> float
    1,          // int -> bool (true)
    "A"         // string -> char
]);

// Same as explicitly casting:
await processor.WriteAsync(definition, [
    (int)42,
    (float)85.5,
    (bool)true,
    (char)'A'
]);

Supported Conversions

  • Numeric types: Automatic conversion between all numeric types (int, float, double, etc.)
  • String to primitives: Numeric strings to numbers, "true"/"false" to booleans
  • String to char: Single-character strings to char
  • Boolean conversions: Numbers (0=false, non-zero=true) and string representations

Variable-Length Fields Are Not Cast

Variable-length fields (byte arrays) are not subject to type casting and must always be provided as byte[]:

var definition = "[length:int][data:length]";
var data = "Hello"u8.ToArray();  // Must be byte[]
await processor.WriteAsync(definition, [data.Length, data]);

Field Definition Syntax

Fields are defined using the format: [fieldName:typeOrLength]

Examples:

  • [id:int] - A 32-bit integer field named "id"
  • [count:byte] - An 8-bit unsigned integer field named "count"
  • [data:count] - A variable-length byte array whose size is determined by the "count" field
  • [temperature:float] - A 32-bit floating-point field named "temperature"

Field Validation

StreamStruct performs comprehensive validation of field definitions to ensure data integrity:

Duplicate Field Names

Field names must be unique within a stream definition. Duplicate field names are automatically detected and rejected:

// This will fail with ParseError.DuplicateFieldName
var result = await processor.ReadAsync("[id:int][name:byte][id:float]");

Reserved Field Names

Field names cannot use reserved type names (byte, int, float, etc.) to prevent conflicts:

// This will fail with ParseError.ReservedFieldName  
var result = await processor.ReadAsync("[int:byte]");

Error Handling

When validation fails, ParseResult provides detailed error information via ErrorCode and ErrorMessage properties.

Bidirectional Communication

For testing or in-memory communication:

using var bidirectional = new BidirectionalMemoryStream();
var serverProcessor = new StreamFieldProcessor(bidirectional.Server);
var clientProcessor = new StreamFieldProcessor(bidirectional.Client);

// Server writes
await serverProcessor.WriteAsync("[msg:int]", new object[] { 123 });

// Client reads
var result = await clientProcessor.ReadAsync("[msg:int]");

Building

dotnet build src/StreamStruct.slnx

Testing

dotnet test src/StreamStruct.Tests/StreamStruct.Tests.csproj

License

This project is licensed under the MIT License.

Product Compatible and additional computed target framework versions.
.NET net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net9.0

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.3.3 83 7/30/2025
0.3.2 86 7/30/2025
0.3.1 85 7/30/2025
0.3.0 83 7/30/2025
0.2.0 87 7/29/2025
0.1.2 83 7/28/2025
0.1.1 87 7/28/2025
0.1.0 83 7/28/2025