Пример #1
0
        public override async Task InvokeAsync(ILoadingContext <TResult> context, PipeDelegate <TResult> next, CancellationToken cancellationToken = default(CancellationToken))
        {
            var uri = context.Current as Uri;

            if (uri == null)
            {
                await next(context, cancellationToken);

                return;
            }

            if (uri.IsHttp())
            {
                try
                {
                    var task = GetDownloadTask(uri, cancellationToken);
                    var(bytes, cacheControl) = await task;
                    context.Current          = bytes;
                    await next(context, cancellationToken);

                    if (cacheControl != null && !cacheControl.NoCache)
                    {
                        context.HttpResponseBytes = bytes;
                    }
                }
                finally
                {
                    UriPipeInternal.DownloadTasks.Remove(uri);
                }
            }
            else if (string.Equals(uri.Scheme, Uri.UriSchemeFile, StringComparison.OrdinalIgnoreCase))
            {
                using (var fileStream = File.OpenRead(uri.AbsoluteUri.Substring("file:///".Length)))
                {
                    var buffer = new byte[fileStream.Length];
                    await fileStream.ReadAsync(buffer, 0, buffer.Length, cancellationToken);

                    context.Current = buffer;
                }
                await next(context, cancellationToken);
            }
            else if (string.Equals(uri.Scheme, "data", StringComparison.OrdinalIgnoreCase))
            {
                var          base64      = uri.OriginalString;
                const string base64Head  = "base64,";
                var          base64Index = base64.IndexOf(base64Head, StringComparison.Ordinal);
                var          bytes       = Convert.FromBase64String(base64.Substring(base64Index + base64Head.Length));
                context.Current = bytes;
                await next(context, cancellationToken);
            }
            else
            {
                // ms-appx:/ or ms-appdata:/
                var file = await StorageFile.GetFileFromApplicationUriAsync(uri);

                var buffer = (await FileIO.ReadBufferAsync(file)).ToArray();
                context.Current = buffer;
                await next(context, cancellationToken);
            }
        }
Пример #2
0
        public override async Task InvokeAsync(ILoadingContext <TResult> context, PipeDelegate <TResult> next, CancellationToken cancellationToken = default(CancellationToken))
        {
            if (IsInDesignMode)
            {
                await next(context, cancellationToken);

                return;
            }

            var source = context.Current;

            if (source is string || source is Uri)
            {
                if (MemoryCache.TryGetValue(source, out var cache))
                {
                    context.Result = cache;
                    return;
                }

                await next(context, cancellationToken);

                var result = context.Result;
                if (result != null)
                {
                    MemoryCache[source] = result;
                }

                return;
            }

            await next(context, cancellationToken);
        }
Пример #3
0
 public override Task InvokeAsync(ILoadingContext <TResult> context, PipeDelegate <TResult> next, CancellationToken cancellationToken = default(CancellationToken))
 {
     if (context.Current is string source)
     {
         context.Current = ToUriSource(source);
     }
     return(next(context, cancellationToken));
 }
Пример #4
0
        public override Task InvokeAsync(ILoadingContext <TResult> context, PipeDelegate <TResult> next, CancellationToken cancellationToken = default(CancellationToken))
        {
            if (context.Current is byte[] bytes)
            {
                context.Current = new MemoryStream(bytes);
            }

            return(next(context, cancellationToken));
        }
Пример #5
0
        public override Task InvokeAsync(ILoadingContext <TResult> context, PipeDelegate <TResult> next, CancellationToken cancellationToken = default(CancellationToken))
        {
            if (context.Current is TResult result)
            {
                context.Result = result;
                return(Task.CompletedTask);
            }

            return(next(context, cancellationToken));
        }
