Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/aspnet/MessagePack-CSharp.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sandbox/Sandbox/Program.cs24
-rw-r--r--src/MessagePack/Formatters/CollectionFormatter.cs218
-rw-r--r--src/MessagePack/Formatters/IMessagePackFormatter.cs8
-rw-r--r--src/MessagePack/Formatters/IgnoreFormatter.cs16
-rw-r--r--src/MessagePack/Resolvers/CompositeResolver.cs51
-rw-r--r--src/MessagePack/Resolvers/DynamicGenericResolver.cs21
-rw-r--r--tests/MessagePack.Tests/MessagePack.Tests.csproj1
-rw-r--r--tests/MessagePack.Tests/NonGenericCollectionTest.cs60
8 files changed, 390 insertions, 9 deletions
diff --git a/sandbox/Sandbox/Program.cs b/sandbox/Sandbox/Program.cs
index 67862abe..5ffb46a3 100644
--- a/sandbox/Sandbox/Program.cs
+++ b/sandbox/Sandbox/Program.cs
@@ -16,6 +16,7 @@ using Newtonsoft.Json;
using System.Text;
using System.IO.Compression;
using System.Collections.Concurrent;
+using System.Reflection;
namespace Sandbox
{
@@ -280,21 +281,32 @@ namespace Sandbox
public IEntity Entity { get; }
}
+ public class Dummy___
+ {
+ public MethodBase MyProperty { get; set; }
+ }
class Program
{
static void Main(string[] args)
{
+ try
+ {
+ throw new InvalidOperationException("foo bar");
+ }
+ catch (Exception ex)
+ {
+ // var ex = new Dummy___();
- var gb = 1024 * 1024 * 1024;
- byte[] bytes = null;
- MessagePackBinary.EnsureCapacity(ref bytes, 0, gb);
- MessagePackBinary.EnsureCapacity(ref bytes, gb, 1);
-
- MessagePackBinary.EnsureCapacity(ref bytes, 0x7FFFFFC7, 1);
+ MessagePack.Resolvers.CompositeResolver.RegisterAndSetAsDefault(
+ new[] { new IgnoreFormatter<MethodBase>() },
+ new[] { ContractlessStandardResolver.Instance });
+ var bin = MessagePack.MessagePackSerializer.Serialize(ex);
+ Console.WriteLine(MessagePack.MessagePackSerializer.ToJson(bin));
+ }
}
static void Benchmark<T>(T target)
diff --git a/src/MessagePack/Formatters/CollectionFormatter.cs b/src/MessagePack/Formatters/CollectionFormatter.cs
index f2dc69df..0dc6bd55 100644
--- a/src/MessagePack/Formatters/CollectionFormatter.cs
+++ b/src/MessagePack/Formatters/CollectionFormatter.cs
@@ -703,6 +703,224 @@ namespace MessagePack.Formatters
}
}
+ // NonGenerics
+
+ public sealed class NonGenericListFormatter<T> : IMessagePackFormatter<T>
+ where T : class, IList, new()
+ {
+ public int Serialize(ref byte[] bytes, int offset, T value, IFormatterResolver formatterResolver)
+ {
+ if (value == null)
+ {
+ MessagePackBinary.WriteNil(ref bytes, offset);
+ return 1;
+ }
+
+ var formatter = formatterResolver.GetFormatterWithVerify<object>();
+ var startOffset = offset;
+
+ offset += MessagePackBinary.WriteArrayHeader(ref bytes, offset, value.Count);
+ foreach (var item in value)
+ {
+ offset += formatter.Serialize(ref bytes, offset, item, formatterResolver);
+ }
+
+ return offset - startOffset;
+ }
+
+ public T Deserialize(byte[] bytes, int offset, IFormatterResolver formatterResolver, out int readSize)
+ {
+ if (MessagePackBinary.IsNil(bytes, offset))
+ {
+ readSize = 1;
+ return default(T);
+ }
+
+ var formatter = formatterResolver.GetFormatterWithVerify<object>();
+ var startOffset = offset;
+
+ var count = MessagePackBinary.ReadArrayHeader(bytes, offset, out readSize);
+ offset += readSize;
+
+ var list = new T();
+ for (int i = 0; i < count; i++)
+ {
+ list.Add(formatter.Deserialize(bytes, offset, formatterResolver, out readSize));
+ offset += readSize;
+ }
+
+ readSize = offset - startOffset;
+ return list;
+ }
+ }
+
+ public sealed class NonGenericInterfaceListFormatter : IMessagePackFormatter<IList>
+ {
+ public static readonly IMessagePackFormatter<IList> Instance = new NonGenericInterfaceListFormatter();
+
+ NonGenericInterfaceListFormatter()
+ {
+
+ }
+
+ public int Serialize(ref byte[] bytes, int offset, IList value, IFormatterResolver formatterResolver)
+ {
+ if (value == null)
+ {
+ MessagePackBinary.WriteNil(ref bytes, offset);
+ return 1;
+ }
+
+ var formatter = formatterResolver.GetFormatterWithVerify<object>();
+ var startOffset = offset;
+
+ offset += MessagePackBinary.WriteArrayHeader(ref bytes, offset, value.Count);
+ foreach (var item in value)
+ {
+ offset += formatter.Serialize(ref bytes, offset, item, formatterResolver);
+ }
+
+ return offset - startOffset;
+ }
+
+ public IList Deserialize(byte[] bytes, int offset, IFormatterResolver formatterResolver, out int readSize)
+ {
+ if (MessagePackBinary.IsNil(bytes, offset))
+ {
+ readSize = 1;
+ return default(IList);
+ }
+
+ var formatter = formatterResolver.GetFormatterWithVerify<object>();
+ var startOffset = offset;
+
+ var count = MessagePackBinary.ReadArrayHeader(bytes, offset, out readSize);
+ offset += readSize;
+
+ var list = new object[count];
+ for (int i = 0; i < count; i++)
+ {
+ list[i] = formatter.Deserialize(bytes, offset, formatterResolver, out readSize);
+ offset += readSize;
+ }
+
+ readSize = offset - startOffset;
+ return list;
+ }
+ }
+
+ public sealed class NonGenericDictionaryFormatter<T> : IMessagePackFormatter<T>
+ where T : class, IDictionary, new()
+ {
+ public int Serialize(ref byte[] bytes, int offset, T value, IFormatterResolver formatterResolver)
+ {
+ if (value == null)
+ {
+ MessagePackBinary.WriteNil(ref bytes, offset);
+ return 1;
+ }
+
+ var formatter = formatterResolver.GetFormatterWithVerify<object>();
+ var startOffset = offset;
+
+ offset += MessagePackBinary.WriteMapHeader(ref bytes, offset, value.Count);
+ foreach (DictionaryEntry item in value)
+ {
+ offset += formatter.Serialize(ref bytes, offset, item.Key, formatterResolver);
+ offset += formatter.Serialize(ref bytes, offset, item.Value, formatterResolver);
+ }
+
+ return offset - startOffset;
+ }
+
+ public T Deserialize(byte[] bytes, int offset, IFormatterResolver formatterResolver, out int readSize)
+ {
+ if (MessagePackBinary.IsNil(bytes, offset))
+ {
+ readSize = 1;
+ return null;
+ }
+
+ var formatter = formatterResolver.GetFormatterWithVerify<object>();
+ var startOffset = offset;
+
+ var count = MessagePackBinary.ReadMapHeader(bytes, offset, out readSize);
+ offset += readSize;
+
+ var dict = new T();
+ for (int i = 0; i < count; i++)
+ {
+ var key = formatter.Deserialize(bytes, offset, formatterResolver, out readSize);
+ offset += readSize;
+ var value = formatter.Deserialize(bytes, offset, formatterResolver, out readSize);
+ offset += readSize;
+ dict.Add(key, value);
+ }
+
+ readSize = offset - startOffset;
+ return dict;
+ }
+ }
+
+ public sealed class NonGenericInterfaceDictionaryFormatter : IMessagePackFormatter<IDictionary>
+ {
+ public static readonly IMessagePackFormatter<IDictionary> Instance = new NonGenericInterfaceDictionaryFormatter();
+
+ NonGenericInterfaceDictionaryFormatter()
+ {
+
+ }
+
+ public int Serialize(ref byte[] bytes, int offset, IDictionary value, IFormatterResolver formatterResolver)
+ {
+ if (value == null)
+ {
+ MessagePackBinary.WriteNil(ref bytes, offset);
+ return 1;
+ }
+
+ var formatter = formatterResolver.GetFormatterWithVerify<object>();
+ var startOffset = offset;
+
+ offset += MessagePackBinary.WriteMapHeader(ref bytes, offset, value.Count);
+ foreach (DictionaryEntry item in value)
+ {
+ offset += formatter.Serialize(ref bytes, offset, item.Key, formatterResolver);
+ offset += formatter.Serialize(ref bytes, offset, item.Value, formatterResolver);
+ }
+
+ return offset - startOffset;
+ }
+
+ public IDictionary Deserialize(byte[] bytes, int offset, IFormatterResolver formatterResolver, out int readSize)
+ {
+ if (MessagePackBinary.IsNil(bytes, offset))
+ {
+ readSize = 1;
+ return null;
+ }
+
+ var formatter = formatterResolver.GetFormatterWithVerify<object>();
+ var startOffset = offset;
+
+ var count = MessagePackBinary.ReadMapHeader(bytes, offset, out readSize);
+ offset += readSize;
+
+ var dict = new Dictionary<object, object>(count);
+ for (int i = 0; i < count; i++)
+ {
+ var key = formatter.Deserialize(bytes, offset, formatterResolver, out readSize);
+ offset += readSize;
+ var value = formatter.Deserialize(bytes, offset, formatterResolver, out readSize);
+ offset += readSize;
+ dict.Add(key, value);
+ }
+
+ readSize = offset - startOffset;
+ return dict;
+ }
+ }
+
#if NETSTANDARD1_4
public sealed class ObservableCollectionFormatter<T> : CollectionFormatterBase<T, ObservableCollection<T>>
diff --git a/src/MessagePack/Formatters/IMessagePackFormatter.cs b/src/MessagePack/Formatters/IMessagePackFormatter.cs
index 7015b21b..2ae40a15 100644
--- a/src/MessagePack/Formatters/IMessagePackFormatter.cs
+++ b/src/MessagePack/Formatters/IMessagePackFormatter.cs
@@ -1,7 +1,13 @@

