using System; using System.Runtime.InteropServices; namespace Capnp { /// /// Provides extensions to the and interfaces for type-safe reading and writing. /// public static class SerializerExtensions { /// /// Reads a boolean field. /// /// Type implementing /// "this" instance /// Start bit /// Field default value (will be XORed with the result) /// The read value public static bool ReadDataBool(this T d, ulong bitOffset, bool defaultValue = false) where T: IStructDeserializer { return (d.StructReadData(bitOffset, 1) != 0) != defaultValue; } /// /// Writes a boolean field. /// /// Type implementing /// "this" instance /// Start bit /// Value to write /// Field default value (will be XORed with the value to write) public static void WriteData(this T d, ulong bitOffset, bool value, bool defaultValue = false) where T : IStructSerializer { d.StructWriteData(bitOffset, 1, value != defaultValue ? 1ul : 0); } /// /// Reads a byte field. /// /// Type implementing /// "this" instance /// Start bit /// Field default value (will be XORed with the result) /// The read value public static byte ReadDataByte(this T d, ulong bitOffset, byte defaultValue = 0) where T : IStructDeserializer { return (byte)(d.StructReadData(bitOffset, 8) ^ defaultValue); } /// /// Writes a byte field. /// /// Type implementing /// "this" instance /// Start bit /// Value to write /// Field default value (will be XORed with the value to write) public static void WriteData(this T d, ulong bitOffset, byte value, byte defaultValue = 0) where T : IStructSerializer { d.StructWriteData(bitOffset, 8, (byte)(value ^ defaultValue)); } /// /// Reads a signed byte field. /// /// Type implementing /// "this" instance /// Start bit /// Field default value (will be XORed with the result) /// The read value public static sbyte ReadDataSByte(this T d, ulong bitOffset, sbyte defaultValue = 0) where T : IStructDeserializer { return (sbyte)((sbyte)d.StructReadData(bitOffset, 8) ^ defaultValue); } /// /// Writes a signed byte field. /// /// Type implementing /// "this" instance /// Start bit /// Value to write /// Field default value (will be XORed with the value to write) public static void WriteData(this T d, ulong bitOffset, sbyte value, sbyte defaultValue = 0) where T : IStructSerializer { d.StructWriteData(bitOffset, 8, unchecked((ulong)(value ^ defaultValue))); } /// /// Reads a ushort field. /// /// Type implementing /// "this" instance /// Start bit /// Field default value (will be XORed with the result) /// The read value public static ushort ReadDataUShort(this T d, ulong bitOffset, ushort defaultValue = 0) where T : IStructDeserializer { return (ushort)(d.StructReadData(bitOffset, 16) ^ defaultValue); } /// /// Writes a ushort field. /// /// Type implementing /// "this" instance /// Start bit /// Value to write /// Field default value (will be XORed with the value to write) public static void WriteData(this T d, ulong bitOffset, ushort value, ushort defaultValue = 0) where T : IStructSerializer { d.StructWriteData(bitOffset, 16, (ushort)(value ^ defaultValue)); } /// /// Reads a short field. /// /// Type implementing /// "this" instance /// Start bit /// Field default value (will be XORed with the result) /// The read value public static short ReadDataShort(this T d, ulong bitOffset, short defaultValue = 0) where T : IStructDeserializer { return (short)((short)d.StructReadData(bitOffset, 16) ^ defaultValue); } /// /// Writes a short field. /// /// Type implementing /// "this" instance /// Start bit /// Value to write /// Field default value (will be XORed with the value to write) public static void WriteData(this T d, ulong bitOffset, short value, short defaultValue = 0) where T : IStructSerializer { d.StructWriteData(bitOffset, 16, unchecked((ulong)(value ^ defaultValue))); } /// /// Reads a uint field. /// /// Type implementing /// "this" instance /// Start bit /// Field default value (will be XORed with the result) /// The read value public static uint ReadDataUInt(this T d, ulong bitOffset, uint defaultValue = 0) where T : IStructDeserializer { return (uint)(d.StructReadData(bitOffset, 32) ^ defaultValue); } /// /// Writes a uint field. /// /// Type implementing /// "this" instance /// Start bit /// Value to write /// Field default value (will be XORed with the value to write) public static void WriteData(this T d, ulong bitOffset, uint value, uint defaultValue = 0) where T : IStructSerializer { d.StructWriteData(bitOffset, 32, value ^ defaultValue); } /// /// Performs a "reinterpret cast" of the struct's data section and returns a reference to a single element of the cast result. /// /// The cast target type. Must be a primitive type which qualifies for ()]]> /// "this" instance /// Index within the cast result, conceptually into U[] /// A reference to the data element public static ref U RefData(this IStructSerializer d, int woffset) where U: struct { var data = MemoryMarshal.Cast(d.StructDataSection); return ref MemoryMarshal.GetReference(data.Slice(woffset, 1)); } /// /// Reads an int field. /// /// Type implementing /// "this" instance /// Start bit /// Field default value (will be XORed with the result) /// The read value public static int ReadDataInt(this T d, ulong bitOffset, int defaultValue = 0) where T : IStructDeserializer { return (int)d.StructReadData(bitOffset, 32) ^ defaultValue; } /// /// Writes an int field. /// /// Type implementing /// "this" instance /// Start bit /// Value to write /// Field default value (will be XORed with the value to write) public static void WriteData(this T d, ulong bitOffset, int value, int defaultValue = 0) where T : IStructSerializer { d.StructWriteData(bitOffset, 32, unchecked((ulong)(value ^ defaultValue))); } /// /// Reads a ulong field. /// /// Type implementing /// "this" instance /// Start bit /// Field default value (will be XORed with the result) /// The read value public static ulong ReadDataULong(this T d, ulong bitOffset, ulong defaultValue = 0) where T : IStructDeserializer { return d.StructReadData(bitOffset, 64) ^ defaultValue; } /// /// Writes a ulong field. /// /// Type implementing /// "this" instance /// Start bit /// Value to write /// Field default value (will be XORed with the value to write) public static void WriteData(this T d, ulong bitOffset, ulong value, ulong defaultValue = 0) where T : IStructSerializer { d.StructWriteData(bitOffset, 64, value ^ defaultValue); } /// /// Reads a long field. /// /// Type implementing /// "this" instance /// Start bit /// Field default value (will be XORed with the result) /// The read value public static long ReadDataLong(this T d, ulong bitOffset, long defaultValue = 0) where T : IStructDeserializer { return (long)d.StructReadData(bitOffset, 64) ^ defaultValue; } /// /// Writes a long field. /// /// Type implementing /// "this" instance /// Start bit /// Value to write /// Field default value (will be XORed with the value to write) public static void WriteData(this T d, ulong bitOffset, long value, long defaultValue = 0) where T : IStructSerializer { d.StructWriteData(bitOffset, 64, unchecked((ulong)(value ^ defaultValue))); } /// /// Reads a float field. /// /// Type implementing /// "this" instance /// Start bit /// Field default value (raw bits will be XORed with the result) /// The read value public static float ReadDataFloat(this T d, ulong bitOffset, float defaultValue = 0) where T : IStructDeserializer { int defaultBits = defaultValue.ReplacementSingleToInt32Bits(); int bits = (int)d.StructReadData(bitOffset, 32) ^ defaultBits; return bits.ReplacementInt32ToSingleBits(); } /// /// Writes a float field. /// /// Type implementing /// "this" instance /// Start bit /// Value to write /// Field default value (raw bits will be XORed with the value to write) public static void WriteData(this T d, ulong bitOffset, float value, float defaultValue = 0.0f) where T : IStructSerializer { int bits = value.ReplacementSingleToInt32Bits(); int defaultBits = defaultValue.ReplacementSingleToInt32Bits(); WriteData(d, bitOffset, bits, defaultBits); } /// /// Reads a double field. /// /// Type implementing /// "this" instance /// Start bit /// Field default value (raw bits will be XORed with the result) /// The read value public static double ReadDataDouble(this T d, ulong bitOffset, double defaultValue = 0) where T : IStructDeserializer { long defaultBits = BitConverter.DoubleToInt64Bits(defaultValue); long bits = (long)d.StructReadData(bitOffset, 64) ^ defaultBits; return BitConverter.Int64BitsToDouble(bits); } /// /// Writes a double field. /// /// Type implementing /// "this" instance /// Start bit /// Value to write /// Field default value (raw bits will be XORed with the value to write) public static void WriteData(this T d, ulong bitOffset, double value, double defaultValue = 0.0) where T : IStructSerializer { long bits = BitConverter.DoubleToInt64Bits(value); long defaultBits = BitConverter.DoubleToInt64Bits(defaultValue); WriteData(d, bitOffset, bits, defaultBits); } } }