Example #1
0
        /// <summary>
        /// Function to return all the parents up to the root directory.
        /// </summary>
        /// <returns>A list of all the parents, up to and including the root.</returns>
        /// <remarks>
        /// If this value is empty, then there is no parent for this directory. This indicates that the current directory is the root directory for the file system.
        /// </remarks>
        public IEnumerable <IGorgonVirtualDirectory> GetParents()
        {
            IGorgonVirtualDirectory parent = Parent;

            while (parent != null)
            {
                yield return(parent);

                parent = parent.Parent;
            }
        }
        /// <summary>
        /// Function to locate the associated texture codec and file for a sprite.
        /// </summary>
        /// <param name="fileSystem">The file system to evaluate.</param>
        /// <param name="localDir">The local directory for the sprite file.</param>
        /// <param name="renderer">The renderer used for resource look up.</param>
        /// <param name="textureName">The name of the texture.</param>
        /// <param name="codecs">The list of available image codecs to use when determining texture type.</param>
        /// <returns>A tuple containing the codec, the texture file, and a flag to indicate that the texture was previously loaded into memory.</returns>
        private static (IGorgonImageCodec codec, IGorgonVirtualFile file, bool alreadyLoaded) LocateTextureCodecAndFile(
            IGorgonFileSystem fileSystem,
            IGorgonVirtualDirectory localDir,
            Gorgon2D renderer,
            string textureName,
            IEnumerable <IGorgonImageCodec> codecs)
        {
            // First, attempt to locate the resource by its name.  If it's already loaded, we should not load it again.
            GorgonTexture2D texture = renderer.Graphics
                                      .LocateResourcesByName <GorgonTexture2D>(textureName)
                                      .FirstOrDefault();

            if (texture != null)
            {
                return(null, null, true);
            }

            IGorgonImageCodec codec;

            // We couldn't find the texture in our loaded resources, so try to locate it on the file system.

            // First, check the local directory.
            IEnumerable <IGorgonVirtualFile> files = fileSystem.FindFiles(localDir.FullPath, $"{textureName}.*", false);

            foreach (IGorgonVirtualFile file in files)
            {
                codec = FindTextureCodec(file, codecs);

                if (codec != null)
                {
                    return(codec, file, false);
                }
            }

            // Check to see if the name has path information for the texture in the name.
            // The GorgonEditor from v2 does this.
            if (!textureName.Contains("/"))
            {
                // It is not.  We cannot load the texture.
                return(null, null, false);
            }

            IGorgonVirtualFile textureFile = fileSystem.GetFile(textureName);

            if (textureFile == null)
            {
                return(null, null, false);
            }

            // Try to find a codec for the image file.
            codec = FindTextureCodec(textureFile, codecs);

            return(codec == null ? (null, null, false) : (codec, textureFile, false));
        }
        /// <summary>
        /// Function to enumerate the files and directories from a physical location and map it to a virtual location.
        /// </summary>
        /// <param name="physicalLocation">The physical location containing files and directories to enumerate.</param>
        /// <param name="mountPoint">A <see cref="IGorgonVirtualDirectory"/> that the directories and files from the physical file system will be mounted into.</param>
        /// <returns>A <see cref="GorgonPhysicalFileSystemData"/> object containing information about the directories and files contained within the physical file system.</returns>
        /// <exception cref="ArgumentNullException">Thrown when the <paramref name="physicalLocation"/>, or the <paramref name="mountPoint"/> parameters are <b>null</b>.</exception>
        /// <exception cref="ArgumentEmptyException">Thrown when the <paramref name="physicalLocation"/> parameter is empty.</exception>
        /// <remarks>
        /// <para>
        /// This will return a <see cref="GorgonPhysicalFileSystemData"/> representing the paths to directories and <see cref="IGorgonPhysicalFileInfo"/> objects under the virtual file system. Each file
        /// system file and directory is mapped from its <paramref name="physicalLocation"/> on the physical file system to a <paramref name="mountPoint"/> on the virtual file system. For example, if the
        /// mount point is set to <c>/MyMount/</c>, and the physical location of a file is <c>c:\SourceFileSystem\MyDirectory\MyTextFile.txt</c>, then the returned value should be
        /// <c>/MyMount/MyDirectory/MyTextFile.txt</c>.
        /// </para>
        /// <para>
        /// Implementors of a <see cref="GorgonFileSystemProvider"/> plug in can override this method to read the list of files from another type of file system, like a Zip file.
        /// </para>
        /// </remarks>
        public GorgonPhysicalFileSystemData Enumerate(string physicalLocation, IGorgonVirtualDirectory mountPoint)
        {
            if (physicalLocation == null)
            {
                throw new ArgumentNullException(nameof(physicalLocation));
            }

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

            if (string.IsNullOrWhiteSpace(physicalLocation))
            {
                throw new ArgumentEmptyException(nameof(physicalLocation));
            }

            return(OnEnumerate(physicalLocation, mountPoint));
        }
        /// <summary>
        /// Function to enumerate the available directories stored in the packed file.
        /// </summary>
        /// <param name="index">The XML file containing the index of files and directories.</param>
        /// <param name="mountPoint">The mount point to map into.</param>
        /// <returns>A read only list of directory paths mapped to the virtual file system.</returns>
        private static IReadOnlyList <string> EnumerateDirectories(XDocument index, IGorgonVirtualDirectory mountPoint)
        {
            var result = new List <string>();
            IEnumerable <XElement> directories = index.Descendants("Path");

            foreach (XElement directoryNode in directories)
            {
                XAttribute pathAttrib = directoryNode.Attribute("FullPath");

                if (string.IsNullOrWhiteSpace(pathAttrib?.Value))
                {
                    throw new FileLoadException(Resources.GORFS_GORPACK_ERR_FILEINDEX_CORRUPT);
                }

                // Add the directory.
                result.Add((mountPoint.FullPath + pathAttrib.Value).FormatDirectory('/'));
            }

            return(result);
        }
