private JToken VisitArray(JavaScriptValue value)
        {
            var array = new JArray();
            var propertyId = JavaScriptPropertyId.FromString("length");
            var length = (int)value.GetProperty(propertyId).ToDouble();
            for (var i = 0; i < length; ++i)
            {
                var index = JavaScriptValue.FromInt32(i);
                var element = value.GetIndexedProperty(index);
                array.Add(Visit(element));
            }

            return array;
        }
Пример #2
0
        private List <object> VisitJavascriptArray(JavaScriptValue value)
        {
            var result = new List <object>();

            {
                var currentIndex = 0;
                while (value.HasIndexedProperty(currentIndex.ToJavaScriptValue()))
                {
                    result.Add(Visit(value.GetIndexedProperty(currentIndex.ToJavaScriptValue()), null));
                    currentIndex++;
                }
            }
            return(result);
        }
        private JToken VisitArray(JavaScriptValue value)
        {
            var array      = new JArray();
            var propertyId = JavaScriptPropertyId.FromString("length");
            var length     = (int)value.GetProperty(propertyId).ToDouble();

            for (var i = 0; i < length; ++i)
            {
                var index   = JavaScriptValue.FromInt32(i);
                var element = value.GetIndexedProperty(index);
                array.Add(Visit(element));
            }

            return(array);
        }
Пример #4
0
        /// <summary>
        /// Converts a <see cref="JavaScriptValue"/> array into a host array.
        /// </summary>
        public object ToHostArray(JavaScriptValue arg, Type toType)
        {
            if (!toType.IsArray)
            {
                throw new Exception($"Cannot convert javascript array to type: {toType}");
            }

            var elementType = toType.GetElementType();
            var length      = arg.GetProperty(JavaScriptPropertyId.FromString("length")).ToInt32();
            var resultArray = Array.CreateInstance(elementType, length);

            for (int i = 0; i < length; ++i)
            {
                var atIndex = arg.GetIndexedProperty(JavaScriptValue.FromInt32(i));
                resultArray.SetValue(ToHostObject(atIndex, elementType), i);
            }

            return(resultArray);
        }
Пример #5
0
 static JavaScriptValue body(JavaScriptValue callee,
                             [MarshalAs(UnmanagedType.U1)] bool isConstructCall,
                             [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] JavaScriptValue[] arguments,
                             ushort argumentCount,
                             IntPtr callbackData)
 {
     try
     {
         var that = (FunctionWrapper)GCHandle.FromIntPtr(callbackData).Target;
         if (that.constructOnly && !isConstructCall)
         {
             return(JavaScriptValue.Undefined);
         }
         if (arguments.Length - 1 != that.neededArgumentsCount)
         {
             Native.JsSetException(
                 JavaScriptValue.CreateError(
                     JavaScriptValue.FromString(
                         string.Format("Argument count is not satisfacted. needs {0}, got {1}: {2}",
                                       that.neededArgumentsCount, arguments.Length - 1, that.GetName()))));
             return(JavaScriptValue.Invalid);
         }
         if (that.wrapdg == null)
         {
             that.wrapdg = that.WrapFirst();
         }
         var obj = that.wrapdg(arguments);
         var v   = JSValue.FromObject(obj).rawvalue;
         if (isConstructCall)
         {
             var pt = callee.GetIndexedProperty(JavaScriptValue.FromString("prototype"));
             if (pt.IsValid)
             {
                 v.Prototype = pt;
             }
         }
         return(v);
     }
     catch (Exception e)
     {
         return(ExceptionUtil.SetJSException(e));
     }
 }
Пример #6
0
        /// <summary>
        /// Determines whether or not the <see cref="Type"/> is a valid JS type for array conversions.
        /// </summary>
        private static bool IsArrayType(JavaScriptValue value, JsBinder bindingData, Type type)
        {
            if (!type.IsArray)
            {
                return(false);
            }

            // Check length, if empty, we can assume it matches any of the array types
            var length = value.GetProperty(JavaScriptPropertyId.FromString("length")).ToInt32();

            if (length <= 0)
            {
                return(true);
            }

            // Look at the first element, type check against the host array element type
            var firstElement = value.GetIndexedProperty(JavaScriptValue.FromInt32(0));
            var elementType  = type.GetElementType();

            return(IsAssignable(firstElement, bindingData, elementType));
        }
