mirror of https://github.com/quasar/Quasar.git
111 lines
2.7 KiB
C#
111 lines
2.7 KiB
C#
/*
|
|
* Copyright 2015 Tomi Valkeinen
|
|
*
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
*/
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Reflection;
|
|
|
|
namespace xClient.Core.NetSerializer
|
|
{
|
|
public sealed class TypeData
|
|
{
|
|
public TypeData(ushort typeID, IDynamicTypeSerializer serializer)
|
|
{
|
|
this.TypeID = typeID;
|
|
this.TypeSerializer = serializer;
|
|
|
|
this.NeedsInstanceParameter = true;
|
|
}
|
|
|
|
public TypeData(ushort typeID, MethodInfo writer, MethodInfo reader)
|
|
{
|
|
this.TypeID = typeID;
|
|
this.WriterMethodInfo = writer;
|
|
this.ReaderMethodInfo = reader;
|
|
|
|
this.NeedsInstanceParameter = writer.GetParameters().Length == 3;
|
|
}
|
|
|
|
public readonly ushort TypeID;
|
|
public bool IsGenerated { get { return this.TypeSerializer != null; } }
|
|
public readonly IDynamicTypeSerializer TypeSerializer;
|
|
public MethodInfo WriterMethodInfo;
|
|
public MethodInfo ReaderMethodInfo;
|
|
|
|
public bool NeedsInstanceParameter { get; private set; }
|
|
}
|
|
|
|
public sealed class CodeGenContext
|
|
{
|
|
readonly Dictionary<Type, TypeData> m_typeMap;
|
|
|
|
public CodeGenContext(Dictionary<Type, TypeData> typeMap)
|
|
{
|
|
m_typeMap = typeMap;
|
|
|
|
var td = m_typeMap[typeof(object)];
|
|
this.SerializerSwitchMethodInfo = td.WriterMethodInfo;
|
|
this.DeserializerSwitchMethodInfo = td.ReaderMethodInfo;
|
|
}
|
|
|
|
public MethodInfo SerializerSwitchMethodInfo { get; private set; }
|
|
public MethodInfo DeserializerSwitchMethodInfo { get; private set; }
|
|
|
|
public MethodInfo GetWriterMethodInfo(Type type)
|
|
{
|
|
return m_typeMap[type].WriterMethodInfo;
|
|
}
|
|
|
|
public MethodInfo GetReaderMethodInfo(Type type)
|
|
{
|
|
return m_typeMap[type].ReaderMethodInfo;
|
|
}
|
|
|
|
public bool IsGenerated(Type type)
|
|
{
|
|
return m_typeMap[type].IsGenerated;
|
|
}
|
|
|
|
public IDictionary<Type, TypeData> TypeMap { get { return m_typeMap; } }
|
|
|
|
bool CanCallDirect(Type type)
|
|
{
|
|
// We can call the (De)serializer method directly for:
|
|
// - Value types
|
|
// - Array types
|
|
// - Sealed types with static (De)serializer method, as the method will handle null
|
|
// Other reference types go through the (De)serializerSwitch
|
|
|
|
bool direct;
|
|
|
|
if (type.IsValueType || type.IsArray)
|
|
direct = true;
|
|
else if (type.IsSealed && IsGenerated(type) == false)
|
|
direct = true;
|
|
else
|
|
direct = false;
|
|
|
|
return direct;
|
|
}
|
|
|
|
public TypeData GetTypeData(Type type)
|
|
{
|
|
return m_typeMap[type];
|
|
}
|
|
|
|
public TypeData GetTypeDataForCall(Type type)
|
|
{
|
|
bool direct = CanCallDirect(type);
|
|
if (!direct)
|
|
type = typeof(object);
|
|
|
|
return GetTypeData(type);
|
|
}
|
|
}
|
|
}
|