namespace MessagePack.Formatters
{
- public interface IMessagePackFormatter<T>
+ // marker
+ public interface IMessagePackFormatter
+ {
+
+ }
+
+ public interface IMessagePackFormatter<T> : IMessagePackFormatter
{
int Serialize(ref byte[] bytes, int offset, T value, IFormatterResolver formatterResolver);
T Deserialize(byte[] bytes, int offset, IFormatterResolver formatterResolver, out int readSize);
diff --git a/src/MessagePack/Formatters/IgnoreFormatter.cs b/src/MessagePack/Formatters/IgnoreFormatter.cs
new file mode 100644
index 00000000..cbf38bac
--- /dev/null
+++ b/src/MessagePack/Formatters/IgnoreFormatter.cs
@@ -0,0 +1,16 @@
+namespace MessagePack.Formatters
+{
+ public sealed class IgnoreFormatter<T> : IMessagePackFormatter<T>
+ {
+ public int Serialize(ref byte[] bytes, int offset, T value, IFormatterResolver formatterResolver)
+ {
+ return MessagePackBinary.WriteNil(ref bytes, offset);
+ }
+
+ public T Deserialize(byte[] bytes, int offset, IFormatterResolver formatterResolver, out int readSize)
+ {
+ readSize = MessagePackBinary.ReadNextBlock(bytes, offset);
+ return default(T);
+ }
+ }
+} \ No newline at end of file
diff --git a/src/MessagePack/Resolvers/CompositeResolver.cs b/src/MessagePack/Resolvers/CompositeResolver.cs
index ea4b409e..beac4d22 100644
--- a/src/MessagePack/Resolvers/CompositeResolver.cs
+++ b/src/MessagePack/Resolvers/CompositeResolver.cs
@@ -1,7 +1,6 @@
using MessagePack.Formatters;
using System;
-using System.Collections.Generic;
-using System.Text;
+using System.Reflection;
namespace MessagePack.Resolvers
{
@@ -10,6 +9,7 @@ namespace MessagePack.Resolvers
public static readonly CompositeResolver Instance = new CompositeResolver();
static bool isFreezed = false;
+ static IMessagePackFormatter[] formatters = new IMessagePackFormatter[0];
static IFormatterResolver[] resolvers = new IFormatterResolver[0];
CompositeResolver()
@@ -26,12 +26,46 @@ namespace MessagePack.Resolvers
CompositeResolver.resolvers = resolvers;
}
+ public static void Register(params IMessagePackFormatter[] formatters)
+ {
+ if (isFreezed)
+ {
+ throw new InvalidOperationException("Register must call on startup(before use GetFormatter<T>).");
+ }
+
+ CompositeResolver.formatters = formatters;
+ }
+
+ public static void Register(IMessagePackFormatter[] formatters, IFormatterResolver[] resolvers)
+ {
+ if (isFreezed)
+ {
+ throw new InvalidOperationException("Register must call on startup(before use GetFormatter<T>).");
+ }
+
+ CompositeResolver.resolvers = resolvers;
+ CompositeResolver.formatters = formatters;
+ }
+
public static void RegisterAndSetAsDefault(params IFormatterResolver[] resolvers)
{
Register(resolvers);
MessagePack.MessagePackSerializer.SetDefaultResolver(CompositeResolver.Instance);
}
+ public static void RegisterAndSetAsDefault(params IMessagePackFormatter[] formatters)
+ {
+ Register(formatters);
+ MessagePack.MessagePackSerializer.SetDefaultResolver(CompositeResolver.Instance);
+ }
+
+ public static void RegisterAndSetAsDefault(IMessagePackFormatter[] formatters, IFormatterResolver[] resolvers)
+ {
+ Register(formatters);
+ Register(resolvers);
+ MessagePack.MessagePackSerializer.SetDefaultResolver(CompositeResolver.Instance);
+ }
+
public IMessagePackFormatter<T> GetFormatter<T>()
{
return FormatterCache<T>.formatter;
@@ -45,6 +79,19 @@ namespace MessagePack.Resolvers
{
isFreezed = true;
+ foreach (var item in formatters)
+ {
+ foreach (var implInterface in item.GetType().GetTypeInfo().ImplementedInterfaces)
+ {
+ var ti = implInterface.GetTypeInfo();
+ if (ti.IsGenericType && ti.GenericTypeArguments[0] == typeof(T))
+ {
+ formatter = (IMessagePackFormatter<T>)item;
+ return;
+ }
+ }
+ }
+
foreach (var item in resolvers)
{
var f = item.GetFormatter<T>();
diff --git a/src/MessagePack/Resolvers/DynamicGenericResolver.cs b/src/MessagePack/Resolvers/DynamicGenericResolver.cs
index ef68368f..eb4f4fcb 100644
--- a/src/MessagePack/Resolvers/DynamicGenericResolver.cs
+++ b/src/MessagePack/Resolvers/DynamicGenericResolver.cs
@@ -7,6 +7,7 @@ using System;
using System.Collections.Generic;
using System.Reflection;
using System.Collections.ObjectModel;
+using System.Collections;
#if NETSTANDARD1_4
using System.Threading.Tasks;
@@ -268,6 +269,26 @@ namespace MessagePack.Internal
}
}
}
+ else
+ {
+ // NonGeneric Collection
+ if (t == typeof(IList))
+ {
+ return NonGenericInterfaceListFormatter.Instance;
+ }
+ else if (t == typeof(IDictionary))
+ {
+ return NonGenericInterfaceDictionaryFormatter.Instance;
+ }
+ if (typeof(IList).GetTypeInfo().IsAssignableFrom(ti) && ti.DeclaredConstructors.Any(x => x.GetParameters().Length == 0))
+ {
+ return Activator.CreateInstance(typeof(NonGenericListFormatter<>).MakeGenericType(t));
+ }
+ else if (typeof(IDictionary).GetTypeInfo().IsAssignableFrom(ti) && ti.DeclaredConstructors.Any(x => x.GetParameters().Length == 0))
+ {
+ return Activator.CreateInstance(typeof(NonGenericDictionaryFormatter<>).MakeGenericType(t));
+ }
+ }
return null;
}
diff --git a/tests/MessagePack.Tests/MessagePack.Tests.csproj b/tests/MessagePack.Tests/MessagePack.Tests.csproj
index aabec998..5e934092 100644
--- a/tests/MessagePack.Tests/MessagePack.Tests.csproj
+++ b/tests/MessagePack.Tests/MessagePack.Tests.csproj
@@ -109,6 +109,7 @@
<Compile Include="CollectionTest.cs" />
<Compile Include="DataContractTest.cs" />
<Compile Include="DynamicObjectFallbackTest.cs" />
+ <Compile Include="NonGenericCollectionTest.cs" />
<Compile Include="StreamStrictTest.cs" />
<Compile Include="ThreadsafeHashtableTest.cs" />
<Compile Include="TypelessContractlessStandardResolverTest.cs" />
diff --git a/tests/MessagePack.Tests/NonGenericCollectionTest.cs b/tests/MessagePack.Tests/NonGenericCollectionTest.cs
new file mode 100644
index 00000000..857f9e1b
--- /dev/null
+++ b/tests/MessagePack.Tests/NonGenericCollectionTest.cs
@@ -0,0 +1,60 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Xunit;
+
+namespace MessagePack.Tests
+{
+ public class NonGenericCollectionTest
+ {
+ [Fact]
+ public void List()
+ {
+ var xs = new System.Collections.ArrayList { 1, 100, "hoge", 999.888 };
+ {
+ var bin = MessagePackSerializer.Serialize<IList>(xs);
+ var v = MessagePackSerializer.Deserialize<IList>(bin);
+
+ ((byte)v[0]).Is((byte)1);
+ ((byte)v[1]).Is((byte)100);
+ ((string)v[2]).Is("hoge");
+ ((double)v[3]).Is(999.888);
+ }
+ {
+ var bin = MessagePackSerializer.Serialize(xs);
+ var v = MessagePackSerializer.Deserialize<ArrayList>(bin);
+
+ ((byte)v[0]).Is((byte)1);
+ ((byte)v[1]).Is((byte)100);
+ ((string)v[2]).Is("hoge");
+ ((double)v[3]).Is(999.888);
+ }
+ }
+
+ [Fact]
+ public void Dictionary()
+ {
+ {
+ var xs = new System.Collections.Hashtable { { "a", 1 }, { 100, "hoge" }, { "foo", 999.888 } };
+ var bin = MessagePackSerializer.Serialize<IDictionary>(xs);
+ var v = MessagePackSerializer.Deserialize<IDictionary>(bin);
+
+ v["a"].Is((object)(byte)1);
+ v[(byte)100].Is((object)(string)"hoge");
+ v["foo"].Is((object)(double)999.888);
+ }
+ {
+ var xs = new System.Collections.Hashtable { { "a", 1 }, { 100, "hoge" }, { "foo", 999.888 } };
+ var bin = MessagePackSerializer.Serialize<Hashtable>(xs);
+ var v = MessagePackSerializer.Deserialize<Hashtable>(bin);
+
+ v["a"].Is((object)(byte)1);
+ v[(byte)100].Is((object)(string)"hoge");
+ v["foo"].Is((object)(double)999.888);
+ }
+ }
+ }
+}