Exemplo n.º 1
0
        /// <summary>
        /// Supports navigation into <see cref="JToken"/> return types.
        /// </summary>
        /// <param name="expression"></param>
        /// <param name="name"></param>
        /// <param name="navigate"></param>
        /// <returns></returns>
        public static Expression JTokenNavigateFunc(Expression expression, string name, NavigateFunc navigate)
        {
            if (expression == null)
            {
                throw new ArgumentNullException(nameof(expression));
            }
            if (name == null)
            {
                throw new ArgumentNullException(nameof(name));
            }
            if (navigate == null)
            {
                throw new ArgumentNullException(nameof(navigate));
            }

            // source expression is a JToken; it might really be a JObject
            if (typeof(JToken).IsAssignableFrom(expression.Type))
            {
                return(Expression.Condition(
                           Expression.TypeEqual(expression, typeof(JObject)),
                           navigate(Expression.Convert(expression, typeof(JObject)), name, navigate),
                           Expression.Constant(JValue.CreateUndefined(), typeof(JToken))));
            }

            return(null);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Supports navigation into <see cref="JObject"/> return types.
        /// </summary>
        /// <param name="expression"></param>
        /// <param name="name"></param>
        /// <param name="navigate"></param>
        /// <returns></returns>
        public static Expression JObjectNavigateFunc(Expression expression, string name, NavigateFunc navigate)
        {
            if (expression == null)
            {
                throw new ArgumentNullException(nameof(expression));
            }
            if (name == null)
            {
                throw new ArgumentNullException(nameof(name));
            }

            // source expression is a JObject
            if (typeof(JObject).IsAssignableFrom(expression.Type))
            {
                return(Expression.Condition(
                           Expression.ReferenceEqual(expression, Expression.Constant(null, expression.Type)),
                           Expression.Constant(JValue.CreateUndefined(), typeof(JToken)),
                           InvokeIndexer(expression, typeof(JObject), Expression.Constant(name), typeof(string))));
            }

            return(null);
        }
Exemplo n.º 3
0
        /// <summary>
        /// Supports navigation into <see cref="JArray"/> return types.
        /// </summary>
        /// <param name="expression"></param>
        /// <param name="name"></param>
        /// <param name="navigate"></param>
        /// <returns></returns>
        public static Expression JArrayNavigateFunc(Expression expression, string name, NavigateFunc navigate)
        {
            if (expression == null)
            {
                throw new ArgumentNullException(nameof(expression));
            }
            if (name == null)
            {
                throw new ArgumentNullException(nameof(name));
            }

            // cannot navigate into any JArray
            if (typeof(JArray).IsAssignableFrom(expression.Type))
            {
                return(Expression.Constant(JValue.CreateUndefined()));
            }

            return(null);
        }
Exemplo n.º 4
0
        /// <summary>
        /// Default NavigateFunc. Handles standard .NET properties and <see cref="JToken"/> traversal.
        /// </summary>
        /// <param name="expression"></param>
        /// <param name="name"></param>
        /// <param name="navigate"></param>
        /// <returns></returns>
        public static Expression DefaultNavigateFunc(Expression expression, string name, NavigateFunc navigate)
        {
            if (expression == null)
            {
                throw new ArgumentNullException(nameof(expression));
            }
            if (name == null)
            {
                throw new ArgumentNullException(nameof(name));
            }

            // returns the nullable version of the type
            Type NullableOfType(Type type) =>
            type.IsValueType ? typeof(Nullable <>).MakeGenericType(type) : type;

            // returns a nullable version of the given type
            Expression NullableExpressionOfType(Type type) =>
            Expression.Default(NullableOfType(type));

            // ensure the result is nullable
            Expression NullableExpression(Expression expr) =>
            Expression.Convert(expr, NullableOfType(expr.Type));

            // resolve member
            var member = expression.Type.GetPropertyOrField(name);

            // member is a property
            if (member is PropertyInfo property)
            {
                return(Expression.Condition(
                           Expression.Equal(expression, NullableExpressionOfType(expression.Type)),
                           NullableExpressionOfType(property.PropertyType),
                           NullableExpression(Expression.Property(expression, property))));
            }

            // member is a field
            if (member is FieldInfo field)
            {
                return(Expression.Condition(
                           Expression.Equal(expression, NullableExpressionOfType(expression.Type)),
                           NullableExpressionOfType(field.FieldType),
                           NullableExpression(Expression.Field(expression, field))));
            }

            // source expression implements a generic dictionary
            if (typeof(IEnumerable).IsAssignableFrom(expression.Type) && // early breakout
                expression.Type.GetAssignableTypes().FirstOrDefault(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IDictionary <,>)) is Type iface)
            {
                // invoke get_Item on dictionary, with key type as described by interface
                // conditional is used to prevent index missing exceptions
                var keyType = iface.GetGenericArguments()[0];
                var valType = iface.GetGenericArguments()[1];

                // if key type is supported, use it, else try to change type
                var keyExpr = Expression.Convert(
                    keyType.IsInstanceOfType(name) ?
                    (Expression)Expression.Constant(name, keyType) :
                    Expression.Call(typeof(Convert).GetMethod(nameof(Convert.ChangeType)), Expression.Constant(name), Expression.Constant(keyType)),
                    keyType);

                // if null, return nullable; else invoke ContainsKey before trying get_Item; convert result to nullable
                return(Expression.Condition(
                           Expression.Equal(expression, Expression.Constant(null, expression.Type)),
                           NullableExpressionOfType(valType),
                           Expression.Condition(
                               Expression.Call(expression, iface.GetMethod("ContainsKey", new[] { keyType }), keyExpr),
                               NullableExpression(InvokeIndexer(expression, iface, keyExpr, keyType)),
                               NullableExpressionOfType(valType))));
            }

            // no way to navigate found, use untyped null
            return(NullableExpressionOfType(typeof(object)));
        }
