Files
StandardSence/StandardScene.Signal/Plc/PlcAddress.cs
T

64 lines
2.1 KiB
C#

using System;
using System.Text.RegularExpressions;
namespace StandardScene.Signal.Plc
{
/// <summary>西门子 DB 字节/位地址拼装与缓冲区位操作。</summary>
internal static class PlcAddress
{
private static readonly Regex Addr = new Regex(
@"^DB(\d+)\.(?:DBB|DBX|DBW)?(\d+)(?:\.(\d+))?$",
RegexOptions.IgnoreCase | RegexOptions.Compiled);
public static string Bit(int db, int absByte, int bit) =>
$"DB{Math.Max(1, db)}.DBX{Math.Max(0, absByte)}.{ClampBit(bit)}";
public static string Byte(int db, int absByte) =>
$"DB{Math.Max(1, db)}.DBB{Math.Max(0, absByte)}";
public static int ClampBit(int bit)
{
if (bit < 0) return 0;
if (bit > 7) return 7;
return bit;
}
public static bool TryParse(string address, out int db, out int absByte, out int bit)
{
db = 0;
absByte = 0;
bit = 0;
if (string.IsNullOrWhiteSpace(address))
return false;
var m = Addr.Match(address.Trim());
if (!m.Success)
return false;
db = int.Parse(m.Groups[1].Value);
absByte = int.Parse(m.Groups[2].Value);
if (m.Groups[3].Success)
bit = ClampBit(int.Parse(m.Groups[3].Value));
return true;
}
public static bool GetBit(byte[] buffer, int originByte, int absByte, int bit)
{
var i = absByte - originByte;
if (buffer == null || i < 0 || i >= buffer.Length)
return false;
return (buffer[i] & (1 << ClampBit(bit))) != 0;
}
public static void SetBit(byte[] buffer, int originByte, int absByte, int bit, bool value)
{
var i = absByte - originByte;
if (buffer == null || i < 0 || i >= buffer.Length)
return;
var mask = (byte)(1 << ClampBit(bit));
if (value)
buffer[i] |= mask;
else
buffer[i] = (byte)(buffer[i] & ~mask);
}
}
}