Skip to content

Commit e13f310

Browse files
committed
fix: BinaryObjects with constant arrays are tagged correctly as well
1 parent bbc4b0f commit e13f310

File tree

3 files changed

+57
-46
lines changed

3 files changed

+57
-46
lines changed

src/Darp.BinaryObjects.Generator/BinaryMemberInfo.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -638,6 +638,9 @@ and not WellKnownTypeKind.SByte
638638
and not WellKnownTypeKind.Byte
639639
and not WellKnownTypeKind.EnumSByte
640640
and not WellKnownTypeKind.EnumByte;
641+
// Binary object generation does not depend on the byte length
642+
if (typeKind is WellKnownTypeKind.BinaryObject)
643+
byteLength = UtilityData.UnknownLength;
641644
return collectionKind switch
642645
{
643646
WellKnownCollectionKind.None =>
@@ -732,6 +735,9 @@ and not WellKnownTypeKind.SByte
732735
and not WellKnownTypeKind.Byte
733736
and not WellKnownTypeKind.EnumSByte
734737
and not WellKnownTypeKind.EnumByte;
738+
// Binary object generation does not depend on the byte length
739+
if (typeKind is WellKnownTypeKind.BinaryObject)
740+
byteLength = UtilityData.UnknownLength;
735741
return collectionKind switch
736742
{
737743
WellKnownCollectionKind.None =>
@@ -1212,7 +1218,7 @@ not null
12121218
bytesRead = list.Count * {byteLength};
12131219
return list;
12141220
""",
1215-
(WellKnownCollectionKind.List, WellKnownTypeKind.BinaryObject, not null) => (_, _, isLittleEndian) =>
1221+
(WellKnownCollectionKind.List, WellKnownTypeKind.BinaryObject, _) => (_, _, isLittleEndian) =>
12161222
$$"""
12171223
var numberOfElements = source.Length / elementLength;
12181224
var array = new List<T>(numberOfElements);

src/Darp.BinaryObjects.Generator/BinaryObjectsGenerator.Parser.cs

Lines changed: 33 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -424,44 +424,59 @@ out ITypeSymbol? underlyingTypeSymbol
424424
return true;
425425
}
426426

427-
private static bool IsConstant(ITypeSymbol typeSymbol, out int constantLength)
427+
private static bool IsConstant(ITypeSymbol typeSymbol, out int totalLength)
428428
{
429429
AttributeData? binaryConstantObjectAttribute = typeSymbol
430430
.GetAttributes()
431431
.FirstOrDefault(x => x.AttributeClass?.ToDisplayString() == "Darp.BinaryObjects.BinaryConstantAttribute");
432432
if (binaryConstantObjectAttribute?.ConstructorArguments[0].Value is int value)
433433
{
434-
constantLength = value;
434+
totalLength = value;
435435
return true;
436436
}
437437

438-
constantLength = default;
438+
totalLength = 0;
439439
foreach (
440-
ITypeSymbol memberTypeSymbol in typeSymbol
440+
ISymbol symbol in typeSymbol
441441
.GetMembers()
442442
.Where(x => x.Kind is SymbolKind.Field or SymbolKind.Property)
443443
.Where(x => !x.IsImplicitlyDeclared)
444-
.Select(x =>
445-
x switch
446-
{
447-
IFieldSymbol s => s.Type,
448-
IPropertySymbol s => s.Type,
449-
_ => throw new ArgumentOutOfRangeException(nameof(x)),
450-
}
451-
)
452444
)
453445
{
454-
if (
455-
memberTypeSymbol.TryGetArrayType(out WellKnownCollectionKind collectionKind, out ITypeSymbol? _)
456-
|| collectionKind is not WellKnownCollectionKind.None
457-
)
458-
return false;
446+
(bool HasAttribute, int? Length) hasElementCountTuple = symbol
447+
.GetAttributes()
448+
.Select(a =>
449+
{
450+
if (a.AttributeClass?.ToDisplayString() != "Darp.BinaryObjects.BinaryElementCountAttribute")
451+
return (false, 1);
452+
if (
453+
!a.GetArguments()
454+
.ToDictionary(x => x.Key, x => x.Value)
455+
.TryGetValue("length", out TypedConstant lengthValue)
456+
)
457+
return (false, 1);
458+
return (true, (int?)lengthValue.Value);
459+
})
460+
.FirstOrDefault(x => x.Item1);
461+
var arrayLength = hasElementCountTuple.Length ?? 1;
462+
ITypeSymbol memberTypeSymbol = symbol switch
463+
{
464+
IFieldSymbol s => s.Type,
465+
IPropertySymbol s => s.Type,
466+
_ => throw new ArgumentException($"Invalid symbol type {symbol.ToDisplayString()}"),
467+
};
468+
if (memberTypeSymbol.TryGetArrayType(out WellKnownCollectionKind _, out ITypeSymbol? arrayTypeSymbol))
469+
{
470+
if (!hasElementCountTuple.HasAttribute)
471+
return false;
472+
memberTypeSymbol = arrayTypeSymbol;
473+
}
459474
WellKnownTypeKind typeKind = GetWellKnownTypeKind(memberTypeSymbol);
460475
if (typeKind is WellKnownTypeKind.BinaryObject)
461476
return false;
462477
if (!typeKind.TryGetLength(out var length))
463478
return false;
464-
constantLength += length;
479+
totalLength += length * arrayLength;
465480
}
466481
return true;
467482
}

test/Darp.BinaryObjects.Generator.Tests/Snapshots/IntegrationTest.BinaryObject_DefaultAsync#BinaryObjectsGenerator.g.verified.cs

Lines changed: 17 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -175,15 +175,17 @@ public static bool TryReadBigEndian(global::System.ReadOnlySpan<byte> source, [g
175175
/// <remarks> <list type="table">
176176
/// <item> <term><b>Field</b></term> <description><b>Byte Length</b></description> </item>
177177
/// <item> <term><see cref="Value"/></term> <description>1</description> </item>
178-
/// <item> <term><see cref="Array"/></term> <description><see cref="OneArray.GetByteCount()"/></description> </item>
179-
/// <item> <term> --- </term> <description>1 + <see cref="OneArray.GetByteCount()"/></description> </item>
178+
/// <item> <term><see cref="Array"/></term> <description>2</description> </item>
179+
/// <item> <term> --- </term> <description>3</description> </item>
180180
/// </list> </remarks>
181+
[global::Darp.BinaryObjects.BinaryConstant(3)]
181182
public sealed partial record OneBinaryObject : global::Darp.BinaryObjects.IBinaryObject<OneBinaryObject>
182183
{
183184
/// <inheritdoc />
185+
[global::System.Diagnostics.Contracts.Pure]
184186
[global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
185187
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Darp.BinaryObjects.Generator", "GeneratorVersion")]
186-
public int GetByteCount() => 1 + this.Array.GetByteCount();
188+
public int GetByteCount() => 3;
187189

188190
/// <inheritdoc />
189191
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Darp.BinaryObjects.Generator", "GeneratorVersion")]
@@ -194,14 +196,11 @@ public bool TryWriteLittleEndian(global::System.Span<byte> destination, out int
194196
{
195197
bytesWritten = 0;
196198

197-
if (destination.Length < 1)
199+
if (destination.Length < 3)
198200
return false;
199201
global::Darp.BinaryObjects.Generated.Utilities.WriteBinaryObjectLittleEndian(destination[0..], this.Value);
200-
bytesWritten += 1;
201-
202-
if (!this.Array.TryWriteLittleEndian(destination[1..], out var ___bytesWrittenArray))
203-
return false;
204-
bytesWritten += ___bytesWrittenArray;
202+
global::Darp.BinaryObjects.Generated.Utilities.WriteBinaryObjectLittleEndian(destination[1..], this.Array);
203+
bytesWritten += 3;
205204

206205
return true;
207206
}
@@ -214,14 +213,11 @@ public bool TryWriteBigEndian(global::System.Span<byte> destination, out int byt
214213
{
215214
bytesWritten = 0;
216215

217-
if (destination.Length < 1)
216+
if (destination.Length < 3)
218217
return false;
219218
global::Darp.BinaryObjects.Generated.Utilities.WriteBinaryObjectBigEndian(destination[0..], this.Value);
220-
bytesWritten += 1;
221-
222-
if (!this.Array.TryWriteBigEndian(destination[1..], out var ___bytesWrittenArray))
223-
return false;
224-
bytesWritten += ___bytesWrittenArray;
219+
global::Darp.BinaryObjects.Generated.Utilities.WriteBinaryObjectBigEndian(destination[1..], this.Array);
220+
bytesWritten += 3;
225221

226222
return true;
227223
}
@@ -236,14 +232,11 @@ public static bool TryReadLittleEndian(global::System.ReadOnlySpan<byte> source,
236232
bytesRead = 0;
237233
value = default;
238234

239-
if (source.Length < 1)
235+
if (source.Length < 3)
240236
return false;
241237
var ___readValue = global::Darp.BinaryObjects.Generated.Utilities.ReadBinaryObjectLittleEndian<OneBool>(source[0..1]);
242-
bytesRead += 1;
243-
244-
if (!OneArray.TryReadLittleEndian(source[1..], out var ___readArray, out var ___bytesReadArray))
245-
return false;
246-
bytesRead += ___bytesReadArray;
238+
var ___readArray = global::Darp.BinaryObjects.Generated.Utilities.ReadBinaryObjectLittleEndian<OneArray>(source[1..3]);
239+
bytesRead += 3;
247240

248241
value = new OneBinaryObject(___readValue, ___readArray);
249242
return true;
@@ -258,14 +251,11 @@ public static bool TryReadBigEndian(global::System.ReadOnlySpan<byte> source, [g
258251
bytesRead = 0;
259252
value = default;
260253

261-
if (source.Length < 1)
254+
if (source.Length < 3)
262255
return false;
263256
var ___readValue = global::Darp.BinaryObjects.Generated.Utilities.ReadBinaryObjectBigEndian<OneBool>(source[0..1]);
264-
bytesRead += 1;
265-
266-
if (!OneArray.TryReadBigEndian(source[1..], out var ___readArray, out var ___bytesReadArray))
267-
return false;
268-
bytesRead += ___bytesReadArray;
257+
var ___readArray = global::Darp.BinaryObjects.Generated.Utilities.ReadBinaryObjectBigEndian<OneArray>(source[1..3]);
258+
bytesRead += 3;
269259

270260
value = new OneBinaryObject(___readValue, ___readArray);
271261
return true;

0 commit comments

Comments
 (0)