BITKit/Src/Core/Binary/BITBinary.cs

223 lines
7.4 KiB
C#
Raw Normal View History

2023-10-06 23:43:19 +08:00
#if NET5_0_OR_GREATER
#else
2023-06-05 19:57:17 +08:00
using UnityEngine;
#endif
using System;
2024-06-20 10:04:18 +08:00
using System.Collections;
2023-06-29 14:57:11 +08:00
using System.Collections.Generic;
using System.IO;
2023-06-05 19:57:17 +08:00
using System.Linq;
2024-03-31 23:31:00 +08:00
using System.Text;
2023-08-23 01:59:26 +08:00
using Cysharp.Threading.Tasks;
2024-03-31 23:31:00 +08:00
using Microsoft.SqlServer.Server;
2023-10-06 23:43:19 +08:00
#if NET5_0_OR_GREATER
2023-06-29 14:57:11 +08:00
using Microsoft.SqlServer.Server;
2023-10-06 23:43:19 +08:00
#endif
2023-06-29 14:57:11 +08:00
using Newtonsoft.Json;
2023-06-05 19:57:17 +08:00
namespace BITKit
{
public class BITBinary
{
2023-08-23 01:59:26 +08:00
private static readonly Dictionary<string, INetMessageReader> netReaders = new();
2023-10-06 23:43:19 +08:00
public static readonly List<Type> serializableTypes = new();
2023-08-23 01:59:26 +08:00
public static async UniTask Start()
2023-06-05 19:57:17 +08:00
{
netReaders.Clear();
2023-10-06 23:43:19 +08:00
#if NET5_0_OR_GREATER
2023-06-05 19:57:17 +08:00
serializableTypes.Clear();
2023-10-06 23:43:19 +08:00
#endif
2024-03-31 23:31:00 +08:00
var stringBuilder = new StringBuilder();
2023-06-05 19:57:17 +08:00
foreach (var x in await ReflectionHelper.GetInstances<INetMessageReader>())
{
var typeName = x.GetMessageType().FullName;
2023-10-06 23:43:19 +08:00
if (typeName == null) continue;
2023-06-05 19:57:17 +08:00
netReaders.Add(typeName, x);
2024-03-31 23:31:00 +08:00
stringBuilder.AppendLine(typeName);
}
var serializes = await ReflectionHelper.GetInstances<IBinarySerialize>();
#if NET5_0_OR_GREATER
#else
serializes = serializes.Where(x => x.GetType().IsAssignableFrom(typeof(UnityEngine.Object)) is false);
#endif
foreach (var x in serializes)
{
serializableTypes.Add(x.GetType());
//BIT4Log.Log<BITBinary>($"已注册类型:{x.GetType().FullName}");
stringBuilder.AppendLine(x.GetType().FullName);
2023-06-05 19:57:17 +08:00
}
2024-03-31 23:31:00 +08:00
BIT4Log.Log<BITBinary>($"已注册类型:\n{stringBuilder}");
2023-06-05 19:57:17 +08:00
}
2024-03-31 23:31:00 +08:00
public static T Read<T>(byte[] buffer) => (T)ReadAsValue(buffer);
2023-06-07 02:02:14 +08:00
public static object ReadAsValue(byte[] buffer)
2023-06-05 19:57:17 +08:00
{
using var ms = new MemoryStream(buffer);
using var reader = new BinaryReader(ms);
2023-06-07 02:02:14 +08:00
return Read(reader);
2023-06-05 19:57:17 +08:00
}
2023-08-23 01:59:26 +08:00
2023-06-05 19:57:17 +08:00
public static object Read(BinaryReader reader)
{
2024-06-20 10:04:18 +08:00
// 检测是否为数组
2024-06-12 16:01:56 +08:00
if (reader.ReadBoolean())
2023-08-23 01:59:26 +08:00
{
2024-06-20 10:04:18 +08:00
//读取数组类型的名称
var arrayTypeName = reader.ReadString();
//获取数组类型
var arrayType = BITSharp.GetTypeFromFullName(arrayTypeName);
2024-06-26 15:39:00 +08:00
if(string.IsNullOrEmpty(arrayTypeName) || arrayType is null)
throw new Exception($"未找到类型:{arrayTypeName}");
2024-06-20 10:04:18 +08:00
//创建数组实例
var array = Array.CreateInstance(arrayType, reader.ReadInt32());
//循环Reader
for (var i = 0; i < array.Length; i++)
2023-08-23 01:59:26 +08:00
{
2024-06-20 10:04:18 +08:00
//设置值
array.SetValue(ReadInternel(reader),i);
2023-08-23 01:59:26 +08:00
}
2024-06-20 10:06:25 +08:00
//返回数组
2024-06-20 10:04:18 +08:00
return array;
2024-03-31 23:31:00 +08:00
}
2024-06-12 16:01:56 +08:00
return ReadInternel(reader);
object ReadInternel(BinaryReader reader)
2023-06-05 19:57:17 +08:00
{
2024-06-12 16:01:56 +08:00
var typeName = reader.ReadString();
if (netReaders.TryGetValue(typeName, out var netReader))
return netReader.ReadBinaryAsObject(reader);
2024-06-20 10:04:18 +08:00
var type = BITSharp.GetTypeFromFullName(typeName);
2024-06-21 10:52:32 +08:00
if (type is null)
{
throw new Exception($"反序列化时未找到类型:{typeName}");
}
2024-06-20 10:06:25 +08:00
var instance = System.Activator.CreateInstance(type);
2024-06-20 10:04:18 +08:00
2024-06-12 16:01:56 +08:00
if (instance is IBinarySerialize serialize)
{
serialize.Read(reader);
return instance;
}
var json = reader.ReadString();
if (string.IsNullOrEmpty(json))
{
throw new Exception($"从二进制中读取的json值为空");
}
try
{
2024-06-20 10:04:18 +08:00
if (BITSharp.TryGetTypeFromFullName(typeName, out type))
2024-06-12 16:01:56 +08:00
return JsonConvert.DeserializeObject(json, type);
}
catch (Exception e)
{
BIT4Log.Warning<BITBinary>($"反序列化失败,类型:{typeName},值:\n{json}");
BIT4Log.LogException(e);
}
throw new Exception("未找到读取该二进制的BinaryReader");
2023-06-05 19:57:17 +08:00
}
}
public static byte[] WriteAsBytes(object value)
{
using var ms = new MemoryStream();
using var writer = new BinaryWriter(ms);
Write(writer, value);
return ms.ToArray();
}
public static void Write(BinaryWriter writer, object value)
{
2024-06-20 10:04:18 +08:00
if (value is IEnumerable enumerable)
2023-08-23 01:59:26 +08:00
{
2024-06-20 10:04:18 +08:00
var pars = enumerable.Cast<object>().ToArray();
2024-06-12 16:01:56 +08:00
writer.Write(true);
2024-06-20 10:04:18 +08:00
writer.Write(value.GetType().GetElementType()!.FullName!);
writer.Write(pars.Count());
foreach (var obj in pars)
2023-08-23 01:59:26 +08:00
{
2024-06-12 16:01:56 +08:00
WriteInterel(writer, obj);
2023-08-23 01:59:26 +08:00
}
}
else
{
writer.Write(false);
2024-06-12 16:01:56 +08:00
WriteInterel(writer,value);
2023-08-23 01:59:26 +08:00
}
2024-06-12 16:01:56 +08:00
return;
void WriteInterel(BinaryWriter writer, object value)
2024-03-31 23:31:00 +08:00
{
2024-06-12 16:01:56 +08:00
var typeName = value.GetType().FullName;
writer.Write(typeName!);
if (netReaders.TryGetValue(typeName, out var netReader))
2024-03-31 23:31:00 +08:00
{
2024-06-12 16:01:56 +08:00
netReader.WriteBinaryAsObject(writer,value);
2024-03-31 23:31:00 +08:00
}
2024-06-12 16:01:56 +08:00
else if (value is IBinarySerialize serialize)
2024-03-31 23:31:00 +08:00
{
2024-06-12 16:01:56 +08:00
serialize.Write(writer);
2024-03-31 23:31:00 +08:00
}
2024-06-12 16:01:56 +08:00
else
{
try
{
writer.Write(JsonConvert.SerializeObject(value));
}
catch (Exception e)
{
BIT4Log.Warning<BITBinary>(typeName);
throw;
}
2024-03-31 23:31:00 +08:00
2024-06-12 16:01:56 +08:00
}
2023-06-05 19:57:17 +08:00
}
}
2023-06-07 02:02:14 +08:00
public static bool IsSupport(object obj) => IsSupport(obj.GetType().FullName);
public static bool IsSupport(Type type) => IsSupport(type.FullName);
public static bool IsSupport<T>() => IsSupport(typeof(T).FullName);
2023-06-05 19:57:17 +08:00
public static bool IsSupport(string typeName)
{
2024-03-31 23:31:00 +08:00
return netReaders.ContainsKey(typeName) || serializableTypes.Any(x => x.FullName == typeName);
2023-06-05 19:57:17 +08:00
}
2023-06-07 02:02:14 +08:00
public static bool TryWrite(object obj, out byte[] bytes)
{
2023-06-29 14:57:11 +08:00
bytes = null;
2023-06-07 02:02:14 +08:00
if (IsSupport(obj))
{
bytes = WriteAsBytes(obj);
return true;
}
2023-06-29 14:57:11 +08:00
else
{
using var ms = new MemoryStream();
using var writer = new BinaryWriter(ms);
try
{
writer.Write(obj!.GetType()!.FullName!);
var json = JsonHelper.Get(obj);
writer.Write(json);
}
catch (Exception e)
{
BIT4Log.Log(e);
return false;
}
}
return true;
//bytes = null;
//return false;
2023-06-07 02:02:14 +08:00
}
2023-06-05 19:57:17 +08:00
}
}