예제 #1
0
 /// <summary>
 /// Attempts to select a compatible adapter that is capable of identifying files.
 /// </summary>
 /// <param name="kli">The file to be selected against.</param>
 /// <returns>Returns a working ILoadFiles plugin or null.</returns>
 private ILoadFiles SelectAdapter(KoreLoadInfo kli)
 {
     // Return an adapter that can Identify, whose extension matches that of our filename and successfully identifies the file.
     return(_pluginLoader.GetAdapters <ILoadFiles>().
            Where(x => _pluginLoader.GetMetadata <PluginExtensionInfoAttribute>(x) != null).Where(x => _pluginLoader.GetMetadata <PluginExtensionInfoAttribute>(x).Extension.
                                                                                                  ToLower().TrimEnd(';').Split(';').Any(s => kli.FileName.ToLower().EndsWith(s.TrimStart('*')))
                                                                                                  ).FirstOrDefault(adapter => CheckAdapter(adapter, kli)));
 }
예제 #2
0
        /// <summary>
        /// Toggles an event for the UI to let the user select a blind adapter manually.
        /// </summary>
        /// <returns>The selected adapter or null.</returns>
        private ILoadFiles SelectAdapterManually(KoreLoadInfo kli)
        {
            var blindAdapters = _pluginLoader.GetAdapters <ILoadFiles>().Where(a => !(a is IIdentifyFiles)).ToList();

            var args = new IdentificationFailedEventArgs(kli.FileName, blindAdapters);

            IdentificationFailed?.Invoke(this, args);

            return(args.SelectedAdapter);
        }
예제 #3
0
        /// <summary>
        /// Does the actual identification with IIdentifyFiles and checks the availablity of the data stream.
        /// </summary>
        /// <param name="adapter">Adapter to identify with.</param>
        /// <param name="kli">Kore information for identification.</param>
        /// <returns>Returns if the adapter was capable of identifying the file.</returns>
        private bool CheckAdapter(ILoadFiles adapter, KoreLoadInfo kli)
        {
            if (!(adapter is IIdentifyFiles iif))
            {
                return(false);
            }
            adapter.LeaveOpen = true;

            kli.FileData.Position = 0;
            var info = new StreamInfo {
                FileData = kli.FileData, FileName = kli.FileName
            };
            var res = iif.Identify(info, kli.FileSystem);

            if (!kli.FileData.CanRead)
            {
                throw new InvalidOperationException($"Plugin with ID '{_pluginLoader.GetMetadata<PluginInfoAttribute>(adapter).ID}' closed the stream(s) while identifying the file(s).");
            }

            return(res);
        }
예제 #4
0
        // TODO: We want to somehow reflect these names and also possibly return a class holding the Type and a DisplayName vs. the plain interface name.

        /// <summary>
        /// Load a file using Kore.
        /// </summary>
        /// <param name="kli"></param>
        /// <returns></returns>
        public KoreFileInfo LoadFile(KoreLoadInfo kli)
        {
            if (kli.Adapter == null)
            {
                // Select adapter automatically and if failed select it manually
                var adapter = SelectAdapter(kli) ?? SelectAdapterManually(kli);

                // If still no adapter was chosen, return
                if (adapter == null)
                {
                    return(null);
                }

                kli.Adapter = adapter;
            }

            // Instantiate a new instance of the adapter
            // ReSharper disable once SuspiciousTypeConversion.Global
            kli.Adapter = _pluginLoader.CreateNewAdapter <ILoadFiles>((IPlugin)kli.Adapter);

            // Load files(s)
            // TODO: Make KLI contain a StreamInfo of the given file
            kli.FileData.Position = 0;
            var streamInfo = new StreamInfo
            {
                FileData = kli.FileData,
                FileName = kli.FileName
            };

            try
            {
                // TODO: Subject to remove
                kli.Adapter.LeaveOpen = kli.LeaveOpen;
                // Try to load the file via adapter
                kli.Adapter.Load(streamInfo, kli.FileSystem);
            }
            catch (Exception ex)
            {
                // Catch any exception thrown by the plugin and expose it
                var pi  = _pluginLoader.GetMetadata <PluginInfoAttribute>(kli.Adapter);
                var msg = $"The {pi?.Name} plugin failed to load \"{Path.GetFileName(kli.FileName)}\".";
                throw new LoadFileException(msg, ex);
            }

            // TODO: Subject to remove
            // Check if the stream still follows the LeaveOpen restriction
            if (!kli.FileData.CanRead && kli.LeaveOpen)
            {
                throw new InvalidOperationException($"Plugin with ID {_pluginLoader.GetMetadata<PluginInfoAttribute>(kli.Adapter).ID} closed the streams while loading the file.");
            }

            // Create a KoreFileInfo to keep track of the now open file.
            var kfi = new KoreFileInfo
            {
                StreamFileInfo = streamInfo,
                HasChanges     = false,
                Adapter        = kli.Adapter
            };

            if (kli.TrackFile)
            {
                OpenFiles.Add(kfi);
            }

            return(kfi);
        }