Files
DP44/enriched-qwen3-coder-next/Common/DTS.Common/Utils.md
2026-04-17 14:55:32 -04:00

207 lines
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
source_files:
- Common/DTS.Common/Utils/XMLUtils.cs
- Common/DTS.Common/Utils/EnumUtils.cs
- Common/DTS.Common/Utils/ValueStopWatch.cs
- Common/DTS.Common/Utils/ImageButton.cs
- Common/DTS.Common/Utils/PNGImageUtil.cs
- Common/DTS.Common/Utils/MouseUtils.cs
- Common/DTS.Common/Utils/StopWatch.cs
- Common/DTS.Common/Utils/SerializableDictionary.cs
- Common/DTS.Common/Utils/TestUtils.cs
- Common/DTS.Common/Utils/IPUtils.cs
- Common/DTS.Common/Utils/SecureQueue.cs
- Common/DTS.Common/Utils/ByteConverter.cs
- Common/DTS.Common/Utils/NetworkUtils.cs
- Common/DTS.Common/Utils/BusyWaitAnimation.cs
generated_at: "2026-04-16T02:53:58.796981+00:00"
model: "Qwen/Qwen3-Coder-Next-FP8"
schema_version: 1
sha256: "95511667ddecb834"
---
# DTS.Common.Utils Module Documentation
## 1. Purpose
This module provides a collection of utility classes and static helper methods for common operations across the DTS system. It serves as a foundational layer for low-level functionality including time measurement (`ValueStopwatch`, `StopWatchQueue`), data serialization/deserialization (`SerializableDictionary`, `ByteConvertor`), UI components (`ImageButton`, `BusyWaitAnimation`), network operations (`NetworkUtils`, `IPUtils`), and test/data processing (`TestUtils`, `EnumUtil`). The module exists to centralize reusable logic, reduce code duplication, and provide consistent behavior for cross-cutting concerns such as timing, byte-order conversion, IP address handling, and UI feedback mechanisms.
## 2. Public Interface
### `EnumUtil` (static class)
- `public static IEnumerable<T> GetValues<T>()`
Returns all enum values of type `T` using `Enum.GetValues`.
- `public static ItemCollection GetValuesList<T>()`
Returns an `ItemCollection` (from `Xceed.Wpf.Toolkit`) containing enum values and their names, suitable for binding to property grids.
### `ValueStopwatch` (readonly struct)
- `public static ValueStopwatch StartNew()`
Creates and starts a new `ValueStopwatch` instance.
- `public TimeSpan GetElapsedTime()`
Returns the elapsed time since the stopwatch was started, computed using `Stopwatch.GetTimestamp()` and `Stopwatch.Frequency`.
### `ImageButton` (class)
- Inherits from `System.Windows.Controls.Button`.
- `public ImageSource Source { get; set; }`
Gets/sets the image displayed in the button.
- `public string ImageText { get; set; }`
Gets/sets the text displayed below the image in the button.
- Internally uses a `StackPanel` with vertical orientation to arrange an `Image` and `TextBlock`.
### `PNGImageUtil` (static class)
- `public static void SaveImage(FrameworkElement view, string fileName)`
Renders the given `FrameworkElement` as a PNG image to the specified file path using `RenderTargetBitmap` and `PngBitmapEncoder`.
### `MouseUtilities` (class)
- `public static Point GetMousePosition(Visual relativeTo)`
Returns the current mouse cursor position relative to a given WPF `Visual`. Uses Win32 API (`GetCursorPos`, `ScreenToClient`) and WPF transform logic to compute coordinates.
### `StopWatchQueue` (class)
- `public StopWatchQueue(string name)`
Constructor; initializes a queue for storing elapsed tick values (max ~5000 entries).
- `public void Start()`
Starts the internal `Stopwatch`.
- `public void Stop()`
Stops the `Stopwatch`, enqueues the elapsed ticks, and resets the `Stopwatch`.
- `public void DumpData()`
Writes timing statistics (count, min, max, avg, stddev) and all recorded values (in milliseconds) to a CSV file named `<name><FileTime>.csv`.
- Finalizer calls `DumpData()` on disposal.
### `SerializableDictionary<TKey, TValue>` (class)
- Inherits `Dictionary<TKey, TValue>` and implements `IXmlSerializable`.
- `public void ReadXml(XmlReader reader)`
Deserializes XML into the dictionary; expects `<items><item><key>...</key><value>...</value></item>...</items>` structure.
- `public void WriteXml(XmlWriter writer)`
Serializes the dictionary to XML in the same structure.
- Uses `XmlSerializer` for key and value types.
### `TestUtils` (static class)
- `public static Tuple<double, double> MinUnixTime(IEnumerable<TestModuleTimeStamp> basemodules)`
Returns the earliest valid timestamp (as `(sec, nanosec)`) from a collection of `TestModuleTimeStamp` objects, filtering out outliers beyond `utcAverage - utcStandardDeviation` and clamping stddev to ≤10ms. Returns `null` if input is null/empty.
- `public static string ParseROISuffix(string test)`
Extracts ROI suffix from a colon-separated test string. Tries multiple heuristics based on `DTS.Common.Constants.EventNumber`.
### `IPUtils` (namespace)
- `public class IPRange`
Holds a start and end `IPAddressIntForm` representing an IP range.
- `public class IPAddressIntForm`
Represents an IPv4 address as four byte components (`ByteOne``ByteFour`).
- `public static bool TryParse(string input, out IPAddressIntForm output)`
Parses a dotted-decimal IP string into an `IPAddressIntForm`.
- `public static string[] GetAllIPs(IPAddressIntForm a, IPAddressIntForm b)`
Returns all IPs between `a` and `b` (inclusive), regardless of input order.
- `internal class IPComparer : IComparer<IPAddressIntForm>`
Lexicographic comparison of IP addresses by byte components.
### `SecureQueue<T>` (class)
- Generic thread-safe queue with configurable null-handling policy (`NullPolicy` enum: `DenyNull`, `SkipNull`, `AllowNull`).
- `public void Enqueue(T[] newData)`
Adds a byte array to the queue; enforces null policy and logs if enabled.
- `public bool WaitForData(int timeoutMillisec)`
Blocks for up to `timeoutMillisec` ms waiting for data.
- `public T[] Dequeue(bool resetEvent)`
Dequeues and concatenates all queued arrays into a single array; resets internal event.
- `public void Flush()`
Clears the queue and resets the event.
- `public bool IsEmpty()`
Returns `true` if queue is empty.
- `public WaitHandle QueueWaitHandle => ByteQueueEvent`
Exposes the internal `ManualResetEvent` for external wait operations.
### `ByteConvertor` (class)
- Static class for converting between integral types and byte arrays in **network byte order (big-endian)**.
- `public static void Convert(byte[] input, int offset, out T value)`
Reads a value of type `T` (e.g., `ushort`, `int`, `long`, `float`, `double`, `string`) from `input` at `offset`, interpreting bytes in big-endian order.
- `public static byte[] ToByteArray(T value)`
Converts `value` to a big-endian byte array (e.g., `ToByteArray(ushort)` returns 2 bytes, `ToByteArray(int)` returns 4 bytes, `ToByteArray(string)` appends null terminator).
### `NetworkUtils` (static class)
- `public static bool IsNetworkInterfaceUp(IPAddress ip)`
Checks if a network interface with the given IP is active, supports multicast, and is not loopback or internal-only (unless `AllowInternalNICIPs` is `true`).
- `public static List<HostInfo> GetAvailableHosts(bool supportMulticastOnly = false)`
Returns a list of `HostInfo` objects for all available IPv4 network interfaces (filters out loopback, virtual, low-speed, and Npcap interfaces).
- `public static bool TryParseConnectionString(string connectionString, out string ipAddress)`
Attempts to extract an IP address from a DAS connection string (supports URI or colon-separated formats). Returns `false` for non-IP (e.g., USB) strings.
- `public static bool AllowInternalNICIPs { get; set; }`
Controls whether 169.254.x.x (link-local) addresses are included in interface filtering.
### `BusyWaitAnimation` (class)
- WPF/WinForms-compatible busy indicator (spinning circle).
- `public bool Active { get; set; }`
Starts/stops the animation timer.
- `public StylePresets StylePreset { get; set; }`
Sets appearance to presets: `MacOsx`, `Firefox`, `Ie7`, or `Custom`.
- `public Color Color { get; set; }`
Base color for the spinning spokes.
- `public int OuterCircleRadius`, `InnerCircleRadius`, `NumberSpoke`, `SpokeThickness`, `RotationSpeed`
Properties to customize appearance and behavior.
- Requires `SetDrawArea(Rectangle)` and `hDC` setter for rendering; uses GDI+ for drawing.
## 3. Invariants
- **`ByteConvertor`**: All multi-byte conversions use big-endian (network) order. Little-endian host systems must convert appropriately.
- **`ValueStopwatch`**: Elapsed time is computed using `Stopwatch.Frequency` and `TimeSpan.TicksPerSecond`; precision is limited to `Stopwatch` resolution.
- **`StopWatchQueue`**: Stores up to ~5000 tick values; older values are overwritten only when the queue is full (not explicitly implemented—queue grows until `DumpData()` is called).
- **`SerializableDictionary`**: Keys and values must be serializable via `XmlSerializer`; no validation of key uniqueness or type compatibility is performed during deserialization.
- **`SecureQueue<T>`**:
- `Dequeue()` always concatenates all queued arrays into a single array (not one per enqueue).
- `Dequeue()` and `Flush()` reset the internal `ManualResetEvent`, breaking existing waiters.
- Null/empty arrays are handled per `NullPolicy`; `Clone()` is used for enqueue to prevent external mutation.
- **`TestUtils.MinUnixTime`**:
- Uses `Common.Constants.NANOS_PER_SECOND` and `Common.Constants.TEN_MILLIS_IN_SEC` (not defined in this module).
- Filters out timestamps where `moduleTime ≤ utcAverage - utcStandardDeviation`.
- Returns the *first* module satisfying the filter, not necessarily the absolute earliest.
- **`NetworkUtils.IsNetworkInterfaceUp`**: Skips interfaces with 169.254.x.x addresses unless `AllowInternalNICIPs` is `true`.
- **`IPUtils.IPAddressIntForm.GetAllIPs`**: Iterates over all bytes in lexicographic order; may produce invalid IPs (e.g., 256.x.x.x) if input bytes exceed 0255.
## 4. Dependencies
### Internal Dependencies (within `DTS.Common`)
- `DTS.Common.Interface` (for `TestModuleTimeStamp` and `TestUtils`)
- `DTS.Common.Utilities.Logging` (for `APILogger`)
- `DTS.Common.Constants` (referenced by `TestUtils` and `NetworkUtils`)
- `DTS.Common.Utilities` (referenced by `SecureQueue`)
### External Dependencies
- **.NET Framework**: `System`, `System.Collections.Generic`, `System.Diagnostics`, `System.IO`, `System.Linq`, `System.Net`, `System.Net.NetworkInformation`, `System.Net.Sockets`, `System.Runtime.InteropServices`, `System.Threading`, `System.Windows`, `System.Windows.Media`, `System.Windows.Media.Imaging`, `System.Windows.Threading`, `System.Xml`, `System.Xml.Serialization`
- **WPF Toolkit**: `Xceed.Wpf.Toolkit.PropertyGrid.Attributes` (for `ItemCollection`)
- **Win32 API**: `user32.dll` (`GetCursorPos`, `GetPhysicalCursorPos`, `ScreenToClient`)
- **Windows Forms**: `System.Windows.Forms`, `System.Drawing`, `System.Drawing.Drawing2D` (for `BusyWaitAnimation`)
### Dependencies on This Module
- `DTS.Common.Interface` (via `TestUtils`)
- Networking modules (via `NetworkUtils`, `IPUtils`)
- UI components (via `ImageButton`, `BusyWaitAnimation`)
- Data processing pipelines (via `ByteConvertor`, `SerializableDictionary`, `SecureQueue`)
## 5. Gotchas
- **`ByteConvertor`**: The `Convert` methods for `float`/`double` use `BitConverter` (host-endian), **not** network byte order. Only integer/string conversions are big-endian.
- **`StopWatchQueue`**:
- Finalizer calls `DumpData()` but does not prevent multiple calls (e.g., explicit `DumpData()` + finalizer).
- `DumpData()` dequeues all values, leaving the queue empty.
- No explicit disposal pattern; `~StopWatchQueue()` is the only cleanup.
- **`SecureQueue<T>`**:
- `Dequeue()` concatenates all queued arrays into one—this may be unexpected if callers expect per-enqueue chunks.
- `Dequeue()` and `Flush()` reset the `ManualResetEvent`, invalidating any pending `WaitOne()` calls.
- `ByteQueueEvent` is recreated on each `Dequeue()`/`Flush()`, breaking external references to the `WaitHandle`.
- **`TestUtils.MinUnixTime`**:
- Uses `Common.Constants.NANOS_PER_SECOND` and `TEN_MILLIS_IN_SEC`—these must be defined elsewhere.
- The filtering logic (`moduleTime > utcAverage - utcStandardDeviation`) may exclude valid early timestamps if they are statistical outliers.
- **`NetworkUtils.GetAvailableHosts`**:
- Filters out interfaces with 169.254.x.x addresses by default (configurable via `AllowInternalNICIPs`).
- Skips interfaces with "Npcap" in description (Wireshark).
- **`IPUtils.IPAddressIntForm.GetAllIPs`**:
- Iterates over all byte combinations (e.g., 256.0.0.0 if `ByteOne=256`), which may produce invalid IPs.
- No validation that `start ≤ end` in IP order (handled via `IPComparer`).
- **`BusyWaitAnimation`**:
- Requires manual setup: `SetDrawArea()` and `hDC` setter must be called before rendering.
- Uses GDI+ (`Graphics.FromHdc`), which is not thread-safe and requires a valid HDC.
- **`ImageButton`**:
- Uses `StackPanel` with fixed `Margin=10`; not configurable.
- No support for horizontal layout or custom content beyond image + text.
- **`PNGImageUtil.SaveImage`**:
- Uses `view.ActualWidth`/`ActualHeight`, which may be zero if the element is not rendered.
- Does not handle DPI scaling beyond hardcoded 96 DPI.
- **`EnumUtil.GetValuesList<T>`**:
- Returns `ItemCollection` (WPF Toolkit type), which may not be available in non-WPF contexts.