Example #5
0
        /// <summary>
        /// Initializes a new instance of the <see cref="ZipPhysicalFileInfo" /> class.
        /// </summary>
        /// <param name="entry">The entry.</param>
        /// <param name="physicalLocation">The physical location of the zip file.</param>
        /// <param name="mountPoint">Mount point path.</param>
        public ZipPhysicalFileInfo(ZipEntry entry, string physicalLocation, IGorgonVirtualDirectory mountPoint)
        {
            string directory = Path.GetDirectoryName(entry.Name);

            directory = mountPoint.FullPath + directory;

            if (string.IsNullOrWhiteSpace(directory))
            {
                directory = "/";
            }

            directory = directory.FormatDirectory('/');

            CompressedLength = entry.CompressedSize;
            CreateDate       = entry.DateTime;
            FullPath         = physicalLocation + "::/" + entry.Name;
            Length           = entry.Size;
            Offset           = entry.Offset;
            Name             = Path.GetFileName(entry.Name).FormatFileName();
            VirtualPath      = directory + Name;
        }
Example #6
0
        /// <summary>
        /// Function to fill the file system tree view.
        /// </summary>
        /// <param name="directory">Parent directory to fill, or <b>null</b> to fill the root directory.</param>
        private void FillTree(IGorgonVirtualDirectory directory)
        {
            TreeNodeCollection nodes;
            TreeNode           parentNode;

            if (directory == null)
            {
                directory = _fileSystem.RootDirectory;
                nodes     = treeFileSystem.Nodes;

                // Set root node.
                parentNode = new TreeNode("/")
                {
                    Name = "/"
                };
                parentNode.SelectedImageIndex = parentNode.ImageIndex = 0;
            }
            else
            {
                // Find the node with the directory.
                TreeNode[] searchNodes = treeFileSystem.Nodes.Find(directory.FullPath, true);

                if (searchNodes.Length > 0)
                {
                    parentNode = searchNodes[0];
                    nodes      = parentNode.Nodes;
                }
                else
                {
                    GorgonDialogs.ErrorBox(this, "Could not find the virtual directory '" + directory.FullPath + "'");
                    return;
                }
            }

            parentNode.Tag = directory;

            // Turn off the expand event.
            treeFileSystem.BeforeExpand -= TreeFileSystem_BeforeExpand;

            try
            {
                // Clean up the tree node.
                treeFileSystem.BeginUpdate();
                nodes.Clear();

                // Add the root node if necessary.
                if (parentNode.Tag == _fileSystem.RootDirectory)
                {
                    nodes.Add(parentNode);
                }

                // Enumerate the data.  For the purposed of this example, we will filter out known binary files from our file system.
                IOrderedEnumerable <IGorgonVirtualDirectory> directories = directory.Directories.OrderBy(item => item.Name);
                IEnumerable <IGorgonVirtualFile>             files       = directory.Files.OrderBy(item => item.Name).Where(item => item.Extension != ".gorSprite" && item.Extension != ".gal");

                // Get directories.
                foreach (IGorgonVirtualDirectory subDirectory in directories)
                {
                    var directoryNode = new TreeNode(subDirectory.Name)
                    {
                        Name = subDirectory.FullPath,
                        Tag  = subDirectory
                    };

                    // Put a special icon on the zip file so we have a visual representation
                    // of where it is in our VFS.
                    // The VFS does not care if the data is in a zip file or folder, and Gorgon
                    // does very little to differentiate it.  After all, the whole point of
                    // have a unified file system is to abstract away the differences.
                    if (subDirectory.Name != "ZipFile")
                    {
                        directoryNode.SelectedImageIndex = directoryNode.ImageIndex = 0;
                    }
                    else
                    {
                        directoryNode.SelectedImageIndex = directoryNode.ImageIndex = 2;
                    }

                    // Add a dummy node if there are files or sub directories.
                    if ((subDirectory.Directories.Count > 0) || (subDirectory.Files.Count(item => item.Extension != ".gorSprite" && item.Extension != ".gal") > 0))
                    {
                        directoryNode.Nodes.Add(new TreeNode("This is a dummy node."));
                    }

                    parentNode.Nodes.Add(directoryNode);
                }

                // Get files.
                foreach (IGorgonVirtualFile file in files)
                {
                    if (file.Extension == ".gorSprite")
                    {
                        continue;
                    }

                    var fileNode = new TreeNode(file.Name)
                    {
                        Name = file.FullPath,
                        Tag  = file
                    };
                    fileNode.SelectedImageIndex = fileNode.ImageIndex = 1;
                    parentNode.Nodes.Add(fileNode);
                }

                parentNode.Expand();
            }
            finally
            {
                treeFileSystem.EndUpdate();
                treeFileSystem.BeforeExpand += TreeFileSystem_BeforeExpand;
            }
        }
 /// <summary>
 /// Function to enumerate the files and directories from a physical location and map it to a virtual location.
 /// </summary>
 /// <param name="physicalLocation">The physical location containing files and directories to enumerate.</param>
 /// <param name="mountPoint">A <see cref="IGorgonVirtualDirectory"/> that the directories and files from the physical file system will be mounted into.</param>
 /// <returns>A <see cref="GorgonPhysicalFileSystemData"/> object containing information about the directories and files contained within the physical file system.</returns>
 /// <exception cref="ArgumentNullException">Thrown when the <paramref name="physicalLocation"/>, or the <paramref name="mountPoint"/> parameters are <b>null</b>.</exception>
 /// <exception cref="ArgumentEmptyException">Thrown when the <paramref name="physicalLocation"/> parameter is empty.</exception>
 /// <remarks>
 /// <para>
 /// This will return a <see cref="GorgonPhysicalFileSystemData"/> representing the paths to directories and <see cref="IGorgonPhysicalFileInfo"/> objects under the virtual file system. Each file
 /// system file and directory is mapped from its <paramref name="physicalLocation"/> on the physical file system to a <paramref name="mountPoint"/> on the virtual file system. For example, if the
 /// mount point is set to <c>/MyMount/</c>, and the physical location of a file is <c>c:\SourceFileSystem\MyDirectory\MyTextFile.txt</c>, then the returned value should be
 /// <c>/MyMount/MyDirectory/MyTextFile.txt</c>.
 /// </para>
 /// <para>
 /// Implementors of a <see cref="GorgonFileSystemProvider"/> plug in can override this method to read the list of files from another type of file system, like a Zip file.
 /// </para>
 /// <para>
 /// Implementors of a <see cref="GorgonFileSystemProvider"/> should override this method to read the list of directories and files from another type of file system, like a Zip file.
 /// The default functionality will only enumerate directories and files from the operating system file system.
 /// </para>
 /// </remarks>
 protected virtual GorgonPhysicalFileSystemData OnEnumerate(string physicalLocation, IGorgonVirtualDirectory mountPoint) => new GorgonPhysicalFileSystemData(EnumerateDirectories(physicalLocation, mountPoint), EnumerateFiles(physicalLocation, mountPoint));
