review(Driver.AbCip): thread ElementCount/IsArray through factory tag DTOs
Cross-module fix from the review sweep. -018 (Medium): AbCipTagDto/AbCipMemberDto dropped elementCount/isArray, so driver-config-authored array tags read as a single scalar. Added the two optional JSON fields (additive; missing -> scalar as before) threaded into the tag def + TDD.
This commit is contained in:
@@ -269,7 +269,7 @@ were spot-checked as still in force.
|
||||
|
||||
| # | Category | Result |
|
||||
|---|---|---|
|
||||
| 1 | Correctness & logic bugs | Driver.AbCip-016 |
|
||||
| 1 | Correctness & logic bugs | Driver.AbCip-016, Driver.AbCip-018 |
|
||||
| 2 | OtOpcUa conventions | No issues found |
|
||||
| 3 | Concurrency & thread safety | No issues found |
|
||||
| 4 | Error handling & resilience | No issues found |
|
||||
@@ -356,3 +356,39 @@ severity read is Bad, or add an XML/inline comment on `Tick` stating that severi
|
||||
`Low` when its read fails. Deferred (Open): the right fallback is a small alarm-semantics design
|
||||
decision (what severity to surface when it is genuinely unknown) rather than a mechanical fix,
|
||||
and the impact is negligible given the single-batch read shape.
|
||||
|
||||
### Driver.AbCip-018
|
||||
|
||||
| Field | Value |
|
||||
|---|---|
|
||||
| Severity | Medium |
|
||||
| Category | Correctness & logic bugs |
|
||||
| Location | `AbCipDriverFactoryExtensions.cs:89-109` (`BuildTag`), `AbCipDriverFactoryExtensions.cs:205-246` (`AbCipTagDto`), `AbCipDriverFactoryExtensions.cs:248-269` (`AbCipMemberDto`) |
|
||||
| Status | Resolved |
|
||||
|
||||
**Description:** The driver-config factory path dropped the array shape of a pre-declared tag.
|
||||
`AbCipTagDto` and `AbCipMemberDto` had no `ElementCount` / `IsArray` fields, so a `tags[]` entry
|
||||
in the driver-config JSON authored with an explicit `"isArray": true, "elementCount": 4`
|
||||
deserialised into a **scalar** `AbCipTagDefinition` (both fields silently dropped → defaulting to
|
||||
`IsArray=false` / `ElementCount=1`). At read time `IsArrayTag(def)` was therefore `false`, so the
|
||||
tag decoded via `DecodeValue` (single scalar) instead of the `DecodeArray` path — a declared
|
||||
`REAL[4]` array tag read as one element. This is the factory/driver-config path; the
|
||||
equipment-tag path (`AbCipEquipmentTagParser` in Driver.AbCip.Contracts) already threads array
|
||||
shape correctly, and the in-driver UDT member fan-out was fixed under Driver.AbCip-016 — but the
|
||||
factory `tags[]` array still lost the signal.
|
||||
|
||||
#### Recommendation
|
||||
|
||||
Add `ElementCount` (int?) and `IsArray` (bool) to `AbCipTagDto` and `AbCipMemberDto` with the
|
||||
correct camelCase `[JsonPropertyName]` (`elementCount` / `isArray`), and thread them into the
|
||||
`AbCipTagDefinition` / `AbCipStructureMember` construction in `BuildTag`, applying the
|
||||
positive-value guard (`elementCount is > 0` ⇒ value, else `1`). Additive/optional — a config
|
||||
without the fields keeps the legacy scalar default.
|
||||
|
||||
**Resolution:** Resolved 2026-06-19 — `AbCipTagDto` + `AbCipMemberDto` gained `IsArray` (bool,
|
||||
`[JsonPropertyName("isArray")]`) and `ElementCount` (int?, `[JsonPropertyName("elementCount")]`);
|
||||
`BuildTag` threads them into the `AbCipTagDefinition` and each fanned-out `AbCipStructureMember`
|
||||
with the `m.ElementCount is > 0 ? m.ElementCount.Value : 1` guard (mirroring the equipment-tag
|
||||
parser), so a driver-config array tag now reads as a typed array. Additive — missing fields still
|
||||
produce a scalar. Regression: `AbCipFactoryArrayTagTests` (4 cases — top-level tag, UDT member,
|
||||
absent-fields-stay-scalar, non-positive-elementCount-clamps-to-1). Full suite green (307 tests).
|
||||
|
||||
Reference in New Issue
Block a user