Files
DP44/docs/ai/Common/DTS.Common.Serialization.md
2026-04-17 14:55:32 -04:00

292 lines
16 KiB
Markdown

---
source_files:
- Common/DTS.Common.Serialization/StringWriterWithEncoding.cs
- Common/DTS.Common.Serialization/TickEventHandler.cs
- Common/DTS.Common.Serialization/InvariantStreamWriter.cs
- Common/DTS.Common.Serialization/BadCRCBypass.cs
- Common/DTS.Common.Serialization/IProgressAware.cs
- Common/DTS.Common.Serialization/ToyotaCsv.File.cs
- Common/DTS.Common.Serialization/EventHandlers.cs
- Common/DTS.Common.Serialization/Test.IConvertable.cs
- Common/DTS.Common.Serialization/TestSetup.TestObject.Channel.cs
- Common/DTS.Common.Serialization/Test.Module.IConvertable.cs
- Common/DTS.Common.Serialization/Test.Module.Channel.IConvertable.cs
- Common/DTS.Common.Serialization/TestSetup.TestObject.DASHardware.cs
- Common/DTS.Common.Serialization/TestSetup.Sensor.cs
- Common/DTS.Common.Serialization/File.Writer.cs
- Common/DTS.Common.Serialization/IReadable.cs
- Common/DTS.Common.Serialization/TestSetup.Graph.cs
- Common/DTS.Common.Serialization/FilteredData.cs
- Common/DTS.Common.Serialization/File.Writer.CharacterCountingStreamWriter.cs
- Common/DTS.Common.Serialization/Diadem.File.cs
- Common/DTS.Common.Serialization/TestSetup.TestObject.DASHardware.DASChannel.cs
- Common/DTS.Common.Serialization/File.cs
- Common/DTS.Common.Serialization/File.Reader.cs
- Common/DTS.Common.Serialization/TestSetup.Graph.Channel.cs
- Common/DTS.Common.Serialization/EventInfoAggregate.cs
- Common/DTS.Common.Serialization/IWriteable.cs
generated_at: "2026-04-17T15:26:29.501527+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "fe2305d939ea2131"
---
# DTS.Serialization Module Documentation
## 1. Purpose
The `DTS.Serialization` namespace provides a framework for serializing and deserializing test data to various file formats (CSV, Diadem, etc.). It implements an abstract file-based architecture with reader/writer patterns, progress reporting via events, and support for converting domain objects to/from a canonical `Test` object model. The module handles data acquisition system (DAS) hardware configuration, sensor definitions, channel mappings, and filtered data representations for technical/scientific data exchange.
---
## 2. Public Interface
### Core File Abstractions
#### `File` (abstract partial class)
- **Signature:** `public abstract partial class File : Exceptional`
- **Purpose:** Base class for all DTS export file types.
- **Constructor:** `File(string formatName)` - Initializes with a format name.
- **Properties:**
- `string FormatName` - Gets the file format name (private setter).
- `static string BaseExportDirectory` - Gets/sets the base export directory path.
- `int DefaultEncoding` - Gets/sets the default encoding (defaults to UTF-8 code page).
- `static bool UseLegacyTDCSoftwareFiltering` - Controls filtered data sample adjustment behavior.
- `Common.Enums.IsoViewMode ISOViewMode` - Gets/sets ISO view mode.
- **Methods:**
- `string EnsureTrailingBackslashOnPathString(string path)` - Ensures path ends with backslash.
- `virtual void SetEUData(string channelID, FilteredData fd)` - Stores EU data for linearized channels.
- `virtual FilteredData GetEUData(string channelID)` - Retrieves EU data for a channel.
- `virtual int GetChannelNumberFromChannelFileName(string channelFileName)` - Returns -1 by default; overridden in TDAS.File and SliceRaw.File.
#### `File.Reader<T>` (abstract class)
- **Signature:** `public abstract class Reader<T> : Exceptional, IReader where T : File`
- **Purpose:** Base class for file readers.
- **Constructor:** `protected Reader(T fileType)` - Protected constructor; readers created by hosting File class.
- **Properties:**
- `protected T FileType` - The associated file type.
- `protected ChannelFilenameComparer ChFileCompare` - Comparer for channel filenames.
- **Nested Class:** `ChannelFilenameComparer` - Implements `IComparer<string>` for sorting channel files by channel number.
#### `File.Writer<T>` (abstract partial class)
- **Signature:** `public abstract partial class Writer<T> : Exceptional, IWriter where T : File`
- **Purpose:** Base class for file writers.
- **Constructor:** `public Writer(T fileType, int encoding)`
- **Properties:**
- `protected T FileType` - The associated file type.
- `virtual int DefaultEncoding` - Gets/sets the default encoding.
- **Nested Class:** `CharacterCountingStreamWriter` - A `StreamWriter` that counts characters written via `WriteLine(string)`.
### Interfaces
#### `IReadable` / `IReadable<T>`
- **Purpose:** Marker interface and typed interface for readable files.
- **Property:** `IReader<T> Importer { get; }` - Gets the deserializer.
#### `IReader` / `IReader<T>`
- **Purpose:** Defines requirements for file readers.
- **Method:** `void Read(string pathname, out T target)` - Deserializes file into target object.
#### `IWritable` / `IWritable<T>`
- **Purpose:** Marker interface and typed interface for writable files.
- **Property:** `IWriter<T> Exporter { get; }` - Gets the serializer.
#### `IWriter` / `IWriter<T>`
- **Purpose:** Defines requirements for file writers.
- **Methods:**
- `void Write(string pathname, string id, T target, bool bFiltering, bool includeGroupNameInISOExport, double minStartTime, int dataCollectionLength)`
- `void Write(string pathname, string id, string dataFolder, T target, bool bFiltering, bool includeGroupNameInISOExport, FilteredData fd, Test.Module.Channel tmChannel, int channelNumber, BeginEventHandler onBeginEvent, CancelEventHandler onCancelEvent, EndEventHandler onEndEvent, TickEventHandler onTickEvent, ErrorEventHandler onErrorEvent, CancelRequested cancelRequested, double minStartTime, int dataCollectionLength)`
- `void Initialize(...)` - Same parameters as Write minus minStartTime and dataCollectionLength.
#### `IProgressAware`
- **Purpose:** Interface for receiving progress updates from serialization objects.
- **Events:**
- `event BeginEventHandler OnBegin`
- `event EndEventHandler OnEnd`
- `event TickEventHandler OnTick`
- `event CancelEventHandler OnCancel`
- `event ErrorEventHandler OnError`
### Delegates
#### `BeginEventHandler`
- **Signature:** `delegate void BeginEventHandler(object sender, uint numberOfTicks)`
#### `EndEventHandler`
- **Signature:** `delegate void EndEventHandler(object sender)`
#### `TickEventHandler`
- **Signature:** `delegate void TickEventHandler(object sender, double percentageComplete)`
#### `CancelEventHandler`
- **Signature:** `delegate void CancelEventHandler(object sender)`
#### `ErrorEventHandler`
- **Signature:** `delegate void ErrorEventHandler(object sender, Exception ex)`
#### `CancelRequested`
- **Signature:** `delegate bool CancelRequested()`
### Utility Classes
#### `StringWriterWithEncoding`
- **Signature:** `public sealed class StringWriterWithEncoding : StringWriter`
- **Constructor:** `StringWriterWithEncoding(Encoding encoding)`
- **Property:** `override Encoding Encoding` - Returns the encoding passed to constructor.
#### `InvariantStreamWriter`
- **Signature:** `public class InvariantStreamWriter : System.IO.StreamWriter`
- **Constructors:**
- `InvariantStreamWriter(string path)`
- `InvariantStreamWriter(string path, bool bAppend)`
- **Property:** `override IFormatProvider FormatProvider` - Always returns `CultureInfo.InvariantCulture`.
#### `FilteredData`
- **Signature:** `public class FilteredData : Exceptional, IComparable<FilteredData>`
- **Constructor:** `FilteredData(string filterDescription, double filterFrequencyHz, double[] data, int absoluteDisplayOrder)`
- **Properties:**
- `string FilterDescription`
- `double FilterFrequencyHz`
- `double[] Data`
- `int AbsoluteDisplayOrder` (read-only)
- **Method:** `int CompareTo(FilteredData other)` - Compares by AbsoluteDisplayOrder.
#### `BadCRCBypass` (Windows Form)
- **Signature:** `public partial class BadCRCBypass : Form`
- **Properties:**
- `string FileName` - Gets/sets `txtFileName.Text`.
- `bool RememberChoice` - Gets/sets `cbRememberChoice.Checked`.
- **Events:** OK and Cancel buttons set `DialogResult` and close the form.
### Domain Model Classes
#### `Test` (partial class)
- **Nested Interface:** `Test.IConvertable` - Objects that can convert to/from `Test`.
- `Test ToDtsSerializationTest()`
- `void FromDtsSerializationTest(Test test, ReportErrors reportErrors)`
- **Nested Delegate:** `delegate void ReportErrors(List<string> errors)`
#### `Test.Module` (partial class)
- **Nested Interface:** `Test.Module.IConvertable`
- `Test.Module ToDtsSerializationTestModule(DTS.Serialization.Test parentTest)`
- `void FromDtsSerializationTestModule(Test.Module testModule, DTS.Serialization.Test.ReportErrors reportErrors)`
#### `Test.Module.Channel` (partial class)
- **Nested Interface:** `Test.Module.Channel.IConvertable`
- `Test.Module.Channel ToDtsSerializationTestModuleChannel()`
- `void FromDtsSerializationTestModuleChannel(Test.Module.Channel channel)`
#### `TestSetup` (partial class hierarchy)
- **Base:** `Exceptional`
- **Nested Classes:**
- `TestSetup.TestObject : Exceptional`
- `TestSetup.TestObject.TOChannel : Exceptional` - Properties: `Name`, `SensorName`, `Version`
- `TestSetup.TestObject.DASHardware : Exceptional` - Properties: `DASChannels`, `SampleRate`, `SerialNumber`, `Version`
- `TestSetup.TestObject.DASHardware.DASChannel : Exceptional` - Properties: `Location`, `MeasurementUnits`, `Name`, `NumberOfSamples`, `SensorName`, `SerialNumber`, `Version`
- `TestSetup.Sensor : Exceptional` - Properties: `FilterClass`, `Name`, `Polarity`, `Position`, `Range`, `Version`
- `TestSetup.Graph : Exceptional`
- Properties: `Channels`, `Name`, `HardwareChannelName`, `DisplayName`, `Version`, `IsSingleChannelGraph`, `FirstChannel`, `FirstTestChannel`, `Identifier`
- Methods: `void UnSet()`, `override string ToString()`
- Nested Class: `TestSetup.Graph.Channel : Exceptional`
- Constructors: `Channel(DTS.Serialization.Test.Module.Channel channel)`, `Channel(string channelId)`
- Properties: `ChannelId`, `ChannelGroupName`, `Name`, `SensorName`, `AxisUnit`, `SerialNumber`
- Fields: `ParentTestModule`, `TestChannel` (both with `[System.Xml.Serialization.XmlIgnoreAttribute]`)
#### `EventInfoAggregate`
- **Signature:** `public class EventInfoAggregate`
- **Constructor:** `EventInfoAggregate(DownloadReport.EventInfo newEvent)`
- **Properties:** `EventId`, `EventDescription`, `DurationSeconds`, `GUID`, `HasBeenDownloaded`, `WasTriggered`, `NumberOfChannels`, `NumberOfSamples`, `NumberOfBytes`, `Faulted`, `EventNumber`
- **Methods:**
- `Slice.Control.Event GetEvent(bool bClear)`
- `Slice.Control.Event GetEvent()`
- `int GetEventIndex(IDASCommunication idas)`
- `List<IDASCommunication> GetDasList()`
- `void Add(DownloadReport.EventInfo newEvent)` - Aggregates additional event info.
### File Format Implementations
#### `DTS.Serialization.ToyotaCsv.File`
- **Signature:** `public partial class File : Serialization.File, IWritable<Test>`
- **Constructor:** `File()` - Initializes with format name "Toyota CSV".
- **Properties:**
- `static string Extension` - Returns ".csv".
- `IWriter<Test> Exporter` - Lazy-initialized `Writer` instance.
#### `DTS.Serialization.Diadem.File`
- **Signature:** `public partial class File : Serialization.File, IWritable<Test>`
- **Constructor:** `File(bool bUseEVG20, TestPlan plan)`
- **Properties:**
- `static string Extension` - Returns ".dat".
- `bool UseIsoCodeForDiadem200` - Defaults to `true`.
- `bool UseZeroForUnfiltered` - Defaults to `false`.
- `DiademOptions ChannelName200Option`
- `DiademOptions UserComment201Option`
- `DiademOptionsReserved1 Reserved1_301Option`
- `DiademOptionsReserved2 Reserved2_302Option`
- `IWriter<Test> Exporter` - Lazy-initialized, configures `Writer` with all options.
- **Enums:**
- `DiademOptions`: `NONE`, `ISO_CODE`, `SENSOR_SERIAL_NUMBER`, `CHANNEL_NAME`
- `DiademOptionsReserved1`: `NONE`, `AAF_RATE`, `GROUP_NAME`
- `DiademOptionsReserved2`: `NONE`, `CHANNEL_SENSITIVITY`
---
## 3. Invariants
1. **Reader/Writer Construction:** `File.Reader<T>` and `File.Writer<T>` instances must be created by their hosting `File` class via factory properties (`Importer`, `Exporter`), not directly instantiated by consumers.
2. **Encoding Defaults:** All file types default to UTF-8 encoding (`Encoding.UTF8.CodePage`) unless explicitly overridden.
3. **Property Pattern:** Domain model classes (e.g., `TestSetup.Graph`, `TestSetup.Sensor`) use a `Property<T>` wrapper pattern with namespace-qualified property names for identification.
4. **Version Defaults:** All version properties in `TestSetup` nested classes default to `"1.0.0.0"`.
5. **Channel Filename Comparison:** `ChannelFilenameComparer` relies on `GetChannelNumberFromChannelFileName()` returning -1 for non-SLICE/TDAS file types, resulting in standard string comparison.
6. **Event Aggregation:** `EventInfoAggregate.Add()` logs warnings but does not throw when encountering mismatched event data (TestId, Description, Duration, GUID, etc.); it takes minimum values for samples/duration on mismatch.
7. **Character Counting:** `CharacterCountingStreamWriter.CharactersCounted` only increments via `WriteLine(string)` override; other write methods do not update the count.
---
## 4. Dependencies
### This Module Depends On:
- `System` (core .NET)
- `System.IO` (stream operations)
- `System.Text` (encoding)
- `System.Collections.Generic` (collections)
- `System.Linq` (LINQ operations)
- `System.Globalization` (`CultureInfo.InvariantCulture`)
- `System.Windows.Forms` (for `BadCRCBypass` form)
- `System.Xml.Serialization` (`XmlIgnoreAttribute`)
- `DTS.Common.Utilities` / `DTS.Utilities` - `Exceptional` base class, `Property<T>`
- `DTS.Common.Utilities.DotNetProgrammingConstructs` / `DTS.Utilities.DotNetProgrammingConstructs` - `Property<T>`
- `DTS.Common.ISO` - referenced in `Diadem.File`
- `DTS.Common.Utilities.Logging` - `APILogger` in `EventInfoAggregate`
- `DTS.DASLib.Service` - `IDASCommunication`, `DownloadReport` in `EventInfoAggregate`
- `Slice.Control` - `Event` class in `EventInfoAggregate`
- `DTS.Common.Enums` - `IsoViewMode` enum
### What Depends On This Module:
- Not determinable from source alone; this appears to be a core library consumed by higher-level application modules.
---
## 5. Gotchas
1. **Typo in XML Documentation:** `IProgressAware.OnTick` documentation references `DTS.Seralization.EventHandler` (misspelled namespace - missing second 'i').
2. **CharacterCountingStreamWriter Incomplete Implementation:** Only `WriteLine(string)` updates `CharactersCounted`. Other `Write` overloads and `WriteLine` variants do not count characters, which could lead to incorrect progress reporting.
3. **Lazy Exporter Initialization with Side Effects:** `Diadem.File.Exporter` getter has side effects - it casts and sets `WriterParent` on the cached exporter on every access, not just first initialization.
4. **Exception Swallowing in Comparer:** `ChannelFilenameComparer.Compare` will throw `NullReferenceException` if `file` is null (when `fileType` passed to constructor is not a `File`), rather than handling gracefully.
5. **Hardcoded "EU" Fallback:** `TestSetup.Graph.Channel.AxisUnit` returns `"EU"` for non-AnalogInputChannel types and null TestChannel, which may not be appropriate for all channel types.
6. **DisplayName Concatenation:** `TestSetup.Graph.DisplayName` concatenates `Name` and `HardwareChannelName` with underscore, but if either is null, the result may be unexpected (e.g., `"_hardwareName"` or `"name_"`).
7. **EventInfoAggregate Mismatch Handling:** When aggregating events with mismatched properties, the class logs warnings but silently takes minimum values for `DurationSeconds` and `NumberOfSamples`, potentially losing data without caller awareness.
8. **Partial Class Sprawl:** Classes like `Test`, `TestSetup`, `File`, and their nested classes are spread across many files with `IConvertable` interfaces defined separately, making the complete type definition difficult to trace without IDE support.