From 939e343f3a1fd8f6109b16de3e84bcf6294cea2c Mon Sep 17 00:00:00 2001
From: wanshenmean <cathay_xy@163.com>
Date: 星期五, 13 三月 2026 13:32:35 +0800
Subject: [PATCH] feat: implement MemoryStore with address-based access
---
Code/WCS/WIDESEAWCS_S7Simulator/WIDESEAWCS_S7Simulator.Core/Interfaces/IMemoryStore.cs | 67 +++++
Code/WCS/WIDESEAWCS_S7Simulator/WIDESEAWCS_S7Simulator.Core/Memory/MemoryStore.cs | 605 ++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 672 insertions(+), 0 deletions(-)
diff --git a/Code/WCS/WIDESEAWCS_S7Simulator/WIDESEAWCS_S7Simulator.Core/Interfaces/IMemoryStore.cs b/Code/WCS/WIDESEAWCS_S7Simulator/WIDESEAWCS_S7Simulator.Core/Interfaces/IMemoryStore.cs
new file mode 100644
index 0000000..ed2a25e
--- /dev/null
+++ b/Code/WCS/WIDESEAWCS_S7Simulator/WIDESEAWCS_S7Simulator.Core/Interfaces/IMemoryStore.cs
@@ -0,0 +1,67 @@
+using System;
+using System.Collections.Generic;
+
+namespace WIDESEAWCS_S7Simulator.Core.Interfaces
+{
+ /// <summary>
+ /// 鍐呭瓨瀛樺偍鎺ュ彛
+ /// 鎻愪緵缁熶竴鐨勫唴瀛樿闂帴鍙o紝鏀寔鍦板潃鏍煎紡璇诲啓
+ /// </summary>
+ public interface IMemoryStore : IDisposable
+ {
+ /// <summary>
+ /// 璇诲彇瀛楄妭鏁版嵁
+ /// </summary>
+ /// <param name="address">鍦板潃锛堝 "M100", "DB1.DBD0", "I0.0", "T1"锛�</param>
+ /// <param name="length">闀垮害</param>
+ /// <returns>瀛楄妭鏁扮粍</returns>
+ byte[] ReadBytes(string address, ushort length);
+
+ /// <summary>
+ /// 璇诲彇鎸囧畾绫诲瀷鏁版嵁
+ /// </summary>
+ /// <typeparam name="T">鍊肩被鍨�</typeparam>
+ /// <param name="address">鍦板潃</param>
+ /// <returns>鏁版嵁鍊�</returns>
+ T Read<T>(string address) where T : struct;
+
+ /// <summary>
+ /// 鍐欏叆瀛楄妭鏁版嵁
+ /// </summary>
+ /// <param name="address">鍦板潃</param>
+ /// <param name="data">鏁版嵁</param>
+ void WriteBytes(string address, byte[] data);
+
+ /// <summary>
+ /// 鍐欏叆鎸囧畾绫诲瀷鏁版嵁
+ /// </summary>
+ /// <typeparam name="T">鍊肩被鍨�</typeparam>
+ /// <param name="address">鍦板潃</param>
+ /// <param name="value">鏁版嵁鍊�</param>
+ void Write<T>(string address, T value) where T : struct;
+
+ /// <summary>
+ /// 鑾峰彇鍐呭瓨鍖哄煙
+ /// </summary>
+ /// <param name="regionType">鍖哄煙绫诲瀷锛圡/DB/I/Q/T/C锛�</param>
+ /// <returns>鍐呭瓨鍖哄煙鎺ュ彛</returns>
+ IMemoryRegion GetRegion(string regionType);
+
+ /// <summary>
+ /// 娓呯┖鎵�鏈夊唴瀛�
+ /// </summary>
+ void Clear();
+
+ /// <summary>
+ /// 瀵煎嚭鍐呭瓨鏁版嵁
+ /// </summary>
+ /// <returns>鍖哄煙绫诲瀷 -> 瀛楄妭鏁扮粍鐨勫瓧鍏�</returns>
+ Dictionary<string, byte[]> Export();
+
+ /// <summary>
+ /// 瀵煎叆鍐呭瓨鏁版嵁
+ /// </summary>
+ /// <param name="data">鍖哄煙绫诲瀷 -> 瀛楄妭鏁扮粍鐨勫瓧鍏�</param>
+ void Import(Dictionary<string, byte[]> data);
+ }
+}
diff --git a/Code/WCS/WIDESEAWCS_S7Simulator/WIDESEAWCS_S7Simulator.Core/Memory/MemoryStore.cs b/Code/WCS/WIDESEAWCS_S7Simulator/WIDESEAWCS_S7Simulator.Core/Memory/MemoryStore.cs
new file mode 100644
index 0000000..73f5cc4
--- /dev/null
+++ b/Code/WCS/WIDESEAWCS_S7Simulator/WIDESEAWCS_S7Simulator.Core/Memory/MemoryStore.cs
@@ -0,0 +1,605 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using WIDESEAWCS_S7Simulator.Core.Entities;
+using WIDESEAWCS_S7Simulator.Core.Interfaces;
+
+namespace WIDESEAWCS_S7Simulator.Core.Memory
+{
+ /// <summary>
+ /// 鍐呭瓨瀛樺偍瀹炵幇
+ /// 绠$悊鎵�鏈塖7 PLC鍐呭瓨鍖哄煙锛屾彁渚涚粺涓�鐨勫湴鍧�璁块棶鎺ュ彛
+ /// </summary>
+ public class MemoryStore : IMemoryStore
+ {
+ /// <summary>
+ /// 鏍囪瘑瀵硅薄鏄惁宸茶閲婃斁
+ /// </summary>
+ private bool _disposed = false;
+
+ /// <summary>
+ /// M鍖猴紙浣嶅瓨鍌ㄥ櫒锛�
+ /// </summary>
+ private readonly MRegion _mRegion;
+
+ /// <summary>
+ /// DB鍖猴紙鏁版嵁鍧楋級
+ /// </summary>
+ private readonly DBRegion _dbRegion;
+
+ /// <summary>
+ /// I鍖猴紙杈撳叆鍖猴級
+ /// </summary>
+ private readonly IRegion _iRegion;
+
+ /// <summary>
+ /// Q鍖猴紙杈撳嚭鍖猴級
+ /// </summary>
+ private readonly QRegion _qRegion;
+
+ /// <summary>
+ /// T鍖猴紙瀹氭椂鍣ㄥ尯锛�
+ /// </summary>
+ private readonly TRegion _tRegion;
+
+ /// <summary>
+ /// C鍖猴紙璁℃暟鍣ㄥ尯锛�
+ /// </summary>
+ private readonly CRegion _cRegion;
+
+ /// <summary>
+ /// 鍐呭瓨鍖哄煙閰嶇疆
+ /// </summary>
+ private readonly MemoryRegionConfig _config;
+
+ /// <summary>
+ /// 鏋勯�犲嚱鏁�
+ /// </summary>
+ /// <param name="config">鍐呭瓨鍖哄煙閰嶇疆</param>
+ public MemoryStore(MemoryRegionConfig config)
+ {
+ _config = config ?? throw new ArgumentNullException(nameof(config));
+
+ _mRegion = new MRegion(config.MRegionSize);
+ _dbRegion = new DBRegion(1, config.DBBlockSize);
+ _iRegion = new IRegion(config.IRegionSize);
+ _qRegion = new QRegion(config.QRegionSize);
+ _tRegion = new TRegion(config.TRegionCount);
+ _cRegion = new CRegion(config.CRegionCount);
+ }
+
+ /// <summary>
+ /// 璇诲彇瀛楄妭鏁版嵁
+ /// </summary>
+ public byte[] ReadBytes(string address, ushort length)
+ {
+ if (_disposed)
+ throw new ObjectDisposedException(nameof(MemoryStore));
+
+ if (string.IsNullOrEmpty(address))
+ throw new ArgumentException("鍦板潃涓嶈兘涓虹┖", nameof(address));
+
+ var (regionType, offset, dbNumber, bitOffset) = ParseAddress(address);
+
+ return regionType switch
+ {
+ "M" => _mRegion.Read(offset, length),
+ "DB" => _dbRegion.Read(dbNumber.Value, offset, length),
+ "I" => _iRegion.Read(offset, length),
+ "Q" => _qRegion.Read(offset, length),
+ "T" => throw new NotSupportedException("T鍖轰笉鏀寔鐩存帴璇诲彇瀛楄妭锛岃浣跨敤Read<T>"),
+ "C" => throw new NotSupportedException("C鍖轰笉鏀寔鐩存帴璇诲彇瀛楄妭锛岃浣跨敤Read<T>"),
+ _ => throw new ArgumentException($"涓嶆敮鎸佺殑鍦板潃鍖哄煙: {regionType}")
+ };
+ }
+
+ /// <summary>
+ /// 璇诲彇鎸囧畾绫诲瀷鏁版嵁
+ /// </summary>
+ public T Read<T>(string address) where T : struct
+ {
+ if (_disposed)
+ throw new ObjectDisposedException(nameof(MemoryStore));
+
+ if (string.IsNullOrEmpty(address))
+ throw new ArgumentException("鍦板潃涓嶈兘涓虹┖", nameof(address));
+
+ var (regionType, offset, dbNumber, bitOffset) = ParseAddress(address);
+
+ return regionType switch
+ {
+ "M" => ReadMRegion<T>(offset),
+ "DB" => ReadDBRegion<T>(dbNumber.Value, offset),
+ "I" => ReadIRegion<T>(offset, bitOffset),
+ "Q" => ReadQRegion<T>(offset, bitOffset),
+ "T" => ReadTRegion<T>(offset),
+ "C" => ReadCRegion<T>(offset),
+ _ => throw new ArgumentException($"涓嶆敮鎸佺殑鍦板潃鍖哄煙: {regionType}")
+ };
+ }
+
+ /// <summary>
+ /// 鍐欏叆瀛楄妭鏁版嵁
+ /// </summary>
+ public void WriteBytes(string address, byte[] data)
+ {
+ if (_disposed)
+ throw new ObjectDisposedException(nameof(MemoryStore));
+
+ if (string.IsNullOrEmpty(address))
+ throw new ArgumentException("鍦板潃涓嶈兘涓虹┖", nameof(address));
+
+ if (data == null)
+ throw new ArgumentNullException(nameof(data));
+
+ var (regionType, offset, dbNumber, bitOffset) = ParseAddress(address);
+
+ switch (regionType)
+ {
+ case "M":
+ _mRegion.Write(offset, data);
+ break;
+ case "DB":
+ _dbRegion.Write(dbNumber.Value, offset, data);
+ break;
+ case "I":
+ _iRegion.Write(offset, data);
+ break;
+ case "Q":
+ _qRegion.Write(offset, data);
+ break;
+ case "T":
+ throw new NotSupportedException("T鍖轰笉鏀寔鐩存帴鍐欏叆瀛楄妭");
+ case "C":
+ throw new NotSupportedException("C鍖轰笉鏀寔鐩存帴鍐欏叆瀛楄妭");
+ default:
+ throw new ArgumentException($"涓嶆敮鎸佺殑鍦板潃鍖哄煙: {regionType}");
+ }
+ }
+
+ /// <summary>
+ /// 鍐欏叆鎸囧畾绫诲瀷鏁版嵁
+ /// </summary>
+ public void Write<T>(string address, T value) where T : struct
+ {
+ if (_disposed)
+ throw new ObjectDisposedException(nameof(MemoryStore));
+
+ if (string.IsNullOrEmpty(address))
+ throw new ArgumentException("鍦板潃涓嶈兘涓虹┖", nameof(address));
+
+ var (regionType, offset, dbNumber, bitOffset) = ParseAddress(address);
+
+ switch (regionType)
+ {
+ case "M":
+ WriteMRegion(offset, value);
+ break;
+ case "DB":
+ WriteDBRegion(dbNumber.Value, offset, value);
+ break;
+ case "I":
+ WriteIRegion(offset, bitOffset, value);
+ break;
+ case "Q":
+ WriteQRegion(offset, bitOffset, value);
+ break;
+ case "T":
+ WriteTRegion(offset, value);
+ break;
+ case "C":
+ WriteCRegion(offset, value);
+ break;
+ default:
+ throw new ArgumentException($"涓嶆敮鎸佺殑鍦板潃鍖哄煙: {regionType}");
+ }
+ }
+
+ /// <summary>
+ /// 鑾峰彇鍐呭瓨鍖哄煙
+ /// </summary>
+ public IMemoryRegion GetRegion(string regionType)
+ {
+ if (_disposed)
+ throw new ObjectDisposedException(nameof(MemoryStore));
+
+ return regionType.ToUpper() switch
+ {
+ "M" => _mRegion,
+ "DB" => _dbRegion,
+ "I" => _iRegion,
+ "Q" => _qRegion,
+ "T" => _tRegion,
+ "C" => _cRegion,
+ _ => throw new ArgumentException($"涓嶆敮鎸佺殑鍐呭瓨鍖哄煙: {regionType}")
+ };
+ }
+
+ /// <summary>
+ /// 娓呯┖鎵�鏈夊唴瀛�
+ /// </summary>
+ public void Clear()
+ {
+ if (_disposed)
+ throw new ObjectDisposedException(nameof(MemoryStore));
+
+ _mRegion.Clear();
+ _dbRegion.Clear();
+ _iRegion.Clear();
+ _qRegion.Clear();
+ _tRegion.Clear();
+ _cRegion.Clear();
+ }
+
+ /// <summary>
+ /// 瀵煎嚭鍐呭瓨鏁版嵁
+ /// </summary>
+ public Dictionary<string, byte[]> Export()
+ {
+ if (_disposed)
+ throw new ObjectDisposedException(nameof(MemoryStore));
+
+ return new Dictionary<string, byte[]>
+ {
+ ["M"] = _mRegion.Read(0, (ushort)_mRegion.Size),
+ ["DB"] = ExportDBRegion(),
+ ["I"] = _iRegion.Read(0, (ushort)_iRegion.Size),
+ ["Q"] = _qRegion.Read(0, (ushort)_qRegion.Size),
+ ["T"] = _tRegion.Read(0, (ushort)_tRegion.Size),
+ ["C"] = _cRegion.Read(0, (ushort)_cRegion.Size)
+ };
+ }
+
+ /// <summary>
+ /// 瀵煎叆鍐呭瓨鏁版嵁
+ /// </summary>
+ public void Import(Dictionary<string, byte[]> data)
+ {
+ if (_disposed)
+ throw new ObjectDisposedException(nameof(MemoryStore));
+
+ if (data == null)
+ throw new ArgumentNullException(nameof(data));
+
+ if (data.ContainsKey("M"))
+ _mRegion.Write(0, data["M"]);
+ if (data.ContainsKey("DB"))
+ ImportDBRegion(data["DB"]);
+ if (data.ContainsKey("I"))
+ _iRegion.Write(0, data["I"]);
+ if (data.ContainsKey("Q"))
+ _qRegion.Write(0, data["Q"]);
+ if (data.ContainsKey("T"))
+ _tRegion.Write(0, data["T"]);
+ if (data.ContainsKey("C"))
+ _cRegion.Write(0, data["C"]);
+ }
+
+ /// <summary>
+ /// 瑙f瀽S7鍦板潃鏍煎紡
+ /// 鏀寔鏍煎紡: M100, DB1.DBD0, I0.0, Q0.0, T1, C1
+ /// </summary>
+ private (string regionType, ushort offset, ushort? dbNumber, byte? bitOffset) ParseAddress(string address)
+ {
+ address = address.Trim().ToUpper();
+
+ // DB鍧楀湴鍧�: DB1.DBD0, DB1.DBW10, DB1.DBB20
+ if (address.StartsWith("DB"))
+ {
+ var parts = address.Split(new[] { '.' }, 2);
+ var dbPart = parts[0]; // DB1
+ var offsetPart = parts.Length > 1 ? parts[1] : null; // DBD0, DBW10, etc.
+
+ var dbNumber = ushort.Parse(dbPart.Substring(2));
+ ushort offset = 0;
+
+ if (offsetPart != null)
+ {
+ // 瑙f瀽鍋忕Щ绫诲瀷: DBD(4瀛楄妭), DBW(2瀛楄妭), DBB(1瀛楄妭)
+ if (offsetPart.StartsWith("DBD"))
+ offset = ushort.Parse(offsetPart.Substring(3));
+ else if (offsetPart.StartsWith("DBW"))
+ offset = ushort.Parse(offsetPart.Substring(3));
+ else if (offsetPart.StartsWith("DBB"))
+ offset = ushort.Parse(offsetPart.Substring(3));
+ else
+ offset = ushort.Parse(offsetPart);
+ }
+
+ return ("DB", offset, dbNumber, null);
+ }
+
+ // 甯︿綅鍦板潃: I0.0, Q0.0, M0.0
+ if (address.Contains("."))
+ {
+ var parts = address.Split('.');
+ var regionType = new string(parts[0].TakeWhile(char.IsLetter).ToArray());
+ var byteOffset = ushort.Parse(new string(parts[0].SkipWhile(char.IsLetter).ToArray()));
+ var bitOffset = byte.Parse(parts[1]);
+
+ return (regionType, byteOffset, null, (byte?)bitOffset);
+ }
+
+ // 瀹氭椂鍣�/璁℃暟鍣�: T1, C1
+ if (address.StartsWith("T") || address.StartsWith("C"))
+ {
+ var regionType = address[0].ToString();
+ var number = ushort.Parse(address.Substring(1));
+ return (regionType, number, null, null);
+ }
+
+ // 鏅�氬湴鍧�: M100, I100, Q100
+ var region = new string(address.TakeWhile(char.IsLetter).ToArray());
+ var addr = ushort.Parse(new string(address.SkipWhile(char.IsLetter).ToArray()));
+ return (region, addr, null, null);
+ }
+
+ /// <summary>
+ /// 璇诲彇M鍖烘暟鎹�
+ /// </summary>
+ private T ReadMRegion<T>(ushort offset) where T : struct
+ {
+ var size = System.Runtime.InteropServices.Marshal.SizeOf<T>();
+ var data = _mRegion.Read(offset, (ushort)size);
+
+ if (typeof(T) == typeof(bool))
+ return default; // M鍖轰笉鏀寔bool璇诲彇锛屽簲璇ョ敤Mx.x鏍煎紡
+
+ return ConvertFromBytes<T>(data);
+ }
+
+ /// <summary>
+ /// 璇诲彇DB鍖烘暟鎹�
+ /// </summary>
+ private T ReadDBRegion<T>(ushort dbNumber, ushort offset) where T : struct
+ {
+ return typeof(T).Name switch
+ {
+ "Boolean" => (T)(object)_dbRegion.ReadBool(dbNumber, offset, 0),
+ "Int16" => (T)(object)_dbRegion.ReadInt(dbNumber, offset),
+ "Int32" => (T)(object)_dbRegion.ReadDInt(dbNumber, offset),
+ "Single" => (T)(object)_dbRegion.ReadReal(dbNumber, offset),
+ "String" => (T)(object)_dbRegion.ReadString(dbNumber, offset, 254),
+ _ => ConvertFromBytes<T>(_dbRegion.Read(dbNumber, offset, (ushort)System.Runtime.InteropServices.Marshal.SizeOf<T>()))
+ };
+ }
+
+ /// <summary>
+ /// 璇诲彇I鍖烘暟鎹�
+ /// </summary>
+ private T ReadIRegion<T>(ushort offset, byte? bitOffset) where T : struct
+ {
+ if (typeof(T) == typeof(bool) && bitOffset.HasValue)
+ return (T)(object)_iRegion.ReadBit(offset, bitOffset.Value);
+
+ var size = System.Runtime.InteropServices.Marshal.SizeOf<T>();
+ var data = _iRegion.Read(offset, (ushort)size);
+ return ConvertFromBytes<T>(data);
+ }
+
+ /// <summary>
+ /// 璇诲彇Q鍖烘暟鎹�
+ /// </summary>
+ private T ReadQRegion<T>(ushort offset, byte? bitOffset) where T : struct
+ {
+ if (typeof(T) == typeof(bool) && bitOffset.HasValue)
+ return (T)(object)_qRegion.ReadBit(offset, bitOffset.Value);
+
+ var size = System.Runtime.InteropServices.Marshal.SizeOf<T>();
+ var data = _qRegion.Read(offset, (ushort)size);
+ return ConvertFromBytes<T>(data);
+ }
+
+ /// <summary>
+ /// 璇诲彇T鍖烘暟鎹�
+ /// </summary>
+ private T ReadTRegion<T>(ushort timerNumber) where T : struct
+ {
+ return (T)(object)_tRegion.ReadTimer(timerNumber);
+ }
+
+ /// <summary>
+ /// 璇诲彇C鍖烘暟鎹�
+ /// </summary>
+ private T ReadCRegion<T>(ushort counterNumber) where T : struct
+ {
+ return (T)(object)_cRegion.ReadCounter(counterNumber);
+ }
+
+ /// <summary>
+ /// 鍐欏叆M鍖烘暟鎹�
+ /// </summary>
+ private void WriteMRegion<T>(ushort offset, T value) where T : struct
+ {
+ var data = ConvertToBytes(value);
+ _mRegion.Write(offset, data);
+ }
+
+ /// <summary>
+ /// 鍐欏叆DB鍖烘暟鎹�
+ /// </summary>
+ private void WriteDBRegion<T>(ushort dbNumber, ushort offset, T value) where T : struct
+ {
+ switch (typeof(T).Name)
+ {
+ case "Boolean":
+ _dbRegion.WriteBool(dbNumber, offset, 0, (bool)(object)value);
+ break;
+ case "Int16":
+ _dbRegion.WriteInt(dbNumber, offset, (short)(object)value);
+ break;
+ case "Int32":
+ _dbRegion.WriteDInt(dbNumber, offset, (int)(object)value);
+ break;
+ case "Single":
+ _dbRegion.WriteReal(dbNumber, offset, (float)(object)value);
+ break;
+ case "String":
+ _dbRegion.WriteString(dbNumber, offset, (string)(object)value, 254);
+ break;
+ default:
+ var data = ConvertToBytes(value);
+ _dbRegion.Write(dbNumber, offset, data);
+ break;
+ }
+ }
+
+ /// <summary>
+ /// 鍐欏叆I鍖烘暟鎹�
+ /// </summary>
+ private void WriteIRegion<T>(ushort offset, byte? bitOffset, T value) where T : struct
+ {
+ if (typeof(T) == typeof(bool) && bitOffset.HasValue)
+ {
+ _iRegion.WriteBit(offset, bitOffset.Value, (bool)(object)value);
+ return;
+ }
+
+ var data = ConvertToBytes(value);
+ _iRegion.Write(offset, data);
+ }
+
+ /// <summary>
+ /// 鍐欏叆Q鍖哄尯鏁版嵁
+ /// </summary>
+ private void WriteQRegion<T>(ushort offset, byte? bitOffset, T value) where T : struct
+ {
+ if (typeof(T) == typeof(bool) && bitOffset.HasValue)
+ {
+ _qRegion.WriteBit(offset, bitOffset.Value, (bool)(object)value);
+ return;
+ }
+
+ var data = ConvertToBytes(value);
+ _qRegion.Write(offset, data);
+ }
+
+ /// <summary>
+ /// 鍐欏叆T鍖烘暟鎹�
+ /// </summary>
+ private void WriteTRegion<T>(ushort timerNumber, T value) where T : struct
+ {
+ _tRegion.WriteTimer(timerNumber, (ushort)(object)value);
+ }
+
+ /// <summary>
+ /// 鍐欏叆C鍖烘暟鎹�
+ /// </summary>
+ private void WriteCRegion<T>(ushort counterNumber, T value) where T : struct
+ {
+ _cRegion.WriteCounter(counterNumber, (ushort)(object)value);
+ }
+
+ /// <summary>
+ /// 浠庡瓧鑺傛暟缁勮浆鎹负鍊肩被鍨�
+ /// </summary>
+ private T ConvertFromBytes<T>(byte[] data) where T : struct
+ {
+ if (typeof(T) == typeof(short))
+ return (T)(object)(short)((data[0] << 8) | data[1]);
+
+ if (typeof(T) == typeof(int))
+ return (T)(object)((data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3]);
+
+ if (typeof(T) == typeof(ushort))
+ return (T)(object)((ushort)((data[0] << 8) | data[1]));
+
+ if (typeof(T) == typeof(float))
+ return (T)(object)BitConverter.ToSingle(data, 0);
+
+ return default;
+ }
+
+ /// <summary>
+ /// 灏嗗�肩被鍨嬭浆鎹负瀛楄妭鏁扮粍
+ /// </summary>
+ private byte[] ConvertToBytes<T>(T value) where T : struct
+ {
+ if (typeof(T) == typeof(short))
+ return new[] { (byte)((short)(object)value >> 8), (byte)((short)(object)value & 0xFF) };
+
+ if (typeof(T) == typeof(int))
+ return new[] {
+ (byte)((int)(object)value >> 24),
+ (byte)(((int)(object)value >> 16) & 0xFF),
+ (byte)(((int)(object)value >> 8) & 0xFF),
+ (byte)((int)(object)value & 0xFF)
+ };
+
+ if (typeof(T) == typeof(ushort))
+ return new[] { (byte)((ushort)(object)value >> 8), (byte)((ushort)(object)value & 0xFF) };
+
+ if (typeof(T) == typeof(float))
+ return BitConverter.GetBytes((float)(object)value);
+
+ if (typeof(T) == typeof(bool))
+ return new[] { (byte)((bool)(object)value ? 1 : 0) };
+
+ throw new NotSupportedException($"涓嶆敮鎸佺殑绫诲瀷: {typeof(T).Name}");
+ }
+
+ /// <summary>
+ /// 瀵煎嚭DB鍖烘暟鎹�
+ /// </summary>
+ private byte[] ExportDBRegion()
+ {
+ // 绠�鍖栫増鏈細瀵煎嚭鎵�鏈塂B鍧楃殑杩炵画鏁版嵁
+ // 瀹為檯瀹炵幇鍙兘闇�瑕佹洿澶嶆潅鐨勫簭鍒楀寲鏍煎紡
+ var result = new List<byte>();
+ for (ushort i = 1; i <= _config.DBBlockCount; i++)
+ {
+ var blockData = _dbRegion.Read(i, 0, (ushort)_config.DBBlockSize);
+ result.AddRange(blockData);
+ }
+ return result.ToArray();
+ }
+
+ /// <summary>
+ /// 瀵煎叆DB鍖烘暟鎹�
+ /// </summary>
+ private void ImportDBRegion(byte[] data)
+ {
+ // 绠�鍖栫増鏈細鎸夐『搴忓鍏ユ墍鏈塂B鍧�
+ int offset = 0;
+ for (ushort i = 1; i <= _config.DBBlockCount && offset < data.Length; i++)
+ {
+ var blockSize = Math.Min(_config.DBBlockSize, data.Length - offset);
+ var blockData = new byte[blockSize];
+ Array.Copy(data, offset, blockData, 0, blockSize);
+ _dbRegion.Write(i, 0, blockData);
+ offset += blockSize;
+ }
+ }
+
+ /// <summary>
+ /// 閲婃斁璧勬簮
+ /// </summary>
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ /// <summary>
+ /// 閲婃斁璧勬簮
+ /// </summary>
+ /// <param name="disposing">鏄惁姝e湪閲婃斁鎵樼璧勬簮</param>
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!_disposed)
+ {
+ if (disposing)
+ {
+ _mRegion?.Dispose();
+ _dbRegion?.Dispose();
+ _iRegion?.Dispose();
+ _qRegion?.Dispose();
+ _tRegion?.Dispose();
+ _cRegion?.Dispose();
+ }
+ _disposed = true;
+ }
+ }
+ }
+}
--
Gitblit v1.9.3