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

74 lines
5.5 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.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.