Esempio n. 1
0
        public async Task OpenFile_FallsBackToStreamIfFileOver2GB()
        {
            // Create a file that's too big
            // If we tried to do it in memory, it would require over 2GB of RAM.
            // This isn't practical and won't work on all machines, so let's use the filesystem instead
            // It's a safer bet we'll have over 2GB of disk space than  over 2GB of RAM
            var provider = new PhysicalFileSystem();
            var filename = "a2GBfile.bin";

            if (!File.Exists(filename) || (new FileInfo(filename)).Length <= (long)int.MaxValue + 1)
            {
                using (var stream = provider.OpenFileWriteOnly(filename))
                {
                    var buffer = new byte[50000];
                    stream.SetLength((long)int.MaxValue + 1);
                    stream.Seek(0, SeekOrigin.Begin);
                    while (stream.Position < stream.Length)
                    {
                        await stream.WriteAsync(buffer, 0, buffer.Length);
                    }
                }
            }

            // Now on with the test
            var file = new GenericFile();

            file.EnableInMemoryLoad = true;
            await file.OpenFile(filename, provider);

            Assert.IsFalse(file.IsThreadSafe); // No thread safety indicates we're using an underlying stream
        }
Esempio n. 2
0
        /// <summary>
        /// Using the given file, auto-detects the file type and creates an instance of an appropriate object to model it.
        /// If no such class could be found, will return the original file
        /// </summary>
        /// <param name="file">The file for which to find a better class</param>
        /// <param name="duplicateFileTypeSelector">Resolves duplicate file type detections</param>
        /// <param name="manager">Instance of the current plugin manager</param>
        /// <returns>An object that represents the given file, or <paramref name="file"/> if no such class could be found.</returns>
        /// <exception cref="ArgumentNullException">Thrown if <see cref="file"/>, <paramref name="duplicateFileTypeSelector"/>, or <paramref name="manager"/> is null.</exception>
        public static async Task <object> OpenFile(GenericFile file, DuplicateMatchSelector duplicateFileTypeSelector, PluginManager manager)
        {
            if (file == null)
            {
                throw new ArgumentNullException(nameof(file));
            }

            if (duplicateFileTypeSelector == null)
            {
                throw new ArgumentNullException(nameof(duplicateFileTypeSelector));
            }

            if (manager == null)
            {
                throw new ArgumentNullException(nameof(manager));
            }

            var type = await GetFileType(file, duplicateFileTypeSelector, manager);

            var fileOpeners        = manager.GetRegisteredObjects <IFileOpener>().Where(x => x.SupportsType(type));
            var genericFileOpeners = manager.GetRegisteredObjects <IFileFromGenericFileOpener>().Where(x => x.SupportsType(type));

            if (type == null
                ||
                !(fileOpeners.Any() || genericFileOpeners.Any())
                )
            {
                // Nothing can model the file
                // Re-open GenericFile so it's not readonly
                var newFile = new GenericFile();
                await newFile.OpenFile(file.Filename, manager.CurrentFileSystem);

                return(newFile);
            }
            else
            {
                var openers = new List <IBaseFileOpener>();
                openers.AddRange(fileOpeners);
                openers.AddRange(genericFileOpeners);
                var fileOpener = openers.OrderByDescending(x => x.GetUsagePriority(type)).First();
                if (fileOpener is IFileOpener fromFileOpener)
                {
                    return(await fromFileOpener.OpenFile(type, file.Filename, manager.CurrentFileSystem));
                }
                else if (fileOpener is IFileFromGenericFileOpener fromGenericFileOpener)
                {
                    return(await fromGenericFileOpener.OpenFile(type, file));
                }
                else
                {
                    throw new Exception("Unsupported IBaseFileOpener type: " + fileOpener.GetType().Name);
                }
            }
        }
Esempio n. 3
0
        public async Task OpenFile_InMemory()
        {
            var provider = new MemoryFileSystem();

            provider.WriteAllBytes("/test.bin", new byte[] { 0, 1, 2, 3 });

            var file = new GenericFile();

            file.EnableInMemoryLoad = true;
            await file.OpenFile("/test.bin", provider);

            Assert.AreEqual(4, file.Length, "Failed to determine length.");
            Assert.IsTrue(file.Read().SequenceEqual(new byte[] { 0, 1, 2, 3 }), "Failed to read sample data.");
        }
