上海苏宁宝丽嘉酒店,2020.11.17 15:30改为单机版本,以后合成单机版本可以以此版本为模板
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.
 
 
 
 

246 lines
12 KiB

using System;
using System.Reflection;
using System.Collections.Generic;
namespace MessagePack.Formatters
{
public sealed class PrimitiveObjectFormatter : IMessagePackFormatter<object>
{
public static readonly IMessagePackFormatter<object> Instance = new PrimitiveObjectFormatter();
static readonly Dictionary<Type, int> typeToJumpCode = new Dictionary<Type, int>()
{
{ typeof(Boolean), 0 },
{ typeof(Char), 1 },
{ typeof(SByte), 2 },
{ typeof(Byte), 3 },
{ typeof(Int16), 4 },
{ typeof(UInt16), 5 },
{ typeof(Int32), 6 },
{ typeof(UInt32), 7 },
{ typeof(Int64), 8 },
{ typeof(UInt64),9 },
{ typeof(Single), 10 },
{ typeof(Double), 11 },
{ typeof(DateTime), 12 },
{ typeof(string), 13 },
{ typeof(byte[]), 14 }
};
PrimitiveObjectFormatter()
{
}
#if !UNITY_WSA
public static bool IsSupportedType(Type type, TypeInfo typeInfo, object value)
{
if (value == null) return true;
if (typeToJumpCode.ContainsKey(type)) return true;
if (typeInfo.IsEnum) return true;
if (value is System.Collections.IDictionary) return true;
if (value is System.Collections.ICollection) return true;
return false;
}
#endif
public int Serialize(ref byte[] bytes, int offset, object value, IFormatterResolver formatterResolver)
{
if (value == null)
{
return MessagePackBinary.WriteNil(ref bytes, offset);
}
var t = value.GetType();
int code;
if (typeToJumpCode.TryGetValue(t, out code))
{
switch (code)
{
case 0:
return MessagePackBinary.WriteBoolean(ref bytes, offset, (bool)value);
case 1:
return MessagePackBinary.WriteChar(ref bytes, offset, (char)value);
case 2:
return MessagePackBinary.WriteSByteForceSByteBlock(ref bytes, offset, (sbyte)value);
case 3:
return MessagePackBinary.WriteByteForceByteBlock(ref bytes, offset, (byte)value);
case 4:
return MessagePackBinary.WriteInt16ForceInt16Block(ref bytes, offset, (Int16)value);
case 5:
return MessagePackBinary.WriteUInt16ForceUInt16Block(ref bytes, offset, (UInt16)value);
case 6:
return MessagePackBinary.WriteInt32ForceInt32Block(ref bytes, offset, (Int32)value);
case 7:
return MessagePackBinary.WriteUInt32ForceUInt32Block(ref bytes, offset, (UInt32)value);
case 8:
return MessagePackBinary.WriteInt64ForceInt64Block(ref bytes, offset, (Int64)value);
case 9:
return MessagePackBinary.WriteUInt64ForceUInt64Block(ref bytes, offset, (UInt64)value);
case 10:
return MessagePackBinary.WriteSingle(ref bytes, offset, (Single)value);
case 11:
return MessagePackBinary.WriteDouble(ref bytes, offset, (double)value);
case 12:
return MessagePackBinary.WriteDateTime(ref bytes, offset, (DateTime)value);
case 13:
return MessagePackBinary.WriteString(ref bytes, offset, (string)value);
case 14:
return MessagePackBinary.WriteBytes(ref bytes, offset, (byte[])value);
default:
throw new InvalidOperationException("Not supported primitive object resolver. type:" + t.Name);
}
}
else
{
#if UNITY_WSA && !NETFX_CORE
if (t.IsEnum)
#else
if (t.GetTypeInfo().IsEnum)
#endif
{
var underlyingType = Enum.GetUnderlyingType(t);
var code2 = typeToJumpCode[underlyingType];
switch (code2)
{
case 2:
return MessagePackBinary.WriteSByteForceSByteBlock(ref bytes, offset, (sbyte)value);
case 3:
return MessagePackBinary.WriteByteForceByteBlock(ref bytes, offset, (byte)value);
case 4:
return MessagePackBinary.WriteInt16ForceInt16Block(ref bytes, offset, (Int16)value);
case 5:
return MessagePackBinary.WriteUInt16ForceUInt16Block(ref bytes, offset, (UInt16)value);
case 6:
return MessagePackBinary.WriteInt32ForceInt32Block(ref bytes, offset, (Int32)value);
case 7:
return MessagePackBinary.WriteUInt32ForceUInt32Block(ref bytes, offset, (UInt32)value);
case 8:
return MessagePackBinary.WriteInt64ForceInt64Block(ref bytes, offset, (Int64)value);
case 9:
return MessagePackBinary.WriteUInt64ForceUInt64Block(ref bytes, offset, (UInt64)value);
default:
break;
}
}
else if (value is System.Collections.IDictionary) // check IDictionary first
{
var d = value as System.Collections.IDictionary;
var startOffset = offset;
offset += MessagePackBinary.WriteMapHeader(ref bytes, offset, d.Count);
foreach (System.Collections.DictionaryEntry item in d)
{
offset += Serialize(ref bytes, offset, item.Key, formatterResolver);
offset += Serialize(ref bytes, offset, item.Value, formatterResolver);
}
return offset - startOffset;
}
else if (value is System.Collections.ICollection)
{
var c = value as System.Collections.ICollection;
var startOffset = offset;
offset += MessagePackBinary.WriteArrayHeader(ref bytes, offset, c.Count);
foreach (var item in c)
{
offset += Serialize(ref bytes, offset, item, formatterResolver);
}
return offset - startOffset;
}
}
throw new InvalidOperationException("Not supported primitive object resolver. type:" + t.Name);
}
public object Deserialize(byte[] bytes, int offset, IFormatterResolver formatterResolver, out int readSize)
{
var type = MessagePackBinary.GetMessagePackType(bytes, offset);
switch (type)
{
case MessagePackType.Integer:
var code = bytes[offset];
if (MessagePackCode.MinNegativeFixInt <= code && code <= MessagePackCode.MaxNegativeFixInt) return MessagePackBinary.ReadSByte(bytes, offset, out readSize);
else if (MessagePackCode.MinFixInt <= code && code <= MessagePackCode.MaxFixInt) return MessagePackBinary.ReadByte(bytes, offset, out readSize);
else if (code == MessagePackCode.Int8) return MessagePackBinary.ReadSByte(bytes, offset, out readSize);
else if (code == MessagePackCode.Int16) return MessagePackBinary.ReadInt16(bytes, offset, out readSize);
else if (code == MessagePackCode.Int32) return MessagePackBinary.ReadInt32(bytes, offset, out readSize);
else if (code == MessagePackCode.Int64) return MessagePackBinary.ReadInt64(bytes, offset, out readSize);
else if (code == MessagePackCode.UInt8) return MessagePackBinary.ReadByte(bytes, offset, out readSize);
else if (code == MessagePackCode.UInt16) return MessagePackBinary.ReadUInt16(bytes, offset, out readSize);
else if (code == MessagePackCode.UInt32) return MessagePackBinary.ReadUInt32(bytes, offset, out readSize);
else if (code == MessagePackCode.UInt64) return MessagePackBinary.ReadUInt64(bytes, offset, out readSize);
throw new InvalidOperationException("Invalid primitive bytes.");
case MessagePackType.Boolean:
return MessagePackBinary.ReadBoolean(bytes, offset, out readSize);
case MessagePackType.Float:
if (MessagePackCode.Float32 == bytes[offset])
{
return MessagePackBinary.ReadSingle(bytes, offset, out readSize);
}
else
{
return MessagePackBinary.ReadDouble(bytes, offset, out readSize);
}
case MessagePackType.String:
return MessagePackBinary.ReadString(bytes, offset, out readSize);
case MessagePackType.Binary:
return MessagePackBinary.ReadBytes(bytes, offset, out readSize);
case MessagePackType.Extension:
var ext = MessagePackBinary.ReadExtensionFormatHeader(bytes, offset, out readSize);
if (ext.TypeCode == ReservedMessagePackExtensionTypeCode.DateTime)
{
return MessagePackBinary.ReadDateTime(bytes, offset, out readSize);
}
throw new InvalidOperationException("Invalid primitive bytes.");
case MessagePackType.Array:
{
var length = MessagePackBinary.ReadArrayHeader(bytes, offset, out readSize);
var startOffset = offset;
offset += readSize;
var objectFormatter = formatterResolver.GetFormatter<object>();
var array = new object[length];
for (int i = 0; i < length; i++)
{
array[i] = objectFormatter.Deserialize(bytes, offset, formatterResolver, out readSize);
offset += readSize;
}
readSize = offset - startOffset;
return array;
}
case MessagePackType.Map:
{
var length = MessagePackBinary.ReadMapHeader(bytes, offset, out readSize);
var startOffset = offset;
offset += readSize;
var objectFormatter = formatterResolver.GetFormatter<object>();
var hash = new Dictionary<object, object>(length);
for (int i = 0; i < length; i++)
{
var key = objectFormatter.Deserialize(bytes, offset, formatterResolver, out readSize);
offset += readSize;
var value = objectFormatter.Deserialize(bytes, offset, formatterResolver, out readSize);
offset += readSize;
hash.Add(key, value);
}
readSize = offset - startOffset;
return hash;
}
case MessagePackType.Nil:
readSize = 1;
return null;
default:
throw new InvalidOperationException("Invalid primitive bytes.");
}
}
}
}