--- source_files: - Common/DTS.CommonCore/Classes/TMAT/TMTTemplate.cs generated_at: "2026-04-16T02:40:28.075233+00:00" model: "Qwen/Qwen3-Coder-Next-FP8" schema_version: 1 sha256: "759eebf6c2f0302e" --- # TMAT ## Documentation: `TMTTemplate` Module ### 1. Purpose This module provides infrastructure for processing template files (`.tmt` files) used in test configuration and reporting workflows. It enables programmatic substitution of predefined placeholders (e.g., `{NAME OF PROGRAM}`, `{{CHANNEL {0} NAME}}`) with runtime values. The module decouples template structure from data population, supporting both global metadata (e.g., test ID, serial number) and per-channel properties (e.g., hardware channel number, scaling factors). It is part of the `DTS.Common.Classes.TMAT` namespace and serves as a foundational component for generating or modifying test configuration files dynamically. --- ### 2. Public Interface #### Enums - **`TMTGlobalKeys`** Enumerates global placeholder keys used in templates. Each member is decorated with a `[TMTKey]` attribute specifying the literal pattern to search for. Examples: - `NameOfProgram` → pattern: `"{NAME OF PROGRAM}"` - `DASSerialNumber` → pattern: `"{DAS SERIAL NUMBER}"` - `UdpStreamTimeChannelId` → pattern: `"{UDP STREAM TIME CHANNEL ID}"` - **`TMTChannelKeys`** Enumerates per-channel placeholder keys. Each pattern includes a format specifier `{0}` for the channel number. Examples: - `HardwareChannelNumber` → pattern: `"{{CHANNEL {0} HARDWARE CHANNEL NUMBER}}"` - `ChannelName` → pattern: `"{{CHANNEL {0} NAME}}"` - `ScaleFactorEU` → pattern: `"{{CHANNEL {0} SCALEFACTOR EU}}"` #### Attribute - **`TMTKeyAttribute`** - `public string Key { get; }` – Stores the literal pattern string (e.g., `"{NAME OF PROGRAM}"`). - `public TMTKey(string key)` – Constructor initializing `Key`. - `public static string GetKey(TMTGlobalKeys key)` – Returns the pattern string for a global key. - `public static string GetKey(TMTChannelKeys key, int channelNumber)` – Returns the pattern string for a channel key, with `{0}` replaced by `channelNumber`. #### Interface - **`ITMTTemplate`** - `void UpdateValue(TMTGlobalKeys key, string value)` Replaces all occurrences of the pattern associated with `key` in the template with `value`. - `void UpdateValue(TMTChannelKeys key, string value, int channelNumber)` Replaces all occurrences of the pattern associated with `key` (formatted with `channelNumber`) in the template with `value`. - `string[] GetAllLines()` Returns the current content of the template as an array of lines. #### Class - **`TMTTemplate : ITMTTemplate`** - `public TMTTemplate(string templateLocation)` Loads all lines from the file at `templateLocation` into internal storage. - `public TMTTemplate(string[] lines)` Initializes the template with the provided `lines` (e.g., for in-memory templates). - `public void UpdateValue(TMTGlobalKeys key, string value)` Iterates through all lines; for each line containing the pattern for `key`, replaces the pattern with `value`. - `public void UpdateValue(TMTChannelKeys key, string value, int channelNumber)` Iterates through all lines; for each line containing the formatted pattern for `key` (with `channelNumber`), replaces the pattern with `value`. - `public string[] GetAllLines()` Returns a copy of the internal line list as an array. --- ### 3. Invariants - **Template file existence is not enforced at construction**: If `templateLocation` is invalid or the file does not exist, `_allLines` remains empty (no exception thrown). - **Pattern replacement is literal and non-semantic**: - `Contains(pattern)` is used for matching, so partial matches (e.g., `"{NAME OF PROGRA}"` inside `"{NAME OF PROGRAM}"`) may cause unintended replacements. - Replacements are done via `string.Replace`, which replaces *all* occurrences of the pattern in a line (not just the first). - **Channel keys require exact formatting**: The pattern for channel keys includes double braces (`{{...}}`) to support `string.Format`, but the module does not validate that `channelNumber` produces a syntactically valid pattern (e.g., negative numbers are allowed). - **No deduplication or ordering guarantees**: Multiple updates to the same key in a single line will overwrite each other in sequence, but the final state depends on line order and replacement count. --- ### 4. Dependencies - **Internal dependencies**: - `System.Collections.Generic` (for `List`) - `System.IO` (for `File.Exists`, `File.ReadAllLines`) - Reflection (`System.Type.GetMember`, `Attribute.GetCustomAttribute`) for pattern extraction from enums. - **External dependencies**: - Consumers must provide valid `.tmt` template files (or line arrays) to `TMTTemplate` constructors. - The module is used by other components (e.g., test execution or reporting systems) that populate template values. - **No external libraries or services** beyond core .NET types. --- ### 5. Gotchas - **Case sensitivity**: Pattern matching via `Contains` is case-sensitive. A template line `" {NAME OF PROGRAM} "` will match, but `" {name of program} "` will not. - **Brace escaping in channel keys**: The `{{CHANNEL {0} ...}}` pattern relies on `string.Format` semantics. If `channelNumber` is `0`, the pattern becomes `"{{CHANNEL 0 ...}}"`, which is correct. However, if `channelNumber` is negative (e.g., `-1`), the result is `"{{CHANNEL -1 ...}}"`—syntactically valid but semantically questionable. - **No validation of placeholder presence**: `UpdateValue` silently does nothing if the pattern is not found in any line. - **No thread safety**: The class is not thread-safe; concurrent calls to `UpdateValue` on the same instance may cause race conditions. - **Memory overhead**: All template lines are held in memory (`_allLines`) during processing. Large templates may consume significant memory. - **No error handling for malformed templates**: If a template line contains unbalanced braces or invalid `string.Format` syntax (e.g., `{{CHANNEL {0} NAME`), `string.Format` in `GetKey(TMTChannelKeys, int)` will throw an exception. - **Historical quirk (commented)**: - `UdpStreamTimeChannelId`/`UdpStreamDataChannelId` and `CreateDate` were added in fixes FB 26736 and FB 29996, respectively—suggesting these keys were added post-initial design.