You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

161 lines
5.2 KiB

using Mirle.Component.MPLC.DataBlocks.DeviceRange.Interfaces;
using System;
using System.Diagnostics;
using System.Globalization;
namespace Mirle.Component.MPLC.DataBlocks.DeviceRange
{
/// <summary>
/// B 設備範圍
/// </summary>
public class BDeviceRange : ITypeDeviceRange
{
/// <summary>
/// 建構式
/// </summary>
/// <param name="startAddress">起始位置</param>
/// <param name="endAddress">結束位置</param>
/// <exception cref="ArgumentException"></exception>
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;
}
/// <summary>
/// 設備類別
/// </summary>
private const string _type = nameof(DeviceType.B);
/// <summary>
/// 起始偏移量
/// </summary>
private readonly int _startOffset;
/// <summary>
/// 結束偏移量
/// </summary>
private readonly int _endOffset;
/// <summary>
/// 起始位置
/// </summary>
public string StartAddress { get; }
/// <summary>
/// 結束位置
/// </summary>
public string EndAddress { get; }
/// <summary>
/// 字元長度
/// </summary>
public int WordLength { get; }
/// <summary>
/// 位元組陣列長度
/// </summary>
/// <value>WordLength * 2</value>
public int ByteArrayLength => WordLength * 2;
/// <summary>
/// 是否為同樣設備範圍
/// </summary>
/// <param name="address">起始位置</param>
/// <returns>True/False</returns>
public bool IsSameRange(string address)
{
return TryGetIndex(address, out _);
}
/// <summary>
/// 是否為同樣設備類別
/// </summary>
/// <param name="address">位置</param>
/// <returns>True/False</returns>
private static bool IsSameType(string address)
{
return address.ToUpper().StartsWith(_type);
}
/// <summary>
/// 取得索引
/// </summary>
/// <param name="address">位置</param>
/// <param name="index">索引</param>
/// <returns>True/False</returns>
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;
}
/// <summary>
/// 取得偏移量
/// </summary>
/// <param name="address">位置</param>
/// <param name="offset">偏移量</param>
/// <returns>True/False</returns>
public bool TryGetOffset(string address, out int offset)
{
if (TryGetIndex(address, out int index))
{
offset = index - _startOffset;
return true;
}
offset = -1;
return false;
}
/// <summary>
/// 取得位元組陣列偏移量
/// </summary>
/// <param name="address">位置</param>
/// <param name="offset">偏移量</param>
/// <returns>True/False</returns>
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;
}
/// <summary>
/// 取得位元組陣列位元索引
/// </summary>
/// <param name="address">位置</param>
/// <param name="index">索引</param>
/// <returns>True/False</returns>
public bool TryGetByteArrayBitIndex(string address, out int index)
{
if (TryGetIndex(address, out int bitIndex))
{
index = (bitIndex - _startOffset) % 16;
return true;
}
index = -1;
return false;
}
}
}