Skip to content

Commit

Permalink
Fix DirectCopy and ValueTuple<T> detection.
Browse files Browse the repository at this point in the history
  • Loading branch information
Umdrahschua authored Dec 21, 2023
1 parent a62998f commit a0ca30c
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 30 deletions.
17 changes: 7 additions & 10 deletions src/Tmds.DBus/CodeGen/ArgTypeInspector.cs
Original file line number Diff line number Diff line change
Expand Up @@ -162,17 +162,14 @@ public static bool IsStructType(Type type, out bool isValueTuple)
{
return false;
}
if (!typeInfo.IsLayoutSequential)
if (IsValueTuple(typeInfo))
{
if (IsValueTuple(typeInfo))
{
isValueTuple = true;
return true;
}
else
{
return false;
}
isValueTuple = true;
return true;
}
else if (!typeInfo.IsLayoutSequential)
{
return false;
}

if (typeInfo.ImplementedInterfaces.Contains(s_idbusObjectType))
Expand Down
15 changes: 8 additions & 7 deletions src/Tmds.DBus/Protocol/MessageReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -504,30 +504,31 @@ TArray[] MarshalArray<TArray> (uint length)
_pos += (int)length;
} else {
GCHandle handle = GCHandle.Alloc (array, GCHandleType.Pinned);
DirectCopy (sof, length, handle);
DirectCopy (sof, array.Length, handle);
handle.Free ();
}

return array;
}

void DirectCopy (int sof, uint length, GCHandle handle)
void DirectCopy (int sof, int length, GCHandle handle)
{
DirectCopy (sof, length, handle.AddrOfPinnedObject ());
}

unsafe void DirectCopy (int sof, uint length, IntPtr handle)
unsafe void DirectCopy (int sof, int length, IntPtr handle)
{
int byteLength = length * sof;
if (_endianness == Environment.NativeEndianness) {
Marshal.Copy (_data.Array, _data.Offset + _pos, handle, (int)length);
Marshal.Copy (_data.Array, _data.Offset + _pos, handle, byteLength);
} else {
byte* ptr = (byte*)(void*)handle;
for (int i = _pos; i < _pos + length; i += sof)
for (int i = _pos; i < _pos + byteLength; i += sof)
for (int j = i; j < i + sof; j++)
ptr[2 * i - _pos + (sof - 1) - j] = _data.Array[_data.Offset + j];
}

_pos += (int)length * sof;
_pos += byteLength;
}

bool[] MarshalBoolArray (uint length)
Expand Down Expand Up @@ -599,7 +600,7 @@ object MarshalStruct (Type structType, FieldInfo[] fis)
object strct = Activator.CreateInstance (structType);
int sof = Marshal.SizeOf (fis[0].FieldType);
GCHandle handle = GCHandle.Alloc (strct, GCHandleType.Pinned);
DirectCopy (sof, (uint)(fis.Length * sof), handle);
DirectCopy (sof, fis.Length, handle);
handle.Free ();

