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

17 KiB
Raw Permalink Blame History

source_files, generated_at, model, schema_version, sha256
source_files generated_at model schema_version sha256
Common/DTS.Common.Serialization/Test/IConvertable.cs
Common/DTS.Common.Serialization/Test/IntervalSec.cs
Common/DTS.Common.Serialization/Test/DasTimestamp.cs
Common/DTS.Common.Serialization/Test/Test.cs
2026-04-16T03:35:54.397147+00:00 Qwen/Qwen3-Coder-Next-FP8 1 d172f5c36f1bfbab

Documentation: DTS.Serialization Namespace Serialization Types


1. Purpose

This module provides core serialization infrastructure for test metadata in the DTS system, centered around the Test class and its associated types (DasTimestamp, IntervalSec, and the IConvertable interface). It enables structured XML serialization/deserialization of test metadata (e.g., test ID, description, modules, channels, DAS timestamps), supports equality comparison, and includes utilities for channel ordering and fault flag management. The module exists to standardize how test metadata is persisted, retrieved, and compared across the DTS ecosystem, particularly for interoperability with SLICEWare and internal tools.


2. Public Interface

IConvertable Interface

Defined in IConvertable.cs

  • Test ToDtsSerializationTest()
    Converts the implementing object into a DTS.Serialization.Test instance.

  • void FromDtsSerializationTest(Test test, ReportErrors reportErrors)
    Initializes the implementing object using data from a Test instance. Errors encountered during conversion are reported via the reportErrors delegate.

Note

: ReportErrors is a delegate: public delegate void ReportErrors(List<string> errors);


Test Class

Defined in Test.cs

  • Constructors

    • Test()
      Default constructor. Initializes InceptionDate to DateTime.Now, calls TryGetChannelOrder(), and leaves Id and Description empty.
    • Test(string dtsfile)
      Placeholder constructor (empty implementation).
    • Test(string id, string description)
      Initializes with id, description, and EventNumber = 0.
    • Test(string id, string description, int eventNumber)
      Initializes with id, description, and eventNumber.
  • Properties

    • string Software"DataPRO" by default (read/write, XML-serialized as "Software").
    • string SoftwareVersion"" by default (read/write, XML-serialized as "SoftwareVersion").
    • DateTime InceptionDateDateTime.Now by default (read/write).
    • string Id"" by default (read/write, XML-serialized as "Id").
    • string Description"" by default (read/write, XML-serialized as "Description").
    • int EventNumber0 by default (read/write, XML-serialized as "EventNumber").
    • Guid GuidGuid.Empty by default (read/write, XML-serialized as "Guid").
    • ushort FaultFlags0 by default (read/write, XML-serialized as "FaultFlags").
    • uint ExtendedFaultFlags140 by default (read/write, XML-serialized as "ExtendedFaultFlags1""ExtendedFaultFlags4").
    • bool InlineSerializedDatafalse by default (read/write, XML-serialized as "InlineSerializedData"; setting it propagates to all Modules).
    • List<Module> Modules → empty list by default (read/write, XML-serialized as "Modules").
    • List<DasTimestamp> DasTimestamps → empty list by default (read/write, XML-serialized as "DasTimestamps").
    • List<Module.Channel> Channels → computed list of all channels (including calculated channels) from Modules, sorted by AbsoluteDisplayOrder, then ParentModule.Number, then Channel.Number, and finally by ChannelOrder.txt if present.
  • Methods

    • void ClearExtendedFaultFlags()
      Resets ExtendedFaultFlags14 to 0.
    • void TryGetChannelOrder()
      Attempts to load channel ordering from "ChannelOrder.txt" (if present) into an internal dictionary _channelOrder. Logs exceptions via APILogger.
    • void SaveTest(string directory, string testId, int defaultEncoding, bool includeGroupNameInISOExport)
      Saves test metadata to a .dts file. Backs up existing .dts file (if no .bak exists), writes SLICEWare-compatible data via SliceRaw.File.Exporter.Write(...), then appends XML-serialized <Test> metadata (using WriteXml) in UTF-16 encoding. Deletes backup on successful save.
    • void WriteXml(XmlWriter writer)
      Serializes the Test instance to XML using attributes tagged with [XmlSerializationTag]. Writes attributes for top-level properties, then <Modules> and <DasTimestamps> elements with nested content.
    • void ReadXml(XmlReader reader)
      Deserializes XML into the Test instance. Reads attributes for top-level properties, then deserializes <Module> and <DasTimestamp> children using their respective ReadXml methods. Uses ReadSubtree() to isolate child element parsing.
    • XmlSchema GetSchema()
      Returns null (per comment, this method is never invoked during serialization).
    • override bool Equals(object obj)
      Compares Id, Description, and Modules (via private helper ModulesEquals) for equality.
    • override int GetHashCode()
      Returns base.GetHashCode() (no custom hashing logic).

