namespace ZB.MOM.WW.OtOpcUa.Driver.S7.SymbolImport; /// /// PR-S7-D2 — one named member of an . Mirrors the /// STEP 7 / TIA Portal UDT layout: each member sits at a fixed byte offset relative /// to the UDT's base, has a primitive S7 type (or another UDT for nested STRUCTs), /// and may be a 1-D array. /// /// Member name; concatenated with the parent tag's name via dot-separator at fan-out. /// Byte offset within the parent UDT. Must be ascending and non-overlapping across the member list. /// Primitive S7 type. Ignored when is set (nested-UDT case). /// Optional 1-D array length. null / 1 = scalar; > 1 emits indexed sub-tags Member[0], Member[1], ... /// When set, this member is itself a UDT — the fan-out recurses into the named UDT's layout. Mutually exclusive with the primitive interpretation of . public sealed record S7UdtMember( string Name, int Offset, S7DataType DataType, int? ArrayDim = null, string? UdtName = null); /// /// PR-S7-D2 — declarative description of a Siemens UDT (User-Defined Type) / /// STRUCT layout. Tags whose matches /// get fanned-out into one scalar leaf tag per recursive /// member at time, so the rest of the /// read/write/subscribe pipeline never has to know about UDTs. /// /// UDT name. Case-insensitively matched against and against nested members' . /// Ordered member list. Members must have ascending non-overlapping offsets; offsets that re-use bytes are rejected at fan-out time. /// Total UDT byte size, used as a sanity bound for the last member's offset + width. /// /// /// Optimized block access: TIA Portal can mark a DB or UDT as /// "Optimized block access" which lets the runtime reorder members for /// memory alignment. The static-offset model used here REQUIRES "Optimized /// block access" turned OFF on the parent DB; otherwise the declared /// offsets won't match the runtime layout. Same constraint applies to /// general absolute-offset DB addressing (see docs/v2/s7.md). /// /// /// Nesting depth: nested UDT-of-UDT is supported up to 4 levels. /// The fan-out throws on the 5th /// level — picked as a generous-but-still-bounded ceiling that catches /// pathological / accidentally-recursive declarations early. /// /// public sealed record S7UdtDefinition( string Name, IReadOnlyList Members, int SizeBytes);