Skip to content

Commit

Permalink
Added flag read/writes
Browse files Browse the repository at this point in the history
  • Loading branch information
abledbody committed Nov 15, 2023
1 parent cf38f69 commit c9bf7a0
Show file tree
Hide file tree
Showing 4 changed files with 121 additions and 0 deletions.
18 changes: 18 additions & 0 deletions Assets/QuickBin/Deserializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
namespace QuickBin {
public sealed partial class Deserializer {
readonly byte[] buffer;
int boolPlace = 0;
byte flagByte = 0;

/// <summary>
/// The next index in the buffer that will be read from.
Expand Down Expand Up @@ -106,6 +108,7 @@ private Deserializer ReadGeneric<T>(int width, Func<byte[], int, T> f, out T pro

produced = f(buffer, ReadIndex);
ReadIndex = nextIndex;
boolPlace = 0;
return this;
}

Expand All @@ -119,6 +122,7 @@ private Deserializer ReadGeneric<T>(int? byteLength, Func<byte[], int, int, T> f

produced = f(buffer, ReadIndex, byteLength.Value);
ReadIndex = nextIndex;
boolPlace = 0;
return this;
}

Expand All @@ -138,6 +142,20 @@ private Deserializer ReadGeneric<T>(int? byteLength, Func<byte[], int, int, T> f
public Deserializer Read(out string produced, int? length = null) => ReadGeneric(length, TextEncoding.UTF8.GetString, out produced);
public Deserializer Read(out byte[] produced, int? length = null) => ReadGeneric(length, Extract, out produced);

/// <summary>
/// Reads booleans from the same byte if possible.
/// </summary>
public Deserializer ReadFlag(out bool produced) {
if (boolPlace == 0)
Read(out flagByte);

produced = (flagByte & (1 << boolPlace)) != 0;

boolPlace++;
boolPlace %= 8;
return this;
}

public Deserializer Read(out DateTime produced) =>
Read(out long ticks)
.Return(new(ticks), out produced);
Expand Down
18 changes: 18 additions & 0 deletions Assets/QuickBin/Serializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
namespace QuickBin {
public sealed partial class Serializer {
readonly List<byte> bytes;
int boolPlace = 0;

/// <summary>
/// The number of bytes in the Serializer.
Expand Down Expand Up @@ -56,11 +57,13 @@ public Serializer ForEach<T>(IEnumerable<T> values, Action<T> action) {

private Serializer WriteGeneric<T>(T value, Func<T, byte> f) {
bytes.Add(f(value));
boolPlace = 0;
return this;
}

private Serializer WriteGeneric<T>(T value, Func<T, byte[]> f) {
bytes.AddRange(f(value));
boolPlace = 0;
return this;
}

Expand All @@ -83,6 +86,21 @@ private Serializer WriteGeneric<T>(T value, Func<T, byte[]> f) {
public Serializer Write(DateTime value) => Write(value.Ticks);
public Serializer Write(TimeSpan value) => Write(value.Ticks);

/// <summary>
/// Writes booleans into the same byte if possible.
/// </summary>
public Serializer WriteFlag(bool value) {
if (boolPlace == 0)
Write(value);
else
bytes[^1] |= (byte)(value ? 1 << boolPlace : 0);

boolPlace++;
boolPlace %= 8;

return this;
}

public Serializer Write(Version value) =>
Write(value.Major)
.Write(value.Minor)
Expand Down
74 changes: 74 additions & 0 deletions Assets/Tester.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
using UnityEngine;
using UnityEngine.Assertions;
using UnityEditor;
using QuickBin;

public static class Tester {
[MenuItem("QuickBin/Test")]
public static void Test() {
var testString = "Hello, world!";

var buffer = new Serializer()
.WriteFlag(false)
.WriteFlag(true)
.WriteFlag(true)
.WriteFlag(false)
.WriteFlag(true)
.WriteFlag(false)
.WriteFlag(false)
.WriteFlag(false)
.WriteFlag(true)
.WriteFlag(true)
.WriteFlag(false)
.WriteFlag(true)
.Write(10)
.WriteFlag(true)
.Write(testString.Length)
.Write(testString)
.WriteFlag(false)
.WriteFlag(true);

Assert.AreEqual(((byte[])buffer)[0], (byte)0b0001_0110);
Assert.AreEqual(((byte[])buffer)[1], (byte)0b0000_1011);

new Deserializer(buffer)
.ReadFlag(out bool a)
.ReadFlag(out bool b)
.ReadFlag(out bool c)
.ReadFlag(out bool d)
.ReadFlag(out bool e)
.ReadFlag(out bool f)
.ReadFlag(out bool g)
.ReadFlag(out bool h)
.ReadFlag(out bool i)
.ReadFlag(out bool j)
.ReadFlag(out bool k)
.ReadFlag(out bool l)
.Read(out int m)
.ReadFlag(out bool n)
.Read(out int length)
.Read(out string o, length)
.ReadFlag(out bool p)
.ReadFlag(out bool q);

Assert.IsFalse(a);
Assert.IsTrue(b);
Assert.IsTrue(c);
Assert.IsFalse(d);
Assert.IsTrue(e);
Assert.IsFalse(f);
Assert.IsFalse(g);
Assert.IsFalse(h);
Assert.IsTrue(i);
Assert.IsTrue(j);
Assert.IsFalse(k);
Assert.IsTrue(l);
Assert.AreEqual(10, m);
Assert.IsTrue(n);
Assert.AreEqual(testString, o);
Assert.IsFalse(p);
Assert.IsTrue(q);

Debug.Log("QuickBin tests passed.");
}
}
11 changes: 11 additions & 0 deletions Assets/Tester.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit c9bf7a0

Please sign in to comment.