using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Runtime.CompilerServices;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;
using ZeroLevel.Services.Extensions;
using ZeroLevel.Services.Memory;
namespace ZeroLevel.Services.Serialization
{
///
/// A wrapper over a MemoryStream for reading, with a check for overflow
///
public partial class MemoryStreamReader
: IBinaryReader
{
private readonly IViewAccessor _accessor;
private bool _reverseByteOrder = false;
public void ReverseByteOrder(bool use_reverse_byte_order)
{
_reverseByteOrder = use_reverse_byte_order;
}
///
/// End of stream
///
public bool EOS => _accessor.EOV;
public MemoryStreamReader(byte[] data)
{
if (data == null)
throw new ArgumentNullException(nameof(data));
_accessor = new StreamVewAccessor(new MemoryStream(data));
}
public MemoryStreamReader(Stream stream)
{
if (stream == null)
throw new ArgumentNullException(nameof(stream));
_accessor = new StreamVewAccessor(stream);
}
public MemoryStreamReader(MemoryStreamReader reader)
{
if (reader == null)
throw new ArgumentNullException(nameof(reader));
_accessor = reader._accessor;
}
public MemoryStreamReader(IViewAccessor accessor)
{
if (accessor == null)
throw new ArgumentNullException(nameof(accessor));
_accessor = accessor;
}
public long Position => _accessor.Position;
public void SetPosition(long position) => _accessor.Seek(position);
///
/// Flag reading
///
public bool ReadBoolean()
{
return BitConverter.ToBoolean(new byte[1] { ReadByte() }, 0);
}
///
/// Reading byte
///
public byte ReadByte()
{
var buffer = ReadBuffer(1);
return buffer[0];
}
public char ReadChar()
{
var buffer = ReadBuffer(2);
return BitConverter.ToChar(buffer, 0);
}
///
/// Reading bytes
///
///
public byte[] ReadBytes()
{
var length = BitConverter.ToInt32(ReadBuffer(4), 0);
if (length == 0) return new byte[0];
return ReadBuffer(length);
}
public short ReadShort()
{
var buffer = ReadBuffer(2);
return BitConverter.ToInt16(buffer, 0);
}
public ushort ReadUShort()
{
var buffer = ReadBuffer(2);
return BitConverter.ToUInt16(buffer, 0);
}
///
/// Read 32-bit integer (4 bytes)
///
public Int32 ReadInt32()
{
var buffer = ReadBuffer(4);
return BitConverter.ToInt32(buffer, 0);
}
public UInt32 ReadUInt32()
{
var buffer = ReadBuffer(4);
return BitConverter.ToUInt32(buffer, 0);
}
public decimal ReadDecimal()
{
var arr = ReadBuffer(16);
var p1 = BitConverter.ToInt32(arr, 0);
var p2 = BitConverter.ToInt32(arr, 4);
var p3 = BitConverter.ToInt32(arr, 8);
var p4 = BitConverter.ToInt32(arr, 12);
return BitConverterExt.ToDecimal(new int[] { p1, p2, p3, p4 });
}
///
/// Read integer 64-bit number (8 bytes)
///
public Int64 ReadLong()
{
var buffer = ReadBuffer(8);
return BitConverter.ToInt64(buffer, 0);
}
public UInt64 ReadULong()
{
var buffer = ReadBuffer(8);
return BitConverter.ToUInt64(buffer, 0);
}
public TimeSpan ReadTimeSpan()
{
return new TimeSpan(ReadLong());
}
public float ReadFloat()
{
var buffer = ReadBuffer(4);
return BitConverter.ToSingle(buffer, 0);
}
public double ReadDouble()
{
var buffer = ReadBuffer(8);
return BitConverter.ToDouble(buffer, 0);
}
///
/// Read string (4 bytes per length + Length bytes)
///
public string ReadString()
{
var length = BitConverter.ToInt32(ReadBuffer(4), 0);
if (length == 0) return null;
var buffer = ReadBuffer(length);
return Encoding.UTF8.GetString(buffer);
}
///
/// Read GUID (16 bytes)
///
public Guid ReadGuid()
{
var buffer = ReadBuffer(16);
return new Guid(buffer);
}
///
/// Reading byte-package (read the size of the specified number of bytes, and then the packet itself read size)
///
public byte[] ReadBuffer(int count)
{
if (CheckOutOfRange(count))
throw new OutOfMemoryException("Array index out of bounds");
var buffer = _accessor.ReadBuffer(count).Result;
if (_reverseByteOrder && count > 1)
{
byte b;
for (int i = 0; i < (count >> 1); i++)
{
b = buffer[i];
buffer[i] = buffer[count - i - 1];
buffer[count - i - 1] = b;
}
}
return buffer;
}
public bool TryReadBuffer(int count, out byte[] buffer)
{
if (CheckOutOfRange(count))
{
buffer = null;
return false;
}
try
{
buffer = _accessor.ReadBuffer(count).Result;
if (_reverseByteOrder && count > 1)
{
byte b;
for (int i = 0; i < (count >> 1); i++)
{
b = buffer[i];
buffer[i] = buffer[count - i - 1];
buffer[count - i - 1] = b;
}
}
}
catch (Exception ex)
{
Log.SystemError(ex, $"[MemoryStreamReader.TryReadBuffer] Fault read {count} bytes");
buffer = null;
return false;
}
return true;
}
///
/// Reading the datetime
///
///
public DateTime? ReadDateTime()
{
var is_null = ReadByte();
if (is_null == 0) return null;
var buffer = ReadBuffer(8);
long deserialized = BitConverter.ToInt64(buffer, 0);
return DateTime.FromBinary(deserialized);
}
public TimeOnly? ReadTime()
{
var is_null = ReadByte();
if (is_null == 0) return null;
var ts = ReadTimeSpan();
return TimeOnly.FromTimeSpan(ts);
}
public DateOnly? ReadDate()
{
var is_null = ReadByte();
if (is_null == 0) return null;
var days = ReadInt32();
return DateOnly.FromDayNumber(days);
}
public IPAddress ReadIP()
{
var exists = ReadByte();
if (exists == 1)
{
var addr = ReadBytes();
return new IPAddress(addr);
}
return null;
}
public IPEndPoint ReadIPEndpoint()
{
var exists = ReadByte();
if (exists == 1)
{
var addr = ReadIP();
var port = ReadInt32();
return new IPEndPoint(addr, port);
}
return null;
}
///
/// Check if data reading is outside the stream
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool CheckOutOfRange(int offset) => _accessor.CheckOutOfRange(offset);
#region Extensions
#region Collections
private List ReadList(Func read)
{
int count = ReadInt32();
var collection = new List(count);
if (count > 0)
{
for (int i = 0; i < count; i++)
{
collection.Add(read.Invoke());
}
}
return collection;
}
public List ReadCollection()
where T : IBinarySerializable, new()
=>
ReadList(() =>
{
var item = new T();
item.Deserialize(this);
return item;
});
public List ReadStringCollection() => ReadList(ReadString);
public List ReadIPCollection() => ReadList(ReadIP);
public List ReadIPEndPointCollection() => ReadList(ReadIPEndpoint);
public List ReadGuidCollection() => ReadList(ReadGuid);
public List ReadDateTimeCollection() => ReadList(ReadDateTime);
public List ReadInt64Collection() => ReadList(ReadLong);
public List ReadInt32Collection() => ReadList(ReadInt32);
public List ReadUInt64Collection() => ReadList(ReadULong);
public List ReadUInt32Collection() => ReadList(ReadUInt32);
public List ReadCharCollection() => ReadList(ReadChar);
public List ReadShortCollection() => ReadList(ReadShort);
public List ReadUShortCollection() => ReadList(ReadUShort);
public List ReadFloatCollection() => ReadList(ReadFloat);
public List ReadDoubleCollection() => ReadList(ReadDouble);
public List ReadBooleanCollection() => ReadList(ReadBoolean);
public List ReadByteCollection() => ReadList(ReadByte);
public List ReadByteArrayCollection() => ReadList(ReadBytes);
public List ReadDecimalCollection() => ReadList(ReadDecimal);
public List ReadTimeSpanCollection() => ReadList(ReadTimeSpan);
#endregion
#region Collections lazy
private IEnumerable ReadEnumerable(Func read)
{
int count = ReadInt32();
if (count > 0)
{
for (int i = 0; i < count; i++)
{
yield return read.Invoke();
}
}
}
public IEnumerable ReadCollectionLazy()
where T : IBinarySerializable, new()
=>
ReadEnumerable(() =>
{
var item = new T();
item.Deserialize(this);
return item;
});
public IEnumerable ReadStringCollectionLazy() => ReadEnumerable(ReadString);
public IEnumerable ReadIPCollectionLazy() => ReadEnumerable(ReadIP);
public IEnumerable ReadIPEndPointCollectionLazy() => ReadEnumerable(ReadIPEndpoint);
public IEnumerable ReadGuidCollectionLazy() => ReadEnumerable(ReadGuid);
public IEnumerable ReadDateTimeCollectionLazy() => ReadEnumerable(ReadDateTime);
public IEnumerable ReadInt64CollectionLazy() => ReadEnumerable(ReadLong);
public IEnumerable ReadInt32CollectionLazy() => ReadEnumerable(ReadInt32);
public IEnumerable ReadUInt64CollectionLazy() => ReadEnumerable(ReadULong);
public IEnumerable ReadUInt32CollectionLazy() => ReadEnumerable(ReadUInt32);
public IEnumerable ReadCharCollectionLazy() => ReadEnumerable(ReadChar);
public IEnumerable ReadShortCollectionLazy() => ReadEnumerable(ReadShort);
public IEnumerable ReadUShortCollectionLazy() => ReadEnumerable(ReadUShort);
public IEnumerable ReadFloatCollectionLazy() => ReadEnumerable(ReadFloat);
public IEnumerable ReadDoubleCollectionLazy() => ReadEnumerable(ReadDouble);
public IEnumerable ReadBooleanCollectionLazy() => ReadEnumerable(ReadBoolean);
public IEnumerable ReadByteCollectionLazy() => ReadEnumerable(ReadByte);
public IEnumerable ReadByteArrayCollectionLazy() => ReadEnumerable(ReadBytes);
public IEnumerable ReadDecimalCollectionLazy() => ReadEnumerable(ReadDecimal);
public IEnumerable ReadTimeSpanCollectionLazy() => ReadEnumerable(ReadTimeSpan);
#endregion
#region Arrays
private T[] ReadArray(Func read)
{
int count = ReadInt32();
var array = new T[count];
if (count > 0)
{
for (int i = 0; i < count; i++)
{
array[i] = read.Invoke();
}
}
return array;
}
public T[] ReadArray()
where T : IBinarySerializable, new()
=>
ReadArray(() =>
{
var item = new T();
item.Deserialize(this);
return item;
});
public string[] ReadStringArray() => ReadArray(ReadString);
public IPAddress[] ReadIPArray() => ReadArray(ReadIP);
public IPEndPoint[] ReadIPEndPointArray() => ReadArray(ReadIPEndpoint);
public Guid[] ReadGuidArray() => ReadArray(ReadGuid);
public DateTime?[] ReadDateTimeArray() => ReadArray(ReadDateTime);
public Int64[] ReadInt64Array() => ReadArray(ReadLong);
public Int32[] ReadInt32Array() => ReadArray(ReadInt32);
public UInt64[] ReadUInt64Array() => ReadArray(ReadULong);
public UInt32[] ReadUInt32Array() => ReadArray(ReadUInt32);
public char[] ReadCharArray() => ReadArray(ReadChar);
public short[] ReadShortArray() => ReadArray(ReadShort);
public ushort[] ReadUShortArray() => ReadArray(ReadUShort);
public float[] ReadFloatArray() => ReadArray(ReadFloat);
public Double[] ReadDoubleArray() => ReadArray(ReadDouble);
public bool[] ReadBooleanArray() => ReadArray(ReadBoolean);
public byte[] ReadByteArray() => ReadBytes();
public byte[][] ReadByteArrayArray() => ReadArray(ReadBytes);
public decimal[] ReadDecimalArray() => ReadArray(ReadDecimal);
public TimeSpan[] ReadTimeSpanArray() => ReadArray(ReadTimeSpan);
#endregion
public Dictionary ReadDictionary()
{
int count = ReadInt32();
var collection = new Dictionary(count);
if (count > 0)
{
TKey key;
TValue value;
for (int i = 0; i < count; i++)
{
key = ReadCompatible();
value = ReadCompatible();
collection.Add(key, value);
}
}
return collection;
}
public ConcurrentDictionary ReadDictionaryAsConcurrent()
{
int count = ReadInt32();
var collection = new ConcurrentDictionary();
if (count > 0)
{
TKey key;
TValue value;
for (int i = 0; i < count; i++)
{
key = ReadCompatible();
value = ReadCompatible();
collection.TryAdd(key, value);
}
}
return collection;
}
public T ReadCompatible()
{
return MessageSerializer.DeserializeCompatible(this);
}
public T Read() where T : IBinarySerializable
{
byte type = ReadByte();
if (type == 0) return default(T);
var item = (T)Activator.CreateInstance();
item.Deserialize(this);
return item;
}
public bool TryReadByte(out byte b)
{
if (TryReadBuffer(1, out var buffer))
{
b = buffer[0];
return true;
}
b = default;
return false;
}
public bool TryRead(out T item) where T : IBinarySerializable
{
if (TryReadByte(out var type))
{
if (type == 0)
{
item = default(T);
return true;
}
try
{
var o = (IBinarySerializable)FormatterServices.GetUninitializedObject(typeof(T));
o.Deserialize(this);
item = (T)o;
return true;
}
catch (Exception ex)
{
Log.SystemError(ex, "[MemoryStreamReader.TryRead]");
}
}
item = default;
return false;
}
public T Read(object arg) where T : IBinarySerializable
{
byte type = ReadByte();
if (type == 0) return default(T);
var item = (T)Activator.CreateInstance(typeof(T), arg);
item.Deserialize(this);
return item;
}
#endregion Extensions
public void Dispose()
{
_accessor.Dispose();
}
}
public partial class MemoryStreamReader
: IAsyncBinaryReader
{
///
/// Reading byte-package (read the size of the specified number of bytes, and then the packet itself read size)
///
public async Task ReadBufferAsync(int count)
{
if (CheckOutOfRange(count))
throw new OutOfMemoryException("Array index out of bounds");
var buffer = await _accessor.ReadBuffer(count);
if (_reverseByteOrder && count > 1)
{
byte b;
for (int i = 0; i < (count >> 1); i++)
{
b = buffer[i];
buffer[i] = buffer[count - i - 1];
buffer[count - i - 1] = b;
}
}
return buffer;
}
public async Task TryReadBufferAsync(int count, byte[] buffer)
{
if (CheckOutOfRange(count))
{
buffer = null;
return false;
}
try
{
buffer = await _accessor.ReadBuffer(count);
if (_reverseByteOrder && count > 1)
{
byte b;
for (int i = 0; i < (count >> 1); i++)
{
b = buffer[i];
buffer[i] = buffer[count - i - 1];
buffer[count - i - 1] = b;
}
}
}
catch (Exception ex)
{
Log.SystemError(ex, $"[MemoryStreamReader.TryReadBufferAsync] Fault read {count} bytes");
buffer = null;
return false;
}
return true;
}
///
/// Flag reading
///
public async Task ReadBooleanAsync()
{
return BitConverter.ToBoolean(new byte[1] { await ReadByteAsync() }, 0);
}
///
/// Reading byte
///
public async Task ReadByteAsync()
{
var buffer = await ReadBufferAsync(1);
return buffer[0];
}
public async Task ReadCharAsync()
{
var buffer = await ReadBufferAsync(2);
return BitConverter.ToChar(buffer, 0);
}
///
/// Reading bytes
///
///
public async Task ReadBytesAsync()
{
var length = BitConverter.ToInt32(await ReadBufferAsync(4), 0);
if (length == 0) return new byte[0];
return ReadBuffer(length);
}
public async Task ReadShortAsync()
{
var buffer = await ReadBufferAsync(2);
return BitConverter.ToInt16(buffer, 0);
}
public async Task ReadUShortAsync()
{
var buffer = await ReadBufferAsync(2);
return BitConverter.ToUInt16(buffer, 0);
}
///
/// Read 32-bit integer (4 bytes)
///
public async Task ReadInt32Async()
{
var buffer = await ReadBufferAsync(4);
return BitConverter.ToInt32(buffer, 0);
}
public async Task ReadUInt32Async()
{
var buffer = await ReadBufferAsync(4);
return BitConverter.ToUInt32(buffer, 0);
}
public async Task ReadDecimalAsync()
{
var arr = await ReadBufferAsync(16);
var p1 = BitConverter.ToInt32(arr, 0);
var p2 = BitConverter.ToInt32(arr, 4);
var p3 = BitConverter.ToInt32(arr, 8);
var p4 = BitConverter.ToInt32(arr, 12);
return BitConverterExt.ToDecimal(new int[] { p1, p2, p3, p4 });
}
///
/// Read integer 64-bit number (8 bytes)
///
public async Task ReadLongAsync()
{
var buffer = await ReadBufferAsync(8);
return BitConverter.ToInt64(buffer, 0);
}
public async Task ReadULongAsync()
{
var buffer = await ReadBufferAsync(8);
return BitConverter.ToUInt64(buffer, 0);
}
public async Task ReadTimeSpanAsync()
{
return new TimeSpan(await ReadLongAsync());
}
public async Task ReadFloatAsync()
{
var buffer = await ReadBufferAsync(4);
return BitConverter.ToSingle(buffer, 0);
}
public async Task ReadDoubleAsync()
{
var buffer = await ReadBufferAsync(8);
return BitConverter.ToDouble(buffer, 0);
}
///
/// Read string (4 bytes per length + Length bytes)
///
public async Task ReadStringAsync()
{
var length = BitConverter.ToInt32(await ReadBufferAsync(4), 0);
if (length == 0) return null;
var buffer = await ReadBufferAsync(length);
return Encoding.UTF8.GetString(buffer);
}
///
/// Read GUID (16 bytes)
///
public async Task ReadGuidAsync()
{
var buffer = await ReadBufferAsync(16);
return new Guid(buffer);
}
///
/// Reading the datetime
///
///
public async Task ReadDateTimeAsync()
{
var is_null = ReadByte();
if (is_null == 0) return null;
var buffer = await ReadBufferAsync(8);
long deserialized = BitConverter.ToInt64(buffer, 0);
return DateTime.FromBinary(deserialized);
}
public async Task ReadTimeAsync()
{
var is_null = await ReadByteAsync();
if (is_null == 0) return null;
var ts = await ReadTimeSpanAsync();
return TimeOnly.FromTimeSpan(ts);
}
public async Task ReadDateAsync()
{
var is_null = await ReadByteAsync();
if (is_null == 0) return null;
var days = await ReadInt32Async();
return DateOnly.FromDayNumber(days);
}
public async Task ReadIPAsync()
{
var exists = await ReadByteAsync();
if (exists == 1)
{
var addr = await ReadBytesAsync();
return new IPAddress(addr);
}
return null;
}
public async Task ReadIPEndpointAsync()
{
var exists = await ReadByteAsync();
if (exists == 1)
{
var addr = await ReadIPAsync();
var port = await ReadInt32Async();
return new IPEndPoint(addr, port);
}
return null;
}
#region Extensions
#region Collections
private async Task> ReadListAsync(Func> readAsync, Func read)
{
int count = await ReadInt32Async();
var collection = new List(count);
if (count > 0)
{
if (_accessor.IsMemoryStream)
{
for (int i = 0; i < count; i++)
{
collection.Add(read.Invoke());
}
}
else
{
for (int i = 0; i < count; i++)
{
collection.Add(await readAsync.Invoke());
}
}
}
return collection;
}
public async Task> ReadCollectionAsync()
where T : IAsyncBinarySerializable, new()
{
int count = await ReadInt32Async();
var collection = new List(count);
if (count > 0)
{
for (int i = 0; i < count; i++)
{
var item = new T();
await item.DeserializeAsync(this);
collection.Add(item);
}
}
return collection;
}
public async Task> ReadStringCollectionAsync() => await ReadListAsync(ReadStringAsync, ReadString);
public async Task> ReadIPCollectionAsync() => await ReadListAsync(ReadIPAsync, ReadIP);
public async Task> ReadIPEndPointCollectionAsync() => await ReadListAsync(ReadIPEndpointAsync, ReadIPEndpoint);
public async Task> ReadGuidCollectionAsync() => await ReadListAsync(ReadGuidAsync, ReadGuid);
public async Task> ReadDateTimeCollectionAsync() => await ReadListAsync(ReadDateTimeAsync, ReadDateTime);
public async Task> ReadInt64CollectionAsync() => await ReadListAsync(ReadLongAsync, ReadLong);
public async Task> ReadInt32CollectionAsync() => await ReadListAsync(ReadInt32Async, ReadInt32);
public async Task> ReadUInt64CollectionAsync() => await ReadListAsync(ReadULongAsync, ReadULong);
public async Task> ReadUInt32CollectionAsync() => await ReadListAsync(ReadUInt32Async, ReadUInt32);
public async Task> ReadCharCollectionAsync() => await ReadListAsync(ReadCharAsync, ReadChar);
public async Task> ReadShortCollectionAsync() => await ReadListAsync(ReadShortAsync, ReadShort);
public async Task> ReadUShortCollectionAsync() => await ReadListAsync(ReadUShortAsync, ReadUShort);
public async Task> ReadFloatCollectionAsync() => await ReadListAsync(ReadFloatAsync, ReadFloat);
public async Task> ReadDoubleCollectionAsync() => await ReadListAsync(ReadDoubleAsync, ReadDouble);
public async Task> ReadBooleanCollectionAsync() => await ReadListAsync(ReadBooleanAsync, ReadBoolean);
public async Task> ReadByteCollectionAsync() => await ReadListAsync(ReadByteAsync, ReadByte);
public async Task> ReadByteArrayCollectionAsync() => await ReadListAsync(ReadBytesAsync, ReadBytes);
public async Task> ReadDecimalCollectionAsync() => await ReadListAsync(ReadDecimalAsync, ReadDecimal);
public async Task> ReadTimeSpanCollectionAsync() => await ReadListAsync(ReadTimeSpanAsync, ReadTimeSpan);
#endregion
#region Arrays
private async Task ReadArrayAsync(Func> readAsync, Func read)
{
int count = await ReadInt32Async();
var array = new T[count];
if (count > 0)
{
if (_accessor.IsMemoryStream)
{
for (int i = 0; i < count; i++)
{
array[i] = read.Invoke();
}
}
else
{
for (int i = 0; i < count; i++)
{
array[i] = await readAsync.Invoke();
}
}
}
return array;
}
public async Task ReadArrayAsync()
where T : IAsyncBinarySerializable, new()
{
int count = ReadInt32();
var array = new T[count];
if (count > 0)
{
for (int i = 0; i < count; i++)
{
var item = new T();
await item.DeserializeAsync(this);
array[i] = item;
}
}
return array;
}
public async Task ReadStringArrayAsync() => await ReadArrayAsync(ReadStringAsync, ReadString);
public async Task ReadIPArrayAsync() => await ReadArrayAsync(ReadIPAsync, ReadIP);
public async Task ReadIPEndPointArrayAsync() => await ReadArrayAsync(ReadIPEndpointAsync, ReadIPEndpoint);
public async Task ReadGuidArrayAsync() => await ReadArrayAsync(ReadGuidAsync, ReadGuid);
public async Task ReadDateTimeArrayAsync() => await ReadArrayAsync(ReadDateTimeAsync, ReadDateTime);
public async Task ReadInt64ArrayAsync() => await ReadArrayAsync(ReadLongAsync, ReadLong);
public async Task ReadInt32ArrayAsync() => await ReadArrayAsync(ReadInt32Async, ReadInt32);
public async Task ReadUInt64ArrayAsync() => await ReadArrayAsync(ReadULongAsync, ReadULong);
public async Task ReadUInt32ArrayAsync() => await ReadArrayAsync(ReadUInt32Async, ReadUInt32);
public async Task ReadCharArrayAsync() => await ReadArrayAsync(ReadCharAsync, ReadChar);
public async Task ReadShortArrayAsync() => await ReadArrayAsync(ReadShortAsync, ReadShort);
public async Task ReadUShortArrayAsync() => await ReadArrayAsync(ReadUShortAsync, ReadUShort);
public async Task ReadFloatArrayAsync() => await ReadArrayAsync(ReadFloatAsync, ReadFloat);
public async Task ReadDoubleArrayAsync() => await ReadArrayAsync(ReadDoubleAsync, ReadDouble);
public async Task ReadBooleanArrayAsync() => await ReadArrayAsync(ReadBooleanAsync, ReadBoolean);
public async Task ReadByteArrayAsync()
{
if (_accessor.IsMemoryStream)
{
return ReadBytes();
}
return await ReadBytesAsync();
}
public async Task ReadByteArrayArrayAsync() => await ReadArrayAsync(ReadBytesAsync, ReadBytes);
public async Task ReadDecimalArrayAsync() => await ReadArrayAsync(ReadDecimalAsync, ReadDecimal);
public async Task ReadTimeSpanArrayAsync() => await ReadArrayAsync(ReadTimeSpanAsync, ReadTimeSpan);
#endregion
public async Task> ReadDictionaryAsync()
{
int count = ReadInt32();
var collection = new Dictionary(count);
if (count > 0)
{
TKey key;
TValue value;
for (int i = 0; i < count; i++)
{
key = await ReadCompatibleAsync();
value = await ReadCompatibleAsync();
collection.Add(key, value);
}
}
return collection;
}
public async Task> ReadDictionaryAsConcurrentAsync()
{
int count = ReadInt32();
var collection = new ConcurrentDictionary();
if (count > 0)
{
TKey key;
TValue value;
for (int i = 0; i < count; i++)
{
key = await ReadCompatibleAsync();
value = await ReadCompatibleAsync();
collection.TryAdd(key, value);
}
}
return collection;
}
public async Task ReadCompatibleAsync()
{
return await MessageSerializer.DeserializeCompatibleAsync(this);
}
public async Task ReadAsync() where T : IAsyncBinarySerializable
{
byte type = await ReadByteAsync();
if (type == 0) return default(T);
var item = (T)Activator.CreateInstance();
await item.DeserializeAsync(this);
return item;
}
public async Task ReadAsync(object arg) where T : IAsyncBinarySerializable
{
byte type = ReadByte();
if (type == 0) return default(T);
var item = (T)Activator.CreateInstance(typeof(T), arg);
await item.DeserializeAsync(this);
return item;
}
#endregion Extensions
}
}