using System;
using WIDESEAWCS_S7Simulator.Core.Interfaces;
namespace WIDESEAWCS_S7Simulator.Core.Memory
{
///
/// M区(位存储器/Merker)实现
///
public class MRegion : MemoryRegion, IMemoryRegion
{
///
/// 区域类型
///
public override string RegionType => "M";
///
/// 构造函数
///
/// 区域大小(字节)
public MRegion(int size) : base(size)
{
}
///
/// 读取位
///
/// 字节偏移
/// 位偏移(0-7)
/// 位值
public bool ReadBit(ushort byteOffset, byte bitOffset)
{
if (bitOffset > 7)
throw new ArgumentOutOfRangeException(nameof(bitOffset), "位偏移必须在0-7之间");
_lock.EnterReadLock();
try
{
if (byteOffset >= Size)
throw new ArgumentOutOfRangeException(nameof(byteOffset), "字节偏移超出范围");
return (_memory[byteOffset] & (1 << bitOffset)) != 0;
}
finally
{
_lock.ExitReadLock();
}
}
///
/// 写入位
///
/// 字节偏移
/// 位偏移(0-7)
/// 位值
public void WriteBit(ushort byteOffset, byte bitOffset, bool value)
{
if (bitOffset > 7)
throw new ArgumentOutOfRangeException(nameof(bitOffset), "位偏移必须在0-7之间");
_lock.EnterWriteLock();
try
{
if (byteOffset >= Size)
throw new ArgumentOutOfRangeException(nameof(byteOffset), "字节偏移超出范围");
if (value)
_memory[byteOffset] |= (byte)(1 << bitOffset);
else
_memory[byteOffset] &= (byte)~(1 << bitOffset);
}
finally
{
_lock.ExitWriteLock();
}
}
///
/// 读取字(Word,2字节)
///
public ushort ReadWord(ushort byteOffset)
{
var data = Read(byteOffset, 2);
return (ushort)((data[0] << 8) | data[1]);
}
///
/// 写入字(Word,2字节)
///
public void WriteWord(ushort byteOffset, ushort value)
{
var data = new byte[] { (byte)(value >> 8), (byte)(value & 0xFF) };
Write(byteOffset, data);
}
///
/// 读取双字(DWord,4字节)
///
public uint ReadDWord(ushort byteOffset)
{
var data = Read(byteOffset, 4);
return (uint)((data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3]);
}
///
/// 写入双字(DWord,4字节)
///
public void WriteDWord(ushort byteOffset, uint value)
{
var data = new byte[] {
(byte)(value >> 24),
(byte)((value >> 16) & 0xFF),
(byte)((value >> 8) & 0xFF),
(byte)(value & 0xFF)
};
Write(byteOffset, data);
}
///
/// 读取整数(Int,2字节,有符号)
///
public short ReadInt(ushort byteOffset)
{
return (short)ReadWord(byteOffset);
}
///
/// 写入整数(Int,2字节,有符号)
///
public void WriteInt(ushort byteOffset, short value)
{
WriteWord(byteOffset, (ushort)value);
}
///
/// 读取双整数(DInt,4字节,有符号)
///
public int ReadDInt(ushort byteOffset)
{
return (int)ReadDWord(byteOffset);
}
///
/// 写入双整数(DInt,4字节,有符号)
///
public void WriteDInt(ushort byteOffset, int value)
{
WriteDWord(byteOffset, (uint)value);
}
///
/// 读取浮点数(Real,4字节)
///
public float ReadReal(ushort byteOffset)
{
var bytes = Read(byteOffset, 4);
return BitConverter.ToSingle(bytes, 0);
}
///
/// 写入浮点数(Real,4字节)
///
public void WriteReal(ushort byteOffset, float value)
{
var bytes = BitConverter.GetBytes(value);
Write(byteOffset, bytes);
}
}
}