/// <summary> /// Get entry at <paramref name="subpath"/>. /// </summary> /// <param name="subpath"></param> /// <returns></returns> public ArchiveDirectoryEntry GetOrCreateDirectory(string subpath) { if (subpath == null) { throw new ArgumentNullException(nameof(subpath)); } if (subpath == "") { return(this); } // Split to local dir name and rest of the path int slashIx = subpath.IndexOf('/'); string localDirectoryName = slashIx < 0 ? subpath : subpath.Substring(0, slashIx); string restOfThePath = slashIx < 0 ? null : subpath.Substring(slashIx + 1); // Get-or-create local directory ArchiveDirectoryEntry localDirectory = null; if (!directories.TryGetValue(localDirectoryName, out localDirectory)) { localDirectory = new ArchiveDirectoryEntry(localDirectoryName, LastModified, null, null); directories[localDirectory.Name] = localDirectory; } // Return or recurse return(restOfThePath == null ? localDirectory : localDirectory.GetOrCreateDirectory(restOfThePath)); }
/// <summary> /// Find directory /// </summary> /// <param name="subpath">canonized path</param> /// <returns>directory or null if was not found</returns> public ArchiveDirectoryEntry GetDirectory(string subpath) { if (subpath == null) { throw new ArgumentNullException(nameof(subpath)); } if (subpath == "") { return(this); } // Split to local dir name and rest of the path int slashIx = subpath.IndexOf('/'); string localDirectoryName = slashIx < 0 ? subpath : subpath.Substring(0, slashIx); string restOfThePath = slashIx < 0 ? null : subpath.Substring(slashIx + 1); // Get local directory ArchiveDirectoryEntry dir = null; if (!directories.TryGetValue(localDirectoryName, out dir)) { return(null); } // Return or recurse return(restOfThePath == null ? dir : dir.GetDirectory(restOfThePath)); }
/// <summary> /// Search directory from the read-only directory index. /// </summary> /// <param name="path"></param> /// <returns></returns> public virtual IDirectoryContents GetDirectoryContents(string path) { if (IsDisposing) { throw new ObjectDisposedException(GetType().FullName); } if (path == null) { path = ""; } string canonizedPath = CanonizePath(path); ArchiveDirectoryEntry dir = root.GetDirectory(canonizedPath); return((IDirectoryContents)dir ?? NotFoundDirectoryContents.Singleton); }
/// <summary> /// Add <paramref name="archiveEntries"/> into tree structure. /// </summary> /// <param name="root"></param> /// <param name="archiveEntries"></param> /// <param name="streamProvider">stream provider for files</param> /// <param name="convertBackslashesToSlashes">if true converts '\' to '/'</param> /// <returns>this</returns> protected virtual Lexical.FileProvider.Common.ArchiveDirectoryEntry AddArchiveEntries(Lexical.FileProvider.Common.ArchiveDirectoryEntry root, IEnumerable <IArchiveEntry> archiveEntries, Lexical.FileProvider.Common.IStreamProvider streamProvider, bool convertBackslashesToSlashes) { foreach (IArchiveEntry entry in archiveEntries) { string path = convertBackslashesToSlashes ? entry.Key.Replace('\\', '/') : entry.Key; // Is entry a file if (!entry.IsDirectory) { // Split to filename and path int slashIx = path.LastIndexOf('/'); string filename = path.Substring(slashIx + 1); string dirPath = slashIx < 0 ? "" : path.Substring(0, slashIx); // Create file entry Lexical.FileProvider.Common.ArchiveFileEntry fileEntry = new Lexical.FileProvider.Common.ArchiveFileEntry(streamProvider, entry.Key, filename, entry.Size, entry.LastModifiedTime ?? DateTime.MinValue); // Create dir Lexical.FileProvider.Common.ArchiveDirectoryEntry dir = root.GetOrCreateDirectory(dirPath); // Add to dir dir.files[filename] = fileEntry; } else { // Create dir var dir = root.GetOrCreateDirectory(path); if (entry.LastModifiedTime != null) { dir.LastModified = (DateTime)entry.LastModifiedTime; } } } // Return the whole tree return(root); }
/// <summary> /// Find file /// </summary> /// <param name="canonizedPath">file path</param> /// <returns>file or null</returns> public ArchiveFileEntry GetFile(string canonizedPath) { if (canonizedPath == null) { throw new ArgumentNullException(nameof(canonizedPath)); } if (canonizedPath == "") { return(null); } // Find slash int slashIX = canonizedPath.IndexOf('/'); // No slash, return direct file if (slashIX < 0) { ArchiveFileEntry result = null; files.TryGetValue(canonizedPath, out result); return(result); } // Got slash, find local dir string localDirectoryName = canonizedPath.Substring(0, slashIX); ArchiveDirectoryEntry localDirectory = null; if (!directories.TryGetValue(localDirectoryName, out localDirectory)) { return(null); } // Use recursion for the rest the path string restOfThePath = canonizedPath.Substring(slashIX + 1); return(localDirectory.GetFile(restOfThePath)); }
/// <summary> /// Create archive content file provider. /// </summary> /// <param name="hintPath">(optional) clue of the file that is being opened</param> /// <param name="lastModified">Date time for folder entries</param> public ArchiveFileProvider(string hintPath, DateTimeOffset?lastModified = default) { this.root = new ArchiveDirectoryEntry("", lastModified ?? DateTimeOffset.MinValue, null, null); this.HintPath = hintPath; }