using InnovEnergy.Lib.Protocols.DBus.Protocol.DataTypes; using InnovEnergy.Lib.Protocols.DBus.Protocol.DataTypes.Signatures; namespace InnovEnergy.Lib.Protocols.DBus.Protocol.Header; using H = ValueTuple>; using Fields = IReadOnlyList<(Byte code, Variant variant)>; internal static class HeaderExtensions { public static Endian Endian (this H h) => (Endian) h.Item1; public static MessageType MessageType (this H h) => (MessageType) h.Item2; public static Byte Flags (this H h) => h.Item3; public static Byte ProtocolVersion(this H h) => h.Item4; public static UInt32 PayloadLength (this H h) => h.Item5; public static UInt32 Serial (this H h) => h.Item6; public static Fields Fields (this H h) => h.Item7; public static Signature? Signature (this H h) => h.GetField (FieldCode.Signature) ; public static String? Interface (this H h) => h.GetField (FieldCode.Interface) ; public static String? Member (this H h) => h.GetField (FieldCode.Member) ; public static String? Destination (this H h) => h.GetField (FieldCode.Destination) ; public static String? Sender (this H h) => h.GetField (FieldCode.Sender) ; public static String? ErrorName (this H h) => h.GetField (FieldCode.ErrorName) ; public static UInt32? ReplySerial (this H h) => h.GetField (FieldCode.ReplySerial); public static ObjectPath? ObjectPath (this H h) => h.GetField(FieldCode.Path); public static Boolean ReplyExpected (this H h) =>(h.Flags() & 1) == 0; public static Boolean AutoStart (this H h) =>(h.Flags() & 2) == 0; public static Boolean AllowInteractiveAuthorization(this H h) =>(h.Flags() & 4) != 0; private static T? GetField(this H header, FieldCode fieldCode) { // not using a dictionary, list of header fields is always // small, so linear search is probably cheaper overall var fc = (Byte) fieldCode; return header .Fields() .Where(hf => hf.code == fc) .Select(hf => hf.variant.Value) .OfType() .SingleOrDefault(); } public static void AddField(this List<(Byte, Variant)> header, FieldCode fieldCode, Object? value) { if (value is null) return; header.Add(((Byte) fieldCode, value.Variant())); } }