SatorImaging.ZeroSerializer
1.0.1
Prefix Reserved
See the version list below for details.
dotnet add package SatorImaging.ZeroSerializer --version 1.0.1
NuGet\Install-Package SatorImaging.ZeroSerializer -Version 1.0.1
<PackageReference Include="SatorImaging.ZeroSerializer" Version="1.0.1" />
<PackageVersion Include="SatorImaging.ZeroSerializer" Version="1.0.1" />
<PackageReference Include="SatorImaging.ZeroSerializer" />
paket add SatorImaging.ZeroSerializer --version 1.0.1
#r "nuget: SatorImaging.ZeroSerializer, 1.0.1"
#:package SatorImaging.ZeroSerializer@1.0.1
#addin nuget:?package=SatorImaging.ZeroSerializer&version=1.0.1
#tool nuget:?package=SatorImaging.ZeroSerializer&version=1.0.1
<div align="center">
ZeroSerializer
Zero-copy, Zero-allocation, Deserialize-on-Read
</div>
ZeroSerializer is a C# source generator for reading serialized data directly from an existing byte[].
Why ZeroSerializer?
Receiving data over a network, reading a file, or calling another API often leaves you with an unavoidable byte[] allocation. ZeroSerializer generates a read-only view that reuses that allocation and provides strongly typed slices without creating another buffer or a deserialized object graph. Each property is read only when accessed, and strings and arrays remain borrowed from the original memory, like Span<T> or Memory<T>.
Usage
// Some APIs require data to be received into a byte array.
byte[] receivedBuffer = ReceivePacket();
// Like ReadOnlySpan<T> or ReadOnlyMemory<T>,
// a view provides strongly typed access over existing memory without owning it.
var packetView = new PacketView(receivedBuffer.AsMemory());
// Each property is decoded directly from the original buffer only when accessed.
int id = packetView.Id;
ReadOnlySpan<char> name = packetView.Name;
ReadOnlySpan<int> values = packetView.Values;
// Adding attribute to generate readonly struct 'PacketView'.
[ZeroSerializer]
public class Packet
{
public int Id { get; }
public string Name { get; }
public int[] Values { get; }
}
View construction does not read every property. Values are decoded directly from the original memory only on access.
The complete serialized region is also available through implicit conversion:
ReadOnlySpan<byte> serializedData = packetView;
ReadOnlyMemory<byte> retainedData = packetView;
Supported values
- Primitives and enums
- Nullable values
stringstored as UTF-16 (UTF-8 can be stored as byte[] by hand)- Nested
[ZeroSerializer]types - Blittable structs with
[StructLayout(LayoutKind.Sequential, Pack = 1)] - One-dimensional arrays of blittable values or structs
Serialized layout
Non-Blittable types store one relative offset per property, followed by payloads in declaration order:
[ int property offsets... ][ property payloads... ]
Offsets are relative to the start of the containing type. An offset of 0 represents null. Strings and arrays store their byte length before their data:
[ int byte length ][ data... ]
Blittable structs are stored directly as raw struct bytes without an offset table.
Notes
- Keep the original memory alive and unchanged while its View is in use. This is the same rule as for
Span<T>andMemory<T>. RequiredByteLengthis the exact size unless it is negative. A negative value indicates that the type contains variable-length data, such as strings or arrays. Passing the exact serialized region is recommended, but View access only requires the correct starting position.- Validate integrity or authenticity before creating a View when required.
- The wire format requires a little-endian runtime.
Learn more about Target Frameworks and .NET Standard.
-
.NETStandard 2.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 |
|---|---|---|
| 1.1.0-rc.2 | 0 | 8/13/2026 |
| 1.1.0-rc.1 | 58 | 8/10/2026 |
| 1.0.1 | 73 | 8/9/2026 |
| 1.0.0 | 48 | 8/8/2026 |
| 1.0.0-rc.4 | 45 | 8/8/2026 |
| 1.0.0-rc.3 | 44 | 8/8/2026 |
| 1.0.0-rc.2 | 57 | 8/8/2026 |