Esempio n. 4
0
        public virtual async Task OpenFile(string filename, IFileSystem provider)
        {
            Filename          = filename;
            CurrentFileSystem = provider;
            using (var f = new GenericFile())
            {
                f.EnableInMemoryLoad = true;
                f.IsReadOnly         = true;
                await f.OpenFile(filename, provider);

                Bits = new BitBlock(0);
                ProcessRawData(f);
            }
        }
Esempio n. 5
0
        public async Task OpenFile(string filename, IFileSystem provider)
        {
            using (var file = new GenericFile())
            {
                await file.OpenFile(filename, provider);

                using (var compressed = new MemoryStream(await file.ReadAsync()))
                {
                    compressed.Seek(2, SeekOrigin.Begin);
                    using (var decompressed = new MemoryStream())
                    {
                        using (var zlib = new DeflateStream(compressed, CompressionMode.Decompress))
                        {
                            zlib.CopyTo(decompressed);
                        }
                        RawData = decompressed.ToArray();
                    }
                }
            }
        }
Esempio n. 6
0
        public async Task GetFileType_FunctionalityTest()
        {
            // Set up
            var manager = new PluginManager();
            await manager.LoadCore(new TestCoreMod());

            manager.CurrentFileSystem.WriteAllText("/test.txt", "magic data");
            manager.CurrentFileSystem.WriteAllText("/test.custom", "custom data");

            // Test
            using (var txtFile = new GenericFile())
            {
                await txtFile.OpenFile("/test.txt", manager.CurrentFileSystem);

                Assert.AreEqual(typeof(OpenableTextFile).GetTypeInfo(), await IOHelper.GetFileType(txtFile, IOHelper.PickFirstDuplicateMatchSelector, manager));
            }
            using (var customFile = new GenericFile())
            {
                await customFile.OpenFile("/test.custom", manager.CurrentFileSystem);

                Assert.AreEqual(typeof(CustomTextFile).GetTypeInfo(), await IOHelper.GetFileType(customFile, IOHelper.PickFirstDuplicateMatchSelector, manager));
            }
        }
Esempio n. 7
0
        /// <summary>
        /// Opens a file, auto-detecting the correct type
        /// </summary>
        /// <param name="path">Path of the file to open</param>
        /// <param name="duplicateFileTypeSelector">Resolves duplicate file type detections</param>
        /// <param name="manager">Instance of the current plugin manager</param>
        /// <returns>An object that represents the file at the given path</returns>
        /// <exception cref="ArgumentNullException">Thrown if <see cref="file"/>, <paramref name="duplicateFileTypeSelector"/>, or <paramref name="manager"/> is null.</exception>
        /// <exception cref="FileNotFoundException">Thrown if no file or directory could be found at the given path</exception>
        public static async Task <object> OpenFile(string path, DuplicateMatchSelector duplicateFileTypeSelector, PluginManager manager)
        {
            if (string.IsNullOrEmpty(path))
            {
                throw new ArgumentNullException(nameof(path));
            }

            if (duplicateFileTypeSelector == null)
            {
                throw new ArgumentNullException(nameof(duplicateFileTypeSelector));
            }

            if (manager == null)
            {
                throw new ArgumentNullException(nameof(manager));
            }

            if (manager.CurrentFileSystem.FileExists(path))
            {
                using (var file = new GenericFile())
                {
                    file.IsReadOnly = true;
                    await file.OpenFile(path, manager.CurrentFileSystem);

                    return(await OpenFile(file, duplicateFileTypeSelector, manager));
                }
            }
            else if (manager.CurrentFileSystem.DirectoryExists(path))
            {
                return(OpenDirectory(path, duplicateFileTypeSelector, manager));
            }
            else
            {
                throw new FileNotFoundException(Properties.Resources.IO_FileNotFound, path);
            }
        }