Serde

Kind of a port of Rust's Serde crate.
git clone https://git.philomathiclife.com/repos/Serde
Log | Files | Refs | README

BinSer.cs (7921B)


      1 using Serde.Ser;
      2 using Std;
      3 using Std.Maybe;
      4 using Std.Num;
      5 using Std.Result;
      6 using Std.Vec;
      7 using System;
      8 using System.Runtime.InteropServices;
      9 #region Namespaces
     10 namespace Serde.Bin.Ser {
     11     #region Types
     12     public interface IBinSerializable: ISerializable {
     13 
     14         #region Type-level Constructors
     15         #endregion
     16 
     17         #region Instance Constructors
     18         #endregion
     19 
     20         #region Type-level Fields
     21         #endregion
     22 
     23         #region Instance Fields
     24         #endregion
     25 
     26         #region Type-level Properties
     27         #endregion
     28 
     29         #region Instance Properties
     30         #endregion
     31 
     32         #region Type-level Functions
     33         #endregion
     34 
     35         #region Instance Functions
     36         public abstract Unit Ser(ref Serializer ser);
     37         #endregion
     38 
     39         #region Operators
     40         #endregion
     41 
     42         #region Types
     43         #endregion
     44     }
     45     [StructLayout(LayoutKind.Explicit, CharSet = CharSet.Unicode, Pack = 0)]
     46     public struct Serializer: ISerializer<Unit, Bottom> {
     47 
     48         #region Type-level Constructors
     49         #endregion
     50 
     51         #region Instance Constructors
     52         public Serializer() => _buffer = new Vec<byte>();
     53         public Serializer(Vec<byte> buffer) => _buffer = buffer;
     54         public Serializer(uint bufferSize) => _buffer = Vec<byte>.WithCapacity(bufferSize);
     55         #endregion
     56 
     57         #region Type-level Fields
     58         #endregion
     59 
     60         #region Instance Fields
     61         [FieldOffset(0)] Vec<byte> _buffer;
     62         #endregion
     63 
     64         #region Type-level Properties
     65         #endregion
     66 
     67         #region Instance Properties
     68         public readonly uint Len => _buffer.Len;
     69         public readonly Vec<byte> RawBuffer => _buffer;
     70         public readonly ReadOnlySpan<byte> SerializedData => _buffer.AsSlice();
     71         #endregion
     72 
     73         #region Type-level Functions
     74         public static Serializer New() => new();
     75         public static Serializer NewWithBuffer(Vec<byte> buffer) => new(buffer);
     76         public static Serializer NewWithCapacity(uint bufferSize) => new (bufferSize);
     77         #endregion
     78 
     79         #region Instance Functions
     80         // This exists to avoid copying of data. Instead of one feeding the Serializer bytes to copy internally,
     81         // a Span<byte> of its own buffer is handed to downstream code to write into.
     82         // This Span<byte> starts at the current position and is of the passed length.
     83         // The Serializer assumes every byte is written to and changes its position accordingly.
     84         // This means downstream code MUST know exactly how many bytes they want to write as any byte
     85         // that is not written to in the Span<byte> will not be detected.
     86         public Span<byte> AsMutSlice(uint len) {
     87             _ = _buffer.Reserve(len);
     88             var origLen = _buffer.Len;
     89             // This is safe since we first reserve enough additional space to handle this writing.
     90             checked { _ = _buffer.SetLenUnsafe(origLen + len); }
     91             return _buffer.AsMutSlice()[(int)origLen..];
     92         }
     93         public override readonly bool Equals(object? _) => false;
     94         public override readonly int GetHashCode() => 0;
     95         public Unit Reset() => _buffer.Clear();
     96         public Unit SerUnsafe<T>(T val) where T: unmanaged { unsafe { return SerSliceUnsafe(new ReadOnlySpan<T>(&val, 1)); } }
     97         public Unit Ser(ReadOnlySpan<byte> bytes) => _buffer.ExtendFromSlice(bytes);
     98         public Result<Unit, Bottom> Serialize(ReadOnlySpan<byte> bytes) => new(Ser(bytes));
     99         public Unit SerBool(bool val) => _buffer.Push(val ? byte.MaxValue : byte.MinValue);
    100         public Result<Unit, Bottom> SerializeBool(bool val) => new(SerBool(val));
    101         public Unit SerByte(byte val) => SerUnsafe(val);
    102         public Result<Unit, Bottom> SerializeByte(byte val) => new(SerByte(val));
    103         public Unit SerChar(char val) => SerUnsafe(val);
    104         public Result<Unit, Bottom> SerializeChar(char val) => new(SerChar(val));
    105         public Unit SerChars(ReadOnlySpan<char> val) => SerSliceUnsafe(val);
    106         public Result<Unit, Bottom> SerializeChars(ReadOnlySpan<char> val) => new(SerChars(val));
    107         public Unit SerDateTime(DateTime val) => SerUnsafe(val);
    108         public Result<Unit, Bottom> SerializeDateTime(DateTime val) => new(SerDateTime(val));
    109         public Unit SerDateTimeOffset(DateTimeOffset val) {
    110 
    111             _ = SerDateTime(new DateTime(val.Ticks, DateTimeKind.Unspecified));
    112             return SerTimeSpan(val.Offset);
    113         }
    114         public Result<Unit, Bottom> SerializeDateTimeOffset(DateTimeOffset val) => new(SerDateTimeOffset(val));
    115         public Unit SerDecimal(decimal val) {
    116 
    117             Span<int> bits = stackalloc int[4];
    118             _ = decimal.GetBits(val, bits);
    119             return SerSliceUnsafe<int>(bits);
    120         }
    121         public Result<Unit, Bottom> SerializeDecimal(decimal val) => new(SerDecimal(val));
    122         public Unit SerDouble(double val) => SerUnsafe(val);
    123         public Result<Unit, Bottom> SerializeDouble(double val) => new(SerDouble(val));
    124         public Unit SerFloat(float val) => SerUnsafe(val);
    125         public Result<Unit, Bottom> SerializeFloat(float val) => new(SerFloat(val));
    126         public Unit SerGuid(Guid val) => SerUnsafe(val);
    127         public Result<Unit, Bottom> SerializeGuid(Guid val) => new(SerGuid(val));
    128         public Unit SerI128(I128 val) => SerUnsafe(val);
    129         public Result<Unit, Bottom> SerializeI128(I128 val) => new(SerI128(val));
    130         public Unit SerInt(int val) => SerUnsafe(val);
    131         public Result<Unit, Bottom> SerializeInt(int val) => new(SerInt(val));
    132         public Unit SerLong(long val) => SerUnsafe(val);
    133         public Result<Unit, Bottom> SerializeLong(long val) => new(SerLong(val));
    134         public Unit SerMaybe<TSome>(Maybe<TSome> val) where TSome: notnull, IBinSerializable {
    135 
    136             if (val.IsNone) {
    137                 return SerUnsafe(byte.MinValue);
    138             } else {
    139                 _ = SerUnsafe(byte.MaxValue);
    140                 return val.Unwrap().Ser(ref this);
    141             }
    142         }
    143         public Result<Unit, Bottom> SerializeMaybe<TSome>(Maybe<TSome> val) where TSome : notnull, ISerializable {
    144 
    145             if (val.IsNone) {
    146                 return new(SerUnsafe(byte.MinValue));
    147             } else {
    148                 _ = SerUnsafe(byte.MaxValue);
    149                 return val.Unwrap().Serialize<Serializer, Unit, Bottom>(ref this);
    150             }
    151         }
    152         public Unit SerSbyte(sbyte val) => SerUnsafe(val);
    153         public Result<Unit, Bottom> SerializeSbyte(sbyte val) => new(SerSbyte(val));
    154         public Unit SerShort(short val) => SerUnsafe(val);
    155         public Result<Unit, Bottom> SerializeShort(short val) => new(SerShort(val));
    156         public Unit SerSliceUnsafe<T>(ReadOnlySpan<T> val) where T: unmanaged { unsafe { fixed (T* ptr = val) { return _buffer.ExtendFromSlice(new(ptr, val.Length * sizeof(T))); } } }
    157         public Unit SerTimeSpan(TimeSpan val) => SerUnsafe(val);
    158         public Result<Unit, Bottom> SerializeTimeSpan(TimeSpan val) => new(SerTimeSpan(val));
    159         public Unit SerU128(U128 val) => SerUnsafe(val);
    160         public Result<Unit, Bottom> SerializeU128(U128 val) => new(SerU128(val));
    161         public Unit SerUint(uint val) => SerUnsafe(val);
    162         public Result<Unit, Bottom> SerializeUint(uint val) => new(SerUint(val));
    163         public Unit SerUlong(ulong val) => SerUnsafe(val);
    164         public Result<Unit, Bottom> SerializeUlong(ulong val) => new(SerUlong(val));
    165         public Result<Unit, Bottom> SerializeUnit(Unit _) => new(new Unit());
    166         public Unit SerUshort(ushort val) => SerUnsafe(val);
    167         public Result<Unit, Bottom> SerializeUshort(ushort val) => new(SerUshort(val));
    168         public override readonly string ToString() => string.Empty;
    169         #endregion
    170 
    171         #region Operators
    172         #endregion
    173 
    174         #region Types
    175         #endregion
    176     }
    177     #endregion
    178 
    179     #region Namespaces
    180     #endregion
    181 }
    182 #endregion