Пример #1
0
 /// <summary>
 /// Attempts to select a compatible adapter that is capable of identifying files.
 /// </summary>
 /// <param name="file">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).Extension.
                  ToLower().TrimEnd(';').Split(';').Any(s => kli.FileName.ToLower().EndsWith(s.TrimStart('*')))
                  ).Select(x =>
     {
         if (x is IMultipleFiles y)
         {
             y.FileSystem = kli.FileSystem;
         }
         return x;
     }).FirstOrDefault(adapter => CheckAdapter(adapter, kli)));
 }
Пример #2
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))
            {
                return(false);
            }
            adapter.LeaveOpen = true;

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

            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);
        }
Пример #3
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
                var adapter = SelectAdapter(kli);

                // Ask the user to select a plugin directly.
                adapter = adapter ?? SelectAdapterManually();

                if (adapter == null)
                {
                    return(null);
                }
                kli.Adapter = adapter;
            }

            // Instantiate a new instance of the adapter
            kli.Adapter = PluginLoader.CreateAdapter <ILoadFiles>(PluginLoader.GetMetadata <PluginInfoAttribute>(kli.Adapter).ID);

            // Load files(s)
            kli.FileData.Position = 0;
            var streamInfo = new StreamInfo {
                FileData = kli.FileData, FileName = kli.FileName
            };

            try
            {
                if (kli.Adapter is IMultipleFiles multiFileAdapter)
                {
                    multiFileAdapter.FileSystem = kli.FileSystem;
                }

                kli.Adapter.LeaveOpen = kli.LeaveOpen;
                kli.Adapter.Load(streamInfo);
            }
            catch (Exception ex)
            {
                var pi = PluginLoader.GetMetadata <PluginInfoAttribute>(kli.Adapter);
                throw new LoadFileException($"The {pi?.Name} plugin failed to load \"{Path.GetFileName(kli.FileName)}\".{Environment.NewLine}{Environment.NewLine}" +
                                            $"{ex.Message}{Environment.NewLine}{Environment.NewLine}" +
                                            $"{ex.StackTrace}");
            }

            // 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);
        }