This commit is contained in:
2026-04-17 14:55:32 -04:00
commit bc3ac1d4c9
18017 changed files with 4371742 additions and 0 deletions

View File

@@ -0,0 +1,74 @@
---
source_files:
- Common/DTS.Common.Serialization/IRIGCH10/Utils/Utils.cs
generated_at: "2026-04-16T03:42:52.923027+00:00"
model: "Qwen/Qwen3-Coder-Next-FP8"
schema_version: 1
sha256: "675d2f03b19fde67"
---
# Utils
## Documentation: `DTS.Serialization.IRIGCH10.Utils.Utils`
---
### 1. Purpose
This module provides low-level utility functions for handling IRIG CH10 (Inter-Range Instrumentation Group Command Handler, Chapter 10) data format conventions. Specifically, it supports conversion of integer values to Binary-Coded Decimal (BCD) representation (for fields like dates), and computation of checksums (8-bit, 16-bit, and 32-bit) as required by the CH10 specification. It also offers bit-level manipulation helpers for packing/unpacking bitfields from `BitArray` objects—common when serializing/deserializing packet headers and metadata fields.
---
### 2. Public Interface
All members are `static` and defined in the `abstract` class `Utils`. No public constructors or instance members exist.
| Method | Signature | Behavior |
|--------|-----------|----------|
| `GetBCDBytes` | `public static byte[] GetBCDBytes(int value)` | Converts an integer `value` (09999) into a 2-byte BCD representation (least significant digit in lower nibble of byte 0). Throws `ArgumentOutOfRangeException` if `value` is outside [0, 9999]. |
| `GetCheckSum8` | `public static ushort GetCheckSum8(byte[] bytes)` | Computes an 8-bit checksum by summing all bytes in `bytes` and returning the low 16 bits of the sum (i.e., `sum & 0xFFFF`). No padding or alignment assumptions. |
| `GetCheckSum16` | `public static ushort GetCheckSum16(byte[] bytes)` | Computes a 16-bit checksum per CH10 spec: interprets `bytes` as an array of `ushort` (little-endian, via `Buffer.BlockCopy`) and sums all `ushort` values. **Requires** `bytes.Length` to be even; asserts this via `Trace.Assert`. |
| `GetCheckSum32` | `public static uint GetCheckSum32(byte[] bytes)` | Computes a 32-bit checksum per CH10 spec: interprets `bytes` as an array of `uint` (little-endian) and sums all `uint` values. **Requires** `bytes.Length` to be divisible by 4; asserts this via `Trace.Assert`. |
| `BitArrayToInt32` | `public static int BitArrayToInt32(BitArray ba, int startIndex, int endIndex)` | Extracts bits from `ba` between `startIndex` and `endIndex` (inclusive), interpreting them as a little-endian integer (bit 0 = LSB). Returns an `int` (up to 32 bits). |
| `SetBits` | `public static void SetBits(BitArray b, uint value, int startIndex, int endIndex)` | Writes the least-significant bits of `value` (covering `(endIndex - startIndex + 1)` bits) into `b`, starting at `startIndex`. Bits are copied in little-endian order (bit 0 of `value``b[startIndex]`). |
---
### 3. Invariants
- **BCD Range**: `GetBCDBytes` enforces `0 ≤ value ≤ 9999`. Values outside this range throw `ArgumentOutOfRangeException`.
- **Checksum Input Length**:
- `GetCheckSum16` requires `bytes.Length % 2 == 0`.
- `GetCheckSum32` requires `bytes.Length % 4 == 0`.
- These are enforced via `Trace.Assert`, which may be compiled out in Release builds—**no runtime exception is thrown** if the invariant is violated in non-Debug builds.
- **Bit Index Bounds**: `BitArrayToInt32` and `SetBits` assume `0 ≤ startIndex ≤ endIndex < ba.Length` (or `b.Length`). No explicit bounds checking is performed; out-of-range indices will cause `IndexOutOfRangeException` at runtime.
- **Endianness**: All multi-byte integer interpretations (via `Buffer.BlockCopy` into `ushort[]`/`uint[]`) assume **little-endian byte order**, consistent with .NETs default on most platforms.
---
### 4. Dependencies
**Imports/Usings**:
- `System`
- `System.Collections` (`BitArray`)
**Used By**:
- Other modules in `DTS.Serialization.IRIGCH10` (inferred from namespace), particularly those handling packet serialization/deserialization (e.g., header construction, data packet checksumming, date/time field encoding).
**Used For**:
- Encoding/decoding BCD fields (e.g., timestamps, counters).
- Computing checksums for CH10 packet headers (`GetCheckSum16`) and data payloads (`GetCheckSum32`).
- Bit-level manipulation of packet fields (e.g., flags, variable-length integers).
---
### 5. Gotchas
- **`Trace.Assert` is not a runtime guard**: In non-Debug builds, failed assertions in `GetCheckSum16` and `GetCheckSum32` will not throw exceptions—invalid input lengths may cause silent corruption or incorrect checksums. Callers must ensure input alignment themselves.
- **BCD encoding is fixed to 4 decimal digits**: `GetBCDBytes` only supports values up to 9999 (2 bytes). Larger values require multiple calls or a different approach (not provided here).
- **Little-endian assumption**: `GetCheckSum16`/`GetCheckSum32` rely on `Buffer.BlockCopy` interpreting bytes as little-endian `ushort`/`uint`. This is platform-dependent on .NET (true on x86/x64), but may break on big-endian systems.
- **No overflow handling in checksums**: Sums wrap around modulo 2¹⁶ (for `ushort`) or 2³² (for `uint`), per CH10 spec—but this is implicit, not documented in code.
- **`SetBits` uses `BitConverter.GetBytes(value)`**: This assumes little-endian layout for `value`, and only the lowest `(endIndex - startIndex + 1)` bits are copied. If `value` has more bits set than `endIndex - startIndex + 1`, higher bits are silently ignored. No validation ensures `value` fits the bit range.
- **`BitArrayToInt32` uses LSB-first indexing**: Bit 0 of the result corresponds to `ba[startIndex]`, not `ba[endIndex]`. This matches CH10s typical bit numbering but may be counterintuitive.
None identified beyond the above.