Пример #1
0
        public static VMObject CastTo(VMObject srcObj, VMType type)
        {
            if (srcObj.Type == type)
            {
                var result = new VMObject();
                result.Copy(srcObj);
                return(result);
            }

            switch (type)
            {
            case VMType.None:
                return(new VMObject());

            case VMType.String:
            {
                var result = new VMObject();
                result.SetValue(srcObj.AsString());         // TODO does this work for all types?
                return(result);
            }

            case VMType.Timestamp:
            {
                var result = new VMObject();
                result.SetValue(srcObj.AsTimestamp());         // TODO does this work for all types?
                return(result);
            }

            case VMType.Bool:
            {
                var result = new VMObject();
                result.SetValue(srcObj.AsBool());         // TODO does this work for all types?
                return(result);
            }

            case VMType.Bytes:
            {
                var result = new VMObject();
                result.SetValue(srcObj.AsByteArray());         // TODO does this work for all types?
                return(result);
            }

            case VMType.Number:
            {
                var result = new VMObject();
                result.SetValue(srcObj.AsNumber());         // TODO does this work for all types?
                return(result);
            }

            case VMType.Struct:
                switch (srcObj.Type)
                {
                case VMType.Object: return(CastViaReflection(srcObj.Data, 0));

                default: throw new Exception($"invalid cast: {srcObj.Type} to {type}");
                }

            default: throw new Exception($"invalid cast: {srcObj.Type} to {type}");
            }
        }
Пример #2
0
        public static VMObject FromObject(object obj)
        {
            var type = GetVMType(obj.GetType());

            Throw.If(type == VMType.None, "not a valid object");

            var result = new VMObject();

            switch (type)
            {
            case VMType.Bool: result.SetValue((bool)obj); break;

            case VMType.Bytes: result.SetValue((byte[])obj, VMType.Bytes); break;

            case VMType.String: result.SetValue((string)obj); break;

            case VMType.Number: result.SetValue((BigInteger)obj); break;

            case VMType.Enum: result.SetValue((Enum)obj); break;

            case VMType.Object: result.SetValue(obj); break;

            case VMType.Timestamp:
                if (obj.GetType() == typeof(uint))
                {
                    obj = new Timestamp((uint)obj);     // HACK
                }
                result.SetValue((Timestamp)obj);
                break;

            default: return(null);
            }

            return(result);
        }
Пример #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");
            }
        }
Пример #4
0
        public static VMObject CastTo(VMObject srcObj, VMType type)
        {
            if (srcObj.Type == type)
            {
                var result = new VMObject();
                result.Copy(srcObj);
                return(result);
            }

            switch (type)
            {
            case VMType.None:
                return(new VMObject());

            case VMType.String:
            {
                var result = new VMObject();
                result.SetValue(srcObj.AsString());         // TODO does this work for all types?
                return(result);
            }

            case VMType.Timestamp:
            {
                var result = new VMObject();
                result.SetValue(srcObj.AsTimestamp());         // TODO does this work for all types?
                return(result);
            }

            case VMType.Bool:
                // TODO move this stuff to AsBool()
                switch (srcObj.Type)
                {
                case VMType.Number:
                {
                    var result = new VMObject();
                    result.SetValue(srcObj.AsNumber() != 0);
                    return(result);
                }

                case VMType.String:
                {
                    var result = new VMObject();
                    result.SetValue(!(((string)srcObj.Data).Equals("false", StringComparison.OrdinalIgnoreCase)));
                    return(result);
                }

                default: throw new Exception($"invalid cast: {srcObj.Type} to {type}");
                }

            case VMType.Bytes:
                switch (srcObj.Type)
                {
                case VMType.Bool:
                {
                    var result = new VMObject();
                    result.SetValue(new byte[] { (byte)(srcObj.AsBool() ? 1 : 0) }, VMType.Bytes);
                    return(result);
                }

                case VMType.String:
                {
                    var result = new VMObject();
                    result.SetValue(Encoding.UTF8.GetBytes((string)srcObj.Data), VMType.Bytes);
                    return(result);
                }

                case VMType.Number:
                {
                    var result = new VMObject();
                    result.SetValue(((BigInteger)srcObj.Data).ToSignedByteArray(), VMType.Bytes);
                    return(result);
                }

                default: throw new Exception($"invalid cast: {srcObj.Type} to {type}");
                }

            case VMType.Number:
                switch (srcObj.Type)
                {
                case VMType.Bool:
                {
                    var result = new VMObject();
                    result.SetValue(srcObj.AsBool() ? 1 : 0);
                    return(result);
                }

                case VMType.String:
                {
                    var result = new VMObject();
                    result.SetValue(BigInteger.Parse((string)srcObj.Data));
                    return(result);
                }

                case VMType.Bytes:
                {
                    var result = new VMObject();
                    result.SetValue(BigInteger.FromSignedArray((byte[])srcObj.Data));
                    return(result);
                }

                default: throw new Exception($"invalid cast: {srcObj.Type} to {type}");
                }

            case VMType.Struct:
                switch (srcObj.Type)
                {
                case VMType.Object: return(CastViaReflection(srcObj.Data, 0));

                default: throw new Exception($"invalid cast: {srcObj.Type} to {type}");
                }

            default: throw new Exception($"invalid cast: {srcObj.Type} to {type}");
            }
        }
Пример #5
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");
            }
        }