|
|
using Apewer; using System; using System.Collections.Generic; using System.IO; using System.Text;
namespace Apewer.Internals {
internal class BytesDictionary {
private Dictionary<string, byte[]> _dict = new Dictionary<string, byte[]>();
private volatile Func<byte[], byte[]> _valueinbound = null; private volatile Func<byte[], byte[]> _valueoutbound = null;
/// <summary>设置或获取值入站的函数,设置时字典必须为空。设置为 Null 将忽略入站函数。</summary>
public Func<byte[], byte[]> Inbound { get { lock (_dict) return _valueinbound; } set { lock (_dict) _valueinbound = value; } }
/// <summary>设置或获取值出站的函数。设置为 Null 将忽略出站函数。</summary>
public Func<byte[], byte[]> Outbound { get { lock (_dict) return _valueoutbound; } set { lock (_dict) _valueoutbound = value; } }
public int Count { get { var count = 0; lock (_dict) { count = _dict.Count; } return count; } }
public List<string> Keys { get { var list = new List<string>(); lock (_dict) { list.AddRange(_dict.Keys); } return list; } }
public void Clear() { lock (_dict) { foreach (var key in _dict.Keys) { _dict[key] = null; } _dict.Clear(); } }
public bool Import(byte[] argData) { var memory = new MemoryStream(); lock (argData) { if (argData != null) memory.Write(argData, 0, argData.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 = TextUtility.FromBytes(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 = TextUtility.Bytes(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 argKey) { if (argKey == null) return false; var contains = false; lock (_dict) { contains = _dict.ContainsKey(argKey); } return contains; }
public byte[] GetValue(string argKey) { var key = argKey; var value = Constant.EmptyBytes; if (key == null) return value; lock (_dict) { if (_dict.ContainsKey(key)) value = _dict[key]; } if (_valueoutbound != null) { value = _valueoutbound(value); if (value == null) value = Constant.EmptyBytes; } return value; }
public bool SetValue(string argKey, byte[] argValue) { var key = argKey; var value = Constant.EmptyBytes; if (key == null) return false; lock (argValue) { if (argValue != null) value = BytesUtility.Clone(argValue); } if (_valueinbound != null) { value = _valueinbound(value); if (value == null) value = Constant.EmptyBytes; } lock (_dict) { if (_dict.ContainsKey(key)) _dict.Remove(key); _dict.Add(key, value); } return true; }
public BytesDictionary() { }
public BytesDictionary(Func<byte[], byte[]> argValueInbound, Func<byte[], byte[]> argValueOutbound) { _valueinbound = argValueInbound; _valueoutbound = argValueOutbound; }
private static bool CanRead(Stream argStream, int argLength) { if (argLength < 0) return false; if (argStream == null) return false; if (argStream.CanRead == false) return false; if (argStream.Position + argLength > argStream.Length) return false; return true; }
/// <summary>Int32 -> Byte[]</summary>
private static byte[] GetBytes(int argValue) { const int t3 = 256 * 256 * 256; const int t2 = 256 * 256; const int t1 = 256;
byte[] vbs = { 0, 0, 0, 0 };
if (argValue >= 0) { int vint = argValue;
vbs[0] = (byte)(vint / t3); vint = vint % t3;
vbs[1] = (byte)(vint / t2); vint = vint % t2;
vbs[2] = (byte)(vint / t1); vint = vint % t1;
vbs[3] = (byte)(vint); } else { int vminusint = Math.Abs(argValue + 1); var vminusbs = GetBytes(vminusint); vbs[0] = (byte)(255 - vminusbs[0]); vbs[1] = (byte)(255 - vminusbs[1]); vbs[2] = (byte)(255 - vminusbs[2]); vbs[3] = (byte)(255 - vminusbs[3]); }
return vbs; }
/// <summary>Byte[] -> Int32</summary>
private static Int32 GetInt32(byte[] argValue) { if (argValue.Length == 4) { const int t3 = 256 * 256 * 256; const int t2 = 256 * 256; const int t1 = 256;
if (argValue[0] <= 127) { int[] vis = { 0, 0, 0, 0 }; vis[0] = argValue[0] * t3; vis[1] = argValue[1] * t2; vis[2] = argValue[2] * t1; vis[3] = argValue[3]; int vr = vis[0] + vis[1] + vis[2] + vis[3]; return vr; } else { if ((argValue[0] == 128) && (argValue[1] == 0) && (argValue[2] == 0) && (argValue[3] == 0)) { return int.MinValue; } else { var vbs = new byte[4]; vbs[0] = (byte)(255 - argValue[0]); vbs[1] = (byte)(255 - argValue[1]); vbs[2] = (byte)(255 - argValue[2]); vbs[3] = (byte)(255 - argValue[3]); int vminusint = 0 - 1 - GetInt32(vbs); return vminusint; } } } return 0; }
}
}
|