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