Exemplo n.º 5
0
        /// <summary>
        /// Navigates to the root <see cref="JToken"/> of the object as expressed by the '^' path syntax.
        /// </summary>
        /// <param name="expression"></param>
        /// <param name="name"></param>
        /// <param name="navigate"></param>
        /// <returns></returns>
        public static Expression JTokenRootNavigateFunc(Expression expression, string name, NavigateFunc navigate)
        {
            if (expression == null)
            {
                throw new ArgumentNullException(nameof(expression));
            }
            if (name == null)
            {
                throw new ArgumentNullException(nameof(name));
            }

            if (name != "^")
            {
                return(null);
            }

            if (typeof(JToken).IsAssignableFrom(expression.Type) == false)
            {
                throw new NotSupportedException("Unable to use root navigation on non-JToken.");
            }

            return(Expression.Condition(
                       Expression.ReferenceEqual(expression, Expression.Constant(null, expression.Type)),
                       Expression.Constant(null, typeof(JToken)),
                       Expression.Property(expression, nameof(JToken.Root))));
        }
Exemplo n.º 6
0
        /// <summary>
        /// Navigates to the parent <see cref="JObject"/> as expressed by the '&lt;' path syntax.
        /// </summary>
        /// <param name="expression"></param>
        /// <param name="name"></param>
        /// <param name="navigate"></param>
        /// <returns></returns>
        public static Expression JTokenParentNavigateFunc(Expression expression, string name, NavigateFunc navigate)
        {
            if (expression == null)
            {
                throw new ArgumentNullException(nameof(expression));
            }
            if (name == null)
            {
                throw new ArgumentNullException(nameof(name));
            }

            if (name != "<")
            {
                return(null);
            }

            if (typeof(JToken).IsAssignableFrom(expression.Type) == false)
            {
                throw new NotSupportedException("Unable to use root navigation on non-JToken.");
            }

            // parent of incoming token
            var parent = Expression.Condition(
                Expression.ReferenceEqual(expression, Expression.Constant(null, expression.Type)),
                Expression.Constant(null, typeof(JContainer)),
                Expression.Property(expression, nameof(JToken.Parent)));

            // step up to object if on property
            return(Expression.Condition(
                       Expression.TypeIs(parent, typeof(JProperty)),
                       Expression.Property(parent, nameof(JProperty.Parent)),
                       parent));
        }
Exemplo n.º 7
0
        /// <summary>
        /// Loads a specific track number.
        /// </summary>
        public void LoadTrack(int track_number, NavigateFunc navFunc)
        {
            nav_func = navFunc;

            if (!validEngine ())
                return;

            if (current_media == null || !current_media.StartsWith ("cdda://"))
            {
                Stop ();
                MediaEngine.Load ("cdda://");
            }

            current_media = "cdda://" + track_number;
            MediaEngine.SeekToTrack (track_number);

            if (MediaEngine.CurrentStatus != MediaStatus.Playing)
                Play ();
        }
Exemplo n.º 8
0
        /// <summary>
        /// Load the specified file into the media engine and navigate using navFunc.
        /// </summary>
        public void LoadMedia(string path, NavigateFunc navFunc)
        {
            nav_func = navFunc;

            if (!validEngine ())
                return;

            if (System.IO.File.Exists (path))
            {
                switch_engines = !switch_engines;

                Stop ();
                MediaEngine.Load (path);
                current_media = path;

                fadePlay ();
            }
            else
                fuse.ThrowError ("The file doesn't exist:\n\n" + path);
        }