/// <summary> /// convert from jsvalue to managed value /// </summary> /// <param name="v"></param> /// <returns></returns> public object FromJsValue(ref JsValue v) { #if DEBUG_TRACE_API Console.WriteLine("Converting Js value to .net"); #endif switch (v.Type) { case JsValueType.Empty: case JsValueType.Null: return(null); case JsValueType.Boolean: return(v.I32 != 0); case JsValueType.Integer: return(v.I32); case JsValueType.Index: return((UInt32)v.I64); case JsValueType.Number: return(v.Num); case JsValueType.String: return(Marshal.PtrToStringUni(v.Ptr)); case JsValueType.Date: /* * // The formula (v.num * 10000) + 621355968000000000L was taken from a StackOverflow * // question and should be OK. Then why do we need to compensate by -26748000000000L * // (a value determined from the failing tests)?! * return new DateTime((long)(v.Num * 10000) + 621355968000000000L - 26748000000000L); */ //var msFromJsTime = v.I64 % 1000; return(EPOCH_LocalTime.AddMilliseconds(v.I64)); case JsValueType.Array: { int len = v.I32; object[] newarr = new object[len]; unsafe { JsValue *arr = (JsValue *)v.Ptr; for (int i = 0; i < len; ++i) { newarr[i] = FromJsValuePtr((arr + i)); } } return(newarr); } case JsValueType.UnknownError: if (v.Ptr != IntPtr.Zero) { return(new JsException(Marshal.PtrToStringUni(v.Ptr))); } return(new JsInteropException("unknown error without reason")); case JsValueType.StringError: return(new JsException(Marshal.PtrToStringUni(v.Ptr))); case JsValueType.Managed: return(_context.KeepAliveGet(v.I32)); case JsValueType.JsTypeWrap: //auto unwrap return(_context.GetObjectProxy(v.I32).WrapObject); case JsValueType.ManagedError: Exception inner = _context.KeepAliveGet(v.I32) as Exception; string msg = null; if (v.Ptr != IntPtr.Zero) { msg = Marshal.PtrToStringUni(v.Ptr); } else if (inner != null) { msg = inner.Message; } return(new JsException(msg, inner)); case JsValueType.Dictionary: return(CreateJsDictionaryObject(ref v)); case JsValueType.Wrapped: return(new JsObject(_context, v.Ptr)); case JsValueType.Error: return(JsException.Create(this, v.Ptr)); case JsValueType.Function: //convert from js function delegate to managed //this compose of function ptr and delegate's target unsafe { JsValue *arr = (JsValue *)v.Ptr; return(new JsFunction(_context, (arr)->Ptr, (arr + 1)->Ptr)); } default: throw new InvalidOperationException("unknown type code: " + v.Type); } }
public object FromJsValue(JsValue v) { #if DEBUG_TRACE_API Console.WriteLine("Converting Js value to .net"); #endif switch (v.Type) { case JsValueType.Empty: case JsValueType.Null: return(null); case JsValueType.Boolean: return(v.I32 != 0); case JsValueType.Integer: return(v.I32); case JsValueType.Index: return((UInt32)v.I64); case JsValueType.Number: return(v.Num); case JsValueType.String: return(Marshal.PtrToStringUni(v.Ptr)); case JsValueType.Date: /* * // The formula (v.num * 10000) + 621355968000000000L was taken from a StackOverflow * // question and should be OK. Then why do we need to compensate by -26748000000000L * // (a value determined from the failing tests)?! * return new DateTime((long)(v.Num * 10000) + 621355968000000000L - 26748000000000L); */ //var msFromJsTime = v.I64 % 1000; return(EPOCH_LocalTime.AddMilliseconds(v.I64)); // + new TimeSpan(7, 0, 0); //return EPOCH_LocalTime.AddMilliseconds(v.I64);// + new TimeSpan(7, 0, 0); //return EPOCH.AddMilliseconds(v.I64); //return EPOCH.AddMilliseconds(v.Num); //return new DateTime((long)(v.Num * 10000) + 621355968000000000L - 26748000000000L); case JsValueType.Array: { int len = v.Length; var r = new object[len]; for (int i = 0; i < len; i++) { var vi = (JsValue)Marshal.PtrToStructure(new IntPtr(v.Ptr.ToInt64() + (16 * i)), typeof(JsValue)); r[i] = FromJsValue(vi); } return(r); } case JsValueType.UnknownError: if (v.Ptr != IntPtr.Zero) { return(new JsException(Marshal.PtrToStringUni(v.Ptr))); } return(new JsInteropException("unknown error without reason")); case JsValueType.StringError: return(new JsException(Marshal.PtrToStringUni(v.Ptr))); case JsValueType.Managed: return(_context.KeepAliveGet(v.Index)); case JsValueType.JsTypeWrap: //auto unwrap return(this._context.GetObjectProxy(v.Index).WrapObject); case JsValueType.ManagedError: Exception inner = _context.KeepAliveGet(v.Index) as Exception; string msg = null; if (v.Ptr != IntPtr.Zero) { msg = Marshal.PtrToStringUni(v.Ptr); } else { if (inner != null) { msg = inner.Message; } } return(new JsException(msg, inner)); #if NET40 case JsValueType.Wrapped: return(new JsObject(_context, v.Ptr)); #else case JsValueType.Dictionary: return(JsDictionaryObject(v)); #endif case JsValueType.Wrapped: return(new JsObject(_context, v.Ptr)); case JsValueType.Error: return(JsException.Create(this, (JsError)Marshal.PtrToStructure(v.Ptr, typeof(JsError)))); case JsValueType.Function: var fa = new JsValue[2]; for (int i = 0; i < 2; i++) { fa[i] = (JsValue)Marshal.PtrToStructure(new IntPtr(v.Ptr.ToInt64() + (16 * i)), typeof(JsValue)); } return(new JsFunction(_context, fa[0].Ptr, fa[1].Ptr)); default: throw new InvalidOperationException("unknown type code: " + v.Type); } }