Example #8
0
 /// <summary>
 /// Function to enumerate the files and directories from a physical location and map it to a virtual location.
 /// </summary>
 /// <param name="physicalLocation">The physical location containing files and directories to enumerate.</param>
 /// <param name="mountPoint">A <see cref="IGorgonVirtualDirectory"/> that the directories and files from the physical file system will be mounted into.</param>
 /// <returns>A <see cref="GorgonPhysicalFileSystemData"/> object containing information about the directories and files contained within the physical file system.</returns>
 /// <exception cref="ArgumentNullException">Thrown when the <paramref name="physicalLocation"/>, or the <paramref name="mountPoint"/> parameters are <b>null</b>.</exception>
 /// <exception cref="ArgumentEmptyException">Thrown when the <paramref name="physicalLocation"/> parameter is empty.</exception>
 /// <remarks>
 /// Since this provider holds data in its own block of memory, there's nothing to enumerate when the provider is loaded. Thus, this will always return empty data.
 /// </remarks>
 public GorgonPhysicalFileSystemData Enumerate(string physicalLocation, IGorgonVirtualDirectory mountPoint) => OnEnumerate(physicalLocation, mountPoint);
        /// <summary>
        /// Function to enumerate files from the file system.
        /// </summary>
        /// <param name="physicalLocation">The physical file system location to enumerate.</param>
        /// <param name="mountPoint">The mount point to remap the file paths to.</param>
        /// <returns>A read only list of <see cref="IGorgonPhysicalFileInfo"/> entries.</returns>
        private static IReadOnlyList <IGorgonPhysicalFileInfo> EnumerateFiles(string physicalLocation, IGorgonVirtualDirectory mountPoint)
        {
            var directoryInfo = new DirectoryInfo(physicalLocation);

            IEnumerable <FileInfo> files = directoryInfo.GetFiles("*", SearchOption.AllDirectories)
                                           .Where(item =>
                                                  (item.Attributes & FileAttributes.Hidden) != FileAttributes.Hidden &&
                                                  (item.Attributes & FileAttributes.System) != FileAttributes.System &&
                                                  (item.Attributes & FileAttributes.Compressed) != FileAttributes.Compressed &&
                                                  (item.Attributes & FileAttributes.Encrypted) != FileAttributes.Encrypted &&
                                                  (item.Attributes & FileAttributes.Device) != FileAttributes.Device);

            return(files.Select(file =>
                                new PhysicalFileInfo(file,
                                                     MapToVirtualPath(file.DirectoryName.FormatDirectory(Path.DirectorySeparatorChar) + file.Name,
                                                                      physicalLocation,
                                                                      mountPoint.FullPath)))
                   .Cast <IGorgonPhysicalFileInfo>()
                   .ToArray());
        }
        /// <summary>
        /// Function to enumerate directories from the file system.
        /// </summary>
        /// <param name="physicalLocation">The physical file system location to enumerate.</param>
        /// <param name="mountPoint">The mount point to remap the directory paths to.</param>
        /// <returns>A read only list of <see cref="string"/> values representing the mapped directory entries.</returns>
        private static IReadOnlyList <string> EnumerateDirectories(string physicalLocation, IGorgonVirtualDirectory mountPoint)
        {
            var directoryInfo = new DirectoryInfo(physicalLocation);

            IEnumerable <DirectoryInfo> directories =
                directoryInfo.GetDirectories("*", SearchOption.AllDirectories)
                .Where(
                    item =>
                    (item.Attributes & FileAttributes.Hidden) != FileAttributes.Hidden &&
                    (item.Attributes & FileAttributes.System) != FileAttributes.System);

            return(directories.Select(item => MapToVirtualPath(item.FullName.FormatDirectory(Path.DirectorySeparatorChar),
                                                               physicalLocation,
                                                               mountPoint.FullPath))
                   .ToArray());
        }