Пример #7
0
        /// <summary>
        /// Attempts to infer the host type based on the javscript type.
        /// </summary>
        public bool TryInferType(JavaScriptValue arg, out Type type)
        {
            // TODO: This method should be used as a last line of effort to try and build a host
            // TODO: type of method call from JS objects. Would love to get rid of it altogether.
            type = null;
            switch (arg.ValueType)
            {
            case JavaScriptValueType.Undefined: return(true);

            case JavaScriptValueType.Null: return(true);

            case JavaScriptValueType.Array:
            case JavaScriptValueType.TypedArray:
            {
                var length = arg.GetProperty(JavaScriptPropertyId.FromString("length")).ToInt32();
                if (length <= 0)
                {
                    type = typeof(object[]);
                    return(true);
                }

                Type innerType;
                var  firstElement = arg.GetIndexedProperty(JavaScriptValue.FromInt32(0));
                if (TryInferType(firstElement, out innerType))
                {
                    type = innerType.MakeArrayType();
                    return(true);
                }

                type = typeof(object[]);
                return(true);
            }

            case JavaScriptValueType.Boolean:
            {
                type = typeof(bool);
                return(true);
            }

            case JavaScriptValueType.Number:
            {
                type = typeof(double);
                return(true);
            }

            case JavaScriptValueType.String:
            {
                type = typeof(string);
                return(true);
            }

            case JavaScriptValueType.Function:
            {
                type = typeof(IJsCallback);
                return(true);
            }

            case JavaScriptValueType.Object:
            {
                try
                {
                    var hostObject = ToHostBoundObject(arg, typeof(void));
                    type = hostObject.GetType();
                    return(true);
                }
                catch
                {
                    type = typeof(object);
                    return(true);
                }
            }
            }

            return(false);
        }
Пример #8
0
        private static object ConvertJavaScriptValue(JavaScriptValue value)
        {
            JavaScriptValueType t = value.ValueType;

            if (t == JavaScriptValueType.Boolean)
            {
                return(value.ToBoolean());
            }
            else if (t == JavaScriptValueType.Number)
            {
                return(value.ToDouble());
            }
            else if (t == JavaScriptValueType.String)
            {
                return(value.ToString());
            }
            else if (t == JavaScriptValueType.Null)
            {
                return(null);
            }
            else if (t == JavaScriptValueType.Undefined)
            {
                return(null);
            }
            else if (t == JavaScriptValueType.Object)
            {
                Dictionary <string, object> dictionary = new Dictionary <string, object>();
                JavaScriptValue             propNames  = value.GetOwnPropertyNames();

                int             i = 0;
                JavaScriptValue index;

                while (propNames.HasIndexedProperty(index = JavaScriptValue.FromInt32(i)))
                {
                    JavaScriptValue      propName  = propNames.GetIndexedProperty(index);
                    JavaScriptPropertyId propId    = JavaScriptPropertyId.FromString(propName.ToString());
                    JavaScriptValue      propValue = value.GetProperty(propId);
                    object value2 = ConvertJavaScriptValue(propValue);
                    dictionary.Add(propName.ToString(), value2);
                    //Debug.WriteLine(propName.ToString() + ": " + propValue.ConvertToString().ToString());
                    i += 1;
                }

                return(dictionary);
            }
            else if (t == JavaScriptValueType.Array)
            {
                JavaScriptPropertyId lengthPropId = JavaScriptPropertyId.FromString("length");
                JavaScriptValue      arrayLength  = value.GetProperty(lengthPropId);
                int      length = (int)arrayLength.ToDouble();
                object[] array  = new object[length];

                int             i;
                JavaScriptValue index;

                for (i = 0; i < length; i++)
                {
                    if (value.HasIndexedProperty(index = JavaScriptValue.FromInt32(i)))
                    {
                        JavaScriptValue prop = value.GetIndexedProperty(index);
                        array[i] = ConvertJavaScriptValue(prop);
                    }
                }

                return(array);
            }
            return(null);
        }
 public static JavaScriptValue Get(this JavaScriptValue v, int i)
 {
     return(v.GetIndexedProperty(JavaScriptValue.FromInt32(i)));
 }