Skip to content
Merged
29 changes: 29 additions & 0 deletions tests/SerializationModels.cs
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,35 @@ public struct StrictBlittableStruct
public int Value { get; init; }
}

[StructLayout(LayoutKind.Sequential, Pack = 1)]
[ZeroSerializer]
public record struct BadlyAlignedStructWithPackOne
{
public byte A { get; set; }
public short B { get; set; }
}

[StructLayout(LayoutKind.Sequential, Pack = 1)]
[ZeroSerializer]
public record struct BadlyAlignedContainerStructWithPackOne
{
public byte A { get; set; }
public long B { get; set; }
public byte C { get; set; }
public int D { get; set; }
public short E { get; set; }
public double F { get; set; }
public byte G { get; set; }
public BadlyAlignedStructWithPackOne H { get; set; }
public BadlyAlignedStructWithPackOne I { get; set; }
}

[ZeroSerializer]
public sealed class BadlyAlignedContainerArrayStructWithPackOne
Comment thread
sator-imaging marked this conversation as resolved.
Outdated
{
public BadlyAlignedContainerStructWithPackOne[] Values { get; set; } = Array.Empty<BadlyAlignedContainerStructWithPackOne>();
}

[ZeroSerializer]
public record SimpleCsharpRecord
{
Expand Down
53 changes: 53 additions & 0 deletions tests/SerializationTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1228,4 +1228,57 @@ public void BlittableRecordStructNestedPropertyRoundTrip()
TestAssert.True(viewNulls.Values.IsEmpty, nameof(viewNulls.Values.IsEmpty));
TestAssert.Equal(writtenBytesNulls, viewNulls.GetByteLength(), "Nulls GetByteLength");
}

[Fact]
public void BadlyAlignedStructWithPackOneRoundTrip()
{
TestAssert.Equal(3, BadlyAlignedStructWithPackOneView.RequiredByteLength, nameof(BadlyAlignedStructWithPackOneView.RequiredByteLength));
TestAssert.Equal(31, BadlyAlignedContainerStructWithPackOneView.RequiredByteLength, nameof(BadlyAlignedContainerStructWithPackOneView.RequiredByteLength));

var foo = new BadlyAlignedContainerStructWithPackOne
{
A = 0x12,
B = 0x123456789ABCDEF0,
C = 0x34,
D = 0x56789ABC,
E = -1234,
F = 3.141592653589793,
G = 0x77,
H = new BadlyAlignedStructWithPackOne { A = 0xAB, B = 0x5678 },
I = new BadlyAlignedStructWithPackOne { A = 0xCD, B = -4321 }
};

var array = new BadlyAlignedContainerArrayStructWithPackOne();
array.Values = new[] { default, foo, default };

var arrayBuffer = new byte[1024];
int arrayWrittenBytes = array.Serialize(arrayBuffer);
TestAssert.Equal(101, arrayWrittenBytes, nameof(arrayWrittenBytes));

var arrayView = new BadlyAlignedContainerArrayStructWithPackOneView(arrayBuffer);
TestAssert.True(arrayView.Values[0] == default, "1st item");
TestAssert.True(arrayView.Values[1] == foo, "2nd item");
TestAssert.True(arrayView.Values[2] == default, "3rd item");

var buffer = new byte[BadlyAlignedContainerStructWithPackOneView.RequiredByteLength * 3];
int writtenBytes = foo.Serialize(buffer.AsSpan(BadlyAlignedContainerStructWithPackOneView.RequiredByteLength));

TestAssert.Equal(31, writtenBytes, nameof(writtenBytes));
Comment thread
sator-imaging marked this conversation as resolved.

var second = buffer.AsMemory().Slice(BadlyAlignedContainerStructWithPackOneView.RequiredByteLength, BadlyAlignedContainerStructWithPackOneView.RequiredByteLength);
var view = new BadlyAlignedContainerStructWithPackOneView(second);

TestAssert.Equal(foo.A, view.A, nameof(view.A));
TestAssert.Equal(foo.B, view.B, nameof(view.B));
TestAssert.Equal(foo.C, view.C, nameof(view.C));
TestAssert.Equal(foo.D, view.D, nameof(view.D));
TestAssert.Equal(foo.E, view.E, nameof(view.E));
TestAssert.Equal(foo.F, view.F, nameof(view.F));
TestAssert.Equal(foo.G, view.G, nameof(view.G));
TestAssert.Equal(foo.H.A, view.H.A, nameof(view.H.A));
TestAssert.Equal(foo.H.B, view.H.B, nameof(view.H.B));
TestAssert.Equal(foo.I.A, view.I.A, nameof(view.I.A));
TestAssert.Equal(foo.I.B, view.I.B, nameof(view.I.B));
Comment thread
sator-imaging marked this conversation as resolved.
TestAssert.True(foo == view.Materialize(), nameof(view));
}
}