Example #11
0
        /// <summary>
        /// Function to locate specific types of editor content files contained within the file system.
        /// </summary>
        /// <param name="fileSystem">The file system containing the content items.</param>
        /// <param name="path">Path to the directory containing the files to evaluate.</param>
        /// <param name="contentType">The type of content to locate.</param>
        /// <param name="searchMask">[Optional] A mask for filtering the search by file name.</param>
        /// <param name="recursive">[Optional] <b>true</b> to recursively search, <b>false</b> to only search the specified path.</param>
        /// <returns>A list of <see cref="IGorgonVirtualFile"/> items for each content item.</returns>
        /// <remarks>
        /// <para>
        /// Applications can use this to locate specific types of content files within a file system. If <b>null</b> is passed to the <paramref name="contentType"/>, then all content files with
        /// no content type associated will be returned.
        /// </para>
        /// </remarks>
        public static IReadOnlyList <IGorgonVirtualFile> GetContentItems(this IGorgonFileSystem fileSystem, string path, string contentType, string searchMask = "*", bool recursive = false)
        {
            var result = new List <IGorgonVirtualFile>();

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

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

            if (string.IsNullOrWhiteSpace(path))
            {
                throw new ArgumentEmptyException(nameof(path));
            }

            IProjectMetadata metaData = fileSystem.GetMetadata();

            if (metaData == null)
            {
                return(result);
            }

            // We passed in a file name, extract it for a seach pattern.
            if (string.IsNullOrWhiteSpace(searchMask))
            {
                searchMask = "*";
            }

            path = path.FormatDirectory('/');

            IGorgonVirtualDirectory directory = fileSystem.GetDirectory(path);

            if (directory == null)
            {
                throw new DirectoryNotFoundException();
            }

            IEnumerable <IGorgonVirtualFile> files = fileSystem.FindFiles(directory.FullPath, searchMask, recursive);

            // Handle the unassociated files.
            if (string.IsNullOrWhiteSpace(contentType))
            {
                foreach (IGorgonVirtualFile file in files)
                {
                    if (!metaData.ProjectItems.TryGetValue(file.FullPath, out ProjectItemMetadata metaDataItem))
                    {
                        continue;
                    }

                    IReadOnlyDictionary <string, string> attributes = metaDataItem.Attributes;

                    if ((attributes != null) && (attributes.Count > 0) && (attributes.TryGetValue(CommonEditorConstants.ContentTypeAttr, out string type)))
                    {
                        continue;
                    }

                    result.Add(file);
                }
                return(result);
            }

            // Filter the list based on the content type we ask for.
            foreach (IGorgonVirtualFile file in files)
            {
                if (!metaData.ProjectItems.TryGetValue(file.FullPath, out ProjectItemMetadata metaDataItem))
                {
                    continue;
                }

                IReadOnlyDictionary <string, string> attributes = metaDataItem.Attributes;

                if ((attributes == null) ||
                    (attributes.Count == 0) ||
                    (!attributes.TryGetValue(CommonEditorConstants.ContentTypeAttr, out string type)) ||
                    (!string.Equals(contentType, type, StringComparison.OrdinalIgnoreCase)))
                {
                    continue;
                }

                result.Add(file);
            }

            return(result);
        }