Пример #6
0
        /// <summary>
        /// Build configured <see cref="Pipeline"/>.
        /// </summary>
        public Pipeline Build()
        {
            if (_pipes.Count == 0)
            {
                throw new InvalidOperationException("Cannot build pipeline with zero pipes.");
            }

            var pipes = _pipes.ToList();

            pipes.Add(new PipeConfig(typeof(ActionExecutePipe)));

            IPipe previous = null;

            for (int i = pipes.Count; i-- > 0;)
            {
                var pipe    = pipes[i];
                var isLast  = pipes.Count - 1 == i;
                var isFirst = i == 0;

                object[] ctor;
                if (!isLast)
                {
                    PipeDelegate next = previous.Invoke;

                    if (pipe.Args == null)
                    {
                        ctor = new object[] { next }
                    }
                    ;
                    else
                    {
                        const int additionalCtorArgs = 1;
                        ctor    = new object[pipe.Args.Length + additionalCtorArgs];
                        ctor[0] = next;
                        Array.Copy(pipe.Args, 0, ctor, additionalCtorArgs, pipe.Args.Length);
                    }
                }
                else
                {
                    ctor = new object[] { }
                };
                var instance = (IPipe)ActivatorUtilities.CreateInstance(_serviceProvider, pipe.Type, ctor);
                if (isFirst)
                {
                    return(new Pipeline(instance));
                }
                previous = instance;
            }
            throw new InvalidOperationException("Pipeline was not build correctly!");
        }
    }
Пример #7
0
        public override async Task InvokeAsync(ILoadingContext <TResult> context, PipeDelegate <TResult> next, CancellationToken cancellationToken = default(CancellationToken))
        {
            if (IsInDesignMode)
            {
                await next(context, cancellationToken);

                return;
            }

            var uri = context.Current as Uri;

            if (uri == null || !uri.IsHttp())
            {
                await next(context, cancellationToken);

                return;
            }

            var cacheKey = uri.AbsoluteUri;

            if (await _diskCache.IsExistAsync(cacheKey))
            {
                context.Current = await _diskCache.GetAsync(cacheKey, cancellationToken);

                try
                {
                    await next(context, cancellationToken);
                }
                catch
                {
                    _diskCache.DeleteAsync(cacheKey).Forget();
                    throw;
                }
            }
            else
            {
                await next(context, cancellationToken);

                var bytes = context.HttpResponseBytes;
                if (bytes != null)
                {
                    _diskCache.SetAsync(cacheKey, bytes, CancellationToken.None).Forget();
                }
            }
        }
Пример #8
0
        public static PipeDelegate <TResult> Build <TResult>(IServiceCollection services) where TResult : class
        {
            PipeDelegate <TResult> end = (context, cancellationToken) =>
            {
                if (context.Result == null)
                {
                    context.Result = context.Current as TResult;
                }

                if (context.Result == null)
                {
                    throw new NotSupportedException();
                }

                return(Task.CompletedTask);
            };

            var serviceProvider = services.BuildServiceProvider();
            var pipes           = serviceProvider.GetServices <IPipe <TResult> >();

            foreach (var pipe in pipes.Reverse())
            {
                Func <PipeDelegate <TResult>, PipeDelegate <TResult> > handler = next =>
                {
                    return((context, cancellationToken) =>
                    {
                        using (pipe)
                        {
                            return pipe.InvokeAsync(context, next, cancellationToken);
                        }
                    });
                };
                end = handler(end);
            }

            return(end);
        }
        public override async Task InvokeAsync(ILoadingContext <ICompositionSurface> context, PipeDelegate <ICompositionSurface> next, CancellationToken cancellationToken = default(CancellationToken))
        {
            if (context.Current is Stream stream)
            {
                var tcs          = new TaskCompletionSource <LoadedImageSurface>();
                var imageSurface = LoadedImageSurface.StartLoadFromStream(stream.AsRandomAccessStream());

                TypedEventHandler <LoadedImageSurface, LoadedImageSourceLoadCompletedEventArgs> handler = null;
                handler = (sender, args) =>
                {
                    imageSurface.LoadCompleted -= handler;
                    switch (args.Status)
                    {
                    case LoadedImageSourceLoadStatus.Success:
                        tcs.SetResult(sender);
                        break;

                    default:
                        tcs.SetException(new ImageSurfaceFailedStatusException(args.Status));
                        break;
                    }
                };

                imageSurface.LoadCompleted += handler;
                context.Current             = await tcs.Task;
            }

            await next(context, cancellationToken);
        }
Пример #10
0
 public TimerPipe(PipeDelegate next, ILogger <TimerPipe> logger)
 {
     _next   = next;
     _logger = logger;
 }
