Example #1
0
        public object ToStruct(Type structType)
        {
            Throw.If(Type != VMType.Struct, "not a valid source struct");

            Throw.If(!structType.IsStructOrClass(), "not a valid destination struct");

            var dict = this.GetChildren();

            var fields = structType.GetFields();
            var result = Activator.CreateInstance(structType);

            object boxed = result;

            foreach (var field in fields)
            {
                var key = VMObject.FromObject(field.Name);
                Throw.If(!dict.ContainsKey(key), "field not present in source struct: " + field.Name);
                var val = dict[key].ToObject(field.FieldType);

                // here we check if the types mismatch
                // in case of getting a byte[] instead of an object, we try unserializing the bytes in a different approach
                // NOTE this should not be necessary often, but is already getting into black magic territory...
                if (val != null && field.FieldType != typeof(byte[]) && val.GetType() == typeof(byte[]))
                {
                    if (typeof(ISerializable).IsAssignableFrom(field.FieldType))
                    {
                        var temp  = (ISerializable)Activator.CreateInstance(field.FieldType);
                        var bytes = (byte[])val;
                        using (var stream = new MemoryStream(bytes))
                        {
                            using (var reader = new BinaryReader(stream))
                            {
                                temp.UnserializeData(reader);
                            }
                        }
                        val = temp;
                    }
                }

                // HACK allows treating uints as enums, without this it is impossible to transform between C# objects and VM objects
                if (field.FieldType.IsEnum && !val.GetType().IsEnum)
                {
                    val = Enum.Parse(field.FieldType, val.ToString());
                }

                field.SetValue(boxed, val);
            }
            return(boxed);
        }
Example #2
0
        public object ToStruct(Type structType)
        {
            Throw.If(Type != VMType.Struct, "not a valid source struct");

            Throw.If(!structType.IsStructOrClass(), "not a valid destination struct");

            var dict = this.GetChildren();

            var fields = structType.GetFields();
            var result = Activator.CreateInstance(structType);

            object boxed = result;

            foreach (var field in fields)
            {
                var key = VMObject.FromObject(field.Name);
                Throw.If(!dict.ContainsKey(key), "field not present in source struct: " + field.Name);
                var val = dict[key].ToObject(field.FieldType);
                field.SetValue(boxed, val);
            }
            return(boxed);
        }
Example #3
0
        // this does the opposite of ToStruct(), takes a InteropObject and converts it to a VM.Struct
        private static VMObject CastViaReflection(object srcObj, int level)
        {
            var srcType = srcObj.GetType();

            if (srcType.IsArray)
            {
                var children = new Dictionary <VMObject, VMObject>();

                var array = (Array)srcObj;
                for (int i = 0; i < array.Length; i++)
                {
                    var val = array.GetValue(i);
                    var key = new VMObject();
                    key.SetValue(i);
                    var vmVal = CastViaReflection(val, level + 1);
                    children[key] = vmVal;
                }

                var result = new VMObject();
                result.SetValue(children);
                return(result);
            }
            else
            {
                var targetType = VMObject.GetVMType(srcType);

                VMObject result;

                bool isKnownType = typeof(BigInteger) == srcType || typeof(Timestamp) == srcType || typeof(ISerializable).IsAssignableFrom(srcType);

                if (srcType.IsStructOrClass() && !isKnownType)
                {
                    var children = new Dictionary <VMObject, VMObject>();

                    var fields = srcType.GetFields();

                    if (fields.Length > 0)
                    {
                        foreach (var field in fields)
                        {
                            var key = new VMObject();
                            key.SetValue(field.Name);
                            var val   = field.GetValue(srcObj);
                            var vmVal = CastViaReflection(val, level + 1);
                            children[key] = vmVal;
                        }

                        result = new VMObject();
                        result.SetValue(children);
                        return(result);
                    }
                }

                result = VMObject.FromObject(srcObj);
                if (result != null)
                {
                    return(result);
                }

                throw new Exception($"invalid cast: Interop.{srcType.Name} to vm object");
            }
        }
Example #4
0
        // this does the opposite of ToStruct(), takes a InteropObject and converts it to a VM.Struct
        private static VMObject CastViaReflection(object srcObj, int level)
        {
            var srcType = srcObj.GetType();

            if (srcType.IsArray)
            {
                var children = new Dictionary <VMObject, VMObject>();

                var array = (Array)srcObj;
                for (int i = 0; i < array.Length; i++)
                {
                    var val = array.GetValue(i);
                    var key = new VMObject();
                    key.SetValue(i);
                    var vmVal = CastViaReflection(val, level + 1);
                    children[key] = vmVal;
                }

                var result = new VMObject();
                result.SetValue(children);
                return(result);
            }
            else
            {
                VMObject result;

                if (level == 0 && srcType.IsStructOrClass())
                {
                    var children = new Dictionary <VMObject, VMObject>();

                    var fields = srcType.GetFields();

                    if (fields.Length > 0)
                    {
                        foreach (var field in fields)
                        {
                            var key = new VMObject();
                            key.SetValue(field.Name);
                            var val   = field.GetValue(srcObj);
                            var vmVal = CastViaReflection(val, level + 1);
                            children[key] = vmVal;
                        }

                        result = new VMObject();
                        result.SetValue(children);
                        return(result);
                    }
                    else
                    {
                        throw new Exception("Invalid cast, no fields available");
                    }
                }

                result = VMObject.FromObject(srcObj);
                if (result != null)
                {
                    return(result);
                }

                throw new Exception($"invalid cast: Interop.{srcType.Name} to vm object");
            }
        }