review(Driver.AbCip): fix declared UDT array members read as scalar (Medium)
Re-review at 7286d320. AbCip-016 (Medium): two cooperating defects made a declared array
member (e.g. REAL[4]) read one scalar/null — fan-out dropped ElementCount/IsArray, and
UdtMemberLayout.TryBuild ignored array members (mis-placing later members). Fix: thread
array shape through fan-out + opt whole-UDT grouping out when any member is an array + TDD.
AbCip-017 (severity-read StatusCode, Low) deferred.
This commit is contained in:
@@ -279,7 +279,14 @@ public sealed class AbCipDriver : IDriver, IReadable, IWritable, ITagDiscovery,
|
||||
TagPath: $"{tag.TagPath}.{member.Name}",
|
||||
DataType: member.DataType,
|
||||
Writable: member.Writable,
|
||||
WriteIdempotent: member.WriteIdempotent);
|
||||
WriteIdempotent: member.WriteIdempotent,
|
||||
// Driver.AbCip-016 — carry the member's array shape into the fanned-out
|
||||
// runtime definition. Discovery already emits an array node for an array
|
||||
// member (member.IsArray || member.ElementCount > 1); without these the
|
||||
// runtime def defaulted to scalar and the read returned a single element
|
||||
// instead of the typed array, a declared-type-vs-runtime-value mismatch.
|
||||
ElementCount: member.ElementCount,
|
||||
IsArray: member.IsArray);
|
||||
// Member fan-out duplicate check: a member-path collision means two
|
||||
// configured structure tags produce the same member path, or a member
|
||||
// name collides with an independently-declared tag.
|
||||
|
||||
@@ -44,6 +44,14 @@ public static class AbCipUdtMemberLayout
|
||||
if (!TryGetSizeAlign(member.DataType, out var size, out var align))
|
||||
return null;
|
||||
|
||||
// Driver.AbCip-016 — an array member can't be placed by declaration-only layout: the
|
||||
// whole-UDT grouped read decodes one scalar per member at its offset and can't return
|
||||
// an array, and advancing the cursor by the scalar size (not size * count) would
|
||||
// mis-place every member after it. Opt the whole group out so array members fall back
|
||||
// to the per-tag read path, which reads them as typed arrays.
|
||||
if (member.IsArray || member.ElementCount > 1)
|
||||
return null;
|
||||
|
||||
if (cursor % align != 0)
|
||||
cursor += align - (cursor % align);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user