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:
Diffstat (limited to 'src/MessagePack/MessagePackSerializer.cs')
-rw-r--r--src/MessagePack/MessagePackSerializer.cs277
1 files changed, 104 insertions, 173 deletions
diff --git a/src/MessagePack/MessagePackSerializer.cs b/src/MessagePack/MessagePackSerializer.cs
index b11efad4..b48ff70c 100644
--- a/src/MessagePack/MessagePackSerializer.cs
+++ b/src/MessagePack/MessagePackSerializer.cs
@@ -1,6 +1,8 @@
-using MessagePack.Internal;
-using System;
+using System;
+using System.Buffers;
using System.IO;
+using System.Threading.Tasks;
+using MessagePack.Internal;
namespace MessagePack
{
@@ -42,233 +44,162 @@ namespace MessagePack
}
/// <summary>
- /// Serialize to binary.
+ /// Serializes a given value with the specified buffer writer.
/// </summary>
- public byte[] Serialize<T>(T obj) => this.Serialize<T>(obj, this.DefaultResolver);
-
- /// <summary>
- /// Serialize to binary.
- /// </summary>
- public virtual byte[] Serialize<T>(T obj, IFormatterResolver resolver)
+ /// <param name="writer">The buffer writer to serialize with.</param>
+ /// <param name="value">The value to serialize.</param>
+ /// <param name="resolver">The resolver to use during deserialization. Use <c>null</c> to use the <see cref="DefaultResolver"/>.</param>
+ public virtual void Serialize<T>(IBufferWriter<byte> writer, T value, IFormatterResolver resolver)
{
- if (resolver == null) resolver = DefaultResolver;
- var formatter = resolver.GetFormatterWithVerify<T>();
-
- var buffer = InternalMemoryPool.GetBuffer();
+ if (writer == null)
+ {
+ throw new ArgumentNullException(nameof(writer));
+ }
- var len = formatter.Serialize(ref buffer, 0, obj, resolver);
+ if (resolver == null)
+ {
+ resolver = this.DefaultResolver;
+ }
- // do not return MemoryPool.Buffer.
- return MessagePackBinary.FastCloneWithResize(buffer, len);
+ var formatter = resolver.GetFormatterWithVerify<T>();
+ formatter.Serialize(writer, value, resolver);
}
/// <summary>
- /// Serialize to binary. Get the raw memory pool byte[]. The result can not share across thread and can not hold, so use quickly.
+ /// Deserializes a value of a given type from a sequence of bytes.
/// </summary>
- protected ArraySegment<byte> SerializeUnsafe<T>(T obj, IFormatterResolver resolver)
+ /// <typeparam name="T">The type of value to deserialize.</typeparam>
+ /// <param name="byteSequence">The sequence to deserialize from.</param>
+ /// <param name="resolver">The resolver to use during deserialization. Use <c>null</c> to use the <see cref="DefaultResolver"/>.</param>
+ /// <param name="endPosition">The position in the <paramref name="byteSequence"/> just after the last read byte.</param>
+ /// <returns>The deserialized value.</returns>
+ public virtual T Deserialize<T>(ReadOnlySequence<byte> byteSequence, IFormatterResolver resolver, out SequencePosition endPosition)
{
- if (resolver == null) resolver = DefaultResolver;
- var formatter = resolver.GetFormatterWithVerify<T>();
-
- var buffer = InternalMemoryPool.GetBuffer();
-
- var len = formatter.Serialize(ref buffer, 0, obj, resolver);
+ if (resolver == null)
+ {
+ resolver = this.DefaultResolver;
+ }
- // return raw memory pool, unsafe!
- return new ArraySegment<byte>(buffer, 0, len);
+ return resolver.GetFormatterWithVerify<T>().Deserialize(byteSequence, resolver, out endPosition);
}
/// <summary>
- /// Serialize to stream.
+ /// Serializes a given value with the specified buffer writer.
/// </summary>
- public void Serialize<T>(Stream stream, T obj) => this.Serialize<T>(stream, obj, DefaultResolver);
+ /// <param name="value">The value to serialize.</param>
+ /// <param name="resolver">The resolver to use during deserialization. Use <c>null</c> to use the <see cref="DefaultResolver"/>.</param>
+ /// <returns>A byte array with the serialized value.</returns>
+ public byte[] Serialize<T>(T value, IFormatterResolver resolver = null)
+ {
+ throw new NotImplementedException();
+ }
/// <summary>
- /// Serialize to stream.
+ /// Serializes a given value to the specified stream.
/// </summary>
- public virtual void Serialize<T>(Stream stream, T obj, IFormatterResolver resolver)
+ /// <param name="stream">The stream to serialize to.</param>
+ /// <param name="value">The value to serialize.</param>
+ /// <param name="resolver">The resolver to use during deserialization. Use <c>null</c> to use the <see cref="DefaultResolver"/>.</param>
+ public void Serialize<T>(Stream stream, T value, IFormatterResolver resolver = null)
{
- if (stream == null)
- {
- throw new ArgumentNullException(nameof(stream));
- }
-
- 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);
+ throw new NotImplementedException();
}
/// <summary>
- /// Reflect of resolver.GetFormatterWithVerify[T].Serialize.
+ /// Serializes a given value to the specified stream.
/// </summary>
- public int Serialize<T>(ref byte[] bytes, int offset, T value, IFormatterResolver resolver)
+ /// <param name="stream">The stream to serialize to.</param>
+ /// <param name="value">The value to serialize.</param>
+ /// <param name="resolver">The resolver to use during deserialization. Use <c>null</c> to use the <see cref="DefaultResolver"/>.</param>
+ /// <returns>A task that completes with the result of the async serialization operation.</returns>
+ public Task SerializeAsync<T>(Stream stream, T value, IFormatterResolver resolver = null)
{
- if (resolver == null) resolver = DefaultResolver;
- return resolver.GetFormatterWithVerify<T>().Serialize(ref bytes, offset, value, resolver);
+ throw new NotImplementedException();
}
-#if NETSTANDARD || NETFRAMEWORK
-
/// <summary>
- /// Serialize to stream(async).
+ /// Deserializes a value of a given type from a sequence of bytes.
/// </summary>
- public System.Threading.Tasks.Task SerializeAsync<T>(Stream stream, T obj) => SerializeAsync<T>(stream, obj, DefaultResolver);
+ /// <typeparam name="T">The type of value to deserialize.</typeparam>
+ /// <param name="buffer">The buffer to deserialize from.</param>
+ /// <param name="resolver">The resolver to use during deserialization. Use <c>null</c> to use the <see cref="DefaultResolver"/>.</param>
+ /// <returns>The deserialized value.</returns>
+ public T Deserialize<T>(Memory<byte> buffer, IFormatterResolver resolver = null) => this.Deserialize<T>(new ReadOnlySequence<byte>(buffer), resolver, out SequencePosition endPosition);
/// <summary>
- /// Serialize to stream(async).
+ /// Deserializes a value of a given type from a sequence of bytes.
/// </summary>
- public async System.Threading.Tasks.Task SerializeAsync<T>(Stream stream, T obj, IFormatterResolver resolver)
+ /// <typeparam name="T">The type of value to deserialize.</typeparam>
+ /// <param name="buffer">The array to deserialize from.</param>
+ /// <param name="offset">The position in the array to start deserialization.</param>
+ /// <param name="resolver">The resolver to use during deserialization. Use <c>null</c> to use the <see cref="DefaultResolver"/>.</param>
+ /// <returns>The deserialized value.</returns>
+ public T Deserialize<T>(byte[] buffer, int offset = 0, IFormatterResolver resolver = null)
{
- 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
+ if (buffer == null)
{
- BufferPool.Default.Return(rentBuffer);
+ throw new ArgumentNullException(nameof(buffer));
}
- }
-
-#endif
-
- public T Deserialize<T>(byte[] bytes) => Deserialize<T>(bytes, DefaultResolver);
- public T Deserialize<T>(byte[] bytes, IFormatterResolver resolver) => Deserialize<T>(new ArraySegment<byte>(bytes), resolver);
-
- public T Deserialize<T>(ArraySegment<byte> bytes) => Deserialize<T>(bytes, DefaultResolver);
-
- public T Deserialize<T>(ArraySegment<byte> bytes, IFormatterResolver resolver) => Deserialize<T>(bytes, resolver, out int readSize);
-
- public virtual T Deserialize<T>(ArraySegment<byte> bytes, IFormatterResolver resolver, out int readSize)
- {
- if (resolver == null) resolver = DefaultResolver;
- return resolver.GetFormatterWithVerify<T>().Deserialize(bytes.Array, bytes.Offset, resolver, out readSize);
+ var sequence = new ReadOnlySequence<byte>(buffer.AsMemory(offset));
+ return Deserialize<T>(sequence, resolver, out SequencePosition endPosition);
}
- public T Deserialize<T>(Stream stream) => Deserialize<T>(stream, DefaultResolver, readStrict: false);
-
- public T Deserialize<T>(Stream stream, IFormatterResolver resolver) => Deserialize<T>(stream, resolver, readStrict: false);
-
- public T Deserialize<T>(Stream stream, bool readStrict) => Deserialize<T>(stream, DefaultResolver, readStrict);
-
- public virtual T Deserialize<T>(Stream stream, IFormatterResolver resolver, bool readStrict)
+ /// <summary>
+ /// Deserializes a value of a given type from a sequence of bytes.
+ /// </summary>
+ /// <typeparam name="T">The type of value to deserialize.</typeparam>
+ /// <param name="buffer">The array to deserialize from.</param>
+ /// <param name="offset">The position in the array to start deserialization.</param>
+ /// <param name="resolver">The resolver to use during deserialization. Use <c>null</c> to use the <see cref="DefaultResolver"/>.</param>
+ /// <param name="bytesRead">The number of bytes read.</param>
+ /// <returns>The deserialized value.</returns>
+ public T Deserialize<T>(byte[] buffer, int offset, IFormatterResolver resolver, out int bytesRead)
{
- 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
+ if (buffer == null)
{
- int _;
- var bytes = MessagePackBinary.ReadMessageBlockFromStreamUnsafe(stream, false, out _);
- int readSize;
- return formatter.Deserialize(bytes, 0, resolver, out readSize);
+ throw new ArgumentNullException(nameof(buffer));
}
+
+ var sequence = new ReadOnlySequence<byte>(buffer.AsMemory(offset));
+ T result = Deserialize<T>(sequence, resolver, out SequencePosition endPosition);
+ bytesRead = endPosition.GetInteger(); // we know the sequence has just one segment, so this is safe.
+ return result;
}
/// <summary>
- /// Reflect of resolver.GetFormatterWithVerify[T].Deserialize.
+ /// Deserializes a value of a given type from a stream.
/// </summary>
- public T Deserialize<T>(byte[] bytes, int offset, IFormatterResolver resolver, out int readSize) => Deserialize<T>(new ArraySegment<byte>(bytes, offset, bytes.Length - offset), resolver, out readSize);
-
-#if NETSTANDARD || NETFRAMEWORK
-
- public System.Threading.Tasks.Task<T> DeserializeAsync<T>(Stream stream) => DeserializeAsync<T>(stream, DefaultResolver);
-
- // readStrict async read is too slow(many Task garbage) so I don't provide async option.
-
- public async System.Threading.Tasks.Task<T> DeserializeAsync<T>(Stream stream, IFormatterResolver resolver)
+ /// <typeparam name="T">The type of value to deserialize.</typeparam>
+ /// <param name="stream">The stream to deserialize from.</param>
+ /// <param name="resolver">The resolver to use during deserialization. Use <c>null</c> to use the <see cref="DefaultResolver"/>.</param>
+ /// <returns>The deserialized value.</returns>
+ public T Deserialize<T>(Stream stream, IFormatterResolver resolver = null)
{
- if (resolver == null) resolver = DefaultResolver;
- 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);
- }
+ throw new NotImplementedException();
}
-#endif
-
- static int FillFromStream(Stream input, ref byte[] buffer)
+ /// <summary>
+ /// Deserializes a value of a given type from a stream.
+ /// </summary>
+ /// <typeparam name="T">The type of value to deserialize.</typeparam>
+ /// <param name="stream">The stream to deserialize from.</param>
+ /// <param name="resolver">The resolver to use during deserialization. Use <c>null</c> to use the <see cref="DefaultResolver"/>.</param>
+ /// <returns>The deserialized value.</returns>
+ public ValueTask<T> DeserializeAsync<T>(Stream stream, IFormatterResolver resolver = null)
{
- 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;
+ throw new NotImplementedException();
}
}
}
namespace MessagePack.Internal
{
+ // TODO: remove this?
internal static class InternalMemoryPool
{
[ThreadStatic]
- static byte[] buffer = null;
+ private static byte[] buffer = null;
public static byte[] GetBuffer()
{