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}'");
        }
Beispiel #3
0
        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}'");
        }