internal static object ConvertJsValueToNetObject(Jint.Native.JsValue v) { if (v.IsBoolean()) { return(v.AsBoolean()); } if (v.IsNumber()) { return(v.AsNumber()); } if (v.IsNull()) { return(null); } if (v.IsUndefined()) { return("undefined"); } if (v.IsString()) { return(v.AsString()); } if (v.IsObject()) { return(v.ToObject()); } throw new ArgumentException(string.Format("Cannot get display value for JsValue")); }
public void ShouldBeADate() { var value = new JsValue(new DateInstance(null)); Assert.Equal(false, value.IsBoolean()); Assert.Equal(false, value.IsArray()); Assert.Equal(true, value.IsDate()); Assert.Equal(false, value.IsNull()); Assert.Equal(false, value.IsNumber()); Assert.Equal(true, value.IsObject()); Assert.Equal(false, value.IsPrimitive()); Assert.Equal(false, value.IsRegExp()); Assert.Equal(false, value.IsString()); Assert.Equal(false, value.IsUndefined()); Assert.Equal(true, value.AsDate() != null); }
/// <summary> /// http://www.ecma-international.org/ecma-262/5.1/#sec-9.2 /// </summary> /// <param name="o"></param> /// <returns></returns> public static bool ToBoolean(JsValue o) { if (o.IsObject()) { return true; } if (o == Undefined.Instance || o == Null.Instance) { return false; } if (o.IsBoolean()) { return o.AsBoolean(); } if (o.IsNumber()) { var n = o.AsNumber(); if (n.Equals(0) || double.IsNaN(n)) { return false; } else { return true; } } if (o.IsString()) { var s = o.AsString(); if (String.IsNullOrEmpty(s)) { return false; } else { return true; } } return true; }
private RavenJToken ToRavenJToken(JsValue v, string propertyKey) { if (v.IsBoolean()) return new RavenJValue(v.AsBoolean()); if (v.IsString()) { const string RavenDataByteArrayToBase64 = "raven-data:byte[];base64,"; var value = v.AsString(); if (value != null && value.StartsWith(RavenDataByteArrayToBase64)) { value = value.Remove(0, RavenDataByteArrayToBase64.Length); var byteArray = Convert.FromBase64String(value); return new RavenJValue(byteArray); } return new RavenJValue(value); } if (v.IsNumber()) { var num = v.AsNumber(); KeyValuePair<RavenJValue, JsValue> property; if (propertiesByValue.TryGetValue(propertyKey, out property)) { var originalValue = property.Key; if (originalValue.Type == JTokenType.Float) return new RavenJValue(num); if (originalValue.Type == JTokenType.Integer) { // If the current value is exactly as the original value, we can return the original value before we made the JS conversion, // which will convert a Int64 to jsFloat. var originalJsValue = property.Value; if (originalJsValue.IsNumber() && Math.Abs(num - originalJsValue.AsNumber()) < double.Epsilon) return originalValue; return new RavenJValue((long)num); } } // If we don't have the type, assume that if the number ending with ".0" it actually an integer. var integer = Math.Truncate(num); if (Math.Abs(num - integer) < double.Epsilon) return new RavenJValue((long)integer); return new RavenJValue(num); } if (v.IsNull()) return RavenJValue.Null; if (v.IsUndefined()) return RavenJValue.Null; if (v.IsArray()) { var jsArray = v.AsArray(); var rja = new RavenJArray(); foreach (var property in jsArray.Properties) { if (property.Key == "length") continue; var jsInstance = property.Value.Value; if (!jsInstance.HasValue) continue; var ravenJToken = ToRavenJToken(jsInstance.Value, CreatePropertyKey(property.Key, propertyKey)); if (ravenJToken == null) continue; rja.Add(ravenJToken); } return rja; } if (v.IsObject()) return ToRavenJObject(v, propertyKey); if (v.IsRegExp()) return null; throw new NotSupportedException(v.Type.ToString()); }
public static ObjectInstance ToObject(Engine engine, JsValue value) { if (value.IsObject()) { return value.AsObject(); } if (value == Undefined.Instance) { throw new JavaScriptException(engine.TypeError); } if (value == Null.Instance) { throw new JavaScriptException(engine.TypeError); } if (value.IsBoolean()) { return engine.Boolean.Construct(value.AsBoolean()); } if (value.IsNumber()) { return engine.Number.Construct(value.AsNumber()); } if (value.IsString()) { return engine.String.Construct(value.AsString()); } throw new JavaScriptException(engine.TypeError); }
/// <summary> /// http://www.ecma-international.org/ecma-262/5.1/#sec-9.8 /// </summary> /// <param name="o"></param> /// <returns></returns> public static string ToString(JsValue o) { if (o.IsObject()) { var p = o.AsObject() as IPrimitiveInstance; if (p != null) { o = p.PrimitiveValue; } } if (o.IsString()) { return o.AsString(); } if (o == Undefined.Instance) { return Undefined.Text; } if (o == Null.Instance) { return Null.Text; } if (o.IsBoolean()) { return o.AsBoolean() ? "true" : "false"; } if (o.IsNumber()) { return NumberPrototype.ToNumberString(o.AsNumber()); } return ToString(ToPrimitive(o, Types.String)); }
/// <summary> /// http://www.ecma-international.org/ecma-262/5.1/#sec-9.3 /// </summary> /// <param name="o"></param> /// <returns></returns> public static double ToNumber(JsValue o) { // check number first as this is what is usually expected if (o.IsNumber()) { return o.AsNumber(); } if (o.IsObject()) { var p = o.AsObject() as IPrimitiveInstance; if (p != null) { o = p.PrimitiveValue; } } if (o == Undefined.Instance) { return double.NaN; } if (o == Null.Instance) { return 0; } if (o.IsBoolean()) { return o.AsBoolean() ? 1 : 0; } if (o.IsString()) { var s = StringPrototype.TrimEx(o.AsString()); if (String.IsNullOrEmpty(s)) { return 0; } if ("+Infinity".Equals(s) || "Infinity".Equals(s)) { return double.PositiveInfinity; } if ("-Infinity".Equals(s)) { return double.NegativeInfinity; } // todo: use a common implementation with JavascriptParser try { if (!s.StartsWith("0x", StringComparison.OrdinalIgnoreCase)) { var start = s[0]; if (start != '+' && start != '-' && start != '.' && !char.IsDigit(start)) { return double.NaN; } double n = Double.Parse(s, NumberStyles.AllowDecimalPoint | NumberStyles.AllowLeadingSign | NumberStyles.AllowLeadingWhite | NumberStyles.AllowTrailingWhite | NumberStyles.AllowExponent, CultureInfo.InvariantCulture); if (s.StartsWith("-") && n.Equals(0)) { return -0.0; } return n; } int i = int.Parse(s.Substring(2), NumberStyles.HexNumber, CultureInfo.InvariantCulture); return i; } catch (OverflowException) { return s.StartsWith("-") ? double.NegativeInfinity : double.PositiveInfinity; } catch { return double.NaN; } } return ToNumber(ToPrimitive(o, Types.Number)); }
internal JToken ConvertBack(JTokenType type, JsValue value) { switch (type) { case JTokenType.Array: if (value.IsArray()) { var array = value.AsArray(); return new JArray(array.Properties.Where(k => ArrayInstance.IsArrayIndex(new JsValue(k.Key))).Select(kvp => ConvertBack(kvp.Value.Value ?? JsValue.Null))); } break; case JTokenType.Boolean: if (value.IsBoolean()) return new JValue(value.AsBoolean()); break; case JTokenType.Date: if (value.IsDate()) return new JValue(value.AsDate()); break; case JTokenType.Float: if (value.IsNumber()) return new JValue((float)value.AsNumber()); break; case JTokenType.Integer: if (value.IsNumber()) return new JValue((int)value.AsNumber()); break; case JTokenType.String: if (value.IsString()) return JValue.CreateString(value.AsString()); break; } return ConvertBack(value); }
public object UncastJsValue(JsValue value) { if (value.IsBoolean()) { return value.AsBoolean(); } if (value.IsNumber()) { return value.AsNumber(); } if (value.IsObject()) { return value.AsObject(); } if (value.IsString()) { return value.AsString(); } return null; }
private RavenJToken ToRavenJToken(JsValue v, string propertyKey, bool recursiveCall) { if (v.IsBoolean()) return new RavenJValue(v.AsBoolean()); if (v.IsString()) { const string RavenDataByteArrayToBase64 = "raven-data:byte[];base64,"; var valueAsObject = v.ToObject(); var value = valueAsObject != null ? valueAsObject.ToString() : null; if (value != null && value.StartsWith(RavenDataByteArrayToBase64)) { value = value.Remove(0, RavenDataByteArrayToBase64.Length); var byteArray = Convert.FromBase64String(value); return new RavenJValue(byteArray); } return new RavenJValue(value); } if (v.IsNumber()) { var num = v.AsNumber(); KeyValuePair<RavenJValue, JsValue> property; if (propertiesByValue.TryGetValue(propertyKey, out property)) { var originalValue = property.Key; if (originalValue.Type == JTokenType.Float || originalValue.Type == JTokenType.Integer) { // If the current value is exactly as the original value, we can return the original value before we made the JS conversion, // which will convert a Int64 to jsFloat. var originalJsValue = property.Value; if (originalJsValue.IsNumber() && Math.Abs(num - originalJsValue.AsNumber()) < double.Epsilon) return originalValue; //We might have change the type of num from Integer to long in the script by design //Making sure the number isn't a real float before returning it as integer if (originalValue.Type == JTokenType.Integer && (Math.Abs(num - Math.Floor(num)) <= double.Epsilon || Math.Abs(num - Math.Ceiling(num)) <= double.Epsilon)) return new RavenJValue((long)num); return new RavenJValue(num);//float } } // If we don't have the type, assume that if the number ending with ".0" it actually an integer. var integer = Math.Truncate(num); if (Math.Abs(num - integer) < double.Epsilon) return new RavenJValue((long)integer); return new RavenJValue(num); } if (v.IsNull()) return RavenJValue.Null; if (v.IsUndefined()) return RavenJValue.Null; if (v.IsArray()) { var jsArray = v.AsArray(); var rja = new RavenJArray(); foreach (var property in jsArray.Properties) { if (InheritedProperties.Contains(property.Key)) continue; var jsInstance = property.Value.Value; if (!jsInstance.HasValue) continue; var ravenJToken = ToRavenJToken(jsInstance.Value, propertyKey + "["+property.Key +"]", recursiveCall); if (ravenJToken == null) continue; rja.Add(ravenJToken); } return rja; } if (v.IsObject()) { return ToRavenJObject(v, propertyKey, recursiveCall); } if (v.IsRegExp()) return null; throw new NotSupportedException(v.Type.ToString()); }