diff --git a/Directory.Packages.props b/Directory.Packages.props
new file mode 100644
index 0000000..012a22a
--- /dev/null
+++ b/Directory.Packages.props
@@ -0,0 +1,15 @@
+
+
+
+ true
+
+
+
+
+
+
+
+
+
+
+
diff --git a/bench/bench.csproj b/bench/bench.csproj
index c5a530c..315d038 100644
--- a/bench/bench.csproj
+++ b/bench/bench.csproj
@@ -9,8 +9,8 @@
-
-
+
+
diff --git a/src/Serde.MsgPack.csproj b/src/Serde.MsgPack.csproj
index 7c0a8b9..692dc82 100644
--- a/src/Serde.MsgPack.csproj
+++ b/src/Serde.MsgPack.csproj
@@ -8,7 +8,7 @@
-
+
diff --git a/src/reader/ArrayBufReader.cs b/src/reader/ArrayBufReader.cs
index 4cdeb27..a3870bd 100644
--- a/src/reader/ArrayBufReader.cs
+++ b/src/reader/ArrayBufReader.cs
@@ -15,6 +15,6 @@ public void Advance(int count)
public bool FillBuffer(int fillCount)
{
- return false;
+ return _offset + fillCount <= _buffer.Length;
}
}
\ No newline at end of file
diff --git a/src/reader/MsgPackReader.Collections.cs b/src/reader/MsgPackReader.Collections.cs
index 7036829..5a09976 100644
--- a/src/reader/MsgPackReader.Collections.cs
+++ b/src/reader/MsgPackReader.Collections.cs
@@ -1,4 +1,6 @@
+using System.Buffers;
+
namespace Serde.MsgPack;
partial class MsgPackReader
@@ -6,7 +8,8 @@ partial class MsgPackReader
private struct DeserializeCollection(MsgPackReader deserializer, bool isDict, int length) : ITypeDeserializer
{
private int _index;
- int? ITypeDeserializer.SizeOpt => isDict switch {
+ int? ITypeDeserializer.SizeOpt => isDict switch
+ {
true => length / 2,
false => length,
};
@@ -130,5 +133,18 @@ void ITypeDeserializer.SkipValue(ISerdeInfo info, int index)
{
throw new NotImplementedException();
}
+
+ DateTimeOffset ITypeDeserializer.ReadDateTimeOffset(ISerdeInfo info, int index)
+ {
+ var next = deserializer.ReadDateTimeOffset();
+ _index++;
+ return next;
+ }
+
+ void ITypeDeserializer.ReadBytes(ISerdeInfo info, int index, IBufferWriter writer)
+ {
+ deserializer.ReadBytes(writer);
+ _index++;
+ }
}
}
\ No newline at end of file
diff --git a/src/reader/MsgPackReader.ITypeDeserializer.cs b/src/reader/MsgPackReader.ITypeDeserializer.cs
index 6b6bb02..38ea92c 100644
--- a/src/reader/MsgPackReader.ITypeDeserializer.cs
+++ b/src/reader/MsgPackReader.ITypeDeserializer.cs
@@ -1,4 +1,6 @@
+using System.Buffers;
+
namespace Serde.MsgPack;
partial class MsgPackReader
@@ -71,5 +73,13 @@ int ITypeDeserializer.TryReadIndex(ISerdeInfo map, out string? errorName)
return ITypeDeserializer.IndexNotFound;
}
}
+
+ DateTimeOffset ITypeDeserializer.ReadDateTimeOffset(ISerdeInfo info, int index)
+ => deserializer.ReadDateTimeOffset();
+
+ void ITypeDeserializer.ReadBytes(ISerdeInfo info, int index, IBufferWriter writer)
+ {
+ deserializer.ReadBytes(writer);
+ }
}
}
\ No newline at end of file
diff --git a/src/reader/MsgPackReader.cs b/src/reader/MsgPackReader.cs
index 8946973..617f864 100644
--- a/src/reader/MsgPackReader.cs
+++ b/src/reader/MsgPackReader.cs
@@ -1,8 +1,10 @@
+using System.Buffers;
using System.Buffers.Binary;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
+using System.Globalization;
using System.Runtime.CompilerServices;
using System.Text;
using Serde.IO;
@@ -349,6 +351,32 @@ private string ReadString()
return str;
}
+ public DateTimeOffset ReadDateTimeOffset()
+ {
+ return DateTime.Parse(ReadString(), styles: DateTimeStyles.RoundtripKind);
+ }
+
+ public void ReadBytes(IBufferWriter writer)
+ {
+ var b = EatByteOrThrow();
+ int length = b switch
+ {
+ 0xc4 => EatByteOrThrow(),
+ 0xc5 => ReadBigEndianU16(), // 16-bit length
+ 0xc6 => checked((int)ReadBigEndianU32()), // 32-bit length
+ _ => throw new DeserializeException($"Expected bytes, got 0x{b:x}"),
+ };
+ if (!_reader.FillBuffer(length))
+ {
+ ThrowEof();
+ }
+ var inputSpan = _reader.Span[..length];
+ var outSpan = writer.GetSpan(length);
+ inputSpan.CopyTo(outSpan);
+ _reader.Advance(length);
+ writer.Advance(length);
+ }
+
private ReadOnlySpan ReadUtf8Span()
{
var b = EatByteOrThrow();
diff --git a/src/writer/MsgPackWriter.EnumSerializer.cs b/src/writer/MsgPackWriter.EnumSerializer.cs
index 0be0867..78d9b5d 100644
--- a/src/writer/MsgPackWriter.EnumSerializer.cs
+++ b/src/writer/MsgPackWriter.EnumSerializer.cs
@@ -35,5 +35,9 @@ public void WriteValue(ISerdeInfo typeInfo, int index, T value, ISerialize
public void WriteU16(ISerdeInfo typeInfo, int index, ushort u16) => writer.WriteU16(u16);
public void WriteU32(ISerdeInfo typeInfo, int index, uint u32) => writer.WriteU32(u32);
public void WriteU64(ISerdeInfo typeInfo, int index, ulong u64) => writer.WriteU64(u64);
+ public void WriteDateTimeOffset(ISerdeInfo typeInfo, int index, DateTimeOffset dateTimeOffset)
+ => writer.WriteDateTimeOffset(dateTimeOffset);
+ public void WriteBytes(ISerdeInfo typeInfo, int index, ReadOnlyMemory bytes)
+ => writer.WriteBytes(bytes);
}
}
\ No newline at end of file
diff --git a/src/writer/MsgPackWriter.ISerializeCollection.cs b/src/writer/MsgPackWriter.ISerializeCollection.cs
index 3f0b815..afa1625 100644
--- a/src/writer/MsgPackWriter.ISerializeCollection.cs
+++ b/src/writer/MsgPackWriter.ISerializeCollection.cs
@@ -58,5 +58,11 @@ public void WriteU8(ISerdeInfo typeInfo, int index, byte b)
public void WriteValue(ISerdeInfo typeInfo, int index, T value, ISerialize serialize)
where T : class?
=> serialize.Serialize(value, writer);
+
+ public void WriteDateTimeOffset(ISerdeInfo typeInfo, int index, DateTimeOffset dateTimeOffset)
+ => writer.WriteDateTimeOffset(dateTimeOffset);
+
+ public void WriteBytes(ISerdeInfo typeInfo, int index, ReadOnlyMemory bytes)
+ => writer.WriteBytes(bytes);
}
}
\ No newline at end of file
diff --git a/src/writer/MsgPackWriter.ISerializeType.cs b/src/writer/MsgPackWriter.ISerializeType.cs
index baccd46..8bafbfd 100644
--- a/src/writer/MsgPackWriter.ISerializeType.cs
+++ b/src/writer/MsgPackWriter.ISerializeType.cs
@@ -111,4 +111,16 @@ void ITypeSerializer.WriteNull(ISerdeInfo typeInfo, int index)
WritePropertyName(typeInfo, index);
WriteNull();
}
+
+ void ITypeSerializer.WriteDateTimeOffset(ISerdeInfo typeInfo, int index, DateTimeOffset dt)
+ {
+ WritePropertyName(typeInfo, index);
+ WriteDateTimeOffset(dt);
+ }
+
+ void ITypeSerializer.WriteBytes(ISerdeInfo typeInfo, int index, ReadOnlyMemory bytes)
+ {
+ WritePropertyName(typeInfo, index);
+ WriteBytes(bytes);
+ }
}
\ No newline at end of file
diff --git a/src/writer/MsgPackWriter.cs b/src/writer/MsgPackWriter.cs
index 33db05d..22f24e2 100644
--- a/src/writer/MsgPackWriter.cs
+++ b/src/writer/MsgPackWriter.cs
@@ -137,6 +137,43 @@ public void WriteNull()
_out.Add(0xc0);
}
+ public void WriteDateTimeOffset(DateTimeOffset dt)
+ {
+ WriteString(dt.ToString("O"));
+ }
+
+ public void WriteBytes(ReadOnlyMemory bytes)
+ {
+ byte code = bytes.Length switch
+ {
+ <= 0xff => 0xc4,
+ <= 0xffff => 0xc5,
+ _ => 0xc6
+ };
+ var prefixLen = code switch
+ {
+ 0xc4 => 2,
+ 0xc5 => 3,
+ _ => 5
+ };
+ var span = _out.GetAppendSpan(prefixLen + bytes.Length);
+ _out.Count += prefixLen + bytes.Length;
+ span[0] = code;
+ switch (prefixLen)
+ {
+ case 2:
+ span[1] = (byte)bytes.Length;
+ break;
+ case 3:
+ WriteBigEndian((ushort)bytes.Length);
+ break;
+ case 5:
+ WriteBigEndian((uint)bytes.Length);
+ break;
+ }
+ bytes.Span.CopyTo(span[prefixLen..]);
+ }
+
public void WriteI8(sbyte b) => WriteI64(b);
private static readonly Encoding _utf8 = new UTF8Encoding(encoderShouldEmitUTF8Identifier: false, throwOnInvalidBytes: true);
diff --git a/tests/RoundTripTests.cs b/tests/RoundTripTests.cs
index d46a839..952b19a 100644
--- a/tests/RoundTripTests.cs
+++ b/tests/RoundTripTests.cs
@@ -181,6 +181,13 @@ public void TestFloat()
AssertRoundTrip(float.PositiveInfinity, F32Proxy.Instance);
}
+ [Fact]
+ public void TestBytes()
+ {
+ var bytes = new byte[] { 1, 2, 3, 4, 5 };
+ AssertRoundTrip(bytes, ByteArrayProxy.Instance);
+ }
+
private static void AssertRoundTrip(T expected)
where T : ISerializeProvider, IDeserializeProvider, IEquatable
{
diff --git a/tests/Serde.MsgPack.Tests.csproj b/tests/Serde.MsgPack.Tests.csproj
index 1952564..6490b44 100644
--- a/tests/Serde.MsgPack.Tests.csproj
+++ b/tests/Serde.MsgPack.Tests.csproj
@@ -8,12 +8,12 @@
-
-
-
-
-
-
+
+
+
+
+
+