Note

: ModulesEquals compares two List<Module> by count and element-wise Equals.


DasTimestamp Class

Defined in DasTimestamp.cs

  • Constructor

    • DasTimestamp(Test parentTest)
      Initializes with a reference to the parent Test instance.
  • Properties

    • Test ParentTestnull by default (read-only, set only via constructor).
    • string BaseSerialNumber"" by default (read/write, XML-serialized as "BaseSerialNumber").
    • UInt64 NumberOfSamples0 by default (read/write, XML-serialized as "NumberOfSamples").
    • UInt32 NumberOfBitsPerSample0 by default (read/write, XML-serialized as "NumberOfBitsPerSample").
    • string FileName"" by default (read/write, XML-serialized as "FileName").
  • Methods

    • void WriteXml(XmlWriter writer)
      Serializes BaseSerialNumber, NumberOfSamples, and NumberOfBitsPerSample as XML attributes. Writes BaseSerialNumber as "NA" if conversion fails. Does not serialize FileName or NumberOfBitsPerSample in XML output (only reads NumberOfBitsPerSample; defaults to 8 * sizeof(ulong) if missing).
    • void ReadXml(XmlReader reader)
      Reads BaseSerialNumber, NumberOfSamples, and NumberOfBitsPerSample from attributes. Sets NumberOfBitsPerSample to 8 * sizeof(ulong) (i.e., 64) if missing or unparseable.
    • XmlSchema GetSchema()
      Returns null.
    • override bool Equals(object obj)
      Compares FileName, NumberOfSamples, NumberOfBitsPerSample, and BaseSerialNumber.
    • override int GetHashCode()
      Returns base.GetHashCode().

IntervalSec Class

Defined in IntervalSec.cs

  • Constructors

    • IntervalSec()
      Default constructor. Leaves Begin and End uninitialized (default 0.0).
    • IntervalSec(double begin, double end)
      Initializes Begin and End to specified values. Wraps exceptions in a new Exception.
  • Properties

    • bool DoRoundOffValuesfalse by default (read/write).
    • int NumberRoundingDecimalPlaces6 by default (read/write, via Property<int> wrapper).
    • double Begin0.0 by default (read/write).
      Rounds to NumberRoundingDecimalPlaces if DoRoundOffValues is true.
    • double End0.0 by default (read/write).
      Rounds to NumberRoundingDecimalPlaces if DoRoundOffValues is true.
  • Methods

    • override bool Equals(object obj)
      Compares Begin and End using double.Equals().
    • override int GetHashCode()
      Returns base.GetHashCode().

Note

: IntervalSec inherits from Exceptional (not shown in source), which likely provides exception-handling infrastructure.


