ZigZag<T>
ZigZag<T> encodes value-types T using variable-sized encoding combined with zig-zag interleaving of positive and negative values. Encoding uses 7 bits for payload and every 8th bit describes whether 'value' continues into next octet.
WriteLine(Hex.PrintFromBytes(ZigZag<int>.ToArray( 0))); // 00
WriteLine(Hex.PrintFromBytes(ZigZag<int>.ToArray(-1))); // 01
WriteLine(Hex.PrintFromBytes(ZigZag<int>.ToArray(+1))); // 02
WriteLine(Hex.PrintFromBytes(ZigZag<int>.ToArray(-2))); // 03
WriteLine(Hex.PrintFromBytes(ZigZag<int>.ToArray(+2))); // 04
WriteLine(Hex.PrintFromBytes(ZigZag<int>.ToArray(-3))); // 05
WriteLine(Hex.PrintFromBytes(ZigZag<int>.ToArray(+3))); // 06
WriteLine(Hex.PrintFromBytes(ZigZag<int>.ToArray(int.MinValue))); // FFFFFFFF0F
WriteLine(Hex.PrintFromBytes(ZigZag<int>.ToArray(int.MaxValue))); // FEFFFFFF0F
ZigZag<T>.Write(memory, value, bytesWritten, atIndex?) writes value-typed T to 'memory'.
byte[] data = new byte[8];
var memory = new ListMemory<byte[], byte>(data);
ZigZag<ulong>.Write(memory, value: 0x100UL, out int bytesWritten);
WriteLine(bytesWritten); // 2
ZigZag<T>.TryWrite(memory, value, bytesWritten, atIndex?) tries to write 'value' to 'memory'.
byte[] data = new byte[8];
var memory = new ListMemory<byte[], byte>(data);
bool ok = ZigZag<ulong>.TryWrite(memory, value: 0x100UL, out int bytesWritten);
WriteLine(bytesWritten); // 2
ZigZag<T>.Read(memory, bytesRead, atIndex?) reads value-typed T from 'memory'.
byte[] data = new byte[] { 128, 2, 0, 0, 0, 0, 0, 0 };
var memory = new ListMemory<byte[], byte>(data);
ulong value = ZigZag<ulong>.Read(memory, out int bytesRead);
WriteLine(value); // 256
WriteLine(bytesRead); // 2
ZigZag<T>.TryRead(memory, value, bytesRead, atIndex?) tries to read value-typed T from 'memory'.
byte[] data = new byte[] { 128, 2, 0, 0, 0, 0, 0, 0 };
var memory = new ListMemory<byte[], byte>(data);
bool ok = ZigZag<ulong>.TryRead(memory, out ulong value, out int bytesRead);
WriteLine(value); // 256
WriteLine(bytesRead); // 2
ZigZag<T>.Insert(memory, value, bytesWritten, atIndex?) inserts value-typed T to 'memory'.
byte[] data = new byte[8];
var memory = new Slice<ListMemory<byte[], byte>, byte>(new ListMemory<byte[], byte>(data), 0, 0, data.Length);
ZigZag<ulong>.Insert(ref memory, value: 0x100UL, out int bytesWritten);
WriteLine(bytesWritten); // 2
ZigZag<T>.TryInsert(memory, value, bytesWritten, atIndex?) tries to insert 'value' to 'memory'.
byte[] data = new byte[8];
var memory = new Slice<ListMemory<byte[], byte>, byte>(new ListMemory<byte[], byte>(data), 0, 0, data.Length);
ZigZag<ulong>.TryInsert(ref memory, value: 0x100UL, out int bytesWritten);
WriteLine(bytesWritten); // 2
Any value-type T can be read and written.
var memory = new BlockMemory<byte>();
ZigZag<DateTime>.TryInsert(ref memory, DateTime.UtcNow, out int bytesWritten);
ZigZag<Guid>.TryInsert(ref memory, Guid.NewGuid(), out bytesWritten, atIndex: memory.Count);
ZigZag<UInt128>.TryInsert(ref memory, new UInt128(0, 0), out bytesWritten, atIndex: memory.Count);
ZigZag<T>.FixedSize returns the fixed number of bytes of unencoded value-type T.
WriteLine(ZigZag<bool>.FixedSize); // 1
WriteLine(ZigZag<Byte>.FixedSize); // 1
WriteLine(ZigZag<SByte>.FixedSize); // 1
WriteLine(ZigZag<UInt16>.FixedSize); // 1
WriteLine(ZigZag<Int16>.FixedSize); // 2
WriteLine(ZigZag<Int32>.FixedSize); // 4
WriteLine(ZigZag<UInt32>.FixedSize); // 4
WriteLine(ZigZag<Int64>.FixedSize); // 8
WriteLine(ZigZag<UInt64>.FixedSize); // 8
WriteLine(ZigZag<Int128>.FixedSize); // 16
WriteLine(ZigZag<UInt128>.FixedSize); // 16
WriteLine(ZigZag<Guid>.FixedSize); // 16
WriteLine(ZigZag<DateTime>.FixedSize); // 8
WriteLine(ZigZag<DateTimeOffset>.FixedSize); // 16
ZigZag<T>.MaxEncodedSize returns the maximum number of bytes that may be needed for encoding T.
WriteLine(ZigZag<bool>.MaxEncodedSize); // 1
WriteLine(ZigZag<SByte>.MaxEncodedSize); // 2
WriteLine(ZigZag<Byte>.MaxEncodedSize); // 2
WriteLine(ZigZag<Int16>.MaxEncodedSize); // 3
WriteLine(ZigZag<UInt16>.MaxEncodedSize); // 3
WriteLine(ZigZag<Int32>.MaxEncodedSize); // 5
WriteLine(ZigZag<UInt32>.MaxEncodedSize); // 5
WriteLine(ZigZag<Int64>.MaxEncodedSize); // 10
WriteLine(ZigZag<UInt64>.MaxEncodedSize); // 10
WriteLine(ZigZag<Int128>.MaxEncodedSize); // 19
WriteLine(ZigZag<UInt128>.MaxEncodedSize); // 19
WriteLine(ZigZag<Guid>.MaxEncodedSize); // 19
WriteLine(ZigZag<DateTime>.MaxEncodedSize); // 10
WriteLine(ZigZag<DateTimeOffset>.MaxEncodedSize); // 19
ZigZag<T>.EncodedSize(value) returns the exact number of bytes that are needed to encode 'value'.
WriteLine(ZigZag<Int64>.EncodedSize( 0)); // 1
WriteLine(ZigZag<Int64>.EncodedSize(+1)); // 1
WriteLine(ZigZag<Int64>.EncodedSize(-1)); // 1
WriteLine(ZigZag<Int64>.EncodedSize(+127)); // 1
WriteLine(ZigZag<Int64>.EncodedSize(-127)); // 1
WriteLine(ZigZag<Int64>.EncodedSize(+128)); // 2
WriteLine(ZigZag<Int64>.EncodedSize(-128)); // 2
WriteLine(ZigZag<Int64>.EncodedSize(+16383)); // 3
WriteLine(ZigZag<Int64>.EncodedSize(-16383)); // 3
WriteLine(ZigZag<Int64>.EncodedSize(+16384)); // 4
WriteLine(ZigZag<Int64>.EncodedSize(-16384)); // 4
WriteLine(ZigZag<Int64>.EncodedSize(Int64.MinValue)); // 10
WriteLine(ZigZag<Int64>.EncodedSize(Int64.MaxValue)); // 10
ZigZag<T>.IsZigZagRecommended determines whether it is recommended to use zig-zag encoding for T. Zig-zag is recommended for signed integers.
WriteLine(ZigZag<bool>.IsZigZagRecommended); // False
WriteLine(ZigZag<SByte>.IsZigZagRecommended); // True
WriteLine(ZigZag<Byte>.IsZigZagRecommended); // False
WriteLine(ZigZag<Int16>.IsZigZagRecommended); // True
WriteLine(ZigZag<UInt16>.IsZigZagRecommended); // False
WriteLine(ZigZag<Int32>.IsZigZagRecommended); // True
WriteLine(ZigZag<UInt32>.IsZigZagRecommended); // False
WriteLine(ZigZag<Int64>.IsZigZagRecommended); // True
WriteLine(ZigZag<UInt64>.IsZigZagRecommended); // False
WriteLine(ZigZag<Int128>.IsZigZagRecommended); // True
WriteLine(ZigZag<UInt128>.IsZigZagRecommended); // False
Full Example
Full example
using Avalanche.Memory;
using Avalanche.Utilities;
using static System.Console;
public class zigzag
{
public static void Run()
{
{
// <00>
WriteLine(Hex.PrintFromBytes(ZigZag<int>.ToArray( 0))); // 00
WriteLine(Hex.PrintFromBytes(ZigZag<int>.ToArray(-1))); // 01
WriteLine(Hex.PrintFromBytes(ZigZag<int>.ToArray(+1))); // 02
WriteLine(Hex.PrintFromBytes(ZigZag<int>.ToArray(-2))); // 03
WriteLine(Hex.PrintFromBytes(ZigZag<int>.ToArray(+2))); // 04
WriteLine(Hex.PrintFromBytes(ZigZag<int>.ToArray(-3))); // 05
WriteLine(Hex.PrintFromBytes(ZigZag<int>.ToArray(+3))); // 06
WriteLine(Hex.PrintFromBytes(ZigZag<int>.ToArray(int.MinValue))); // FFFFFFFF0F
WriteLine(Hex.PrintFromBytes(ZigZag<int>.ToArray(int.MaxValue))); // FEFFFFFF0F
// </00>
}
{
// <01>
byte[] data = new byte[8];
var memory = new ListMemory<byte[], byte>(data);
ZigZag<ulong>.Write(memory, value: 0x100UL, out int bytesWritten);
WriteLine(bytesWritten); // 2
// </01>
}
{
// <02>
byte[] data = new byte[8];
var memory = new ListMemory<byte[], byte>(data);
bool ok = ZigZag<ulong>.TryWrite(memory, value: 0x100UL, out int bytesWritten);
WriteLine(bytesWritten); // 2
// </02>
}
{
// <03>
byte[] data = new byte[] { 128, 2, 0, 0, 0, 0, 0, 0 };
var memory = new ListMemory<byte[], byte>(data);
ulong value = ZigZag<ulong>.Read(memory, out int bytesRead);
WriteLine(value); // 256
WriteLine(bytesRead); // 2
// </03>
}
{
// <04>
byte[] data = new byte[] { 128, 2, 0, 0, 0, 0, 0, 0 };
var memory = new ListMemory<byte[], byte>(data);
bool ok = ZigZag<ulong>.TryRead(memory, out ulong value, out int bytesRead);
WriteLine(value); // 256
WriteLine(bytesRead); // 2
// </04>
}
{
// <05>
byte[] data = new byte[8];
var memory = new Slice<ListMemory<byte[], byte>, byte>(new ListMemory<byte[], byte>(data), 0, 0, data.Length);
ZigZag<ulong>.Insert(ref memory, value: 0x100UL, out int bytesWritten);
WriteLine(bytesWritten); // 2
// </05>
}
{
// <06>
byte[] data = new byte[8];
var memory = new Slice<ListMemory<byte[], byte>, byte>(new ListMemory<byte[], byte>(data), 0, 0, data.Length);
ZigZag<ulong>.TryInsert(ref memory, value: 0x100UL, out int bytesWritten);
WriteLine(bytesWritten); // 2
// </06>
}
{
// <11>
var memory = new BlockMemory<byte>();
ZigZag<DateTime>.TryInsert(ref memory, DateTime.UtcNow, out int bytesWritten);
ZigZag<Guid>.TryInsert(ref memory, Guid.NewGuid(), out bytesWritten, atIndex: memory.Count);
ZigZag<UInt128>.TryInsert(ref memory, new UInt128(0, 0), out bytesWritten, atIndex: memory.Count);
// </11>
}
{
// <21>
WriteLine(ZigZag<bool>.FixedSize); // 1
WriteLine(ZigZag<Byte>.FixedSize); // 1
WriteLine(ZigZag<SByte>.FixedSize); // 1
WriteLine(ZigZag<UInt16>.FixedSize); // 1
WriteLine(ZigZag<Int16>.FixedSize); // 2
WriteLine(ZigZag<Int32>.FixedSize); // 4
WriteLine(ZigZag<UInt32>.FixedSize); // 4
WriteLine(ZigZag<Int64>.FixedSize); // 8
WriteLine(ZigZag<UInt64>.FixedSize); // 8
WriteLine(ZigZag<Int128>.FixedSize); // 16
WriteLine(ZigZag<UInt128>.FixedSize); // 16
WriteLine(ZigZag<Guid>.FixedSize); // 16
WriteLine(ZigZag<DateTime>.FixedSize); // 8
WriteLine(ZigZag<DateTimeOffset>.FixedSize); // 16
// </21>
}
{
// <22>
WriteLine(ZigZag<bool>.MaxEncodedSize); // 1
WriteLine(ZigZag<SByte>.MaxEncodedSize); // 2
WriteLine(ZigZag<Byte>.MaxEncodedSize); // 2
WriteLine(ZigZag<Int16>.MaxEncodedSize); // 3
WriteLine(ZigZag<UInt16>.MaxEncodedSize); // 3
WriteLine(ZigZag<Int32>.MaxEncodedSize); // 5
WriteLine(ZigZag<UInt32>.MaxEncodedSize); // 5
WriteLine(ZigZag<Int64>.MaxEncodedSize); // 10
WriteLine(ZigZag<UInt64>.MaxEncodedSize); // 10
WriteLine(ZigZag<Int128>.MaxEncodedSize); // 19
WriteLine(ZigZag<UInt128>.MaxEncodedSize); // 19
WriteLine(ZigZag<Guid>.MaxEncodedSize); // 19
WriteLine(ZigZag<DateTime>.MaxEncodedSize); // 10
WriteLine(ZigZag<DateTimeOffset>.MaxEncodedSize); // 19
// </22>
}
{
// <23>
WriteLine(ZigZag<Int64>.EncodedSize( 0)); // 1
WriteLine(ZigZag<Int64>.EncodedSize(+1)); // 1
WriteLine(ZigZag<Int64>.EncodedSize(-1)); // 1
WriteLine(ZigZag<Int64>.EncodedSize(+127)); // 1
WriteLine(ZigZag<Int64>.EncodedSize(-127)); // 1
WriteLine(ZigZag<Int64>.EncodedSize(+128)); // 2
WriteLine(ZigZag<Int64>.EncodedSize(-128)); // 2
WriteLine(ZigZag<Int64>.EncodedSize(+16383)); // 3
WriteLine(ZigZag<Int64>.EncodedSize(-16383)); // 3
WriteLine(ZigZag<Int64>.EncodedSize(+16384)); // 4
WriteLine(ZigZag<Int64>.EncodedSize(-16384)); // 4
WriteLine(ZigZag<Int64>.EncodedSize(Int64.MinValue)); // 10
WriteLine(ZigZag<Int64>.EncodedSize(Int64.MaxValue)); // 10
// </23>
}
{
// <31>
WriteLine(ZigZag<bool>.IsZigZagRecommended); // False
WriteLine(ZigZag<SByte>.IsZigZagRecommended); // True
WriteLine(ZigZag<Byte>.IsZigZagRecommended); // False
WriteLine(ZigZag<Int16>.IsZigZagRecommended); // True
WriteLine(ZigZag<UInt16>.IsZigZagRecommended); // False
WriteLine(ZigZag<Int32>.IsZigZagRecommended); // True
WriteLine(ZigZag<UInt32>.IsZigZagRecommended); // False
WriteLine(ZigZag<Int64>.IsZigZagRecommended); // True
WriteLine(ZigZag<UInt64>.IsZigZagRecommended); // False
WriteLine(ZigZag<Int128>.IsZigZagRecommended); // True
WriteLine(ZigZag<UInt128>.IsZigZagRecommended); // False
// </31>
}
}
}