using Mirle.Component.MPLC.DataBlocks.DeviceRange.Interfaces; using System; using System.Diagnostics; using System.Globalization; namespace Mirle.Component.MPLC.DataBlocks.DeviceRange { /// /// B 設備範圍 /// public class BDeviceRange : ITypeDeviceRange { /// /// 建構式 /// /// 起始位置 /// 結束位置 /// public BDeviceRange(string startAddress, string endAddress) { StartAddress = startAddress; EndAddress = endAddress; if (!startAddress.StartsWith(_type) || !endAddress.StartsWith(_type)) throw new ArgumentException("Wrong Type!!"); try { _startOffset = int.Parse(startAddress[1..], NumberStyles.HexNumber); //Hexadecimal _endOffset = int.Parse(endAddress[1..], NumberStyles.HexNumber); //Hexadecimal } catch (Exception ex) { Debug.WriteLine($"{ex}"); throw new ArgumentException("Wrong Address!!"); } if (_startOffset > _endOffset) throw new ArgumentException("Wrong Address Range!!"); int length = _endOffset - _startOffset + 1; WordLength = length % 16 == 0 ? length / 16 : length / 16 + 1; } /// /// 設備類別 /// private const string _type = nameof(DeviceType.B); /// /// 起始偏移量 /// private readonly int _startOffset; /// /// 結束偏移量 /// private readonly int _endOffset; /// /// 起始位置 /// public string StartAddress { get; } /// /// 結束位置 /// public string EndAddress { get; } /// /// 字元長度 /// public int WordLength { get; } /// /// 位元組陣列長度 /// /// WordLength * 2 public int ByteArrayLength => WordLength * 2; /// /// 是否為同樣設備範圍 /// /// 起始位置 /// True/False public bool IsSameRange(string address) { return TryGetIndex(address, out _); } /// /// 是否為同樣設備類別 /// /// 位置 /// True/False private static bool IsSameType(string address) { return address.ToUpper().StartsWith(_type); } /// /// 取得索引 /// /// 位置 /// 索引 /// True/False public bool TryGetIndex(string address, out int index) { if (!IsSameType(address)) { index = -1; return false; } address = address[1..]; address = address.Split('.')[0]; index = int.Parse(address, NumberStyles.HexNumber); if (index >= _startOffset && index <= _endOffset) return true; index = -1; return false; } /// /// 取得偏移量 /// /// 位置 /// 偏移量 /// True/False public bool TryGetOffset(string address, out int offset) { if (TryGetIndex(address, out int index)) { offset = index - _startOffset; return true; } offset = -1; return false; } /// /// 取得位元組陣列偏移量 /// /// 位置 /// 偏移量 /// True/False public bool TryGetByteArrayOffset(string address, out int offset) { if (TryGetIndex(address, out int index)) { offset = (index - _startOffset) / 16 * 2; return true; } offset = -1; return false; } /// /// 取得位元組陣列位元索引 /// /// 位置 /// 索引 /// True/False public bool TryGetByteArrayBitIndex(string address, out int index) { if (TryGetIndex(address, out int bitIndex)) { index = (bitIndex - _startOffset) % 16; return true; } index = -1; return false; } } }