Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 17 additions & 1 deletion MsgPack/Formatters/DictionaryFormatter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,11 @@ internal static class DictionaryFormatter
{
public static Tuple<Serializer, MethodInfo> Build(Type typeKey, Type typeValue)
{
#if IS_FXSERVER
MethodInfo methodSerialize, methodDeserialize, methodObjectSerialize;
#else
MethodInfo methodDeserialize;
#endif

Type typeKeyValuePair = typeof(KeyValuePair<,>).MakeGenericType(typeKey, typeValue);
Type typeDictionary = typeof(Dictionary<,>).MakeGenericType(typeKey, typeValue);
Expand All @@ -26,22 +30,34 @@ public static Tuple<Serializer, MethodInfo> Build(Type typeKey, Type typeValue)
{
TypeBuilder typeBuilder = MsgPackRegistry.m_moduleBuilder.DefineType(name);

#if IS_FXSERVER
methodSerialize = BuildSerializer(typeKey, typeValue, typeKeyValuePair, typeIDictionary, typeBuilder);
BuildDeserializer(typeKey, typeValue, typeDictionary, typeBuilder);
BuildObjectSerializer(typeIDictionary, methodSerialize, typeBuilder);
#else
BuildDeserializer(typeKey, typeValue, typeDictionary, typeBuilder);
#endif

buildType = typeBuilder.CreateType();
}

#if IS_FXSERVER
methodSerialize = buildType.GetMethod("Serialize", new[] { typeof(MsgPackSerializer), typeIDictionary });
methodDeserialize = buildType.GetMethod("Deserialize");
methodObjectSerialize = buildType.GetMethod("Serialize", new[] { typeof(MsgPackSerializer), typeof(object) });
#else
methodDeserialize = buildType.GetMethod("Deserialize");
#endif

Serializer serializeMethod = new Serializer(methodSerialize, methodObjectSerialize);

#if IS_FXSERVER
Serializer serializeMethod = new Serializer(methodSerialize, methodObjectSerialize);
MsgPackRegistry.RegisterSerializer(typeDictionary, serializeMethod);
MsgPackRegistry.RegisterSerializer(typeIDictionary, serializeMethod);
MsgPackRegistry.RegisterSerializer(typeIReadOnlyDictionary, serializeMethod);
#else
Serializer serializeMethod = new Serializer();
#endif

MsgPackRegistry.RegisterDeserializer(typeDictionary, methodDeserialize);
MsgPackRegistry.RegisterDeserializer(typeIDictionary, methodDeserialize);
Expand Down
8 changes: 4 additions & 4 deletions MsgPack/Formatters/TypeFormatter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1252,7 +1252,7 @@ private static DynamicArray<MemberInfo> GetReadableMembers(Type type)
return members;
}

private static DynamicArray<MemberInfo> GetWritableMembers(Type type)
internal static DynamicArray<MemberInfo> GetWritableMembers(Type type)
{
var members = new DynamicArray<MemberInfo>(type.GetMembers(BindingFlags.Instance | BindingFlags.Public));
members.RemoveAll(m => !((m is FieldInfo || (m is PropertyInfo p && p.CanWrite))
Expand All @@ -1261,7 +1261,7 @@ private static DynamicArray<MemberInfo> GetWritableMembers(Type type)
return members;
}

private static DynamicArray<MemberInfo> GetReadAndWritableKeyedMembers(Type type)
internal static DynamicArray<MemberInfo> GetReadAndWritableKeyedMembers(Type type)
{
var members = new DynamicArray<MemberInfo>(type.GetMembers(BindingFlags.Instance | BindingFlags.Public));
members.RemoveAll(m => !((m is FieldInfo || (m is PropertyInfo p && p.CanWrite && p.GetGetMethod()?.GetParameters().Length == 0))
Expand All @@ -1271,7 +1271,7 @@ private static DynamicArray<MemberInfo> GetReadAndWritableKeyedMembers(Type type
return members;
}

private static DynamicArray<MemberInfo> GetReadableIndexMembers(Type type)
internal static DynamicArray<MemberInfo> GetReadableIndexMembers(Type type)
{
var members = new DynamicArray<MemberInfo>(type.GetMembers(BindingFlags.Instance | BindingFlags.Public));
members.RemoveAll(m => !((m is FieldInfo || (m is PropertyInfo p && p.GetGetMethod()?.GetParameters().Length == 0))
Expand All @@ -1294,7 +1294,7 @@ private static void CallAndStore(ILGenerator g, MethodInfo methodReadInteger, Op
g.Emit(storeLoc);
}

private static void EmitDebugWriteLine(this ILGenerator g, string value)
internal static void EmitDebugWriteLine(this ILGenerator g, string value)
{
g.Emit(OpCodes.Ldstr, value);
#if MONO_V2
Expand Down
66 changes: 45 additions & 21 deletions MsgPack/MsgPackRegistry.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using CitizenFX.MsgPack.Formatters;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using System.Reflection.Emit;
Expand Down Expand Up @@ -113,12 +114,13 @@ internal static void Serialize(MsgPackSerializer serializer, object obj)
// Adding too much checks here could run slower than a hash map lookup, profile accordingly

Type type = obj.GetType();
if (type.IsPrimitive)
if (type.IsPrimitive || obj is string)
{
switch (obj)
{
case bool v: serializer.Serialize(v); break;
case char v: serializer.Serialize(v); break;
case string v: serializer.Serialize(v); break;

case byte v: serializer.Serialize(v); break;
case ushort v: serializer.Serialize(v); break;
Expand All @@ -132,28 +134,50 @@ internal static void Serialize(MsgPackSerializer serializer, object obj)

case float v: serializer.Serialize(v); break;
case double v: serializer.Serialize(v); break;
}
}
}
else if (obj is Delegate del)
{
// add remote function delegate support ? - don't think if it's even planned or supported
serializer.Serialize(del);
}
// byte[] is a special type handled like a Binary object.
// It is not a primitive type, so i serialized as a binary object and deserialized as such.
else if (obj is byte[] b)
else if (obj is Delegate del)
{
// add remote function delegate support ? - don't think if it's even planned or supported
serializer.Serialize(del);
}
#if !IS_FXSERVER
else if (obj is IEnumerable e)
{
serializer.Serialize(e);
}
#endif
else if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(KeyValuePair<,>))
{
var keyProp = type.GetProperty("Key");
var valueProp = type.GetProperty("Value");

var key = keyProp.GetValue(obj);
var value = valueProp.GetValue(obj);

serializer.Serialize(new KeyValuePair<object, object>(key, value));
}
// byte[] is a special type handled like a Binary object.
// It is not a primitive type, so i serialized as a binary object and deserialized as such.
else if (obj is byte[] b)
{
serializer.Serialize(b);
}
// same applies to List<byte>
// same applies to List<byte>
// we serialize it as a byte array and deserialize it as such
// it's not elegant but i needed to handle it like this as byte is a binary format even in List
// Ps: Who the fuck in fivem would retrieve and send List<byte>??????
else if (obj is List<byte> lb)
{
serializer.Serialize(lb.ToArray());
}
else if (TryGetSerializer(type, out var methodInfo))
else if (obj is List<byte> lb)
{
serializer.Serialize(lb.ToArray());
}
#if !IS_FXSERVER
else if (!type.IsPrimitive && !type.IsArray && !type.IsGenericType && type.FullName != "CitizenFX.Core.Player")
{
serializer.SerializeType(obj);
}
#endif
else if (TryGetSerializer(type, out var methodInfo))
{
methodInfo.m_objectSerializer(serializer, obj);
}
Expand Down Expand Up @@ -190,14 +214,14 @@ internal static MethodInfo GetOrCreateSerializer(Type type)

internal static MethodInfo GetOrCreateDeserializer(Type type)
{
return TryGetDeserializer(type, out var methodInfo)
return TryGetDeserializer(type, out var methodInfo)
? methodInfo
: CreateSerializer(type)?.Item2;
}

private static Tuple<Serializer, MethodInfo> CreateSerializer(Type type)
{
if (type.IsPrimitive)
if (type.IsPrimitive)
{
if (m_serializers.ContainsKey(type))
return new Tuple<Serializer, MethodInfo>(m_serializers[type], m_serializers[type].m_method);
Expand All @@ -206,7 +230,7 @@ private static Tuple<Serializer, MethodInfo> CreateSerializer(Type type)
}
else if (type.IsArray)
{
switch (type.GetArrayRank())
switch (type.GetArrayRank())
{
case 1:
return ArrayFormatter.Build(type.GetElementType(), type);
Expand All @@ -215,7 +239,7 @@ private static Tuple<Serializer, MethodInfo> CreateSerializer(Type type)
else if (type.IsGenericType)
{
var genericTypes = type.GetGenericArguments();
switch (genericTypes.Length)
switch (genericTypes.Length)
{
case 1:
{
Expand All @@ -225,7 +249,7 @@ private static Tuple<Serializer, MethodInfo> CreateSerializer(Type type)
break;
case 2:
{
if (ImplementsGenericTypeDefinition(type, typeof(IDictionary<,>)))
if (ImplementsGenericTypeDefinition(type, typeof(IDictionary<,>)))
return DictionaryFormatter.Build(genericTypes[0], genericTypes[1]);
break;
}
Expand Down
Loading