Example #12
0
        /// <summary>
        /// Function to enumerate the files and directories from a physical location and map it to a virtual location.
        /// </summary>
        /// <param name="physicalLocation">The physical location containing files and directories to enumerate.</param>
        /// <param name="mountPoint">A <see cref="IGorgonVirtualDirectory"/> that the directories and files from the physical file system will be mounted into.</param>
        /// <returns>A <see cref="GorgonPhysicalFileSystemData"/> object containing information about the directories and files contained within the physical file system.</returns>
        /// <exception cref="ArgumentNullException">Thrown when the <paramref name="physicalLocation"/>, or the <paramref name="mountPoint"/> parameters are <b>null</b>.</exception>
        /// <exception cref="ArgumentEmptyException">Thrown when the <paramref name="physicalLocation"/> parameter is empty.</exception>
        /// <remarks>
        /// <para>
        /// This will return a <see cref="GorgonPhysicalFileSystemData"/> representing the paths to directories and <see cref="IGorgonPhysicalFileInfo"/> objects under the virtual file system. Each file
        /// system file and directory is mapped from its <paramref name="physicalLocation"/> on the physical file system to a <paramref name="mountPoint"/> on the virtual file system. For example, if the
        /// mount point is set to <c>/MyMount/</c>, and the physical location of a file is <c>c:\SourceFileSystem\MyDirectory\MyTextFile.txt</c>, then the returned value should be
        /// <c>/MyMount/MyDirectory/MyTextFile.txt</c>.
        /// </para>
        /// <para>
        /// Implementors of a <see cref="GorgonFileSystemProvider"/> plug in can override this method to read the list of files from another type of file system, like a Zip file.
        /// </para>
        /// <para>
        /// Implementors of a <see cref="GorgonFileSystemProvider"/> should override this method to read the list of directories and files from another type of file system, like a Zip file.
        /// The default functionality will only enumerate directories and files from the operating system file system.
        /// </para>
        /// </remarks>
        protected override GorgonPhysicalFileSystemData OnEnumerate(string physicalLocation, IGorgonVirtualDirectory mountPoint)
        {
            var directories = new List <string>();
            var files       = new List <IGorgonPhysicalFileInfo>();

            using (var zipStream = new ZipInputStream(File.Open(physicalLocation, FileMode.Open, FileAccess.Read, FileShare.Read)))
            {
                ZipEntry entry;

                while ((entry = zipStream.GetNextEntry()) != null)
                {
                    if (!entry.IsDirectory)
                    {
                        string directoryName = Path.GetDirectoryName(entry.Name).FormatDirectory('/');

                        directoryName = mountPoint.FullPath + directoryName;

                        if (string.IsNullOrWhiteSpace(directoryName))
                        {
                            directoryName = "/";
                        }


                        if (!directories.Contains(directoryName))
                        {
                            directories.Add(directoryName);
                        }

                        files.Add(new ZipPhysicalFileInfo(entry, physicalLocation, mountPoint));
                    }
                    else
                    {
                        directories.Add((mountPoint.FullPath + entry.Name).FormatDirectory('/'));
                    }
                }
            }

            return(new GorgonPhysicalFileSystemData(directories, files));
        }
