using MessagePack.Internal; using System; using System.IO; namespace MessagePack { /// /// High-Level API of MessagePack for C#. /// public static partial class MessagePackSerializer { static IFormatterResolver defaultResolver; /// /// FormatterResolver that used resolver less overloads. If does not set it, used StandardResolver. /// public static IFormatterResolver DefaultResolver { get { if (defaultResolver == null) { defaultResolver = MessagePack.Resolvers.StandardResolver.Instance; } return defaultResolver; } } /// /// Is resolver decided? /// public static bool IsInitialized { get { return defaultResolver != null; } } /// /// Set default resolver of MessagePackSerializer APIs. /// /// public static void SetDefaultResolver(IFormatterResolver resolver) { defaultResolver = resolver; } /// /// Serialize to binary with default resolver. /// public static byte[] Serialize(T obj) { return Serialize(obj, defaultResolver); } /// /// Serialize to binary with specified resolver. /// public static byte[] Serialize(T obj, IFormatterResolver resolver) { if (resolver == null) resolver = DefaultResolver; var formatter = resolver.GetFormatterWithVerify(); var buffer = InternalMemoryPool.GetBuffer(); var len = formatter.Serialize(ref buffer, 0, obj, resolver); // do not return MemoryPool.Buffer. return MessagePackBinary.FastCloneWithResize(buffer, len); } /// /// Serialize to binary. Get the raw memory pool byte[]. The result can not share across thread and can not hold, so use quickly. /// public static ArraySegment SerializeUnsafe(T obj) { return SerializeUnsafe(obj, defaultResolver); } /// /// 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. /// public static ArraySegment SerializeUnsafe(T obj, IFormatterResolver resolver) { if (resolver == null) resolver = DefaultResolver; var formatter = resolver.GetFormatterWithVerify(); var buffer = InternalMemoryPool.GetBuffer(); var len = formatter.Serialize(ref buffer, 0, obj, resolver); // return raw memory pool, unsafe! return new ArraySegment(buffer, 0, len); } /// /// Serialize to stream. /// public static void Serialize(Stream stream, T obj) { Serialize(stream, obj, defaultResolver); } /// /// Serialize to stream with specified resolver. /// public static void Serialize(Stream stream, T obj, IFormatterResolver resolver) { if (resolver == null) resolver = DefaultResolver; var formatter = resolver.GetFormatterWithVerify(); var buffer = InternalMemoryPool.GetBuffer(); var len = formatter.Serialize(ref buffer, 0, obj, resolver); // do not need resize. stream.Write(buffer, 0, len); } public static T Deserialize(byte[] bytes) { return Deserialize(bytes, defaultResolver); } public static T Deserialize(byte[] bytes, IFormatterResolver resolver) { if (resolver == null) resolver = DefaultResolver; var formatter = resolver.GetFormatterWithVerify(); int readSize; return formatter.Deserialize(bytes, 0, resolver, out readSize); } public static T Deserialize(ArraySegment bytes) { return Deserialize(bytes, defaultResolver); } public static T Deserialize(ArraySegment bytes, IFormatterResolver resolver) { if (resolver == null) resolver = DefaultResolver; var formatter = resolver.GetFormatterWithVerify(); int readSize; return formatter.Deserialize(bytes.Array, bytes.Offset, resolver, out readSize); } public static T Deserialize(Stream stream) { return Deserialize(stream, defaultResolver); } public static T Deserialize(Stream stream, IFormatterResolver resolver) { return Deserialize(stream, resolver, false); } public static T Deserialize(Stream stream, bool readStrict) { return Deserialize(stream, defaultResolver, readStrict); } public static T Deserialize(Stream stream, IFormatterResolver resolver, bool readStrict) { if (resolver == null) resolver = DefaultResolver; var formatter = resolver.GetFormatterWithVerify(); if (!readStrict) { #if NETSTANDARD1_4 && !NET45 var ms = stream as MemoryStream; if (ms != null) { // optimize for MemoryStream ArraySegment 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); } } 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; } } }