Пример #11
0
 public abstract Task InvokeAsync(ILoadingContext <TResult> context, PipeDelegate <TResult> next, CancellationToken cancellationToken = default(CancellationToken));
        public override async Task InvokeAsync(ILoadingContext <ImageSource> context, PipeDelegate <ImageSource> next, CancellationToken cancellationToken = default(CancellationToken))
        {
            if (context.Current is Stream stream)
            {
                var isStartWithLessThanSign = false;
                if (stream.CanSeek)
                {
                    stream.Seek(0, SeekOrigin.Begin);
                    isStartWithLessThanSign = stream.ReadByte() == '<'; // svg start with <
                    stream.Seek(0, SeekOrigin.Begin);
                }

                if (isStartWithLessThanSign)
                {
                    var bitmap             = new SvgImageSource();
                    var svgImageLoadStatus = await bitmap.SetSourceAsync(stream.AsRandomAccessStream());

                    if (svgImageLoadStatus != SvgImageSourceLoadStatus.Success)
                    {
                        throw new SvgImageFailedStatusException(svgImageLoadStatus);
                    }
                    cancellationToken.ThrowIfCancellationRequested();
                    context.Current = bitmap;
                }
                else
                {
                    var bitmap = new BitmapImage();
                    await bitmap.SetSourceAsync(stream.AsRandomAccessStream());

                    cancellationToken.ThrowIfCancellationRequested();
                    context.Current = bitmap;
                }
            }

            await next(context, cancellationToken);
        }
Пример #13
0
 public CachePipe(PipeDelegate next, ILogger <CachePipe> logger)
 {
     _next   = next;
     _logger = logger;
 }
        public override async Task InvokeAsync(ILoadingContext <ImageSource> context, PipeDelegate <ImageSource> next, CancellationToken cancellationToken = default(CancellationToken))
        {
            if (context.Current is Stream stream)
            {
                var tcs = new TaskCompletionSource <ImageSource>();
                await Task.Run(() =>
                {
                    try
                    {
                        var bitmap = new BitmapImage();
                        bitmap.BeginInit();
                        bitmap.StreamSource = stream;
                        bitmap.EndInit();
                        bitmap.Freeze();
                        tcs.SetResult(bitmap);
                    }
                    catch (Exception ex)
                    {
                        tcs.SetException(ex);
                    }
                }, cancellationToken);

                context.Current = await tcs.Task;
            }

            await next(context, cancellationToken);
        }
Пример #15
0
        public override async Task InvokeAsync(ILoadingContext <TResult> context, PipeDelegate <TResult> next, CancellationToken cancellationToken = default(CancellationToken))
        {
            var uri = context.Current as Uri;

            if (uri == null)
            {
                await next(context, cancellationToken);

                return;
            }

            if (uri.IsHttp())
            {
                try
                {
                    var task = GetDownloadTask(uri, cancellationToken);
                    var(bytes, cacheControl) = await task;
                    context.Current          = bytes;
                    await next(context, cancellationToken);

                    if (cacheControl != null && !cacheControl.NoCache)
                    {
                        context.HttpResponseBytes = bytes;
                    }
                }
                finally
                {
                    UriPipeInternal.DownloadTasks.Remove(uri);
                }
            }
            else if (string.Equals(uri.Scheme, Uri.UriSchemeFile, StringComparison.OrdinalIgnoreCase))
            {
                using (var fileStream = File.OpenRead(uri.AbsoluteUri.Substring("file:///".Length)))
                {
                    var buffer = new byte[fileStream.Length];
                    await fileStream.ReadAsync(buffer, 0, buffer.Length, cancellationToken);

                    context.Current = buffer;
                }
                await next(context, cancellationToken);
            }
            else if (string.Equals(uri.Scheme, "data", StringComparison.OrdinalIgnoreCase))
            {
                var          base64      = uri.OriginalString;
                const string base64Head  = "base64,";
                var          base64Index = base64.IndexOf(base64Head, StringComparison.Ordinal);
                var          bytes       = Convert.FromBase64String(base64.Substring(base64Index + base64Head.Length));
                context.Current = bytes;
                await next(context, cancellationToken);
            }
            else
            {
                // pack://application:,,,/
                var streamResourceInfo = System.Windows.Application.GetResourceStream(uri);
                if (streamResourceInfo != null)
                {
                    using (var memoryStream = new MemoryStream())
                    {
                        await streamResourceInfo.Stream.CopyToAsync(memoryStream, 81920, cancellationToken);

                        context.Current = memoryStream.ToArray();
                    }
                    await next(context, cancellationToken);
                }
                else
                {
                    throw new FileNotFoundException();
                }
            }
        }