Example #13
0
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        private static void Main()
        {
            _log = new GorgonLog("FolderFileSystem", "Tape_Worm");
            _log.LogStart();

            try
            {
                Console.WindowHeight = 26.Max(Console.WindowHeight);
                Console.BufferHeight = Console.WindowHeight;

                // Create a new file system.
                _fileSystem = new GorgonFileSystem(_log);

                // Set the following directory as root on the virtual file system.
                // To mount a directory we need to put in the trailing slash.
                //
                // If we wanted to, we could mount a directory as a sub directory of
                // the root of the virtual file system.  For example, mounting the
                // directory D:\Dir with Mount(@"D:\Dir", "/VFSDir"); would mount the
                // contents of the D:\Dir directory under /VFSDir.
                //
                // It's also important to point out that the old Gorgon "file system"
                // would load files from the system into memory when mounting a
                // directory.  While this version only loads directory and file
                // information when mounting.  This is considerably more efficient.
                string physicalPath = GetResourcePath(@"FolderSystem\");
                _fileSystem.Mount(physicalPath);

                Console.ForegroundColor = ConsoleColor.White;

                Console.WriteLine("This example will mount a physical file system directory as the root of a");
                Console.WriteLine("virtual file system.  The virtual file system is capable of mounting various");
                Console.WriteLine("types of data such as a zip file, a file system folder, etc... as the root or a");
                Console.WriteLine("sub directory.  You can even mount a zip file as the root, and a physical file");
                Console.WriteLine("system directory as a virtual sub directory in the same virtual file system and");
                Console.WriteLine("access them as a single unified file system.");

                Console.Write("\nMounted: ");
                Console.ForegroundColor = ConsoleColor.Cyan;
                Console.Write("'{0}'", physicalPath.Ellipses(Console.WindowWidth - 20, true));
                Console.ForegroundColor = ConsoleColor.White;
                Console.Write(" as ");
                Console.ForegroundColor = ConsoleColor.Cyan;
                Console.WriteLine("'/'\n");
                Console.ForegroundColor = ConsoleColor.White;

                // Get a count of all sub directories and files under the root directory.
                IGorgonVirtualDirectory[] directoryList = _fileSystem.FindDirectories("*").ToArray();

                // Display directories.
                Console.WriteLine("Virtual file system contents:");

                for (int i = -1; i < directoryList.Length; i++)
                {
                    IGorgonVirtualDirectory directory = _fileSystem.RootDirectory;

                    // Go into the sub directories under root.
                    if (i > -1)
                    {
                        directory = directoryList[i];
                    }

                    Console.ForegroundColor = ConsoleColor.Cyan;
                    Console.WriteLine("{0}", directory.FullPath);

                    Console.ForegroundColor = ConsoleColor.Yellow;

                    foreach (IGorgonVirtualFile file in directory.Files)
                    {
                        Console.Write("   {0}", file.Name);
                        // Align the size to the same place.
                        Console.CursorLeft = 65;
                        Console.WriteLine("{0}", file.Size.FormatMemory());
                    }
                }

                Console.ResetColor();
                Console.WriteLine("\nPress any key to close.");
                Console.ReadKey();
            }
            catch (Exception ex)
            {
                ex.Catch(_ =>
                {
                    Console.Clear();
                    Console.ForegroundColor = ConsoleColor.Red;
                    Console.WriteLine("Exception:\n{0}\n\nStack Trace:{1}", _.Message, _.StackTrace);

                    Console.ResetColor();
#if DEBUG
                    Console.ReadKey();
#endif
                },
                         _log);
            }
            finally
            {
                _log.LogEnd();
            }
        }
Example #14
0
 /// <summary>
 /// Function to enumerate the files and directories from a physical location and map it to a virtual location.
 /// </summary>
 /// <param name="physicalLocation">The physical location containing files and directories to enumerate.</param>
 /// <param name="mountPoint">A <see cref="IGorgonVirtualDirectory"/> that the directories and files from the physical file system will be mounted into.</param>
 /// <returns>A <see cref="GorgonPhysicalFileSystemData"/> object containing information about the directories and files contained within the physical file system.</returns>
 /// <exception cref="ArgumentNullException">Thrown when the <paramref name="physicalLocation"/>, or the <paramref name="mountPoint"/> parameters are <b>null</b>.</exception>
 /// <exception cref="ArgumentEmptyException">Thrown when the <paramref name="physicalLocation"/> parameter is empty.</exception>
 /// <remarks>
 /// Since this provider holds data in its own block of memory, there's nothing to enumerate when the provider is loaded. Thus, this will always return empty data.
 /// </remarks>
 protected virtual GorgonPhysicalFileSystemData OnEnumerate(string physicalLocation, IGorgonVirtualDirectory mountPoint) => new GorgonPhysicalFileSystemData(FileData.GetDirectories(),
                                                                                                                                                             FileData.GetFileInfos()
                                                                                                                                                             .Select(item =>
                                                                                                                                                                     new PhysicalFileInfo(Prefix + "::" + item.FullPath,
                                                                                                                                                                                          item.CreateDate,
                                                                                                                                                                                          item.Size,
                                                                                                                                                                                          item.FullPath,
                                                                                                                                                                                          0,
                                                                                                                                                                                          item.LastModified))
                                                                                                                                                             .ToArray());
        /// <summary>
        /// Function to enumerate the available files stored in the packed file.
        /// </summary>
        /// <param name="index">The XML file containing the index of files and directories.</param>
        /// <param name="offset">The offset into the physical file.</param>
        /// <param name="physicalLocation">Physical location of the packed file.</param>
        /// <param name="mountPoint">The mount point to map into.</param>
        /// <returns>A read only list of <see cref="IGorgonPhysicalFileInfo"/> objects mapped to the virtual file system.</returns>
        private static IReadOnlyList <IGorgonPhysicalFileInfo> EnumerateFiles(XDocument index, long offset, string physicalLocation, IGorgonVirtualDirectory mountPoint)
        {
            IEnumerable <XElement> files = index.Descendants("File");
            var result = new List <IGorgonPhysicalFileInfo>();

            foreach (XElement file in files)
            {
                XElement fileNameNode           = file.Element("Filename");
                XElement fileExtensionNode      = file.Element("Extension");
                XElement fileOffsetNode         = file.Element("Offset");
                XElement fileCompressedSizeNode = file.Element("CompressedSize");
                XElement fileSizeNode           = file.Element("Size");
                XElement fileDateNode           = file.Element("FileDate");
                XElement fileLastModNode        = file.Element("LastModDate");
                string   parentDirectoryPath    = file.Parent?.Attribute("FullPath")?.Value;

                // We need these nodes.
                if ((fileNameNode == null) || (fileOffsetNode == null) ||
                    (fileSizeNode == null) || (fileDateNode == null) ||
                    ((string.IsNullOrWhiteSpace(fileNameNode.Value)) && (string.IsNullOrWhiteSpace(fileExtensionNode.Value))) ||
                    (string.IsNullOrWhiteSpace(fileDateNode.Value)) ||
                    (string.IsNullOrWhiteSpace(parentDirectoryPath)))
                {
                    throw new FileLoadException(Resources.GORFS_GORPACK_ERR_FILEINDEX_CORRUPT);
                }

                parentDirectoryPath = (mountPoint.FullPath + parentDirectoryPath).FormatDirectory('/');

                string fileName       = fileNameNode.Value;
                long?  compressedSize = null;

                // If we don't have a creation date, then don't allow the file to be processed.
                if (!DateTime.TryParse(fileDateNode.Value, CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime fileDate))
                {
                    throw new FileLoadException(Resources.GORFS_GORPACK_ERR_FILEINDEX_CORRUPT);
                }

                if ((fileLastModNode == null) || (!DateTime.TryParse(fileLastModNode.Value, CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime lastModDate)))
                {
                    lastModDate = fileDate;
                }

                if (!long.TryParse(fileOffsetNode.Value, NumberStyles.Integer, CultureInfo.InvariantCulture, out long fileOffset))
                {
                    throw new FileLoadException(Resources.GORFS_GORPACK_ERR_FILEINDEX_CORRUPT);
                }

                fileOffset += offset;

                if (!long.TryParse(fileSizeNode.Value, NumberStyles.Integer, CultureInfo.InvariantCulture, out long fileSize))
                {
                    throw new FileLoadException(Resources.GORFS_GORPACK_ERR_FILEINDEX_CORRUPT);
                }

                string fileExtension = fileExtensionNode.Value ?? string.Empty;

                if (!string.IsNullOrWhiteSpace(fileName))
                {
                    fileName += fileExtension;
                }
                else
                {
                    fileName = fileExtension;
                }

                // If the file is compressed, then add it to a special list.
                if (fileCompressedSizeNode != null)
                {
                    if (!long.TryParse(fileCompressedSizeNode.Value, NumberStyles.Integer, CultureInfo.InvariantCulture, out long compressed))
                    {
                        throw new FileLoadException(Resources.GORFS_GORPACK_ERR_FILEINDEX_CORRUPT);
                    }

                    if (compressed > 0)
                    {
                        compressedSize = compressed;
                    }
                }

                result.Add(new GorPackPhysicalFileInfo(physicalLocation + "::/" + parentDirectoryPath + fileName,
                                                       fileName,
                                                       fileDate,
                                                       lastModDate,
                                                       fileOffset,
                                                       fileSize,
                                                       parentDirectoryPath + fileName,
                                                       compressedSize));
            }

            return(result);
        }
Example #16
0
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        private static void Main()
        {
            _log = new GorgonLog("ZipFileSystem", "Tape_Worm");
            _log.LogStart();

            // Create the plugin assembly cache.
            _pluginAssemblies = new GorgonMefPlugInCache(_log);
            // Create the plugin service.
            _pluginService = new GorgonMefPlugInService(_pluginAssemblies);

            try
            {
                Console.WindowHeight = 28;
                Console.BufferHeight = Console.WindowHeight;

                Console.ForegroundColor = ConsoleColor.White;
                Console.WriteLine("This example will mount a zip file as the root of a virtual file system.  The");
                Console.WriteLine("virtual file system is capable of mounting various types of data such as a zip,");
                Console.WriteLine("a file system folder, etc... as the root or a sub directory.  You can even");
                Console.WriteLine("mount a zip file as the root, and a physical file system directory as a virtual");
                Console.WriteLine("sub directory in the same virtual file system and access them as a single");
                Console.WriteLine("unified file system.");

                // Unlike the folder file system example, we need to load
                // a provider to handle zip files before trying to mount
                // one.
                if (!LoadZipProviderPlugIn())
                {
                    return;
                }

                // Set the following zip file as root on the virtual file system.
                //
                // If we wanted to, we could mount a zip file as a sub directory of
                // the root of the virtual file system.  For example, mounting the
                // directory D:\Dir\zipFile.zip with Mount(@"D:\Dir", "/VFSDir"); would mount
                // the contents of the D:\Dir\zipFile.zip directory under /VFSDir.
                //
                // It's also important to point out that the old Gorgon "file system"
                // would load files from the system into memory when mounting a
                // directory.  While this version only loads directory and file
                // information when mounting.  This is considerably more efficient.
                string physicalPath = GetResourcePath(@"FileSystem.zip");
                _fileSystem.Mount(physicalPath);

                Console.Write("\nMounted: ");
                Console.ForegroundColor = ConsoleColor.Cyan;
                Console.Write("'{0}'", physicalPath.Ellipses(Console.WindowWidth - 20, true));
                Console.ForegroundColor = ConsoleColor.White;
                Console.Write(" as ");
                Console.ForegroundColor = ConsoleColor.Cyan;
                Console.WriteLine("'/'\n");
                Console.ForegroundColor = ConsoleColor.White;

                // Get a count of all sub directories and files under the root directory.
                IGorgonVirtualDirectory[] directoryList = _fileSystem.FindDirectories("*").ToArray();

                // Display directories.
                Console.WriteLine("Virtual file system contents:");

                for (int i = -1; i < directoryList.Length; i++)
                {
                    IGorgonVirtualDirectory directory = _fileSystem.RootDirectory;

                    // Go into the sub directories under root.
                    if (i > -1)
                    {
                        directory = directoryList[i];
                    }

                    Console.ForegroundColor = ConsoleColor.Cyan;
                    Console.WriteLine("{0}", directory.FullPath);

                    Console.ForegroundColor = ConsoleColor.Yellow;

                    foreach (IGorgonVirtualFile file in directory.Files)
                    {
                        Console.Write("   {0}", file.Name);
                        // Align the size to the same place.
                        Console.CursorLeft = 65;
                        Console.WriteLine("{0}", file.Size.FormatMemory());
                    }
                }

                Console.ResetColor();
                Console.WriteLine("\nPress any key to close.");
                Console.ReadKey();
            }
            catch (Exception ex)
            {
                ex.Catch(_ =>
                {
                    Console.Clear();
                    Console.ForegroundColor = ConsoleColor.Red;
                    Console.WriteLine("Exception:\n{0}\n\nStack Trace:{1}", _.Message, _.StackTrace);

                    Console.ResetColor();
#if DEBUG
                    Console.ReadKey();
#endif
                });
            }
            finally
            {
                // Always dispose the cache to clean up the temporary app domain it creates.
                _pluginAssemblies.Dispose();
                _log.LogEnd();
            }
        }
        /// <summary>
        /// Function to enumerate the files and directories from a physical location and map it to a virtual location.
        /// </summary>
        /// <param name="physicalLocation">The physical location containing files and directories to enumerate.</param>
        /// <param name="mountPoint">A <see cref="IGorgonVirtualDirectory"/> that the directories and files from the physical file system will be mounted into.</param>
        /// <returns>A <see cref="GorgonPhysicalFileSystemData"/> object containing information about the directories and files contained within the physical file system.</returns>
        /// <exception cref="ArgumentNullException">Thrown when the <paramref name="physicalLocation"/>, or the <paramref name="mountPoint"/> parameters are <b>null</b>.</exception>
        /// <exception cref="ArgumentEmptyException">Thrown when the <paramref name="physicalLocation"/> parameter is empty.</exception>
        /// <remarks>
        /// <para>
        /// This will return a <see cref="GorgonPhysicalFileSystemData"/> representing the paths to directories and <see cref="IGorgonPhysicalFileInfo"/> objects under the virtual file system. Each file
        /// system file and directory is mapped from its <paramref name="physicalLocation"/> on the physical file system to a <paramref name="mountPoint"/> on the virtual file system. For example, if the
        /// mount point is set to <c>/MyMount/</c>, and the physical location of a file is <c>c:\SourceFileSystem\MyDirectory\MyTextFile.txt</c>, then the returned value should be
        /// <c>/MyMount/MyDirectory/MyTextFile.txt</c>.
        /// </para>
        /// <para>
        /// Implementors of a <see cref="GorgonFileSystemProvider"/> plug in can override this method to read the list of files from another type of file system, like a Zip file.
        /// </para>
        /// <para>
        /// Implementors of a <see cref="GorgonFileSystemProvider"/> should override this method to read the list of directories and files from another type of file system, like a Zip file.
        /// The default functionality will only enumerate directories and files from the operating system file system.
        /// </para>
        /// </remarks>
        protected override GorgonPhysicalFileSystemData OnEnumerate(string physicalLocation, IGorgonVirtualDirectory mountPoint)
        {
            using (var reader = new GorgonBinaryReader(File.Open(physicalLocation, FileMode.Open, FileAccess.Read, FileShare.Read)))
            {
                // Skip the header.
                reader.ReadString();

                int indexLength = reader.ReadInt32();

                byte[] indexData = Decompress(reader.ReadBytes(indexLength));
                string xmlData   = Encoding.UTF8.GetString(indexData);
                var    index     = XDocument.Parse(xmlData, LoadOptions.None);

                return(new GorgonPhysicalFileSystemData(EnumerateDirectories(index, mountPoint),
                                                        EnumerateFiles(index, reader.BaseStream.Position, physicalLocation, mountPoint)));
            }
        }