using Apewer.Internals; using System; using System.Collections.Generic; using System.IO; using System.Text; namespace Apewer { /// public class BytesSet { private Dictionary _dict = new Dictionary(); private volatile Func _inbound = null; private volatile Func _outbound = null; /// public byte[] this[string key] { get { return GetValue(key); } set { SetValue(key, value); } } /// 设置或获取值入站的函数,设置时字典必须为空。设置为 Null 将忽略入站函数。 public Func Inbound { get { lock (_dict) return _inbound; } set { lock (_dict) _inbound = value; } } /// 设置或获取值出站的函数。设置为 Null 将忽略出站函数。 public Func Outbound { get { lock (_dict) return _outbound; } set { lock (_dict) _outbound = value; } } /// public int Count { get { var count = 0; lock (_dict) { count = _dict.Count; } return count; } } /// public List Keys { get { var list = new List(); lock (_dict) { list.AddRange(_dict.Keys); } return list; } } /// public BytesSet() { } /// public BytesSet(Func inbound, Func outbound) { _inbound = inbound; _outbound = outbound; } /// public void Clear() { lock (_dict) { foreach (var key in _dict.Keys) { _dict[key] = null; } _dict.Clear(); } } /// public bool Import(byte[] data) { var memory = new MemoryStream(); lock (data) { if (data != null) memory.Write(data, 0, data.Length); BytesUtility.ResetPosition(memory); } if (memory.Length < 4) return false; var count = 0; var first = true; while (true) { if (!CanRead(memory, 4)) break; if (first) { var buffer = new byte[4]; memory.Read(buffer, 0, 4); count = GetInt32(buffer); first = false; } else { // Read Key Length var keylength = 0; { if (!CanRead(memory, 4)) break; var buffer = new byte[4]; memory.Read(buffer, 0, 4); keylength = GetInt32(buffer); } // Read Key Data var key = Constant.EmptyString; if (keylength > 1) { if (!CanRead(memory, keylength)) break; var buffer = new byte[keylength]; memory.Read(buffer, 0, keylength); key = BytesUtility.ToText(buffer); } // Read Value Length var valuelength = 0; { if (!CanRead(memory, 4)) break; var buffer = new byte[4]; memory.Read(buffer, 0, 4); valuelength = GetInt32(buffer); } // Read Key Data var value = Constant.EmptyBytes; if (valuelength > 1) { if (!CanRead(memory, valuelength)) break; var buffer = new byte[valuelength]; memory.Read(buffer, 0, valuelength); value = BytesUtility.Clone(buffer); } if (_dict.ContainsKey(key)) continue; _dict.Add(key, value); if (_dict.Count >= count) break; } } return count == _dict.Count; } /// public byte[] Export() { var memory = new MemoryStream(); lock (_dict) { var count = _dict.Count; var countbytes = GetBytes(count); memory.Write(countbytes, 0, countbytes.Length); foreach (var pair in _dict) { var keydata = BytesUtility.FromText(pair.Key); var keycount = GetBytes(keydata.Length); memory.Write(keycount, 0, keycount.Length); if (keydata.Length > 0) memory.Write(keydata, 0, keydata.Length); var valuedata = pair.Value ?? Constant.EmptyBytes; var valuecount = GetBytes(valuedata.Length); memory.Write(valuecount, 0, valuecount.Length); if (valuedata.Length > 0) memory.Write(valuedata, 0, valuedata.Length); } } var data = memory.ToArray(); memory.Dispose(); return data; } /// public bool Contains(string key) { if (key == null) return false; var contains = false; lock (_dict) { contains = _dict.ContainsKey(key); } return contains; } /// public byte[] GetValue(string key) { var k = key; var v = Constant.EmptyBytes; if (k == null) return v; lock (_dict) { if (_dict.ContainsKey(k)) v = _dict[k]; } if (_outbound != null) { v = _outbound(v); if (v == null) v = Constant.EmptyBytes; } return v; } /// public bool SetValue(string key, byte[] value) { var k = key; var v = Constant.EmptyBytes; if (k == null) return false; lock (value) { if (value != null) v = BytesUtility.Clone(value); } if (_inbound != null) { v = _inbound(v); if (v == null) v = Constant.EmptyBytes; } lock (_dict) { if (_dict.ContainsKey(k)) _dict.Remove(k); _dict.Add(k, v); } return true; } private static bool CanRead(Stream stream, int length) { if (length < 0) return false; if (stream == null) return false; if (stream.CanRead == false) return false; if (stream.Position + length > stream.Length) return false; return true; } /// Int32 -> Byte[] private static byte[] GetBytes(int value) { const int t3 = 256 * 256 * 256; const int t2 = 256 * 256; const int t1 = 256; byte[] bs = { 0, 0, 0, 0 }; if (value >= 0) { int vint = value; bs[0] = (byte)(vint / t3); vint = vint % t3; bs[1] = (byte)(vint / t2); vint = vint % t2; bs[2] = (byte)(vint / t1); vint = vint % t1; bs[3] = (byte)(vint); } else { int minusInt = Math.Abs(value + 1); var minusBytes = GetBytes(minusInt); bs[0] = (byte)(255 - minusBytes[0]); bs[1] = (byte)(255 - minusBytes[1]); bs[2] = (byte)(255 - minusBytes[2]); bs[3] = (byte)(255 - minusBytes[3]); } return bs; } /// Byte[] -> Int32 private static Int32 GetInt32(byte[] value) { if (value.Length == 4) { const int t3 = 256 * 256 * 256; const int t2 = 256 * 256; const int t1 = 256; if (value[0] <= 127) { int[] vis = { 0, 0, 0, 0 }; vis[0] = value[0] * t3; vis[1] = value[1] * t2; vis[2] = value[2] * t1; vis[3] = value[3]; int vr = vis[0] + vis[1] + vis[2] + vis[3]; return vr; } else { if ((value[0] == 128) && (value[1] == 0) && (value[2] == 0) && (value[3] == 0)) { return int.MinValue; } else { var bytes = new byte[4]; bytes[0] = (byte)(255 - value[0]); bytes[1] = (byte)(255 - value[1]); bytes[2] = (byte)(255 - value[2]); bytes[3] = (byte)(255 - value[3]); int vminusint = 0 - 1 - GetInt32(bytes); return vminusint; } } } return 0; } } }