public void WriteStructure <T>(T value) { FieldInfo[] fis = ArgTypeInspector.GetStructFields(typeof(T)); if (fis.Length == 0) { return; } if (!_skipNextStructPadding) { WritePad(8); } _skipNextStructPadding = false; object boxed = value; if (MessageReader.IsEligibleStruct(typeof(T), fis)) { byte[] buffer = new byte[Marshal.SizeOf(fis[0].FieldType) * fis.Length]; //unsafe { GCHandle valueHandle = GCHandle.Alloc(boxed, GCHandleType.Pinned); Marshal.Copy(valueHandle.AddrOfPinnedObject(), buffer, 0, buffer.Length); valueHandle.Free(); //} stream.Write(buffer, 0, buffer.Length); return; } foreach (var fi in fis) { Write(fi.FieldType, fi.GetValue(boxed)); } }
public void WriteValueTupleStructure <T> (T value) { if (!_skipNextStructPadding) { WritePad(8); } _skipNextStructPadding = false; FieldInfo[] fis = ArgTypeInspector.GetStructFields(typeof(T), isValueTuple: true); if (fis.Length == 0) { return; } object boxed = value; for (int i = 0; i < fis.Length;) { var fi = fis[i]; if (i == 7) { boxed = fi.GetValue(boxed); fis = ArgTypeInspector.GetStructFields(fi.FieldType, isValueTuple: true); i = 0; } else { Write(fi.FieldType, fi.GetValue(boxed), isCompileTimeType: true); i++; } } }
public T ReadValueTupleStruct <T> () { if (!_skipNextStructPadding) { ReadPad(8); } _skipNextStructPadding = false; bool isValueTuple = true; FieldInfo[] fis = ArgTypeInspector.GetStructFields(typeof(T), isValueTuple); // Empty struct? No need for processing if (fis.Length == 0) { return(default(T)); } object val = Activator.CreateInstance <T> (); for (int i = 0; i < fis.Length; i++) { var fi = fis[i]; if (i == 7 && isValueTuple) { _skipNextStructPadding = true; } fi.SetValue(val, Read(fi.FieldType)); } return((T)val); }
public T ReadStruct <T> () { if (!_skipNextStructPadding) { ReadPad(8); } _skipNextStructPadding = false; FieldInfo[] fis = ArgTypeInspector.GetStructFields(typeof(T), isValueTuple: false); // Empty struct? No need for processing if (fis.Length == 0) { return(default(T)); } if (IsEligibleStruct(typeof(T), fis)) { return((T)MarshalStruct(typeof(T), fis)); } object val = Activator.CreateInstance <T> (); foreach (System.Reflection.FieldInfo fi in fis) { fi.SetValue(val, Read(fi.FieldType)); } return((T)val); }
static Type EnsureWriterForType(Type type) { if (type.GetTypeInfo().IsEnum) { type = Enum.GetUnderlyingType(type); } void AddTypeHandler(MethodInfo methodInfo) { var d = methodInfo.CreateCustomDelegate <WriteHandler>(); objHandlers[type] = d; genHandlersCache[type] = methodInfo.CreateDelegate(typeof(WriteHandler <>).MakeGenericType(type)); } if (objHandlers.TryGetValue(type, out WriteHandler handler)) { return(type); } if (ArgTypeInspector.IsDBusObjectType(type)) { return(typeof(IDBusObject)); } var enumerableType = ArgTypeInspector.InspectEnumerableType(type, out Type elementType); if (enumerableType != ArgTypeInspector.EnumerableType.NotEnumerable) { if ((enumerableType == ArgTypeInspector.EnumerableType.EnumerableKeyValuePair) || (enumerableType == ArgTypeInspector.EnumerableType.GenericDictionary)) { AddTypeHandler(s_messageWriterWriteDict.MakeGenericMethod(elementType.GenericTypeArguments)); } else if (enumerableType == ArgTypeInspector.EnumerableType.AttributeDictionary) { AddTypeHandler(s_messageWriterWriteDictionaryObject.MakeGenericMethod(type)); } else // Enumerable { AddTypeHandler(s_messageWriterWriteArray.MakeGenericMethod(new[] { elementType })); } return(type); } if (ArgTypeInspector.IsStructType(type)) { AddTypeHandler(s_messageWriterWriteStruct.MakeGenericMethod(type)); return(type); } throw new ArgumentException($"Cannot (de)serialize Type '{type.FullName}'"); }
public static int GetAlignment(Type type) { if (type.GetTypeInfo().IsEnum) { type = Enum.GetUnderlyingType(type); } if (type == typeof(bool)) { return(GetAlignment(DType.Boolean)); } else if (type == typeof(byte)) { return(GetAlignment(DType.Byte)); } else if (type == typeof(double)) { return(GetAlignment(DType.Double)); } else if (type == typeof(short)) { return(GetAlignment(DType.Int16)); } else if (type == typeof(int)) { return(GetAlignment(DType.Int32)); } else if (type == typeof(long)) { return(GetAlignment(DType.Int64)); } else if (type == typeof(ObjectPath)) { return(GetAlignment(DType.ObjectPath)); } else if (type == typeof(Signature)) { return(GetAlignment(DType.Signature)); } else if (type == typeof(string)) { return(GetAlignment(DType.String)); } else if (type == typeof(float)) { return(GetAlignment(DType.Single)); } else if (type == typeof(ushort)) { return(GetAlignment(DType.UInt16)); } else if (type == typeof(uint)) { return(GetAlignment(DType.UInt32)); } else if (type == typeof(ulong)) { return(GetAlignment(DType.UInt64)); } else if (type == typeof(object)) { return(GetAlignment(DType.Variant)); } else if (type == typeof(IDBusObject)) { return(GetAlignment(DType.Variant)); } if (ArgTypeInspector.IsDBusObjectType(type, isCompileTimeType: true)) { return(GetAlignment(DType.Variant)); } Type elementType; if (ArgTypeInspector.InspectEnumerableType(type, out elementType, isCompileTimeType: true) != ArgTypeInspector.EnumerableType.NotEnumerable) { return(GetAlignment(DType.Array)); } if (ArgTypeInspector.IsStructType(type)) { return(GetAlignment(DType.StructBegin)); } if (ArgTypeInspector.IsSafeHandleType(type)) { return(GetAlignment(DType.UnixFd)); } throw new ArgumentException($"Cannot (de)serialize Type '{type.FullName}'"); }
public static Signature GetSig(Type type) { if (type == null) { throw new ArgumentNullException(nameof(type)); } if (type.GetTypeInfo().IsEnum) { type = Enum.GetUnderlyingType(type); } if (type == typeof(bool)) { return(BoolSig); } else if (type == typeof(byte)) { return(ByteSig); } else if (type == typeof(double)) { return(DoubleSig); } else if (type == typeof(short)) { return(Int16Sig); } else if (type == typeof(int)) { return(Int32Sig); } else if (type == typeof(long)) { return(Int64Sig); } else if (type == typeof(ObjectPath)) { return(ObjectPathSig); } else if (type == typeof(Signature)) { return(SignatureSig); } else if (type == typeof(string)) { return(StringSig); } else if (type == typeof(float)) { return(DoubleSig); // SingleSig } else if (type == typeof(ushort)) { return(UInt16Sig); } else if (type == typeof(uint)) { return(UInt32Sig); } else if (type == typeof(ulong)) { return(UInt64Sig); } else if (type == typeof(object)) { return(VariantSig); } else if (type == typeof(IDBusObject)) { return(ObjectPathSig); } else if (type == typeof(void)) { return(Empty); } if (ArgTypeInspector.IsDBusObjectType(type)) { return(ObjectPathSig); } var enumerableType = ArgTypeInspector.InspectEnumerableType(type, out Type elementType); if (enumerableType != ArgTypeInspector.EnumerableType.NotEnumerable) { if ((enumerableType == ArgTypeInspector.EnumerableType.EnumerableKeyValuePair) || (enumerableType == ArgTypeInspector.EnumerableType.GenericDictionary) || (enumerableType == ArgTypeInspector.EnumerableType.AttributeDictionary)) { Type keyType = elementType.GenericTypeArguments[0]; Type valueType = elementType.GenericTypeArguments[1]; return(Signature.MakeDict(GetSig(keyType), GetSig(valueType))); } else // Enumerable { return(MakeArray(GetSig(elementType))); } } if (ArgTypeInspector.IsStructType(type, out bool isValueTuple)) { Signature sig = Signature.Empty; var fields = ArgTypeInspector.GetStructFields(type, isValueTuple); foreach (FieldInfo fi in fields) { sig += GetSig(fi.FieldType); } return(Signature.MakeStruct(sig)); } throw new ArgumentException($"Cannot (de)serialize Type '{type.FullName}'"); }
public void Write(Type type, object val, bool isCompileTimeType) { if (type.GetTypeInfo().IsEnum) { type = Enum.GetUnderlyingType(type); } if (type == typeof(bool)) { WriteBoolean((bool)val); return; } else if (type == typeof(byte)) { WriteByte((byte)val); return; } else if (type == typeof(double)) { WriteDouble((double)val); return; } else if (type == typeof(short)) { WriteInt16((short)val); return; } else if (type == typeof(int)) { WriteInt32((int)val); return; } else if (type == typeof(long)) { WriteInt64((long)val); return; } else if (type == typeof(ObjectPath)) { WriteObjectPath((ObjectPath)val); return; } else if (type == typeof(Signature)) { WriteSignature((Signature)val); return; } else if (type == typeof(string)) { WriteString((string)val); return; } else if (type == typeof(float)) { WriteSingle((float)val); return; } else if (type == typeof(ushort)) { WriteUInt16((ushort)val); return; } else if (type == typeof(uint)) { WriteUInt32((uint)val); return; } else if (type == typeof(ulong)) { WriteUInt64((ulong)val); return; } else if (type == typeof(object)) { WriteVariant(val); return; } else if (type == typeof(IDBusObject)) { WriteBusObject((IDBusObject)val); return; } if (ArgTypeInspector.IsDBusObjectType(type, isCompileTimeType)) { WriteBusObject((IDBusObject)val); return; } if (ArgTypeInspector.IsSafeHandleType(type)) { WriteSafeHandle((SafeHandle)val); return; } MethodInfo method = WriteMethodFactory.CreateWriteMethodForType(type, isCompileTimeType); if (method.IsStatic) { method.Invoke(null, new object[] { this, val }); } else { method.Invoke(this, new object[] { val }); } }