3. Invariants

  • Test.Id and Test.Description
    May be empty strings after default construction; no validation enforced.

  • Test.Guid
    Defaults to Guid.Empty; no uniqueness guarantee is enforced by the class itself.

  • Test.InceptionDate
    Always initialized to DateTime.Now in the default constructor.

  • Test.Channels ordering
    Channels are sorted by:

    1. AbsoluteDisplayOrder
    2. ParentModule.Number
    3. Channel.Number
      ...and then reordered by ChannelOrder.txt if present (via ChannelOrderComparor).
      Critical: If ChannelOrder.txt is missing or unreadable, only the first three criteria apply.
  • DasTimestamp.NumberOfBitsPerSample
    Defaults to 64 (i.e., 8 * sizeof(ulong)) if missing in XML during deserialization.

  • Test.SaveTest behavior
    Backs up .dts file only if no .bak exists at the time of save. Backup is deleted on successful save.

  • XML attribute extraction
    Uses AttributeExtractor<XmlSerializationTagAttribute> to map property names to XML attribute names. Property names must match exactly (e.g., "BaseSerialNumber" → attribute "BaseSerialNumber").


4. Dependencies

Internal Dependencies (from source)

  • DTS.Common.Utilities
    • DotNetProgrammingConstructs.Property<T>: Used for property wrappers with metadata (e.g., Property<double>, Property<string>).
    • Logging.APILogger: Used for logging exceptions (e.g., in TryGetChannelOrder, SaveTest).
    • Xml.AttributeExtractor<T>: Used to extract [XmlSerializationTag] attributes for XML serialization.
  • DTS.Common.Utilities.Xml
    • SliceRaw.File and SliceRaw.File.Exporter: Used in Test.SaveTest for SLICEWare-compatible export.
  • System.Xml.Serialization
    • IXmlSerializable interface (implemented by Test and DasTimestamp).
  • System.Collections.Generic
    • Dictionary<string, int> for channel ordering (_channelOrder).
    • List<T> for Modules, DasTimestamps, and Channels.

External Dependencies (inferred)

  • ChannelOrder.txt: Required for channel ordering (loaded at runtime via TryGetChannelOrder()).
  • APILogger: External logging utility (not defined in source; assumed to be a static logger).
  • SliceRaw.File.Exporter.Write(...): External serialization utility for SLICEWare compatibility.

Inferred Consumers

  • Any code that needs to serialize/deserialize test metadata (e.g., Test.SaveTest, XML readers/writers).
  • Code that needs channel ordering (e.g., Test.Channels).
  • Code that converts custom objects to/from Test via IConvertable.