return strct;
Expand Down
12 changes: 8 additions & 4 deletions test/Tmds.DBus.Tests/ReaderTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,7 @@ public class PersonProperties
public int? Age;
public Gender? Gender;
public bool IsMarried;
public ValueTuple<byte, byte, byte, byte, byte, byte, byte, ValueTuple<long>>? SomeNumbers;
public override bool Equals(object rhs)
{
var other = rhs as PersonProperties;
Expand All @@ -292,7 +293,9 @@ public override bool Equals(object rhs)
}
return (Name == other.Name) &&
(Age == other.Age) &&
(Gender == other.Gender);
(Gender == other.Gender) &&
(IsMarried == other.IsMarried) &&
(SomeNumbers == other.SomeNumbers);
}
public override int GetHashCode()
{
Expand Down Expand Up @@ -364,7 +367,8 @@ public static IEnumerable<object[]> ReadTestData
Name = "John",
Age = 32,
Gender = Gender.Male,
IsMarried = true
IsMarried = true,
SomeNumbers = new ValueTuple<byte, byte, byte, byte, byte, byte, byte, ValueTuple<long>>(1, 3, 5, 7, 9, 11, 13, new ValueTuple<long>(15))
};
var john2 = new PersonProperties2()
{
Expand Down Expand Up @@ -429,8 +433,8 @@ public static IEnumerable<object[]> ReadTestData
new object[] {typeof(IStringOperations), new MyDBusObject(StringOperations.Path), 4, new byte[] { 0, 0, 0, 4, (byte)'/', (byte)'a', (byte)'/', (byte)'b', 0 },
new byte[] { 4, 0, 0, 0, (byte)'/', (byte)'a', (byte)'/', (byte)'b', 0 },
new DBusObjectComparer()},
new object[] {typeof(PersonProperties), john, 4, new byte[] {0, 0, 0, 88, 0, 0, 0, 0, 0, 0, 0, 4, 78, 97, 109, 101, 0, 1, 115, 0, 0, 0, 0, 4, 74, 111, 104, 110, 0, 0, 0, 0, 0, 0, 0, 3, 65, 103, 101, 0, 1, 105, 0, 0, 0, 0, 0, 32, 0, 0, 0, 6, 71, 101, 110, 100, 101, 114, 0, 1, 105, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 73, 115, 77, 97, 114, 114, 105, 101, 100, 0, 1, 98, 0, 0, 0, 0, 0, 0, 0, 1},
new byte[] {88, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 78, 97, 109, 101, 0, 1, 115, 0, 4, 0, 0, 0, 74, 111, 104, 110, 0, 0, 0, 0, 3, 0, 0, 0, 65, 103, 101, 0, 1, 105, 0, 0, 32, 0, 0, 0, 6, 0, 0, 0, 71, 101, 110, 100, 101, 114, 0, 1, 105, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 73, 115, 77, 97, 114, 114, 105, 101, 100, 0, 1, 98, 0, 0, 0, 0, 1, 0, 0, 0}, null},
new object[] {typeof(PersonProperties), john, 4, new byte[] {0, 0, 0, 136, 0, 0, 0, 0, 0, 0, 0, 4, 78, 97, 109, 101, 0, 1, 115, 0, 0, 0, 0, 4, 74, 111, 104, 110, 0, 0, 0, 0, 0, 0, 0, 3, 65, 103, 101, 0, 1, 105, 0, 0, 0, 0, 0, 32, 0, 0, 0, 6, 71, 101, 110, 100, 101, 114, 0, 1, 105, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 73, 115, 77, 97, 114, 114, 105, 101, 100, 0, 1, 98, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 11, 83, 111, 109, 101, 78, 117, 109, 98, 101, 114, 115, 0, 10, 40, 121, 121, 121, 121, 121, 121, 121, 120, 41, 0, 0, 0, 0, 0, 1, 3, 5, 7, 9, 11, 13, 0, 0, 0, 0, 0, 0, 0, 0, 15},
new byte[] {136, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 78, 97, 109, 101, 0, 1, 115, 0, 4, 0, 0, 0, 74, 111, 104, 110, 0, 0, 0, 0, 3, 0, 0, 0, 65, 103, 101, 0, 1, 105, 0, 0, 32, 0, 0, 0, 6, 0, 0, 0, 71, 101, 110, 100, 101, 114, 0, 1, 105, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 73, 115, 77, 97, 114, 114, 105, 101, 100, 0, 1, 98, 0, 0, 0, 0, 1, 0, 0, 0, 11, 0, 0, 0, 83, 111, 109, 101, 78, 117, 109, 98, 101, 114, 115, 0, 10, 40, 121, 121, 121, 121, 121, 121, 121, 120, 41, 0, 0, 0, 0, 0, 1, 3, 5, 7, 9, 11, 13, 0, 15, 0, 0, 0, 0, 0, 0, 0 }, null},
new object[] {typeof(PersonProperties2), john2, 4, new byte[] {0, 0, 0, 88, 0, 0, 0, 0, 0, 0, 0, 4, 78, 97, 109, 101, 0, 1, 115, 0, 0, 0, 0, 4, 74, 111, 104, 110, 0, 0, 0, 0, 0, 0, 0, 3, 65, 103, 101, 0, 1, 105, 0, 0, 0, 0, 0, 32, 0, 0, 0, 6, 71, 101, 110, 100, 101, 114, 0, 1, 105, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 73, 115, 77, 97, 114, 114, 105, 101, 100, 0, 1, 98, 0, 0, 0, 0, 0, 0, 0, 1},
new byte[] {88, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 78, 97, 109, 101, 0, 1, 115, 0, 4, 0, 0, 0, 74, 111, 104, 110, 0, 0, 0, 0, 3, 0, 0, 0, 65, 103, 101, 0, 1, 105, 0, 0, 32, 0, 0, 0, 6, 0, 0, 0, 71, 101, 110, 100, 101, 114, 0, 1, 105, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 73, 115, 77, 97, 114, 114, 105, 101, 100, 0, 1, 98, 0, 0, 0, 0, 1, 0, 0, 0}, null},
new object[] {typeof(DictionaryWithDash), new DictionaryWithDash { f_d = 5 }, 4, new byte[] {0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 3, 102, (byte)'-', 100, 0, 1, 105, 0, 0, 0, 0, 0, 5},
Expand Down
24 changes: 15 additions & 9 deletions test/Tmds.DBus.Tests/WriterTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ public class PersonProperties
public int? Age;
public Gender? Gender;
public bool IsMarried;
public ValueTuple<byte, byte, byte, byte, byte, byte, byte, ValueTuple<long>>? SomeNumbers;
}

public static IEnumerable<object[]> WriteTestData
Expand All @@ -162,7 +163,8 @@ public static IEnumerable<object[]> WriteTestData
Name = "John",
Age = 32,
Gender = Gender.Male,
IsMarried = true
IsMarried = true,
SomeNumbers = new ValueTuple<byte, byte, byte, byte, byte, byte, byte, ValueTuple<long>>(1, 3, 5, 7, 9, 11, 13, new ValueTuple<long>(15))
};
var unknownPerson = new PersonProperties()
{};
Expand Down Expand Up @@ -210,10 +212,12 @@ public static IEnumerable<object[]> WriteTestData
new byte[] {28, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 111, 110, 101, 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 116, 119, 111, 0}},
new object[] {typeof(IDictionary<byte, string>), myDictionary, 4, new byte[] {0, 0, 0, 28, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 3, 111, 110, 101, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 3, 116, 119, 111, 0},
new byte[] {28, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 111, 110, 101, 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 116, 119, 111, 0}},
new object[] {typeof(PersonProperties), john, 4, new byte[] {0, 0, 0, 88, 0, 0, 0, 0, 0, 0, 0, 4, 78, 97, 109, 101, 0, 1, 115, 0, 0, 0, 0, 4, 74, 111, 104, 110, 0, 0, 0, 0, 0, 0, 0, 3, 65, 103, 101, 0, 1, 105, 0,
0, 0, 0, 0, 32, 0, 0, 0, 6, 71, 101, 110, 100, 101, 114, 0, 1, 105, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 73, 115, 77, 97, 114, 114, 105, 101, 100, 0, 1, 98, 0, 0, 0, 0, 0, 0, 0, 1},
new byte[] {88, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 78, 97, 109, 101, 0, 1, 115, 0, 4, 0, 0, 0, 74, 111, 104, 110, 0, 0, 0, 0, 3, 0, 0, 0, 65, 103, 101, 0, 1, 105, 0,
0, 32, 0, 0, 0, 6, 0, 0, 0, 71, 101, 110, 100, 101, 114, 0, 1, 105, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 73, 115, 77, 97, 114, 114, 105, 101, 100, 0, 1, 98, 0, 0, 0, 0, 1, 0, 0, 0}},
new object[] {typeof(PersonProperties), john, 4, new byte[] {0, 0, 0, 136, 0, 0, 0, 0, 0, 0, 0, 4, 78, 97, 109, 101, 0, 1, 115, 0, 0, 0, 0, 4, 74, 111, 104, 110, 0, 0, 0, 0, 0, 0, 0, 3, 65, 103, 101, 0, 1, 105, 0,
0, 0, 0, 0, 32, 0, 0, 0, 6, 71, 101, 110, 100, 101, 114, 0, 1, 105, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 73, 115, 77, 97, 114, 114, 105, 101, 100, 0, 1, 98, 0, 0, 0, 0, 0, 0, 0, 1,
0, 0, 0, 11, 83, 111, 109, 101, 78, 117, 109, 98, 101, 114, 115, 0, 10, 40, 121, 121, 121, 121, 121, 121, 121, 120, 41, 0, 0, 0, 0, 0, 1, 3, 5, 7, 9, 11, 13, 0, 0, 0, 0, 0, 0, 0, 0, 15},
new byte[] {136, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 78, 97, 109, 101, 0, 1, 115, 0, 4, 0, 0, 0, 74, 111, 104, 110, 0, 0, 0, 0, 3, 0, 0, 0, 65, 103, 101, 0, 1, 105, 0,
0, 32, 0, 0, 0, 6, 0, 0, 0, 71, 101, 110, 100, 101, 114, 0, 1, 105, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 73, 115, 77, 97, 114, 114, 105, 101, 100, 0, 1, 98, 0, 0, 0, 0, 1, 0, 0, 0,
11, 0, 0, 0, 83, 111, 109, 101, 78, 117, 109, 98, 101, 114, 115, 0, 10, 40, 121, 121, 121, 121, 121, 121, 121, 120, 41, 0, 0, 0, 0, 0, 1, 3, 5, 7, 9, 11, 13, 0, 15, 0, 0, 0, 0, 0, 0, 0}},
new object[] {typeof(PersonProperties), unknownPerson, 4, new byte[] {0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 9, 73, 115, 77, 97, 114, 114, 105, 101, 100, 0, 1, 98, 0, 0, 0, 0, 0, 0, 0, 0},
new byte[] {24, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 73, 115, 77, 97, 114, 114, 105, 101, 100, 0, 1, 98, 0, 0, 0, 0, 0, 0, 0, 0}},
new object[] {typeof(ValueTuple<int, int>), (5, 4), 8, new byte[] {0, 0, 0, 5, 0, 0, 0, 4}, new byte[] {5, 0, 0, 0, 4, 0, 0, 0}},
Expand Down Expand Up @@ -259,10 +263,12 @@ public static IEnumerable<object[]> WriteTestData
new object[] {typeof(object), myDictionary, 4, new byte[] {5, 97, 123, 121, 115, 125, 0, 0, 0, 0, 0, 28, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 3, 111, 110, 101, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 3, 116, 119, 111, 0},
new byte[] {5, 97, 123, 121, 115, 125, 0, 0, 28, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 111, 110, 101, 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 116, 119, 111, 0}},

