예제 #1
0
 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"));
 }
예제 #2
0
 private static string GetErrorMessage(JsValue error) 
 {
     if (error.IsObject())
     {
         var oi = error.AsObject();
         var message = oi.Get("message").AsString();
         return message;
     }
     else
         return string.Empty;            
 }
예제 #3
0
        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);
        }
예제 #4
0
        /// <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;
        }
예제 #5
0
        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());
        }
예제 #6
0
        public static Types GetPrimitiveType(JsValue value)
        {
            if (value.IsObject())
            {
                var primitive = value.TryCast<IPrimitiveInstance>();
                if (primitive != null)
                {
                    return primitive.Type;
                }

                return Types.Object;
            }

            return value.Type;
        }
예제 #7
0
        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);
        }
예제 #8
0
        /// <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));
        }
예제 #9
0
        /// <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));
        }
예제 #10
0
        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;
        }
예제 #11
0
        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());
        }