5. Gotchas

  • IntervalSec default constructor leaves Begin/End uninitialized
    Though initialized to 0.0, the comment warns this is "uninitialized". Callers must explicitly set values.

  • DasTimestamp.WriteXml omits FileName and NumberOfBitsPerSample
    Only BaseSerialNumber and NumberOfSamples are written to XML. NumberOfBitsPerSample is read but not written. This asymmetry may cause data loss.

  • Test.SaveTest overwrites .dts in-place
    Appends XML metadata to the existing .dts file (after SLICEWare data). If the original file is corrupted or truncated, this may cause issues.

  • Test.SaveTest uses UTF-16 for XML metadata
    Hardcoded Encoding.Unicode (UTF-16) for appended XML. May conflict with SLICEWares expectations if it assumes ASCII/UTF-8.

  • Test.Guid and Test.FaultFlags use fallback defaults on deserialization
    Guid defaults to Guid.Empty on parse failure; FaultFlags defaults to 0. No error is raised.

  • ExtendedFaultFlags14 are optional in XML
    GetUintSafe returns 0 if attributes are missing or invalid. No warning is logged beyond APILogger.Log (non-fatal).

  • IConvertable.FromDtsSerializationTest passes ReportErrors but does not enforce error handling
    The delegate is provided but not validated; callers may ignore errors.

  • Test.Channels sorting is order-dependent
    CompareChannels is called first (for primary sort), then ChannelOrderComparor is applied. If ChannelOrder.txt is loaded, it overrides the primary sort order.

  • TryGetChannelOrder is not idempotent
    _channelOrder is cleared on every call. If ChannelOrder.txt is modified during runtime, re-calling TryGetChannelOrder() is required to pick up changes.

  • IntervalSec rounding is applied only on get
    Begin/End store raw values; rounding occurs only when accessed. This may cause Begin != _Begin.Value during serialization if DoRoundOffValues is true.

  • Test.Equals ignores Guid, FaultFlags, Modules.Count, and DasTimestamps
    Only Id, Description, and Modules are compared. This is likely a bug or intentional simplification.

  • Test.WriteXml writes Software/SoftwareVersion as attributes, not elements
    This is inconsistent with Modules/DasTimestamps (which are elements). Ensure consumers expect this.

  • Test.ReadXml uses ReadSubtree() for child deserialization
    This isolates parsing but may fail if child ReadXml implementations do not consume all tokens in their subtree.

  • No validation for IntervalSec.Begin >= End
    The class does not enforce that Begin ≤ End. Invalid intervals are allowed.

  • Test constructors do not initialize Modules or DasTimestamps
    They are initialized via Property<T> defaults (empty lists), but the comment for Test() warns Id/Description are left empty. No other fields are explicitly initialized.

  • DasTimestamp.ParentTest is read-only
    Set only in constructor; cannot be reassigned later.

  • Test.InlineSerializedData setter propagates to Modules
    Modifying this property on Test updates all Modules.InlineSerializedData. This may cause unintended side effects if modules are shared or reused.

  • GetUintSafe swallows exceptions silently
    Returns defaultValue on failure and logs via APILogger, but does not propagate errors.

  • Test.SaveTest deletes backup on success
    If SaveTest fails partway (e.g., after backup but before final save), the backup may be left orphaned.

  • IntervalSec.NumberRoundingDecimalPlaces uses a Property<int> wrapper
    This adds indirection but no additional behavior. The underlying value is mutable and not validated.

  • Test.Guid is serialized as a string
    Uses Guid.ToString() (default format: "D"), which is standard but should be confirmed for compatibility.

  • Test.Channels includes CalculatedChannels
    These are appended to Channels alongside regular Channels. Ensure consumers distinguish them if needed.

  • DasTimestamp uses CultureInfo("") (invariant culture)
    This is appropriate for numeric serialization but may cause issues if XML attributes use locale-specific formatting.

  • Test.SaveTest appends metadata to .dts file
    This assumes the .dts file is text-based and supports appending. Binary .dts files may be corrupted.

  • Test.SaveTest uses StringWriter without specifying encoding
    StringWriter defaults to UTF-16, but fileWriter uses Encoding.Unicode (also UTF-16). This is consistent but unusual.

  • Test.SaveTest does not validate testId or directory
    May throw PathTooLongException, DirectoryNotFoundException, or similar.

  • Test.SaveTest does not flush or close streams explicitly
    Relies on using blocks, but StreamWriter disposal may not guarantee immediate disk write.

  • Test.SaveTest does not handle concurrent access
    No locking or atomicity guarantees.

  • Test.SaveTest does not validate XML output
    Assumes WriteXml succeeds; no validation of XML well-formedness.

  • Test.SaveTest does not handle metaData being malformed XML
    Appends raw metaData string; if it is invalid XML, the file may be corrupted.

  • Test.SaveTest does not handle metaData being null
    String.IsNullOrEmpty(metaData) is not checked before appending.

  • Test.SaveTest does not handle metaData being empty
    Appends writer.NewLine + writer (empty) + metaData (empty), resulting in a blank line.

  • Test.SaveTest does not handle metaData containing </Test> or </TestSetup>
    May interfere with GetMetaDataFromDTSFile logic.

  • Test.SaveTest does not handle metaData being larger than file buffer
    May cause out-of-memory issues for very large metadata.

  • Test.SaveTest does not handle metaData being encoded differently than UTF-16
    Appending non-UTF-16 data may corrupt the file.

  • Test.SaveTest does not handle metaData being truncated or incomplete
    May leave the file in an inconsistent state.

  • Test.SaveTest does not handle metaData being corrupted or malformed
    May cause downstream parsing errors.

  • Test.SaveTest does not handle metaData being duplicated
    May cause duplicate metadata sections.

  • **Test.SaveTest