海淀天下城电子沙盘单机版
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.
 
 
 
 

327 lines
10 KiB

using MessagePack.Internal;
using System;
using System.IO;
namespace MessagePack
{
/// <summary>
/// High-Level API of MessagePack for C#.
/// </summary>
public static partial class MessagePackSerializer
{
static IFormatterResolver defaultResolver;
/// <summary>
/// FormatterResolver that used resolver less overloads. If does not set it, used StandardResolver.
/// </summary>
public static IFormatterResolver DefaultResolver
{
get
{
if (defaultResolver == null)
{
defaultResolver = MessagePack.Resolvers.StandardResolver.Instance;
}
return defaultResolver;
}
}
/// <summary>
/// Is resolver decided?
/// </summary>
public static bool IsInitialized
{
get
{
return defaultResolver != null;
}
}
/// <summary>
/// Set default resolver of MessagePackSerializer APIs.
/// </summary>
/// <param name="resolver"></param>
public static void SetDefaultResolver(IFormatterResolver resolver)
{
defaultResolver = resolver;
}
/// <summary>
/// Serialize to binary with default resolver.
/// </summary>
public static byte[] Serialize<T>(T obj)
{
return Serialize(obj, defaultResolver);
}
/// <summary>
/// Serialize to binary with specified resolver.
/// </summary>
public static byte[] Serialize<T>(T obj, IFormatterResolver resolver)
{
if (resolver == null) resolver = DefaultResolver;
var formatter = resolver.GetFormatterWithVerify<T>();
var buffer = InternalMemoryPool.GetBuffer();
var len = formatter.Serialize(ref buffer, 0, obj, resolver);
// do not return MemoryPool.Buffer.
return MessagePackBinary.FastCloneWithResize(buffer, len);
}
/// <summary>
/// Serialize to binary. Get the raw memory pool byte[]. The result can not share across thread and can not hold, so use quickly.
/// </summary>
public static ArraySegment<byte> SerializeUnsafe<T>(T obj)
{
return SerializeUnsafe(obj, defaultResolver);
}
/// <summary>
/// Serialize to binary with specified resolver. Get the raw memory pool byte[]. The result can not share across thread and can not hold, so use quickly.
/// </summary>
public static ArraySegment<byte> SerializeUnsafe<T>(T obj, IFormatterResolver resolver)
{
if (resolver == null) resolver = DefaultResolver;
var formatter = resolver.GetFormatterWithVerify<T>();
var buffer = InternalMemoryPool.GetBuffer();
var len = formatter.Serialize(ref buffer, 0, obj, resolver);
// return raw memory pool, unsafe!
return new ArraySegment<byte>(buffer, 0, len);
}
/// <summary>
/// Serialize to stream.
/// </summary>
public static void Serialize<T>(Stream stream, T obj)
{
Serialize(stream, obj, defaultResolver);
}
/// <summary>
/// Serialize to stream with specified resolver.
/// </summary>
public static void Serialize<T>(Stream stream, T obj, IFormatterResolver resolver)
{
if (resolver == null) resolver = DefaultResolver;
var formatter = resolver.GetFormatterWithVerify<T>();
var buffer = InternalMemoryPool.GetBuffer();
var len = formatter.Serialize(ref buffer, 0, obj, resolver);
// do not need resize.
stream.Write(buffer, 0, len);
}
/// <summary>
/// Reflect of resolver.GetFormatterWithVerify[T].Serialize.
/// </summary>
public static int Serialize<T>(ref byte[] bytes, int offset, T value, IFormatterResolver resolver)
{
return resolver.GetFormatterWithVerify<T>().Serialize(ref bytes, offset, value, resolver);
}
#if NETSTANDARD
/// <summary>
/// Serialize to stream(async).
/// </summary>
public static System.Threading.Tasks.Task SerializeAsync<T>(Stream stream, T obj)
{
return SerializeAsync(stream, obj, defaultResolver);
}
/// <summary>
/// Serialize to stream(async) with specified resolver.
/// </summary>
public static async System.Threading.Tasks.Task SerializeAsync<T>(Stream stream, T obj, IFormatterResolver resolver)
{
if (resolver == null) resolver = DefaultResolver;
var formatter = resolver.GetFormatterWithVerify<T>();
var rentBuffer = BufferPool.Default.Rent();
try
{
var buffer = rentBuffer;
var len = formatter.Serialize(ref buffer, 0, obj, resolver);
// do not need resize.
await stream.WriteAsync(buffer, 0, len).ConfigureAwait(false);
}
finally
{
BufferPool.Default.Return(rentBuffer);
}
}
#endif
public static T Deserialize<T>(byte[] bytes)
{
return Deserialize<T>(bytes, defaultResolver);
}
public static T Deserialize<T>(byte[] bytes, IFormatterResolver resolver)
{
if (resolver == null) resolver = DefaultResolver;
var formatter = resolver.GetFormatterWithVerify<T>();
int readSize;
return formatter.Deserialize(bytes, 0, resolver, out readSize);
}
public static T Deserialize<T>(ArraySegment<byte> bytes)
{
return Deserialize<T>(bytes, defaultResolver);
}
public static T Deserialize<T>(ArraySegment<byte> bytes, IFormatterResolver resolver)
{
if (resolver == null) resolver = DefaultResolver;
var formatter = resolver.GetFormatterWithVerify<T>();
int readSize;
return formatter.Deserialize(bytes.Array, bytes.Offset, resolver, out readSize);
}
public static T Deserialize<T>(Stream stream)
{
return Deserialize<T>(stream, defaultResolver);
}
public static T Deserialize<T>(Stream stream, IFormatterResolver resolver)
{
return Deserialize<T>(stream, resolver, false);
}
public static T Deserialize<T>(Stream stream, bool readStrict)
{
return Deserialize<T>(stream, defaultResolver, readStrict);
}
public static T Deserialize<T>(Stream stream, IFormatterResolver resolver, bool readStrict)
{
if (resolver == null) resolver = DefaultResolver;
var formatter = resolver.GetFormatterWithVerify<T>();
if (!readStrict)
{
#if NETSTANDARD && !NET45
var ms = stream as MemoryStream;
if (ms != null)
{
// optimize for MemoryStream
ArraySegment<byte> buffer;
if (ms.TryGetBuffer(out buffer))
{
int readSize;
return formatter.Deserialize(buffer.Array, buffer.Offset, resolver, out readSize);
}
}
#endif
// no else.
{
var buffer = InternalMemoryPool.GetBuffer();
FillFromStream(stream, ref buffer);
int readSize;
return formatter.Deserialize(buffer, 0, resolver, out readSize);
}
}
else
{
int _;
var bytes = MessagePackBinary.ReadMessageBlockFromStreamUnsafe(stream, false, out _);
int readSize;
return formatter.Deserialize(bytes, 0, resolver, out readSize);
}
}
/// <summary>
/// Reflect of resolver.GetFormatterWithVerify[T].Deserialize.
/// </summary>
public static T Deserialize<T>(byte[] bytes, int offset, IFormatterResolver resolver, out int readSize)
{
return resolver.GetFormatterWithVerify<T>().Deserialize(bytes, offset, resolver, out readSize);
}
#if NETSTANDARD
public static System.Threading.Tasks.Task<T> DeserializeAsync<T>(Stream stream)
{
return DeserializeAsync<T>(stream, defaultResolver);
}
// readStrict async read is too slow(many Task garbage) so I don't provide async option.
public static async System.Threading.Tasks.Task<T> DeserializeAsync<T>(Stream stream, IFormatterResolver resolver)
{
var rentBuffer = BufferPool.Default.Rent();
var buf = rentBuffer;
try
{
int length = 0;
int read;
while ((read = await stream.ReadAsync(buf, length, buf.Length - length).ConfigureAwait(false)) > 0)
{
length += read;
if (length == buf.Length)
{
MessagePackBinary.FastResize(ref buf, length * 2);
}
}
return Deserialize<T>(buf, resolver);
}
finally
{
BufferPool.Default.Return(rentBuffer);
}
}
#endif
static int FillFromStream(Stream input, ref byte[] buffer)
{
int length = 0;
int read;
while ((read = input.Read(buffer, length, buffer.Length - length)) > 0)
{
length += read;
if (length == buffer.Length)
{
MessagePackBinary.FastResize(ref buffer, length * 2);
}
}
return length;
}
}
}
namespace MessagePack.Internal
{
internal static class InternalMemoryPool
{
[ThreadStatic]
static byte[] buffer = null;
public static byte[] GetBuffer()
{
if (buffer == null)
{
buffer = new byte[65536];
}
return buffer;
}
}
}