You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
305 lines
12 KiB
305 lines
12 KiB
#if NETSTANDARD |
|
|
|
using MessagePack.Formatters; |
|
using MessagePack.Internal; |
|
using System; |
|
using System.Collections.Generic; |
|
using System.Text; |
|
|
|
namespace MessagePack.Resolvers |
|
{ |
|
// MEMO: Not completely implemented. |
|
|
|
//public static class ContractlessReflectionObjectResolver |
|
//{ |
|
// // TODO:CamelCase Option? AllowPrivate? |
|
// public static readonly IFormatterResolver Default = new DefaultResolver(); |
|
// public static readonly IFormatterResolver Contractless = new ContractlessResolver(); |
|
// public static readonly IFormatterResolver ContractlessForceStringKey = new ContractlessForceStringResolver(); |
|
|
|
// class DefaultResolver : IFormatterResolver |
|
// { |
|
// const bool ForceStringKey = false; |
|
// const bool Contractless = false; |
|
// const bool AllowPrivate = false; |
|
|
|
// public IMessagePackFormatter<T> GetFormatter<T>() |
|
// { |
|
// return Cache<T>.formatter; |
|
// } |
|
|
|
// static class Cache<T> |
|
// { |
|
// public static readonly IMessagePackFormatter<T> formatter; |
|
|
|
// static Cache() |
|
// { |
|
// var metaInfo = ObjectSerializationInfo.CreateOrNull(typeof(T), ForceStringKey, Contractless, AllowPrivate); |
|
// if (metaInfo != null) |
|
// { |
|
// formatter = new ReflectionObjectFormatter<T>(metaInfo); |
|
// } |
|
// } |
|
// } |
|
// } |
|
|
|
// class ContractlessResolver : IFormatterResolver |
|
// { |
|
// const bool ForceStringKey = false; |
|
// const bool Contractless = true; |
|
// const bool AllowPrivate = false; |
|
|
|
// public IMessagePackFormatter<T> GetFormatter<T>() |
|
// { |
|
// return Cache<T>.formatter; |
|
// } |
|
|
|
// static class Cache<T> |
|
// { |
|
// public static readonly IMessagePackFormatter<T> formatter; |
|
|
|
// static Cache() |
|
// { |
|
// var metaInfo = ObjectSerializationInfo.CreateOrNull(typeof(T), ForceStringKey, Contractless, AllowPrivate); |
|
// if (metaInfo != null) |
|
// { |
|
// formatter = new ReflectionObjectFormatter<T>(metaInfo); |
|
// } |
|
// } |
|
// } |
|
// } |
|
|
|
// class ContractlessForceStringResolver : IFormatterResolver |
|
// { |
|
// const bool ForceStringKey = true; |
|
// const bool Contractless = true; |
|
// const bool AllowPrivate = false; |
|
|
|
// public IMessagePackFormatter<T> GetFormatter<T>() |
|
// { |
|
// return Cache<T>.formatter; |
|
// } |
|
|
|
// static class Cache<T> |
|
// { |
|
// public static readonly IMessagePackFormatter<T> formatter; |
|
|
|
// static Cache() |
|
// { |
|
// var metaInfo = ObjectSerializationInfo.CreateOrNull(typeof(T), ForceStringKey, Contractless, AllowPrivate); |
|
// if (metaInfo != null) |
|
// { |
|
// formatter = new ReflectionObjectFormatter<T>(metaInfo); |
|
// } |
|
// } |
|
// } |
|
// } |
|
|
|
//} |
|
|
|
|
|
//public class ReflectionObjectFormatter<T> : IMessagePackFormatter<T> |
|
//{ |
|
// readonly ObjectSerializationInfo metaInfo; |
|
|
|
// // for write |
|
// readonly byte[][] writeMemberNames; |
|
// readonly ObjectSerializationInfo.EmittableMember[] writeMembers; |
|
|
|
// // for read |
|
// readonly int[] constructorParameterIndexes; |
|
// readonly AutomataDictionary mapMemberDictionary; |
|
// readonly ObjectSerializationInfo.EmittableMember[] readMembers; |
|
|
|
|
|
// internal ReflectionObjectFormatter(ObjectSerializationInfo metaInfo) |
|
// { |
|
// this.metaInfo = metaInfo; |
|
|
|
// // for write |
|
// { |
|
// var memberNameList = new List<byte[]>(metaInfo.Members.Length); |
|
// var emmitableMemberList = new List<ObjectSerializationInfo.EmittableMember>(metaInfo.Members.Length); |
|
// foreach (var item in metaInfo.Members) |
|
// { |
|
// if (item.IsWritable) |
|
// { |
|
// emmitableMemberList.Add(item); |
|
// memberNameList.Add(Encoding.UTF8.GetBytes(item.Name)); |
|
// } |
|
// } |
|
// this.writeMemberNames = memberNameList.ToArray(); |
|
// this.writeMembers = emmitableMemberList.ToArray(); |
|
// } |
|
// // for read |
|
// { |
|
// var automata = new AutomataDictionary(); |
|
// var emmitableMemberList = new List<ObjectSerializationInfo.EmittableMember>(metaInfo.Members.Length); |
|
// int index = 0; |
|
// foreach (var item in metaInfo.Members) |
|
// { |
|
// if (item.IsReadable) |
|
// { |
|
// emmitableMemberList.Add(item); |
|
// automata.Add(item.Name, index++); |
|
// } |
|
// } |
|
// this.readMembers = emmitableMemberList.ToArray(); |
|
// this.mapMemberDictionary = automata; |
|
// } |
|
// } |
|
|
|
// public int Serialize(ref byte[] bytes, int offset, T value, IFormatterResolver formatterResolver) |
|
// { |
|
// // reduce generic method size, avoid write code in <T> type. |
|
// if (metaInfo.IsIntKey) |
|
// { |
|
// return ReflectionObjectFormatterHelper.WriteArraySerialize(metaInfo, writeMembers, ref bytes, offset, value, formatterResolver); |
|
// } |
|
// else |
|
// { |
|
// return ReflectionObjectFormatterHelper.WriteMapSerialize(metaInfo, writeMembers, writeMemberNames, ref bytes, offset, value, formatterResolver); |
|
// } |
|
// } |
|
|
|
// public T Deserialize(byte[] bytes, int offset, IFormatterResolver formatterResolver, out int readSize) |
|
// { |
|
// return (T)ReflectionObjectFormatterHelper.Deserialize(metaInfo, readMembers, constructorParameterIndexes, mapMemberDictionary, bytes, offset, formatterResolver, out readSize); |
|
// } |
|
//} |
|
|
|
//internal static class ReflectionObjectFormatterHelper |
|
//{ |
|
// internal static int WriteArraySerialize(ObjectSerializationInfo metaInfo, ObjectSerializationInfo.EmittableMember[] writeMembers, ref byte[] bytes, int offset, object value, IFormatterResolver formatterResolver) |
|
// { |
|
// var startOffset = offset; |
|
|
|
// offset += MessagePackBinary.WriteArrayHeader(ref bytes, offset, writeMembers.Length); |
|
// foreach (var item in metaInfo.Members) |
|
// { |
|
// if (item == null) |
|
// { |
|
// offset += MessagePackBinary.WriteNil(ref bytes, offset); |
|
// } |
|
// else |
|
// { |
|
// var memberValue = item.ReflectionLoadValue(value); |
|
// offset += MessagePackSerializer.NonGeneric.Serialize(item.Type, ref bytes, offset, memberValue, formatterResolver); |
|
// } |
|
// } |
|
|
|
// return offset - startOffset; |
|
// } |
|
|
|
// internal static int WriteMapSerialize(ObjectSerializationInfo metaInfo, ObjectSerializationInfo.EmittableMember[] writeMembers, byte[][] memberNames, ref byte[] bytes, int offset, object value, IFormatterResolver formatterResolver) |
|
// { |
|
// var startOffset = offset; |
|
|
|
// offset += MessagePackBinary.WriteMapHeader(ref bytes, offset, writeMembers.Length); |
|
|
|
// for (int i = 0; i < writeMembers.Length; i++) |
|
// { |
|
// offset += MessagePackBinary.WriteStringBytes(ref bytes, offset, memberNames[i]); |
|
// var memberValue = writeMembers[i].ReflectionLoadValue(value); |
|
// offset += MessagePackSerializer.NonGeneric.Serialize(writeMembers[i].Type, ref bytes, offset, memberValue, formatterResolver); |
|
// } |
|
|
|
// return offset - startOffset; |
|
// } |
|
|
|
// internal static object Deserialize(ObjectSerializationInfo metaInfo, ObjectSerializationInfo.EmittableMember[] readMembers, int[] constructorParameterIndexes, AutomataDictionary mapMemberDictionary, byte[] bytes, int offset, IFormatterResolver formatterResolver, out int readSize) |
|
// { |
|
// var startOffset = offset; |
|
// object[] parameters = null; |
|
|
|
// var headerType = MessagePackBinary.GetMessagePackType(bytes, offset); |
|
// if (headerType == MessagePackType.Nil) |
|
// { |
|
// readSize = 1; |
|
// return null; |
|
// } |
|
// else if (headerType == MessagePackType.Array) |
|
// { |
|
// var arraySize = MessagePackBinary.ReadArrayHeader(bytes, offset, out readSize); |
|
// offset += readSize; |
|
|
|
// // ReadValues |
|
// parameters = new object[arraySize]; |
|
// for (int i = 0; i < arraySize; i++) |
|
// { |
|
// var info = readMembers[i]; |
|
// if (info != null) |
|
// { |
|
// parameters[i] = MessagePackSerializer.NonGeneric.Deserialize(info.Type, bytes, offset, formatterResolver, out readSize); |
|
// offset += readSize; |
|
// } |
|
// else |
|
// { |
|
// offset += MessagePackBinary.ReadNextBlock(bytes, offset); |
|
// } |
|
// } |
|
// } |
|
// else if (headerType == MessagePackType.Map) |
|
// { |
|
// var mapSize = MessagePackBinary.ReadMapHeader(bytes, offset, out readSize); |
|
// offset += readSize; |
|
|
|
// // ReadValues |
|
// parameters = new object[mapSize]; |
|
// for (int i = 0; i < mapSize; i++) |
|
// { |
|
// var rawPropName = MessagePackBinary.ReadStringSegment(bytes, offset, out readSize); |
|
// offset += readSize; |
|
|
|
// int index; |
|
// if (mapMemberDictionary.TryGetValue(rawPropName.Array, rawPropName.Offset, rawPropName.Count, out index)) |
|
// { |
|
// var info = readMembers[index]; |
|
// parameters[index] = MessagePackSerializer.NonGeneric.Deserialize(info.Type, bytes, offset, formatterResolver, out readSize); |
|
// offset += readSize; |
|
// } |
|
// else |
|
// { |
|
// offset += MessagePackBinary.ReadNextBlock(bytes, offset); |
|
// } |
|
// } |
|
// } |
|
// else |
|
// { |
|
// throw new InvalidOperationException("Invalid MessagePackType:" + MessagePackCode.ToFormatName(bytes[offset])); |
|
// } |
|
|
|
// // CreateObject |
|
// object result = null; |
|
// if (constructorParameterIndexes.Length == 0) |
|
// { |
|
// result = Activator.CreateInstance(metaInfo.Type); |
|
// } |
|
// else |
|
// { |
|
// var args = new object[constructorParameterIndexes.Length]; |
|
// for (int i = 0; i < constructorParameterIndexes.Length; i++) |
|
// { |
|
// args[i] = parameters[constructorParameterIndexes[i]]; |
|
// } |
|
|
|
// result = Activator.CreateInstance(metaInfo.Type, args); |
|
// } |
|
|
|
// // SetMembers |
|
// for (int i = 0; i < readMembers.Length; i++) |
|
// { |
|
// var info = readMembers[i]; |
|
// if (info != null) |
|
// { |
|
// info.ReflectionStoreValue(result, parameters[i]); |
|
// } |
|
// } |
|
|
|
// readSize = offset - startOffset; |
|
// return result; |
|
// } |
|
//} |
|
} |
|
|
|
#endif |