833 lines
37 KiB
C#
833 lines
37 KiB
C#
using System;
|
|
using NUnit.Framework;
|
|
using Unity.Collections.NotBurstCompatible;
|
|
using Unity.Collections.LowLevel.Unsafe;
|
|
using Unity.Jobs;
|
|
using UnityEngine.TestTools;
|
|
using UnityEngine;
|
|
|
|
namespace Unity.Collections.Tests
|
|
{
|
|
internal class DataStreamTests
|
|
{
|
|
internal class ReadAndWrite
|
|
{
|
|
[TestCase(ushort.MaxValue)]
|
|
[TestCase(ushort.MinValue)]
|
|
public void UShort(ushort expected)
|
|
{
|
|
bool Write(ref DataStreamWriter writer) => writer.WriteUShort(expected);
|
|
CheckReadWrite(sizeof(ushort), reader => reader.ReadUShort(), Write, expected);
|
|
}
|
|
|
|
[TestCase((uint) 0b101010)]
|
|
[TestCase((uint) 0b111111)]
|
|
public void RawBits(uint expected)
|
|
{
|
|
bool Write(ref DataStreamWriter writer) => writer.WriteRawBits(expected, 6);
|
|
CheckReadWrite(6, reader => reader.ReadRawBits(6), Write, expected);
|
|
}
|
|
|
|
[Test]
|
|
public void RawBits_OutOfCapacity()
|
|
{
|
|
const uint expected = 0b101011001;
|
|
var writer = new DataStreamWriter(1, Allocator.Temp);
|
|
Assert.False(writer.WriteRawBits(expected, 9));
|
|
Assert.True(writer.HasFailedWrites);
|
|
}
|
|
|
|
[TestCase(uint.MaxValue)]
|
|
[TestCase(uint.MinValue)]
|
|
public void UInt(uint expected)
|
|
{
|
|
bool Write(ref DataStreamWriter writer) => writer.WriteUInt(expected);
|
|
CheckReadWrite(sizeof(uint), reader => reader.ReadUInt(), Write, expected);
|
|
}
|
|
|
|
[TestCase(float.MaxValue)]
|
|
[TestCase(float.MinValue)]
|
|
public void Float(float expected)
|
|
{
|
|
bool Write(ref DataStreamWriter writer) => writer.WriteFloat(expected);
|
|
CheckReadWrite(sizeof(float), reader => reader.ReadFloat(), Write, expected);
|
|
}
|
|
|
|
[TestCase(short.MaxValue)]
|
|
[TestCase(short.MinValue)]
|
|
public void Short(short expected)
|
|
{
|
|
bool Write(ref DataStreamWriter writer) => writer.WriteShort(expected);
|
|
CheckReadWrite(sizeof(short), reader => reader.ReadShort(), Write, expected);
|
|
}
|
|
|
|
[Test]
|
|
public void FixedString32()
|
|
{
|
|
var expected = new FixedString32Bytes("This is a string");
|
|
bool Write(ref DataStreamWriter writer) => writer.WriteFixedString32(expected);
|
|
CheckReadWrite(expected.Length + FixedStringHeader, reader => reader.ReadFixedString32(), Write, expected);
|
|
}
|
|
|
|
[Test]
|
|
public void FixedString64()
|
|
{
|
|
var expected = new FixedString64Bytes("This is a string");
|
|
bool Write(ref DataStreamWriter writer) => writer.WriteFixedString64(expected);
|
|
CheckReadWrite(expected.Length + FixedStringHeader, reader => reader.ReadFixedString64(), Write, expected);
|
|
}
|
|
|
|
[Test]
|
|
public void FixedString128()
|
|
{
|
|
var expected = new FixedString128Bytes("This is a string");
|
|
bool Write(ref DataStreamWriter writer) => writer.WriteFixedString128(expected);
|
|
CheckReadWrite(expected.Length + FixedStringHeader, reader => reader.ReadFixedString128(), Write, expected);
|
|
}
|
|
|
|
[Test]
|
|
public void FixedString512()
|
|
{
|
|
var expected = new FixedString512Bytes("This is a string");
|
|
bool Write(ref DataStreamWriter writer) => writer.WriteFixedString512(expected);
|
|
CheckReadWrite(expected.Length + FixedStringHeader, reader => reader.ReadFixedString512(), Write, expected);
|
|
}
|
|
|
|
[Test]
|
|
public void FixedString4096()
|
|
{
|
|
var expected = new FixedString4096Bytes("This is a string");
|
|
bool Write(ref DataStreamWriter writer) => writer.WriteFixedString4096(expected);
|
|
CheckReadWrite(expected.Length + FixedStringHeader, reader => reader.ReadFixedString4096(), Write,
|
|
expected);
|
|
}
|
|
|
|
[Test]
|
|
public void LongLooped()
|
|
{
|
|
const long baseVal = -99;
|
|
const long expected = -1979;
|
|
bool Write(ref DataStreamWriter writer, long value) => writer.WriteLong(value);
|
|
long Read(ref DataStreamReader reader) => reader.ReadLong();
|
|
CheckReadWriteLooped(sizeof(long), baseVal, expected, Write, Read, (l, u) => l + u);
|
|
}
|
|
}
|
|
|
|
internal class ReadAndWriteNetworkOrder
|
|
{
|
|
[TestCase(int.MaxValue)]
|
|
[TestCase(int.MinValue)]
|
|
public void Int(int expected)
|
|
{
|
|
bool Write(ref DataStreamWriter writer) => writer.WriteIntNetworkByteOrder(expected);
|
|
CheckReadWrite(sizeof(int), reader => reader.ReadIntNetworkByteOrder(), Write, expected);
|
|
}
|
|
|
|
[TestCase(uint.MaxValue)]
|
|
[TestCase(uint.MinValue)]
|
|
public void UInt(uint expected)
|
|
{
|
|
bool Write(ref DataStreamWriter writer) => writer.WriteUIntNetworkByteOrder(expected);
|
|
CheckReadWrite(sizeof(uint), reader => reader.ReadUIntNetworkByteOrder(), Write, expected);
|
|
}
|
|
|
|
[TestCase(short.MaxValue)]
|
|
[TestCase(short.MinValue)]
|
|
public void Short(short expected)
|
|
{
|
|
bool Write(ref DataStreamWriter writer) => writer.WriteShortNetworkByteOrder(expected);
|
|
CheckReadWrite(sizeof(short), reader => reader.ReadShortNetworkByteOrder(), Write, expected);
|
|
}
|
|
|
|
[TestCase(ushort.MaxValue)]
|
|
[TestCase(ushort.MinValue)]
|
|
public void UShort(ushort expected)
|
|
{
|
|
bool Write(ref DataStreamWriter writer) => writer.WriteUShortNetworkByteOrder(expected);
|
|
CheckReadWrite(sizeof(ushort), reader => reader.ReadUShortNetworkByteOrder(), Write, expected);
|
|
}
|
|
|
|
[Test]
|
|
public void ReadIncorrect()
|
|
{
|
|
var dataStream = new DataStreamWriter(4, Allocator.Temp);
|
|
dataStream.WriteIntNetworkByteOrder(1979);
|
|
dataStream.Flush();
|
|
var reader = new DataStreamReader(dataStream.AsNativeArray());
|
|
Assert.AreNotEqual(1979, reader.ReadInt());
|
|
}
|
|
}
|
|
|
|
internal class ReadWritePacked
|
|
{
|
|
[Test]
|
|
public void UInt()
|
|
{
|
|
const uint expected = 1979;
|
|
const uint baseVal = 2000;
|
|
bool Write(ref DataStreamWriter writer) => writer.WriteUInt(expected);
|
|
bool WritePacked(ref DataStreamWriter writer, StreamCompressionModel model, uint value) => writer.WritePackedUInt(value, model);
|
|
uint Read(ref DataStreamReader reader) => reader.ReadUInt();
|
|
uint ReadPacked(ref DataStreamReader reader, StreamCompressionModel model) => reader.ReadPackedUInt(model);
|
|
CheckReadWritePackedLooped(sizeof(uint), baseVal, expected, Write, WritePacked, Read, ReadPacked, (l, u) => l + u);
|
|
}
|
|
|
|
[Test]
|
|
public void IntExistingData()
|
|
{
|
|
unsafe
|
|
{
|
|
var n = 300 * 4;
|
|
var data = stackalloc byte[n];
|
|
var compressionModel = StreamCompressionModel.Default;
|
|
var dataStream = new DataStreamWriter(data, n);
|
|
const int base_val = -10;
|
|
const int count = 20;
|
|
for (int i = 0; i < count; ++i)
|
|
dataStream.WritePackedInt(base_val + i, compressionModel);
|
|
|
|
dataStream.WriteInt((int)1979);
|
|
dataStream.Flush();
|
|
|
|
var na = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray<byte>(data, n, Allocator.Invalid);
|
|
#if ENABLE_UNITY_COLLECTIONS_CHECKS
|
|
NativeArrayUnsafeUtility.SetAtomicSafetyHandle(ref na, AtomicSafetyHandle.GetTempMemoryHandle());
|
|
#endif
|
|
var reader = new DataStreamReader(na);
|
|
for (int i = 0; i < count; ++i)
|
|
{
|
|
var val = reader.ReadPackedInt(compressionModel);
|
|
Assert.AreEqual(base_val + i, val);
|
|
}
|
|
|
|
Assert.AreEqual(1979, reader.ReadInt());
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void Int()
|
|
{
|
|
const int expected = -1979;
|
|
const int baseVal = -10;
|
|
bool Write(ref DataStreamWriter writer) => writer.WriteInt(expected);
|
|
bool WritePacked(ref DataStreamWriter writer, StreamCompressionModel model, int value) => writer.WritePackedInt(value, model);
|
|
int Read(ref DataStreamReader reader) => reader.ReadInt();
|
|
int ReadPacked(ref DataStreamReader reader, StreamCompressionModel model) => reader.ReadPackedInt(model);
|
|
CheckReadWritePackedLooped(sizeof(int), baseVal, expected, Write, WritePacked, Read, ReadPacked, (i, u) => (int)(i + u));
|
|
}
|
|
|
|
[Test]
|
|
public void Long()
|
|
{
|
|
const long expected = -1979;
|
|
const long baseVal = -99;
|
|
bool Write(ref DataStreamWriter writer) => writer.WriteLong(expected);
|
|
bool WritePacked(ref DataStreamWriter writer, StreamCompressionModel model, long value) => writer.WritePackedLong(value, model);
|
|
long Read(ref DataStreamReader reader) => reader.ReadLong();
|
|
long ReadPacked(ref DataStreamReader reader, StreamCompressionModel model) => reader.ReadPackedLong(model);
|
|
|
|
CheckReadWritePackedLooped(sizeof(long), baseVal, expected, Write, WritePacked, Read, ReadPacked, (l, u) => l + u);
|
|
}
|
|
|
|
[Test]
|
|
public void ULong()
|
|
{
|
|
const ulong expected = 1979;
|
|
const ulong baseVal = 2000;
|
|
bool Write(ref DataStreamWriter writer) => writer.WriteULong(expected);
|
|
bool WritePacked(ref DataStreamWriter writer, StreamCompressionModel model, ulong value) => writer.WritePackedULong(value, model);
|
|
ulong Read(ref DataStreamReader reader) => reader.ReadULong();
|
|
ulong ReadPacked(ref DataStreamReader reader, StreamCompressionModel model) => reader.ReadPackedULong(model);
|
|
CheckReadWritePackedLooped(sizeof(ulong), baseVal, expected, Write, WritePacked, Read, ReadPacked, (l, u) => l + u);
|
|
}
|
|
|
|
[Test]
|
|
public void Float()
|
|
{
|
|
const float expected = 1979.1f;
|
|
const float baseVal = 2000.1f;
|
|
bool Write(ref DataStreamWriter writer) => writer.WriteFloat(expected);
|
|
bool WritePacked(ref DataStreamWriter writer, StreamCompressionModel model, float value) => writer.WritePackedFloat(value, model);
|
|
float Read(ref DataStreamReader reader) => reader.ReadFloat();
|
|
float ReadPacked(ref DataStreamReader reader, StreamCompressionModel model) => reader.ReadPackedFloat(model);
|
|
CheckReadWritePackedLooped(sizeof(float), baseVal, expected, Write, WritePacked, Read, ReadPacked, (l, u) => l + u);
|
|
}
|
|
|
|
[Test]
|
|
public void Double()
|
|
{
|
|
const double expected = 1979.1989;
|
|
const double baseVal = 2000.2000;
|
|
bool Write(ref DataStreamWriter writer) => writer.WriteDouble(expected);
|
|
bool WritePacked(ref DataStreamWriter writer, StreamCompressionModel model, double value) => writer.WritePackedDouble(value, model);
|
|
double Read(ref DataStreamReader reader) => reader.ReadDouble();
|
|
double ReadPacked(ref DataStreamReader reader, StreamCompressionModel model) => reader.ReadPackedDouble(model);
|
|
CheckReadWritePackedLooped(sizeof(double), baseVal, expected, Write, WritePacked, Read, ReadPacked, (l, u) => l + u);
|
|
}
|
|
|
|
[Test]
|
|
public void WriteOutSideOfCapacity_Fails()
|
|
{
|
|
var model = StreamCompressionModel.Default;
|
|
var writer = new DataStreamWriter(sizeof(uint) / 2, Allocator.Temp);
|
|
Assert.False(writer.HasFailedWrites);
|
|
Assert.False(writer.WritePackedUInt(uint.MaxValue, model), "Writing a uint where there is no room should fail.");
|
|
Assert.That(writer.HasFailedWrites);
|
|
}
|
|
|
|
[Test]
|
|
[TestRequiresDotsDebugOrCollectionChecks]
|
|
public void ReadOutSideOfCapacity_Fails()
|
|
{
|
|
var model = StreamCompressionModel.Default;
|
|
var reader = new DataStreamReader(new NativeArray<byte>(0, Allocator.Temp));
|
|
LogAssert.Expect(LogType.Error, "Trying to read 2 bits from a stream where only 0 are available");
|
|
Assert.That(reader.ReadPackedUInt(model), Is.EqualTo(0));
|
|
Assert.That(reader.HasFailedReads);
|
|
}
|
|
}
|
|
|
|
internal class ReadWritePackedDelta
|
|
{
|
|
[Test]
|
|
public void Int()
|
|
{
|
|
const int expected = int.MaxValue;
|
|
const int baseline = int.MinValue;
|
|
bool WritePacked(ref DataStreamWriter writer, StreamCompressionModel model) => writer.WritePackedIntDelta(expected, baseline, model);
|
|
int ReadPacked(ref DataStreamReader reader, StreamCompressionModel model) => reader.ReadPackedIntDelta(baseline, model);
|
|
CheckReadWritePacked(sizeof(int), ReadPacked, WritePacked, expected);
|
|
}
|
|
|
|
[Test]
|
|
public void Long()
|
|
{
|
|
const long expected = long.MaxValue;
|
|
const long baseline = long.MinValue;
|
|
bool WritePacked(ref DataStreamWriter writer, StreamCompressionModel model) => writer.WritePackedLongDelta(expected, baseline, model);
|
|
long ReadPacked(ref DataStreamReader reader, StreamCompressionModel model) => reader.ReadPackedLongDelta(baseline, model);
|
|
CheckReadWritePacked(sizeof(long), ReadPacked, WritePacked, expected);
|
|
}
|
|
|
|
[Test]
|
|
public void ULong()
|
|
{
|
|
const ulong expected = ulong.MaxValue;
|
|
const ulong baseline = ulong.MinValue;
|
|
bool WritePacked(ref DataStreamWriter writer, StreamCompressionModel model) => writer.WritePackedULongDelta(expected, baseline, model);
|
|
ulong ReadPacked(ref DataStreamReader reader, StreamCompressionModel model) => reader.ReadPackedULongDelta(baseline, model);
|
|
CheckReadWritePacked(sizeof(ulong), ReadPacked, WritePacked, expected);
|
|
}
|
|
|
|
[Test]
|
|
public void FixedString32()
|
|
{
|
|
var expected = new FixedString32Bytes("This is a string");
|
|
var baseline = new FixedString32Bytes("This is another string");
|
|
bool WritePacked(ref DataStreamWriter writer, StreamCompressionModel model) => writer.WritePackedFixedString32Delta(expected, baseline, model);
|
|
FixedString32Bytes ReadPacked(ref DataStreamReader reader, StreamCompressionModel model) => reader.ReadPackedFixedString32Delta(baseline, model);
|
|
CheckReadWritePacked(expected.Length + FixedStringHeader, ReadPacked, WritePacked, expected);
|
|
}
|
|
|
|
[Test]
|
|
public void FixedString32_LargerBaseline()
|
|
{
|
|
var expected = new FixedString32Bytes("This is another string");
|
|
var baseline = new FixedString32Bytes("This is a string");
|
|
bool WritePacked(ref DataStreamWriter writer, StreamCompressionModel model) => writer.WritePackedFixedString32Delta(expected, baseline, model);
|
|
FixedString32Bytes ReadPacked(ref DataStreamReader reader, StreamCompressionModel model) => reader.ReadPackedFixedString32Delta(baseline, model);
|
|
CheckReadWritePacked(expected.Length + FixedStringHeader, ReadPacked, WritePacked, expected);
|
|
}
|
|
|
|
[Test]
|
|
public void FixedString64()
|
|
{
|
|
var expected = new FixedString64Bytes("This is a string");
|
|
var baseline = new FixedString64Bytes("This is another string");
|
|
bool WritePacked(ref DataStreamWriter writer, StreamCompressionModel model) => writer.WritePackedFixedString64Delta(expected, baseline, model);
|
|
FixedString64Bytes ReadPacked(ref DataStreamReader reader, StreamCompressionModel model) => reader.ReadPackedFixedString64Delta(baseline, model);
|
|
CheckReadWritePacked(expected.Length + FixedStringHeader, ReadPacked, WritePacked, expected);
|
|
}
|
|
|
|
[Test]
|
|
public void FixedString128()
|
|
{
|
|
var expected = new FixedString128Bytes("This is a string");
|
|
var baseline = new FixedString128Bytes("This is another string");
|
|
bool WritePacked(ref DataStreamWriter writer, StreamCompressionModel model) => writer.WritePackedFixedString128Delta(expected, baseline, model);
|
|
FixedString128Bytes ReadPacked(ref DataStreamReader reader, StreamCompressionModel model) => reader.ReadPackedFixedString128Delta(baseline, model);
|
|
CheckReadWritePacked(expected.Length + FixedStringHeader, ReadPacked, WritePacked, expected);
|
|
}
|
|
|
|
[Test]
|
|
public void FixedString512()
|
|
{
|
|
var expected = new FixedString512Bytes("This is a string");
|
|
var baseline = new FixedString512Bytes("This is another string");
|
|
bool WritePacked(ref DataStreamWriter writer, StreamCompressionModel model) => writer.WritePackedFixedString512Delta(expected, baseline, model);
|
|
FixedString512Bytes ReadPacked(ref DataStreamReader reader, StreamCompressionModel model) => reader.ReadPackedFixedString512Delta(baseline, model);
|
|
CheckReadWritePacked(expected.Length + FixedStringHeader, ReadPacked, WritePacked, expected);
|
|
}
|
|
|
|
[Test]
|
|
public void FixedString4096()
|
|
{
|
|
var expected = new FixedString4096Bytes("This is a string");
|
|
var baseline = new FixedString4096Bytes("This is another string");
|
|
bool WritePacked(ref DataStreamWriter writer, StreamCompressionModel model) => writer.WritePackedFixedString4096Delta(expected, baseline, model);
|
|
FixedString4096Bytes ReadPacked(ref DataStreamReader reader, StreamCompressionModel model) => reader.ReadPackedFixedString4096Delta(baseline, model);
|
|
CheckReadWritePacked(expected.Length + FixedStringHeader, ReadPacked, WritePacked, expected);
|
|
}
|
|
|
|
[Test]
|
|
public void Float_OutOfBoundsFails()
|
|
{
|
|
const float expected = float.MaxValue;
|
|
const float baseline = float.MinValue;
|
|
var model = StreamCompressionModel.Default;
|
|
var writer = new DataStreamWriter(sizeof(float) / 2, Allocator.Temp);
|
|
Assert.False(writer.HasFailedWrites);
|
|
Assert.False(writer.WritePackedFloatDelta(expected, baseline, model));
|
|
Assert.That(writer.HasFailedWrites);
|
|
}
|
|
|
|
[Test]
|
|
public void Float_UnchangedData()
|
|
{
|
|
const float expected = float.MaxValue;
|
|
const float baseline = float.MaxValue;
|
|
var model = StreamCompressionModel.Default;
|
|
var writer = new DataStreamWriter(1, Allocator.Temp);
|
|
Assert.True(writer.WritePackedFloatDelta(expected, baseline, model));
|
|
var reader = new DataStreamReader(writer.AsNativeArray());
|
|
Assert.AreEqual(baseline, reader.ReadPackedFloatDelta(baseline, model));
|
|
Assert.That(reader.GetBitsRead(), Is.EqualTo(1));
|
|
}
|
|
|
|
[Test]
|
|
public void Float_ChangedData()
|
|
{
|
|
const float expected = float.MaxValue;
|
|
const float baseline = float.MinValue;
|
|
var model = StreamCompressionModel.Default;
|
|
var writer = new DataStreamWriter(sizeof(float) + 1, Allocator.Temp);
|
|
Assert.True(writer.WritePackedFloatDelta(expected, baseline, model));
|
|
var reader = new DataStreamReader(writer.AsNativeArray());
|
|
Assert.AreEqual(1, reader.ReadRawBits(1));
|
|
var uf = new UIntFloat
|
|
{
|
|
intValue = reader.ReadRawBits(32)
|
|
};
|
|
Assert.AreEqual(expected, uf.floatValue);
|
|
}
|
|
|
|
[Test]
|
|
[TestRequiresDotsDebugOrCollectionChecks]
|
|
public void UInt_OutOfCapacity()
|
|
{
|
|
var model = StreamCompressionModel.Default;
|
|
var writer = new DataStreamWriter(0, Allocator.Temp);
|
|
var reader = new DataStreamReader(writer.AsNativeArray());
|
|
LogAssert.Expect(LogType.Error, "Trying to read 2 bits from a stream where only 0 are available");
|
|
Assert.That(reader.ReadPackedUInt(model), Is.EqualTo(0));
|
|
Assert.That(reader.HasFailedReads);
|
|
}
|
|
|
|
|
|
// We test with a variable amount of writes to ensure we overflow the internal ulong bitBuffer.
|
|
[Test]
|
|
public void Flush_Works([Values(1, 7, 24, 65)]int numWrites)
|
|
{
|
|
const int baseline = 100;
|
|
var model = StreamCompressionModel.Default;
|
|
var writer = new DataStreamWriter(512, Allocator.Temp);
|
|
|
|
// Writer:
|
|
for(int i = 0; i < numWrites; i++)
|
|
writer.WritePackedUIntDelta((uint) (100 + i), baseline, model);
|
|
|
|
// Flush, and write another sentinel value in.
|
|
writer.Flush();
|
|
writer.WritePackedUIntDelta(45, baseline, model);
|
|
writer.Flush();
|
|
Assert.IsFalse(writer.HasFailedWrites, "Sanity: writer.HasFailedWrites");
|
|
|
|
// Reader:
|
|
var reader = new DataStreamReader(writer.AsNativeArray());
|
|
for(int i = 0; i < numWrites; i++)
|
|
{
|
|
var read = reader.ReadPackedUIntDelta(baseline, model);
|
|
Assert.AreEqual((uint)(100 + i), read, "100 + i");
|
|
}
|
|
|
|
// When we flush the reader, we expect to now be aligned.
|
|
reader.Flush();
|
|
var read45 = reader.ReadPackedUIntDelta(baseline, model);
|
|
Assert.AreEqual(45, read45, "45");
|
|
reader.Flush();
|
|
Assert.IsFalse(reader.HasFailedReads, "reader.HasFailedReads");
|
|
Assert.AreEqual(writer.LengthInBits, reader.GetBitsRead(), "writer.LengthInBits vs reader.GetBitsRead()");
|
|
LogAssert.NoUnexpectedReceived();
|
|
}
|
|
|
|
[Test]
|
|
public void NotMirroringFlushCall_Fails()
|
|
{
|
|
const int baseline = 100;
|
|
var model = StreamCompressionModel.Default;
|
|
var writer = new DataStreamWriter(512, Allocator.Temp);
|
|
|
|
// Writer:
|
|
writer.WritePackedUIntDelta(100, baseline, model);
|
|
Assert.AreNotEqual(0, writer.LengthInBits % 8, "Sanity: Not byte aligned!");
|
|
writer.Flush();
|
|
writer.WritePackedUIntDelta(45, baseline, model);
|
|
writer.Flush();
|
|
Assert.IsFalse(writer.HasFailedWrites, "Sanity: writer.HasFailedWrites");
|
|
|
|
// Reader:
|
|
var reader = new DataStreamReader(writer.AsNativeArray());
|
|
var read = reader.ReadPackedUIntDelta(baseline, model);
|
|
Assert.AreEqual(100u, read, "100u");
|
|
|
|
// SKIPPED: reader.Flush();
|
|
// THUS: Read pointer alignment should be wrong.
|
|
LogAssert.ignoreFailingMessages = true; // Defensive: Technically we're reading too FEW bits,
|
|
// so we shouldn't get error logs here.
|
|
Assert.AreNotEqual(45, reader.ReadPackedIntDelta(baseline, model), "!45");
|
|
Assert.AreNotEqual(writer.LengthInBits, reader.GetBitsRead(), "writer.LengthInBits vs reader.GetBitsRead()");
|
|
}
|
|
|
|
[Test]
|
|
public void CanMixPackedAndNonPacked()
|
|
{
|
|
const int baseline = 200;
|
|
var model = StreamCompressionModel.Default;
|
|
var writer = new DataStreamWriter(12, Allocator.Temp);
|
|
|
|
writer.WritePackedIntDelta(201, baseline, model);
|
|
Assert.AreNotEqual(0, writer.LengthInBits % 8, "Sanity: This test is invalid if we accidentally byte-align.");
|
|
writer.WriteInt(202);
|
|
writer.WritePackedInt(203, model);
|
|
writer.WriteInt(204);
|
|
|
|
Assert.IsFalse(writer.HasFailedWrites, "Sanity: writer.HasFailedWrites");
|
|
|
|
var reader = new DataStreamReader(writer.AsNativeArray());
|
|
Assert.AreEqual(201, reader.ReadPackedIntDelta(baseline, model));
|
|
Assert.AreEqual(202, reader.ReadInt());
|
|
Assert.AreEqual(203, reader.ReadPackedInt(model));
|
|
Assert.AreEqual(204, reader.ReadInt());
|
|
Assert.IsFalse(reader.HasFailedReads, "reader.HasFailedReads");
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void IsCreated_ReturnsTrueAfterConstructor()
|
|
{
|
|
var dataStream = new DataStreamWriter(4, Allocator.Temp);
|
|
Assert.True(dataStream.IsCreated, "Buffer must be created after calling constructor.");
|
|
}
|
|
|
|
[Test]
|
|
public void LengthInBits_MatchesWrittenCount()
|
|
{
|
|
var dataStream = new DataStreamWriter(4, Allocator.Temp);
|
|
dataStream.WriteByte(0);
|
|
Assert.That(dataStream.LengthInBits, Is.EqualTo(1 * 8));
|
|
dataStream.WriteByte(1);
|
|
dataStream.WriteByte(1);
|
|
Assert.That(dataStream.LengthInBits, Is.EqualTo(3 * 8));
|
|
}
|
|
|
|
[Test]
|
|
public void CreateStreamWithPartOfSourceByteArray()
|
|
{
|
|
byte[] byteArray =
|
|
{
|
|
(byte)'s', (byte)'o', (byte)'m', (byte)'e',
|
|
(byte)' ', (byte)'d', (byte)'a', (byte)'t', (byte)'a'
|
|
};
|
|
|
|
DataStreamWriter dataStream;
|
|
dataStream = new DataStreamWriter(4, Allocator.Temp);
|
|
dataStream.WriteBytes(new NativeArray<byte>(byteArray, Allocator.Temp).GetSubArray(0, 4));
|
|
Assert.AreEqual(dataStream.Length, 4);
|
|
var reader = new DataStreamReader(dataStream.AsNativeArray());
|
|
for (int i = 0; i < dataStream.Length; ++i)
|
|
{
|
|
Assert.AreEqual(byteArray[i], reader.ReadByte());
|
|
}
|
|
|
|
#if ENABLE_UNITY_COLLECTIONS_CHECKS || UNITY_DOTS_DEBUG
|
|
LogAssert.Expect(LogType.Error, "Trying to read 1 bytes from a stream where only 0 are available");
|
|
Assert.AreEqual(0, reader.ReadByte());
|
|
#endif
|
|
}
|
|
|
|
[Test]
|
|
public void CreateStreamWithSourceByteArray()
|
|
{
|
|
byte[] byteArray = new byte[100];
|
|
byteArray[0] = (byte)'a';
|
|
byteArray[1] = (byte)'b';
|
|
byteArray[2] = (byte)'c';
|
|
|
|
DataStreamWriter dataStream1, dataStream2;
|
|
dataStream1 = new DataStreamWriter(byteArray.Length, Allocator.Temp);
|
|
dataStream2 = new DataStreamWriter(byteArray.Length, Allocator.Temp);
|
|
dataStream1.WriteBytes(new NativeArray<byte>(byteArray, Allocator.Temp));
|
|
dataStream2.WriteBytes(byteArray);
|
|
|
|
var arr1 = dataStream1.AsNativeArray();
|
|
var arr2 = dataStream2.AsNativeArray();
|
|
var reader1 = new DataStreamReader(arr1);
|
|
var reader2 = new DataStreamReader(arr2);
|
|
for (var i = 0; i < byteArray.Length; ++i)
|
|
{
|
|
Assert.AreEqual(byteArray[i], reader1.ReadByte());
|
|
Assert.AreEqual(byteArray[i], reader2.ReadByte());
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void ReadIntoExistingNativeByteArray()
|
|
{
|
|
var byteArray = new NativeArray<byte>(100, Allocator.Temp);
|
|
|
|
DataStreamWriter dataStream;
|
|
dataStream = new DataStreamWriter(3, Allocator.Temp);
|
|
{
|
|
dataStream.WriteByte((byte)'a');
|
|
dataStream.WriteByte((byte)'b');
|
|
dataStream.WriteByte((byte)'c');
|
|
var reader = new DataStreamReader(dataStream.AsNativeArray());
|
|
reader.ReadBytes(byteArray.GetSubArray(0, dataStream.Length));
|
|
reader = new DataStreamReader(dataStream.AsNativeArray());
|
|
for (int i = 0; i < reader.Length; ++i)
|
|
{
|
|
Assert.AreEqual(byteArray[i], reader.ReadByte());
|
|
}
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void ReadIntoExistingByteArray()
|
|
{
|
|
var byteArray = new byte[3];
|
|
|
|
DataStreamWriter dataStream;
|
|
dataStream = new DataStreamWriter(3, Allocator.Temp);
|
|
{
|
|
dataStream.WriteByte((byte)'a');
|
|
dataStream.WriteByte((byte)'b');
|
|
dataStream.WriteByte((byte)'c');
|
|
var reader = new DataStreamReader(dataStream.AsNativeArray());
|
|
reader.ReadBytes(byteArray);
|
|
reader = new DataStreamReader(dataStream.AsNativeArray());
|
|
for (int i = 0; i < reader.Length; ++i)
|
|
{
|
|
Assert.AreEqual(byteArray[i], reader.ReadByte());
|
|
}
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void ReadingDataFromStreamWithSliceOffset()
|
|
{
|
|
var dataStream = new DataStreamWriter(100, Allocator.Temp);
|
|
dataStream.WriteByte((byte)'a');
|
|
dataStream.WriteByte((byte)'b');
|
|
dataStream.WriteByte((byte)'c');
|
|
dataStream.WriteByte((byte)'d');
|
|
dataStream.WriteByte((byte)'e');
|
|
dataStream.WriteByte((byte)'f');
|
|
var reader = new DataStreamReader(dataStream.AsNativeArray().GetSubArray(3, 3));
|
|
Assert.AreEqual('d', reader.ReadByte());
|
|
Assert.AreEqual('e', reader.ReadByte());
|
|
Assert.AreEqual('f', reader.ReadByte());
|
|
}
|
|
|
|
[Test]
|
|
public void GetStreamReaderUnsafePtr()
|
|
{
|
|
var a = new NativeArray<byte>(1, Allocator.Temp);
|
|
a[0] = (byte)42;
|
|
var reader = new DataStreamReader(a);
|
|
|
|
unsafe
|
|
{
|
|
var ptr = (byte*)reader.GetUnsafeReadOnlyPtr();
|
|
Assert.AreEqual((byte)42, *ptr);
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void WriteOutOfBounds()
|
|
{
|
|
var dataStream = new DataStreamWriter(9, Allocator.Temp);
|
|
Assert.IsTrue(dataStream.WriteInt(42));
|
|
Assert.AreEqual(4, dataStream.Length);
|
|
Assert.IsTrue(dataStream.WriteInt(42));
|
|
Assert.AreEqual(8, dataStream.Length);
|
|
Assert.IsFalse(dataStream.HasFailedWrites);
|
|
Assert.IsFalse(dataStream.WriteInt(42));
|
|
Assert.AreEqual(8, dataStream.Length);
|
|
Assert.IsTrue(dataStream.HasFailedWrites);
|
|
|
|
Assert.IsFalse(dataStream.WriteShort(42));
|
|
Assert.AreEqual(8, dataStream.Length);
|
|
Assert.IsTrue(dataStream.HasFailedWrites);
|
|
|
|
Assert.IsTrue(dataStream.WriteByte(42));
|
|
Assert.AreEqual(9, dataStream.Length);
|
|
Assert.IsTrue(dataStream.HasFailedWrites);
|
|
|
|
Assert.IsFalse(dataStream.WriteByte(42));
|
|
Assert.AreEqual(9, dataStream.Length);
|
|
Assert.IsTrue(dataStream.HasFailedWrites);
|
|
}
|
|
|
|
[Test]
|
|
public void ReadWritePackedUIntWithDeferred()
|
|
{
|
|
var compressionModel = StreamCompressionModel.Default;
|
|
var dataStream = new DataStreamWriter(300 * 4, Allocator.Temp);
|
|
uint base_val = 2000;
|
|
uint count = 277;
|
|
var def = dataStream;
|
|
dataStream.WriteInt((int)0);
|
|
for (uint i = 0; i < count; ++i)
|
|
dataStream.WritePackedUInt(base_val + i, compressionModel);
|
|
|
|
dataStream.Flush();
|
|
def.WriteInt(1979);
|
|
def = dataStream;
|
|
dataStream.WriteInt((int)0);
|
|
def.WriteInt(1979);
|
|
dataStream.Flush();
|
|
var reader = new DataStreamReader(dataStream.AsNativeArray());
|
|
Assert.AreEqual(1979, reader.ReadInt());
|
|
for (uint i = 0; i < count; ++i)
|
|
{
|
|
var val = reader.ReadPackedUInt(compressionModel);
|
|
Assert.AreEqual(base_val + i, val);
|
|
}
|
|
|
|
Assert.AreEqual(1979, reader.ReadInt());
|
|
}
|
|
|
|
[Test]
|
|
public void PassDataStreamReaderToJob()
|
|
{
|
|
using (var returnValue = new NativeArray<int>(1, Allocator.TempJob))
|
|
{
|
|
var writer = new DataStreamWriter(sizeof(int), Allocator.Temp);
|
|
writer.WriteInt(42);
|
|
|
|
var reader = new DataStreamReader(writer.AsNativeArray());
|
|
|
|
new ReaderTestJob
|
|
{
|
|
Reader = reader,
|
|
ReturnValue = returnValue
|
|
}.Run();
|
|
|
|
Assert.AreEqual(42, returnValue[0]);
|
|
}
|
|
}
|
|
|
|
private struct ReaderTestJob : IJob
|
|
{
|
|
public DataStreamReader Reader;
|
|
public NativeArray<int> ReturnValue;
|
|
|
|
public void Execute()
|
|
{
|
|
ReturnValue[0] = Reader.ReadInt();
|
|
}
|
|
}
|
|
|
|
delegate T Read<out T>(ref DataStreamReader reader);
|
|
delegate T ReadPacked<out T>(ref DataStreamReader reader, StreamCompressionModel model);
|
|
delegate bool Write(ref DataStreamWriter writer);
|
|
delegate T Sum<T>(T x, uint y);
|
|
delegate bool WriteWithValue<in T>(ref DataStreamWriter writer, T value);
|
|
delegate bool WritePacked(ref DataStreamWriter writer, StreamCompressionModel model);
|
|
delegate bool WritePackedWithValue<in T>(ref DataStreamWriter writer, StreamCompressionModel model, T value);
|
|
|
|
const int FixedStringHeader = 2;
|
|
|
|
static void CheckReadWritePackedLooped<T>(int size, T baseVal, T expected,
|
|
Write write, WritePackedWithValue<T> writePackedWithValue,
|
|
Read<T> read, ReadPacked<T> readPacked, Sum<T> sum)
|
|
{
|
|
var compressionModel = StreamCompressionModel.Default;
|
|
var dataStream = new DataStreamWriter(300 * size, Allocator.Temp);
|
|
const int count = 277;
|
|
for (uint i = 0; i < count; ++i)
|
|
{
|
|
T res = sum(baseVal, i);
|
|
writePackedWithValue(ref dataStream, compressionModel, res);
|
|
}
|
|
|
|
write(ref dataStream);
|
|
dataStream.Flush();
|
|
var reader = new DataStreamReader(dataStream.AsNativeArray());
|
|
for (uint i = 0; i < count; ++i)
|
|
{
|
|
var val = readPacked(ref reader, compressionModel);
|
|
Assert.AreEqual(sum(baseVal, i), val);
|
|
}
|
|
|
|
Assert.AreEqual(expected, read(ref reader));
|
|
}
|
|
|
|
static void CheckReadWritePacked<T>(int size, ReadPacked<T> read, WritePacked write, T value)
|
|
{
|
|
var model = StreamCompressionModel.Default;
|
|
var writer = new DataStreamWriter(size, Allocator.Temp);
|
|
write(ref writer, model);
|
|
writer.Flush();
|
|
var reader = new DataStreamReader(writer.AsNativeArray());
|
|
Assert.That(read(ref reader, model), Is.EqualTo(value));
|
|
}
|
|
|
|
static void CheckReadWrite<T>(int size, Func<DataStreamReader, T> read, Write write, T value)
|
|
{
|
|
var writer = new DataStreamWriter(size, Allocator.Temp);
|
|
write(ref writer);
|
|
writer.Flush();
|
|
Assert.That(read(new DataStreamReader(writer.AsNativeArray())), Is.EqualTo(value));
|
|
}
|
|
|
|
static void CheckReadWriteLooped<T>(int size, T baseVal, T expected, WriteWithValue<T> write, Read<T> read, Sum<T> sum)
|
|
{
|
|
var writer = new DataStreamWriter(300 * size, Allocator.Temp);
|
|
const int count = 277;
|
|
for (uint i = 0; i < count; ++i)
|
|
{
|
|
write(ref writer, sum(baseVal, i));
|
|
}
|
|
|
|
write(ref writer, expected);
|
|
writer.Flush();
|
|
var reader = new DataStreamReader(writer.AsNativeArray());
|
|
for (uint i = 0; i < count; ++i)
|
|
{
|
|
var val = read(ref reader);
|
|
Assert.AreEqual(sum(baseVal, i), val);
|
|
}
|
|
|
|
Assert.AreEqual(expected, read(ref reader));
|
|
}
|
|
|
|
[Test]
|
|
public void MiNiCheck()
|
|
{
|
|
var model = StreamCompressionModel.Default;
|
|
Assert.That(model.ToString(), Is.EqualTo("Unity.Collections.StreamCompressionModel"));
|
|
}
|
|
}
|
|
}
|