|
|
using Mirle.Component.MPLC.DataBlocks.DeviceRange.Interfaces; using System; using System.Collections; using System.Diagnostics; using System.IO; using System.IO.MemoryMappedFiles;
namespace Mirle.Component.MPLC.DataBlocks { /// <summary>
/// SM 資料區塊 (Int32)
/// </summary>
public class SMDataBlockInt32 : SMDataBlock { /// <summary>
/// 建構式
/// </summary>
/// <param name="deviceRange">設備範圍介面</param>
/// <param name="sharedMemoryName">共享記憶體名稱</param>
public SMDataBlockInt32(ITypeDeviceRange deviceRange, string sharedMemoryName) : base(deviceRange, sharedMemoryName) { } /// <summary>
/// 起始偏移量
/// </summary>
private readonly int _startOffset = 4; /// <summary>
/// 初始化
/// </summary>
protected override void Initial() { _mmfLength = DeviceRange.ByteArrayLength; #if NET5_0 || NET6_0
if (OperatingSystem.IsWindows()) { _mmf = MemoryMappedFile.CreateOrOpen(_mmfName, _startOffset + (_mmfLength * 2)); } else { _mmf = MemoryMappedFile.CreateFromFile(_mmfName); } #elif NETFRAMEWORK
_mmf = MemoryMappedFile.CreateOrOpen(_mmfName, _startOffset + (_mmfLength * 2)); #else
_mmf = MemoryMappedFile.CreateFromFile(_mmfName); #endif
} /// <summary>
/// 設置原始資料
/// </summary>
/// <param name="newRawData">原始資料</param>
public override void SetRawData(byte[] newRawData) { try { _rwLock.EnterWriteLock(); MemoryMappedViewStream stream = _mmf.CreateViewStream(); using BinaryWriter writer = new BinaryWriter(stream); stream.Seek(_startOffset, SeekOrigin.Begin); for (int i = 0; i < Math.Min(newRawData.Length, _mmfLength); i += 2) { writer.Write(newRawData[i]); writer.Write(newRawData[i + 1]); stream.Seek(2, SeekOrigin.Current); } } finally { _rwLock.ExitWriteLock(); } } /// <summary>
/// 取得原始資料
/// </summary>
/// <returns>原始資料</returns>
public override byte[] GetRawData() { byte[] data = new byte[_mmfLength]; try { _rwLock.EnterReadLock(); MemoryMappedViewStream stream = _mmf.CreateViewStream(); using BinaryReader reader = new BinaryReader(stream); stream.Seek(_startOffset, SeekOrigin.Begin); for (int i = 0; i < _mmfLength; i += 2) { data[i] = reader.ReadByte(); data[i + 1] = reader.ReadByte(); stream.Seek(2, SeekOrigin.Current); } } finally { _rwLock.ExitReadLock(); } return data; } /// <summary>
/// 取得位元
/// </summary>
/// <param name="address">位置</param>
/// <param name="value">是否成功取得</param>
/// <returns>True/False</returns>
public override bool TryGetBit(string address, out bool value) { value = false; try { _rwLock.EnterReadLock(); if (DeviceRange.TryGetByteArrayOffset(address, out int offset) && DeviceRange.TryGetByteArrayBitIndex(address, out int index)) { MemoryMappedViewStream stream = _mmf.CreateViewStream(); using BinaryReader reader = new BinaryReader(stream); stream.Seek(_startOffset + offset * 2, SeekOrigin.Begin); ushort word = reader.ReadUInt16(); BitArray bitArray = new BitArray(BitConverter.GetBytes(word)); value = bitArray.Get(index); return true; } } catch (Exception ex) { Debug.WriteLine($"{ex.Message}-{ex.StackTrace}"); } finally { _rwLock.ExitReadLock(); } return false; } /// <summary>
/// 設置位元
/// </summary>
/// <param name="address">位置</param>
/// <param name="IsOn">是否開啟</param>
/// <returns>True/False</returns>
protected override bool SetBit(string address, bool IsOn) { try { _rwLock.EnterWriteLock(); if (DeviceRange.TryGetByteArrayOffset(address, out int offset) && DeviceRange.TryGetByteArrayBitIndex(address, out int index)) { int startOffset = _startOffset + offset * 2; MemoryMappedViewStream stream = _mmf.CreateViewStream();
using BinaryReader reader = new BinaryReader(stream); stream.Seek(startOffset, SeekOrigin.Begin); ushort word = reader.ReadUInt16(); BitArray bitArray = new BitArray(BitConverter.GetBytes(word)); bitArray.Set(index, IsOn); byte[] tmpBytes = new byte[2]; bitArray.CopyTo(tmpBytes, 0); stream = _mmf.CreateViewStream();
using BinaryWriter writer = new BinaryWriter(stream); stream.Seek(startOffset, SeekOrigin.Begin); writer.Write(tmpBytes[0]); writer.Write(tmpBytes[1]); return true; } } catch (Exception ex) { Debug.WriteLine($"{ex.Message}-{ex.StackTrace}"); } finally { _rwLock.ExitWriteLock(); } return false; } /// <summary>
/// 取得字元
/// </summary>
/// <param name="address">位置</param>
/// <param name="value">值</param>
/// <returns>True/False</returns>
public override bool TryGetWord(string address, out int value) { value = 0; try { _rwLock.EnterReadLock(); if (DeviceRange.TryGetByteArrayOffset(address, out int offset)) { MemoryMappedViewStream stream = _mmf.CreateViewStream(); using BinaryReader reader = new BinaryReader(stream); stream.Seek(_startOffset + offset * 2, SeekOrigin.Begin); value = reader.ReadUInt16(); return true; } } catch (Exception ex) { Debug.WriteLine($"{ex.Message}-{ex.StackTrace}"); } finally { _rwLock.ExitReadLock(); } return false; } /// <summary>
/// 設置字元
/// </summary>
/// <param name="address">位置</param>
/// <param name="value">值</param>
/// <returns>True/False</returns>
public override bool TrySetWord(string address, int value) { try { _rwLock.EnterWriteLock(); if (DeviceRange.TryGetByteArrayOffset(address, out int offset)) { MemoryMappedViewStream stream = _mmf.CreateViewStream(); using var writer = new BinaryWriter(stream); stream.Seek(_startOffset + offset * 2, SeekOrigin.Begin); byte[] tmpBytes = BitConverter.GetBytes(value); writer.Write(tmpBytes[0]); writer.Write(tmpBytes[1]); return true; } } catch (Exception ex) { Debug.WriteLine($"{ex.Message}-{ex.StackTrace}"); } finally { _rwLock.ExitWriteLock(); } return false; } /// <summary>
/// 取得多個字元
/// </summary>
/// <param name="address">位置</param>
/// <param name="data">資料及</param>
/// <param name="length">長度</param>
/// <returns>True/False</returns>
public override bool TryGetWords(string address, out int[] data, int length) { data = new int[length]; try { _rwLock.EnterReadLock(); if (DeviceRange.TryGetByteArrayOffset(address, out int offset)) { MemoryMappedViewStream stream = _mmf.CreateViewStream(); using BinaryReader reader = new BinaryReader(stream); stream.Seek(_startOffset + offset * 2, SeekOrigin.Begin); for (int i = 0; i < length; i++) { data[i] = reader.ReadUInt16(); stream.Seek(2, SeekOrigin.Current); } return true; } } catch (Exception ex) { Debug.WriteLine($"{ex.Message}-{ex.StackTrace}"); } finally { _rwLock.ExitReadLock(); } return false; } /// <summary>
/// 設置多個字元
/// </summary>
/// <param name="address">位置</param>
/// <param name="data">資料集</param>
/// <returns>True/False</returns>
public override bool TrySetWords(string address, int[] data) { try { _rwLock.EnterWriteLock(); if (DeviceRange.TryGetByteArrayOffset(address, out int offset)) { MemoryMappedViewStream stream = _mmf.CreateViewStream(); using BinaryWriter writer = new BinaryWriter(stream); stream.Seek(_startOffset + offset * 2, SeekOrigin.Begin); for (int i = 0; i < data.Length; i++) { byte[] tmpBytes = BitConverter.GetBytes(data[i]); writer.Write(tmpBytes[0]); writer.Write(tmpBytes[1]); stream.Seek(2, SeekOrigin.Current); } return true; } } catch (Exception ex) { Debug.WriteLine($"{ex.Message}-{ex.StackTrace}"); } finally { _rwLock.ExitWriteLock(); } return false; } } }
|