DanielWillett.SpeedBytes
1.1.2
dotnet add package DanielWillett.SpeedBytes --version 1.1.2
NuGet\Install-Package DanielWillett.SpeedBytes -Version 1.1.2
<PackageReference Include="DanielWillett.SpeedBytes" Version="1.1.2" />
paket add DanielWillett.SpeedBytes --version 1.1.2
#r "nuget: DanielWillett.SpeedBytes, 1.1.2"
// Install DanielWillett.SpeedBytes as a Cake Addin #addin nuget:?package=DanielWillett.SpeedBytes&version=1.1.2 // Install DanielWillett.SpeedBytes as a Cake Tool #tool nuget:?package=DanielWillett.SpeedBytes&version=1.1.2
SpeedBytes
Library for quick and easy manual binary serialization.
Get the latest release on NuGet: https://www.nuget.org/packages/DanielWillett.SpeedBytes
Includes targets for netcoreapp3.1, net5.0, net8.0, and net461
.
Unit tested on .NET Core 3.1, .NET 5, .NET 8, and .NET Framework 4.8.1
.
Main classes:
ByteReader
Contains methods for reading data from a byte array or stream.ByteWriter
Contains methods for writing data to an expandable byte array or stream.ByteFormatter
Contains methods for converting byte sequences and capacities into text.
Features are available for reading and writing binary data from generic types.
Also includes experimental (untested) support for big endian machines. Please create issues for errors if you encounter an error regarding endianness as I have no way to test it.
Standard I/O
Binary Buffer
Writing
// creates a writer with a starting capacity of 1024 B.
ByteWriter writer = new ByteWriter(1024);
// write an int32 (4 bytes)
writer.Write(32);
// write a UTF-8 string (2 byte length header + 11 UTF-8 bytes)
writer.Write("test string");
// write an int32 array (2 byte length header + 16 bytes of int32)
writer.write(new int[] { 1, 76, 14, 9 });
byte[] data = writer.ToArray();
Reading
byte[] data = /* data source */;
ByteReader reader = new ByteReader();
reader.LoadNew(data);
int count = reader.ReadInt32();
string words = reader.ReadString();
int[] array = reader.ReadInt32Array();
Stream Buffer
Also contains support for reading from and writing to Streams.
Writing
using FileStream stream = /* etc */;
ByteWriter writer = new ByteWriter
{
Stream = stream
};
// write 100 int32's (400 bytes)
for (int i = 0; i < 100; i++)
writer.Write(i);
writer.Flush();
Reading
using FileStream stream = /* etc */;
ByteReader reader = new ByteReader();
reader.LoadNew(stream);
// read 400 bytes to the stack
Span<byte> data = stackalloc byte[400];
reader.ReadBlockTo(data);
Generic I/O
Support for generic type reading and writing (or just by passing a Type
).
// generic delegates are cached using a static generic class
Reader<string> readFunc = ByteReader.GetReadMethodDelegate<string>(isNullable: false);
Writer<string> writeFunc = ByteWriter.GetWriteMethodDelegate<string>(isNullable: false);
ByteWriter writer = /* etc */;
writeFunc(writer, "test string");
ByteReader reader = /* etc */;
string testString = readFunc(reader);
Register Custom Types
// entrypoint
public static void Main(string[] args)
{
// adds the type 'Version' to ByteReader.GetReadMethodDelegate and ByteWriter.GetWriteMethodDelegate.
ByteEncoders.TryAddAutoSerializableClassType(
WriteVersion,
WriteNullableVersion,
ReadVersion,
ReadNullableVersion
);
}
private static void WriteVersion(ByteWriter writer, Version version)
{
writer.Write(version.Major);
writer.Write(version.Minor);
writer.Write(version.Build);
writer.Write(version.Revision);
}
private static void WriteNullableVersion(ByteWriter writer, Version? version)
{
if (version != null)
{
writer.Write(true);
WriteVersion(writer, version);
}
else writer.Write(false);
}
private static Version ReadVersion(ByteReader reader)
{
return new Version(
major: reader.ReadInt32(),
minor: reader.ReadInt32(),
build: reader.ReadInt32(),
revision: reader.ReadInt32()
);
}
private static Version? ReadNullableVersion(ByteReader reader)
{
if (!reader.ReadBool())
return null;
return ReadVersion(reader);
}
Byte Formatter
Extra features for formatting binary data into a string.
Formatting Byte Sequences
const ByteStringFormat fmt =
ByteStringFormat.NewLineAtBeginning
| ByteStringFormat.ColumnLabels
| ByteStringFormat.RowLabels
| ByteStringFormat.Columns8;
byte[] data = [ 16, 32, 64, /* etc */ ];
int ct = ByteFormatter.GetMaxBinarySize(data.Length, fmt);
Span<char> binaryString = stackalloc char[ct];
ByteFormatter.FormatBinary(data, binaryString, fmt);
// or
string binaryString = ByteFormatter.FormatBinary(data, fmt);
/* sample output with a 64 byte array
01 02 03 04 05 06 07 08
0x00 10 20 30 44 61 6E 69 65
0x08 6C 57 69 6C 6C 65 74 74
0x10 2E 53 70 65 65 64 42 79
0x18 74 65 73 2E 42 79 74 65
0x20 52 65 61 64 65 72 2C 20
0x28 44 61 6E 69 65 6C 57 69
0x30 6C 6C 65 74 74 2E 53 70
0x38 65 65 64 42 79 74 65 73
*/
Formatting Capacity
const long capacity = 100_445; // ~ 98.091 KiB
int ct = ByteFormatter.GetCapacityLength(capacity, decimals: 2 /* 0.00 */);
Span<char> capacityString = stackalloc char[ct];
ByteFormatter.FormatCapacity(capacity, capacityString, decimals: 2);
// or
string capacityString = ByteFormatter.FormatCapacity(capacity, decimals: 2);
// capacityString = "98.09 KiB"
Zero-Compressed Format
Also includes extension methods for compressing integer spans (of any integral type) into a 'zero-compressed' format, in which long spans of zeros within a span are compressed significantly.
using DanielWillett.SpeedBytes.Compression;
/* writing */
int[] array = [ 1, 0, 0, 30, 16, 255, 2224, 99248240, 0, 0, 0, 0, 0, 0, 0, 21, 0, 4, 52 ];
ByteWriter writer = new ByteWriter();
writer.WriteZeroCompressed(array);
/* resulting data (44 bytes for 19 int32s instead of 78):
01 02 03 04 05 06 07 08
0x00 14 00 02 FF 03 1E 00 00
0x08 00 10 00 00 00 FF 00 00
0x10 00 FF FF 00 00 07 FF 04
0x18 00 00 00 80 00 00 00 00
0x20 0C 00 00 00 0F 00 00 00
0x28 40 00 00 00
*/
/* reading */
ByteReader reader = /* etc */;
int[] array = reader.ReadZeroCompressedInt32Array();
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net5.0 is compatible. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. |
.NET Core | netcoreapp3.0 was computed. netcoreapp3.1 is compatible. |
.NET Standard | netstandard2.1 is compatible. |
.NET Framework | net461 is compatible. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
MonoAndroid | monoandroid was computed. |
MonoMac | monomac was computed. |
MonoTouch | monotouch was computed. |
Tizen | tizen60 was computed. |
Xamarin.iOS | xamarinios was computed. |
Xamarin.Mac | xamarinmac was computed. |
Xamarin.TVOS | xamarintvos was computed. |
Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETCoreApp 3.1
- System.Runtime.CompilerServices.Unsafe (>= 4.5.0)
-
.NETFramework 4.6.1
- System.Memory (>= 4.5.0)
- System.Runtime.CompilerServices.Unsafe (>= 4.5.0)
-
.NETStandard 2.1
- System.Runtime.CompilerServices.Unsafe (>= 4.5.0)
-
net5.0
- No dependencies.
-
net8.0
- No dependencies.
NuGet packages (4)
Showing the top 4 NuGet packages that depend on DanielWillett.SpeedBytes:
Package | Downloads |
---|---|
DevkitServer.Client
Module for Unturned that enables multi-user map editing. |
|
DevkitServer.Server
Module for Unturned that enables multi-user map editing. |
|
Uncreated.Warfare
Main framework for the Uncreated Warfare Military Simulation server based off of the military game Squad. |
|
DanielWillett.SpeedBytes.Unity
Adds support for basic types from UnityEngine. |
GitHub repositories
This package is not used by any popular GitHub repositories.
Fixed bug with writing empty strings.