new object[] {typeof(object), john, 4, new byte[] {5, 97, 123, 115, 118, 125, 0, 0, 0, 0, 0, 88, 0, 0, 0, 0, 0, 0, 0, 4, 78, 97, 109, 101, 0, 1, 115, 0, 0, 0, 0, 4, 74, 111, 104, 110, 0, 0, 0, 0, 0, 0, 0, 3,
65, 103, 101, 0, 1, 105, 0, 0, 0, 0, 0, 32, 0, 0, 0, 6, 71, 101, 110, 100, 101, 114, 0, 1, 105, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 73, 115, 77, 97, 114, 114, 105, 101, 100, 0, 1, 98, 0, 0, 0, 0, 0, 0, 0, 1},
new byte[] {5, 97, 123, 115, 118, 125, 0, 0, 88, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 78, 97, 109, 101, 0, 1, 115, 0, 4, 0, 0, 0, 74, 111, 104, 110, 0, 0, 0, 0, 3, 0, 0, 0,
65, 103, 101, 0, 1, 105, 0, 0, 32, 0, 0, 0, 6, 0, 0, 0, 71, 101, 110, 100, 101, 114, 0, 1, 105, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 73, 115, 77, 97, 114, 114, 105, 101, 100, 0, 1, 98, 0, 0, 0, 0, 1, 0, 0, 0}},
new object[] {typeof(object), john, 4, new byte[] {5, 97, 123, 115, 118, 125, 0, 0, 0, 0, 0, 136, 0, 0, 0, 0, 0, 0, 0, 4, 78, 97, 109, 101, 0, 1, 115, 0, 0, 0, 0, 4, 74, 111, 104, 110, 0, 0, 0, 0, 0, 0, 0, 3,
65, 103, 101, 0, 1, 105, 0, 0, 0, 0, 0, 32, 0, 0, 0, 6, 71, 101, 110, 100, 101, 114, 0, 1, 105, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 73, 115, 77, 97, 114, 114, 105, 101, 100, 0, 1, 98, 0, 0, 0, 0, 0, 0, 0, 1,
0, 0, 0, 11, 83, 111, 109, 101, 78, 117, 109, 98, 101, 114, 115, 0, 10, 40, 121, 121, 121, 121, 121, 121, 121, 120, 41, 0, 0, 0, 0, 0, 1, 3, 5, 7, 9, 11, 13, 0, 0, 0, 0, 0, 0, 0, 0, 15},
new byte[] {5, 97, 123, 115, 118, 125, 0, 0, 136, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 78, 97, 109, 101, 0, 1, 115, 0, 4, 0, 0, 0, 74, 111, 104, 110, 0, 0, 0, 0, 3, 0, 0, 0,
65, 103, 101, 0, 1, 105, 0, 0, 32, 0, 0, 0, 6, 0, 0, 0, 71, 101, 110, 100, 101, 114, 0, 1, 105, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 73, 115, 77, 97, 114, 114, 105, 101, 100, 0, 1, 98, 0, 0, 0, 0, 1, 0, 0, 0,
11, 0, 0, 0, 83, 111, 109, 101, 78, 117, 109, 98, 101, 114, 115, 0, 10, 40, 121, 121, 121, 121, 121, 121, 121, 120, 41, 0, 0, 0, 0, 0, 1, 3, 5, 7, 9, 11, 13, 0, 15, 0, 0, 0, 0, 0, 0, 0}},
new object[] {typeof(object), unknownPerson, 4, new byte[] {5, 97, 123, 115, 118, 125, 0, 0, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 9, 73, 115, 77, 97, 114, 114, 105, 101, 100, 0, 1, 98, 0, 0, 0, 0, 0, 0, 0, 0},
new byte[] {5, 97, 123, 115, 118, 125, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 73, 115, 77, 97, 114, 114, 105, 101, 100, 0, 1, 98, 0, 0, 0, 0, 0, 0, 0, 0}},
new object[] {typeof(object), (5, 4), 8, new byte[] {4, 40, 105, 105, 41, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 4}, new byte[] {4, 40, 105, 105, 41, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0}},
Expand Down

0 comments on commit a0ca30c

Please sign in to comment.