diff --git a/src/Tmds.DBus.Protocol/Message.cs b/src/Tmds.DBus.Protocol/Message.cs index 57cb173..7ca4d03 100644 --- a/src/Tmds.DBus.Protocol/Message.cs +++ b/src/Tmds.DBus.Protocol/Message.cs @@ -140,7 +140,7 @@ private void ClearHeaders() return null; } - headerFieldLength = (uint)ProtocolConstants.Align((int)headerFieldLength, DBusType.Struct); + headerFieldLength = (uint)ProtocolConstants.Align((int)headerFieldLength, ProtocolConstants.StructAlignment); long totalLength = seqReader.Consumed + headerFieldLength + bodyLength; @@ -186,7 +186,7 @@ private void ParseHeader(UnixFdCollection? handles, bool isMonitor) var reader = new Reader(IsBigEndian, _data.AsReadOnlySequence); reader.Advance(HeaderFieldsLengthOffset); - ArrayEnd headersEnd = reader.ReadArrayStart(DBusType.Struct); + ArrayEnd headersEnd = reader.ReadArrayStart(ProtocolConstants.StructAlignment); while (reader.HasNext(headersEnd)) { MessageHeader hdrType = (MessageHeader)reader.ReadByte(); diff --git a/src/Tmds.DBus.Protocol/MessageWriter.Basic.cs b/src/Tmds.DBus.Protocol/MessageWriter.Basic.cs index 0e527dc..bdf3da9 100644 --- a/src/Tmds.DBus.Protocol/MessageWriter.Basic.cs +++ b/src/Tmds.DBus.Protocol/MessageWriter.Basic.cs @@ -6,21 +6,21 @@ public ref partial struct MessageWriter public void WriteBool(bool value) => WriteUInt32(value ? 1u : 0u); - public void WriteByte(byte value) => WritePrimitiveCore(value, DBusType.Byte); + public void WriteByte(byte value) => WritePrimitiveCore(value); - public void WriteInt16(short value) => WritePrimitiveCore(value, DBusType.Int16); + public void WriteInt16(short value) => WritePrimitiveCore(value); - public void WriteUInt16(ushort value) => WritePrimitiveCore(value, DBusType.UInt16); + public void WriteUInt16(ushort value) => WritePrimitiveCore(value); - public void WriteInt32(int value) => WritePrimitiveCore(value, DBusType.Int32); + public void WriteInt32(int value) => WritePrimitiveCore(value); - public void WriteUInt32(uint value) => WritePrimitiveCore(value, DBusType.UInt32); + public void WriteUInt32(uint value) => WritePrimitiveCore(value); - public void WriteInt64(long value) => WritePrimitiveCore(value, DBusType.Int64); + public void WriteInt64(long value) => WritePrimitiveCore(value); - public void WriteUInt64(ulong value) => WritePrimitiveCore(value, DBusType.UInt64); + public void WriteUInt64(ulong value) => WritePrimitiveCore(value); - public void WriteDouble(double value) => WritePrimitiveCore(value, DBusType.Double); + public void WriteDouble(double value) => WritePrimitiveCore(value); public void WriteString(scoped ReadOnlySpan value) => WriteStringCore(value); @@ -156,7 +156,7 @@ private void WriteStringCore(scoped ReadOnlySpan span) private void WriteStringCore(string s) { - WritePadding(DBusType.UInt32); + WritePadding(ProtocolConstants.UInt32Alignment); Span lengthSpan = GetSpan(4); Advance(4); int bytesWritten = WriteRaw(s); @@ -165,10 +165,10 @@ private void WriteStringCore(string s) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - private void WritePrimitiveCore(T value, DBusType type) + private void WritePrimitiveCore(T value) { - WritePadding(type); - int length = ProtocolConstants.GetFixedTypeLength(type); + int length = Marshal.SizeOf(); + WritePadding(length); var span = GetSpan(length); Unsafe.WriteUnaligned(ref MemoryMarshal.GetReference(span), value); Advance(length); diff --git a/src/Tmds.DBus.Protocol/MessageWriter.Dictionary.cs b/src/Tmds.DBus.Protocol/MessageWriter.Dictionary.cs index c5305f8..d1e2278 100644 --- a/src/Tmds.DBus.Protocol/MessageWriter.Dictionary.cs +++ b/src/Tmds.DBus.Protocol/MessageWriter.Dictionary.cs @@ -6,7 +6,7 @@ namespace Tmds.DBus.Protocol; public ref partial struct MessageWriter { public ArrayStart WriteDictionaryStart() - => WriteArrayStart(DBusType.Struct); + => WriteArrayStart(ProtocolConstants.StructAlignment); public void WriteDictionaryEnd(ArrayStart start) => WriteArrayEnd(start); diff --git a/src/Tmds.DBus.Protocol/MessageWriter.Header.cs b/src/Tmds.DBus.Protocol/MessageWriter.Header.cs index e9e10a5..f00b973 100644 --- a/src/Tmds.DBus.Protocol/MessageWriter.Header.cs +++ b/src/Tmds.DBus.Protocol/MessageWriter.Header.cs @@ -186,7 +186,7 @@ public void WriteSignalHeader( private void WriteHeaderEnd(ArrayStart start) { WriteArrayEnd(start); - WritePadding(DBusType.Struct); + WritePadding(ProtocolConstants.StructAlignment); } private ArrayStart WriteHeaderStart(MessageType type, MessageFlags flags) @@ -203,7 +203,7 @@ private ArrayStart WriteHeaderStart(MessageType type, MessageFlags flags) Debug.Assert(_offset == SerialOffset + 4); // headers - ArrayStart start = WriteArrayStart(DBusType.Struct); + ArrayStart start = WriteArrayStart(ProtocolConstants.StructAlignment); // UnixFds WriteStructureStart(); diff --git a/src/Tmds.DBus.Protocol/MessageWriter.IntrospectionXml.cs b/src/Tmds.DBus.Protocol/MessageWriter.IntrospectionXml.cs index d343592..cf2ff5d 100644 --- a/src/Tmds.DBus.Protocol/MessageWriter.IntrospectionXml.cs +++ b/src/Tmds.DBus.Protocol/MessageWriter.IntrospectionXml.cs @@ -36,7 +36,7 @@ internal void WriteIntrospectionXml( scoped ReadOnlySpan childNames, IEnumerable? childNamesEnumerable) { - WritePadding(DBusType.UInt32); + WritePadding(ProtocolConstants.UInt32Alignment); Span lengthSpan = GetSpan(4); Advance(4); diff --git a/src/Tmds.DBus.Protocol/MessageWriter.cs b/src/Tmds.DBus.Protocol/MessageWriter.cs index 950c4b6..e06141b 100644 --- a/src/Tmds.DBus.Protocol/MessageWriter.cs +++ b/src/Tmds.DBus.Protocol/MessageWriter.cs @@ -67,13 +67,16 @@ internal MessageWriter(MessageBufferPool messagePool, uint serial) } public ArrayStart WriteArrayStart(DBusType elementType) + => WriteArrayStart(ProtocolConstants.GetTypeAlignment(elementType)); + + private ArrayStart WriteArrayStart(int alignment) { // Array length. - WritePadding(DBusType.UInt32); + WritePadding(ProtocolConstants.UInt32Alignment); Span lengthSpan = GetSpan(4); Advance(4); - WritePadding(elementType); + WritePadding(alignment); return new ArrayStart(lengthSpan, _offset); } @@ -85,7 +88,7 @@ public void WriteArrayEnd(ArrayStart start) public void WriteStructureStart() { - WritePadding(DBusType.Struct); + WritePadding(ProtocolConstants.StructAlignment); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -96,16 +99,6 @@ private void Advance(int count) _span = _span.Slice(count); } - private void WritePadding(DBusType type) - { - int pad = ProtocolConstants.GetPadding(_offset, type); - if (pad != 0) - { - GetSpan(pad).Slice(0, pad).Fill(0); - Advance(pad); - } - } - private void WritePadding(int alignment) { int pad = ProtocolConstants.GetPadding(_offset, alignment); diff --git a/src/Tmds.DBus.Protocol/ProtocolConstants.cs b/src/Tmds.DBus.Protocol/ProtocolConstants.cs index 085795f..b9d0537 100644 --- a/src/Tmds.DBus.Protocol/ProtocolConstants.cs +++ b/src/Tmds.DBus.Protocol/ProtocolConstants.cs @@ -20,6 +20,9 @@ static class ProtocolConstants public static ReadOnlySpan SignatureSignature => new byte[] { (byte)'g' }; public static ReadOnlySpan VariantSignature => new byte[] { (byte)'v' }; + public const int StructAlignment = 8; + public const int UInt32Alignment = 4; + private static ReadOnlySpan SingleTypes => new byte[] { (byte)'y', (byte)'b', (byte)'n', (byte)'q', (byte)'i', (byte)'u', (byte)'x', (byte)'t', (byte)'d', (byte)'h', (byte)'s', (byte)'o', (byte)'g', (byte)'v' }; public static bool IsSingleCompleteType(byte b) @@ -38,7 +41,7 @@ public static int GetTypeAlignment(DBusType type) case DBusType.Int16: return 2; case DBusType.UInt16: return 2; case DBusType.Int32: return 4; - case DBusType.UInt32: return 4; + case DBusType.UInt32: return UInt32Alignment; case DBusType.Int64: return 8; case DBusType.UInt64: return 8; case DBusType.Double: return 8; @@ -46,7 +49,7 @@ public static int GetTypeAlignment(DBusType type) case DBusType.ObjectPath: return 4; case DBusType.Signature: return 4; case DBusType.Array: return 4; - case DBusType.Struct: return 8; + case DBusType.Struct: return StructAlignment; case DBusType.Variant: return 1; case DBusType.DictEntry: return 8; case DBusType.UnixFd: return 4; @@ -55,35 +58,9 @@ public static int GetTypeAlignment(DBusType type) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int GetFixedTypeLength(DBusType type) - { - switch (type) - { - case DBusType.Byte: return 1; - case DBusType.Bool: return 4; - case DBusType.Int16: return 2; - case DBusType.UInt16: return 2; - case DBusType.Int32: return 4; - case DBusType.UInt32: return 4; - case DBusType.Int64: return 8; - case DBusType.UInt64: return 8; - case DBusType.Double: return 8; - case DBusType.UnixFd: return 4; - default: return 0; - } - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int Align(int offset, DBusType type) - { - return offset + GetPadding(offset, type); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int GetPadding(int offset, DBusType type) + public static int Align(int offset, int alignment) { - int alignment = GetTypeAlignment(type); - return GetPadding(offset ,alignment); + return offset + GetPadding(offset, alignment); } [MethodImpl(MethodImplOptions.AggressiveInlining)] diff --git a/src/Tmds.DBus.Protocol/Reader.Basic.cs b/src/Tmds.DBus.Protocol/Reader.Basic.cs index 119c8c1..6727308 100644 --- a/src/Tmds.DBus.Protocol/Reader.Basic.cs +++ b/src/Tmds.DBus.Protocol/Reader.Basic.cs @@ -21,7 +21,7 @@ public ushort ReadUInt16() public short ReadInt16() { - AlignReader(DBusType.Int16); + AlignReader(alignment: 2); bool dataRead = _isBigEndian ? _reader.TryReadBigEndian(out short rv) : _reader.TryReadLittleEndian(out rv); if (!dataRead) { @@ -35,7 +35,7 @@ public uint ReadUInt32() public int ReadInt32() { - AlignReader(DBusType.Int32); + AlignReader(alignment: 4); bool dataRead = _isBigEndian ? _reader.TryReadBigEndian(out int rv) : _reader.TryReadLittleEndian(out rv); if (!dataRead) { @@ -49,7 +49,7 @@ public ulong ReadUInt64() public long ReadInt64() { - AlignReader(DBusType.Int64); + AlignReader(alignment: 8); bool dataRead = _isBigEndian ? _reader.TryReadBigEndian(out long rv) : _reader.TryReadLittleEndian(out rv); if (!dataRead) { diff --git a/src/Tmds.DBus.Protocol/Reader.Dictionary.cs b/src/Tmds.DBus.Protocol/Reader.Dictionary.cs index 9b794a9..6311dcb 100644 --- a/src/Tmds.DBus.Protocol/Reader.Dictionary.cs +++ b/src/Tmds.DBus.Protocol/Reader.Dictionary.cs @@ -7,7 +7,7 @@ namespace Tmds.DBus.Protocol; public ref partial struct Reader { public ArrayEnd ReadDictionaryStart() - => ReadArrayStart(DBusType.Struct); + => ReadArrayStart(ProtocolConstants.StructAlignment); // Read method for the common 'a{sv}' type. [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026")] // It's safe to call ReadDictionary with these types. diff --git a/src/Tmds.DBus.Protocol/Reader.cs b/src/Tmds.DBus.Protocol/Reader.cs index 2289dbc..3023774 100644 --- a/src/Tmds.DBus.Protocol/Reader.cs +++ b/src/Tmds.DBus.Protocol/Reader.cs @@ -24,16 +24,8 @@ internal Reader(bool isBigEndian, ReadOnlySequence sequence, UnixFdCollect _handleCount = handleCount; } - public void AlignStruct() => AlignReader(DBusType.Struct); - - private void AlignReader(DBusType type) - { - long pad = ProtocolConstants.GetPadding((int)_reader.Consumed, type); - if (pad != 0) - { - _reader.Advance(pad); - } - } + public void AlignStruct() + => AlignReader(ProtocolConstants.StructAlignment); private void AlignReader(int alignment) { @@ -45,17 +37,20 @@ private void AlignReader(int alignment) } public ArrayEnd ReadArrayStart(DBusType elementType) + => ReadArrayStart(ProtocolConstants.GetTypeAlignment(elementType)); + + internal ArrayEnd ReadArrayStart(int alignment) { uint arrayLength = ReadUInt32(); - AlignReader(elementType); + AlignReader(alignment); int endOfArray = (int)(_reader.Consumed + arrayLength); - return new ArrayEnd(elementType, endOfArray); + return new ArrayEnd(alignment, endOfArray); } public bool HasNext(ArrayEnd iterator) { int consumed = (int)_reader.Consumed; - int nextElement = ProtocolConstants.Align(consumed, iterator.Type); + int nextElement = ProtocolConstants.Align(consumed, iterator.Alignment); if (nextElement >= iterator.EndOfArray) { return false; @@ -77,12 +72,12 @@ public void SkipTo(ArrayEnd end) public ref struct ArrayEnd { - internal readonly DBusType Type; + internal readonly int Alignment; internal readonly int EndOfArray; - internal ArrayEnd(DBusType type, int endOfArray) + internal ArrayEnd(int alignment, int endOfArray) { - Type = type; + Alignment = alignment; EndOfArray = endOfArray; } } \ No newline at end of file