Files
2026-04-17 14:55:32 -04:00

181 lines
12 KiB
Markdown

---
source_files:
- Common/DTS.Common.Serialization/IRIGCH10/TMATS/DescriptionDecoder.cs
- Common/DTS.Common.Serialization/IRIGCH10/TMATS/TMATSectionNumbered.cs
- Common/DTS.Common.Serialization/IRIGCH10/TMATS/TMATSSection.cs
- Common/DTS.Common.Serialization/IRIGCH10/TMATS/TMATS.cs
- Common/DTS.Common.Serialization/IRIGCH10/TMATS/GeneralInformation.cs
- Common/DTS.Common.Serialization/IRIGCH10/TMATS/PCM.cs
generated_at: "2026-04-16T03:43:40.628941+00:00"
model: "Qwen/Qwen3-Coder-Next-FP8"
schema_version: 1
sha256: "3279c734bbc2d68c"
---
# Documentation: TMATS Serialization Module
## 1. Purpose
This module provides serialization infrastructure for generating TMATS (Telemetry and Tracking Data Format Standard) documents compliant with IRIG 106 Chapter 10. It enables structured construction of TMATS records by encapsulating attribute-value pairs, handling numbered sections (e.g., per-channel PCM data), and enforcing formatting rules derived from metadata attributes (`DescriptionAttribute`, `MaxLengthAttribute`). The module serves as the foundational serialization layer for converting in-memory telemetry configuration objects into the standardized text-based TMATS format used in IRIG 106-compliant telemetry files.
## 2. Public Interface
### `DescriptionDecoder.GetDescription(Enum value)`
- **Signature**: `public static string GetDescription(Enum value)`
- **Behavior**: Retrieves the `DescriptionAttribute.Description` value associated with the given enum field. If no attribute exists, returns the enum's `ToString()` value.
### `MaxLengthDecoder.GetMaxLength(Enum value)`
- **Signature**: `public static int GetMaxLength(Enum value)`
- **Behavior**: Retrieves the `Length` property of the `MaxLengthAttribute` associated with the given enum field. If no attribute exists, returns `0`.
### `TMATSSection<T>.SetValue(T tag, string value)`
- **Signature**: `public void SetValue(T tag, string value) where T : Enum`
- **Behavior**: Stores the value for the specified enum tag in an internal dictionary.
### `TMATSSection<T>.GetValue(T tag)`
- **Signature**: `public string GetValue(T tag) where T : Enum`
- **Behavior**: Returns the stored value for the given tag, or `null` if not set.
### `TMATSSection<T>.SetDate(T tag, DateTime? value)`
- **Signature**: `public void SetDate(T tag, DateTime? value)`
- **Behavior**: Stores a date as `"MM-DD-YYYY"` string (e.g., `"11-20-2018"`), or an empty string if `value` is `null`.
### `TMATSSection<T>.GetDate(T tag)`
- **Signature**: `public DateTime? GetDate(T tag)`
- **Behavior**: Parses and returns a `DateTime?` from the stored value using `"MM-DD-YYYY"` format. Returns `null` if not set or invalid.
### `TMATSSection<T>.GetIntOrNull(T tag)`
- **Signature**: `public int? GetIntOrNull(T tag)`
- **Behavior**: Parses and returns an `int?` from the stored value. Returns `null` if not set or invalid.
### `TMATSSection<T>.SetIntOrNull(T tag, int? val)`
- **Signature**: `public void SetIntOrNull(T tag, int? val)`
- **Behavior**: Stores the integer as a string, or an empty string if `val` is `null`.
### `TMATSSection<T>.SetValueWithLength(T tag, string value)`
- **Signature**: `public void SetValueWithLength(T tag, string value)`
- **Behavior**: Stores the value. *Note: Length validation is currently disabled (commented out in source).*
### `TMATSSection<T>.Serialize()`
- **Signature**: `public virtual string Serialize()`
- **Behavior**: Serializes all non-empty tag-value pairs into lines of the format `Identifier\Attribute:value;` or `Identifier-N\Attribute:value;` if `_number >= 0`.
### `TMATSSection<T>.Serialize(T tag)`
- **Signature**: `protected string Serialize(T tag)`
- **Behavior**: Serializes a single tag-value pair. Returns `null` if value is empty/whitespace.
### `TMATSSection<T>` constructors
- **`TMATSSection()`**: Default constructor for unnumbered sections.
- **`TMATSSection(AttributeIdentifiers attribute, int number)`**: Constructor for numbered sections (e.g., per-channel PCM). Sets `_attribute` and `_number`.
### `TMATSectionNumbered<T>.SetValue(T tag, string value)`
- **Signature**: `public void SetValue(T tag, string value) where T : Enum`
- **Behavior**: Stores value for the given tag in internal dictionary.
### `TMATSectionNumbered<T>.GetValue(T tag)`
- **Signature**: `public string GetValue(T tag) where T : Enum`
- **Behavior**: Returns stored value for the tag, or `null`.
### `TMATSectionNumbered<T>.Serialize(int number)`
- **Signature**: `public string Serialize(int number)`
- **Behavior**: Serializes all non-empty tag-value pairs. Format:
`Identifier-N\Attribute<number>:value;` if `Number > 0`, else `Identifier\Attribute<number>:value;`.
### `TMATSectionNumbered<T>.SetValueWithLength(T tag, string value)`
- **Signature**: `public void SetValueWithLength(T tag, string value)`
- **Behavior**: Calls `SetValue(tag, value)`. *Note: Length validation is currently disabled.*
### `TMATSectionNumberedArray<T>.SetValue(int number, T tag, string value)`
- **Signature**: `public virtual void SetValue(int number, T tag, string value)`
- **Behavior**: Ensures `_items` has `number` elements via `SetCount`, then calls `SetValueWithLength` on the `number`-th item (1-based index).
### `TMATSectionNumberedArray<T>.GetValue(int number, T tag)`
- **Signature**: `public string GetValue(int number, T tag)`
- **Behavior**: Returns value from the `number`-th item (1-based), or `null`.
### `TMATSectionNumberedArray<T>.Serialize()`
- **Signature**: `public string Serialize()`
- **Behavior**: Serializes all items. Includes a header line `Identifier-N\Tag:Count;` if `_numberedTag` is non-empty. Then serializes each item with its 1-based index.
### `TMATSectionNumberedArray<T>.SetCount(int count)`
- **Signature**: `public void SetCount(int count)`
- **Behavior**: Resizes `_items` list to `count`. Throws `Exception` if `count > _maxNumber`. If shrinking, truncates items; if expanding, creates new `TMATSectionNumbered<T>` instances with `_attributeIdentifier` and `_number` set.
### `TMATSectionNumberedArray<T>.GetCount()`
- **Signature**: `public int GetCount() => _items.Count`
### `AttributeIdentifiers` enum
- **Members**: `GeneralInformation`, `TransmitionAttributes`, `StorageSourceAttributes`, `MultiplexingAttributes`, `PCMFormatAttributes`, `PCMMeasurementDescription`, `BusDataAttributes`, `PacketFormatAttributes`, `PAMAttributes`, `DataConversionAttributes`, `AirborneHardwareAttributes`, `VendorSpecificAttributes`
- **Behavior**: Each member has a `[Description]` attribute (e.g., `"G"`, `"P"`) used in serialization.
### `GeneralInformationGroup` class
- **Key Properties**:
- `ProgramName`, `TestItem`, `IRIG106RevisionLevel`, `OriginationDate`, etc.
- `NumberOfDataSources`, `NumberOfPointsOfContact`
- `PreTestRequirement`, `PostTestRequirement`
- **Methods**:
- `SetDataSourceField(int number, DataSourceIdentificationTags tag, string value)`
Enforces uniqueness of `DataSourceID` (throws `Exception` if duplicate).
- `SetDataSourceType(int number, DataSourceTypes sourceType)`
- `SetContactField(int number, PointOfContactTags tag, string value)`
- **Nested Types**:
- `CommentSection`, `SecuritySection`, `Information` (with nested `PointOfContactTags`, `DataSourceIdentificationTags`, `DataSourceTypes`, `TestInformationTags`).
- `Information.DataSourceIdentificationTags.DataSourceID` has `[MaxLength(32)]`.
### `PCM` class
- **Key Properties**:
- `DataLinkName`, `PCMCode`, `BitsPerSecond`, `DataRandomized`, `Polarity`, `DataDirection`, `TypeFormat`, `NumberOfBitsInCommonWordLength`, `WordTransferOrder`, `PCMWordParity`
- **Constructors**:
- `PCM(int number)` → calls `base(AttributeIdentifiers.PCMFormatAttributes, number)`
- **Nested Types**:
- `PCMTypeFormat` (section for type-specific attributes like `TypeFormat`, `CommonWordLength`, etc.)
- `MinorFrameSection` (section for minor frame sync data)
- `PCMTypeFormats`, `PCMWordTransferOrders`, `PCMWordParities`, `PCMCodes`, `Polarities`, `PCMDataDirections` enums.
### `MinorFrameSection` class
- **Key Properties**:
- `NumberOfMinorFramesInAMajorFrame`, `NumberOfWordsInMinorFrame`, `NumberOfBitsInMinorFrame`, `SyncLength`, `SynchronizationPattern`
- **Constructor**: `MinorFrameSection(int number=1)``base(AttributeIdentifiers.PCMFormatAttributes, number)`
### `TMATSCreationTest.CreateTMATS()`
- **Signature**: `public static string CreateTMATS()`
- **Behavior**: Demonstrates usage by constructing a sample TMATS document for a PCM telemetry system with 4 channels (1 time, 2 PCM, 1 message data). Returns the serialized string.
## 3. Invariants
- **Tag Uniqueness per Section**: In `GeneralInformationGroup.Information`, `DataSourceID` values must be unique across all data sources (enforced in `SetDataSourceField`).
- **Numbered Sections**: Sections requiring numbering (e.g., PCM, MinorFrame) use `_number` to generate identifiers like `P-1\DLN:value;`.
- **Date Format**: Dates are stored and parsed strictly as `"MM-DD-YYYY"` (e.g., `"11-20-2018"`).
- **Enum Serialization**: Enum values are serialized using their `[Description]` attribute, falling back to `ToString()` if missing.
- **Empty Value Handling**: Empty/whitespace values are skipped during serialization (`string.IsNullOrWhiteSpace`).
- **Array Bounds**: `TMATSectionNumberedArray<T>.SetCount` enforces `_maxNumber` limit if set.
## 4. Dependencies
### Internal Dependencies
- **`System.ComponentModel.DataAnnotations`**: Used for `DescriptionAttribute`, `MaxLengthAttribute`.
- **`System.Linq`**: Used for `Enum.GetValues`, `Cast<T>()`, `Any()`, `Take()`, `ToArray()`.
- **`System.Text`**: Used for `StringBuilder`.
- **`IRIGCh10.AttributeIdentifiers`**: Defines section identifiers (e.g., `"P"` for PCM).
- **Nested enums** (e.g., `GeneralTags`, `InformationTags`, `DataSourceIdentificationTags`, `PCMAttributes`, `TypeFormatTags`, `MinorFrameTags`) define attribute names.
### External Dependencies
- **`GeneralInformationGroup`** depends on `Information`, `CommentSection`, `SecuritySection`.
- **`PCM`** depends on `PCMTypeFormat`, `MinorFrameSection`.
- **`TMATSCreationTest.CreateTMATS()`** depends on `GeneralInformationGroup`, `Storage`, `PCM`, `MinorFrameSection`, `SubframeSync`, `MessageDataType` (not shown in source but referenced).
### Inferred Usage
- The module is used by higher-level classes (e.g., `Storage`, `MessageDataType`) to serialize TMATS sections.
- `DescriptionDecoder` and `MaxLengthDecoder` are utility classes used by `TMATSSection<T>`, `TMATSectionNumbered<T>`, and `TMATSectionNumberedArray<T>`.
## 5. Gotchas
- **Length Validation Disabled**: Both `SetValueWithLength` methods (`TMATSSection<T>`, `TMATSectionNumbered<T>`) *do not enforce* `MaxLengthAttribute`—the validation code is commented out. This is explicitly noted in comments:
> *"maxlength is just a suggestion ..."*
> *"apprently maxlength is just a suggestion ..."*
- **DataSourceID Uniqueness Check**: `SetDataSourceField` checks for duplicates *only when setting `DataSourceID`*, but the check uses `_datasources.GetValue(number, tag)` *before* the new value is stored, which may not catch all edge cases (e.g., concurrent modifications).
- **Indexing Inconsistency**: `TMATSectionNumberedArray<T>.SetValue` uses 1-based indexing for `number`, but internal `_items` list is 0-based (`_items[number - 1]`).
- **Date Parsing Strictness**: `GetDate` uses `DateTime.TryParseExact` with `"MM-DD-YYYY"` format and `CultureInfo.InvariantCulture`. Any deviation (e.g., `"11/20/2018"`) will fail.
- **Enum Parsing Fallbacks**: Enum property getters (e.g., `PCM.PCMCode`, `PCM.Polarity`) fall back to default values (`null`, `Normal`) if the stored string does not match any `Description`. This may mask serialization errors.
- **Missing Section Types**: `SubframeSync`, `MessageDataType`, and `Storage` classes are referenced in `CreateTMATS` but not provided in the source files—behavior is inferred but not verifiable.
- **Typo in Enum**: `AttributeIdentifiers.TransmitionAttributes` is misspelled (should be `"Transmission"`).