160 lines
8.6 KiB
Markdown
160 lines
8.6 KiB
Markdown
|
|
---
|
||
|
|
source_files:
|
||
|
|
- Common/DTS.Common.Serialization/Test/Module/Channel/IConvertable.cs
|
||
|
|
- Common/DTS.Common.Serialization/Test/Module/Channel/ChannelWithMeta.cs
|
||
|
|
- Common/DTS.Common.Serialization/Test/Module/Channel/DataArray.cs
|
||
|
|
generated_at: "2026-04-17T15:38:47.836386+00:00"
|
||
|
|
model: "zai-org/GLM-5-FP8"
|
||
|
|
schema_version: 1
|
||
|
|
sha256: "03e73ca9f12d1506"
|
||
|
|
---
|
||
|
|
|
||
|
|
# Documentation: DTS.Serialization.Test.Module.Channel
|
||
|
|
|
||
|
|
## 1. Purpose
|
||
|
|
|
||
|
|
This module provides serialization infrastructure for channel data within the DTS serialization framework. It defines a contract for channel conversion (`IConvertable`), a metadata wrapper for serialization operations (`ChannelWithMeta`), and a generic, XML-serializable data container (`DataArray<DataType>`) that handles typed channel data with associated scaling factors and unit conversions. The module is designed to support the serialization of measurement channel data with full fidelity of engineering unit conversions and timing metadata.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 2. Public Interface
|
||
|
|
|
||
|
|
### `DTS.Serialization.Test.Module.Channel.IConvertable` (Interface)
|
||
|
|
|
||
|
|
**Location:** `IConvertable.cs`
|
||
|
|
|
||
|
|
Defines a conversion contract for objects that can transform to/from a `DTS.Serialization.Test.Module.Channel` object.
|
||
|
|
|
||
|
|
| Method | Signature | Description |
|
||
|
|
|--------|-----------|-------------|
|
||
|
|
| `ToDtsSerializationTestModuleChannel` | `Channel ToDtsSerializationTestModuleChannel()` | Converts the implementing object to a `Channel` instance. |
|
||
|
|
| `FromDtsSerializationTestModuleChannel` | `void FromDtsSerializationTestModuleChannel(Channel channel)` | Initializes the implementing object from a `Channel` instance. |
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### `DTS.Serialization.ChannelWithMeta` (Class)
|
||
|
|
|
||
|
|
**Location:** `ChannelWithMeta.cs`
|
||
|
|
|
||
|
|
A container class bundling a channel with its associated metadata required for serialization.
|
||
|
|
|
||
|
|
**Constructor:**
|
||
|
|
```csharp
|
||
|
|
public ChannelWithMeta(DTS.Serialization.Test.Module.Channel channel, DataScaler scaler, double samplerate, double starttime)
|
||
|
|
```
|
||
|
|
|
||
|
|
**Properties:**
|
||
|
|
|
||
|
|
| Property | Type | Access | Description |
|
||
|
|
|----------|------|--------|-------------|
|
||
|
|
| `Channel` | `Test.Module.Channel` | Get only | The channel to be serialized. |
|
||
|
|
| `Scaler` | `DataScaler` | Get only | Scaling information for the channel. |
|
||
|
|
| `SampleRate` | `double` | Get only | Sample rate of the associated channel. |
|
||
|
|
| `StartTime` | `double` | Get only | Start time of the associated channel. |
|
||
|
|
|
||
|
|
**Static Methods:**
|
||
|
|
|
||
|
|
| Method | Signature | Description |
|
||
|
|
|--------|-----------|-------------|
|
||
|
|
| `GetMinStartTime` | `double GetMinStartTime(double start, IList<ChannelWithMeta> channelsWithMeta)` | Returns the maximum of the provided start value and the minimum start time across all channels. Note: Uses `Math.Max` because start times are typically negative. |
|
||
|
|
| `GetMinStopTime` | `double GetMinStopTime(double stop, IList<ChannelWithMeta> channelsWithMeta)` | Returns the minimum stop time across the provided stop value and all channels. Uses decimal arithmetic internally to avoid floating-point rounding errors. |
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### `DTS.Serialization.Test.Module.Channel.DataArray<DataType>` (Generic Class)
|
||
|
|
|
||
|
|
**Location:** `DataArray.cs`
|
||
|
|
|
||
|
|
A generic, XML-serializable container for channel data with scaling and conversion metadata. Inherits from `Exceptional` and implements `IXmlSerializable`.
|
||
|
|
|
||
|
|
**Constructors:**
|
||
|
|
|
||
|
|
| Constructor | Signature |
|
||
|
|
|-------------|-----------|
|
||
|
|
| Default | `public DataArray()` |
|
||
|
|
| With values | `public DataArray(DataType[] values)` |
|
||
|
|
|
||
|
|
**Implicit Conversion Operators:**
|
||
|
|
|
||
|
|
| Operator | Signature | Description |
|
||
|
|
|----------|-----------|-------------|
|
||
|
|
| From `List<DataType>` | `implicit operator DataArray<DataType>(List<DataType> dataList)` | Converts a `List<DataType>` to a `DataArray<DataType>`. |
|
||
|
|
| To `List<DataType>` | `implicit operator List<DataType>(DataArray<DataType> dataArray)` | Converts a `DataArray<DataType>` to a `List<DataType>`. |
|
||
|
|
|
||
|
|
**Properties:**
|
||
|
|
|
||
|
|
| Property | Type | Default | Description |
|
||
|
|
|----------|------|---------|-------------|
|
||
|
|
| `Values` | `DataType[]` | Empty array | The data values array. Returns empty array if uninitialized or null. |
|
||
|
|
| `ScaleFactorMv` | `double` | `0.0` | ADC to millivolt scale factor. |
|
||
|
|
| `ScaleFactorEU` | `double` | `0.0` | Engineering unit scale factor. |
|
||
|
|
| `UseEUScaleFactors` | `bool` | `false` | Flag indicating whether to use EU scale factors. |
|
||
|
|
| `DataZeroLevel` | `short` | `0` | Zero level offset for data. |
|
||
|
|
| `UnitConversion` | `double` | `1.0` | Unit conversion factor. |
|
||
|
|
| `Multiplier` | `double` | `1.0` | Multiplier for data. |
|
||
|
|
| `UserOffsetEU` | `double` | `0.0` | User-defined offset in engineering units. |
|
||
|
|
| `MvPerEu` | `double` | `0.0` | Millivolts per engineering unit sensitivity. |
|
||
|
|
|
||
|
|
**IXmlSerializable Methods:**
|
||
|
|
|
||
|
|
| Method | Signature | Description |
|
||
|
|
|--------|-----------|-------------|
|
||
|
|
| `WriteXml` | `void WriteXml(XmlWriter writer)` | Writes the data array and metadata to XML. Emits `Data` element with `Length`, `Type`, `ScaleFactorMv`, and `SensitivityMvEu` attributes, followed by individual `Datum` elements. |
|
||
|
|
| `ReadXml` | `void ReadXml(XmlReader reader)` | Reads and reconstructs the data array from XML. Dynamically instantiates the generic type and invokes its `Parse` method via reflection. |
|
||
|
|
| `GetSchema` | `XmlSchema GetSchema()` | Returns `null`. Not invoked during serialization. |
|
||
|
|
|
||
|
|
**Equality Methods:**
|
||
|
|
|
||
|
|
| Method | Signature | Description |
|
||
|
|
|--------|-----------|-------------|
|
||
|
|
| `Equals` | `override bool Equals(object obj)` | Memberwise equality comparison including `ScaleFactorMv`, `MvPerEu`, and all values in the `Values` array. |
|
||
|
|
| `GetHashCode` | `override int GetHashCode()` | Returns base implementation hash code. |
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 3. Invariants
|
||
|
|
|
||
|
|
1. **`DataArray<DataType>` Generic Constraint:** The `DataType` type parameter must have a `Parse(string)` method; otherwise, `ReadXml` will throw an exception with message "data type does not contain a \"Parse\" method".
|
||
|
|
|
||
|
|
2. **`DataArray.Values` Null Safety:** The `Values` property getter will never return `null`. If the internal `_Values` is uninitialized or null, it returns an empty `DataType[0]` array.
|
||
|
|
|
||
|
|
3. **`ChannelWithMeta` Immutability:** All properties on `ChannelWithMeta` are get-only; the class is effectively immutable after construction.
|
||
|
|
|
||
|
|
4. **`GetMinStopTime` Precision:** The method uses `decimal` arithmetic internally to avoid floating-point rounding errors (e.g., `4.999999999999995` vs `5.0`).
|
||
|
|
|
||
|
|
5. **XML Serialization Format:** `DataArray` XML output uses invariant culture (`CultureInfo("")`) for all numeric formatting to ensure locale-independent serialization.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 4. Dependencies
|
||
|
|
|
||
|
|
### This Module Depends On:
|
||
|
|
- `System` (standard library)
|
||
|
|
- `System.Collections.Generic` (standard library)
|
||
|
|
- `System.Linq` (standard library)
|
||
|
|
- `System.Reflection` (standard library)
|
||
|
|
- `System.Xml` (standard library)
|
||
|
|
- `System.Xml.Schema` (standard library)
|
||
|
|
- `System.Xml.Serialization` (standard library)
|
||
|
|
- `DTS.Common.Utilities` (for `Exceptional` base class)
|
||
|
|
- `DTS.Common.Utilities.DotNetProgrammingConstructs` (for `Property<T>` wrapper class)
|
||
|
|
- `DTS.Common.DAS.Concepts` (for `DataScaler` type used in `ChannelWithMeta`)
|
||
|
|
|
||
|
|
### What Depends On This Module:
|
||
|
|
- **Unclear from source alone.** The partial class structure (`Test`, `Test.Module`, `Test.Module.Channel`) suggests other files exist that complete these class definitions, but they are not included in the provided sources.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 5. Gotchas
|
||
|
|
|
||
|
|
1. **`IConvertable` Naming:** The interface is named `IConvertable` (with an 'a'), not the standard .NET spelling `IConvertible`. This is intentional but could cause confusion.
|
||
|
|
|
||
|
|
2. **`GetMinStartTime` Logic Inversion:** The method uses `Math.Max` to find the "minimum" start time because start times are typically negative values. This counterintuitive logic is documented in the source comment but may trip up developers.
|
||
|
|
|
||
|
|
3. **`DataArray.ReadXml` Reflection Dependency:** The XML deserialization relies on reflection to invoke a `Parse` method on the generic type. If `DataType` lacks this method or has an incompatible signature, deserialization will fail at runtime.
|
||
|
|
|
||
|
|
4. **`GetHashCode` Implementation:** The `DataArray<DataType>.GetHashCode()` method calls `base.GetHashCode()` rather than computing a hash from the object's values. This could lead to incorrect behavior if the object is used as a dictionary key or in a hash set.
|
||
|
|
|
||
|
|
5. **Partial Class Structure:** All three files contribute to nested partial classes (`Test.Module.Channel`). The full class definitions are spread across multiple files not provided here, as indicated by comments like `// *** see Test.cs ***`.
|
||
|
|
|
||
|
|
6. **XML End Element Handling:** In `ReadXml`, the call to `ReadEndElement()` is conditional based on whether the element name matches `DataXmlTag`. The comment indicates this handles edge cases with zero-length data, primarily occurring in unit tests.
|