예제 #1
0
        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));
            }
        }
예제 #2
0
        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++;
                }
            }
        }
예제 #3
0
        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);
        }
예제 #4
0
        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);
        }
예제 #5
0
        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}'");
        }
예제 #6
0
        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}'");
        }
예제 #7
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}'");
        }
예제 #8
0
        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 });
            }
        }