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}"); } }
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); }
// 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"); } }
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}"); } }
// 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"); } }