/// <summary> /// Links the entries of the encapsulated <see cref="ZipFile"/> and refreshes the /// <see cref="RootNodes"/> collection. /// </summary> public void Refresh() { RootNode = new ZipNode(RootFolderPath, true) { IsRootNode = true }; var entries = ZipFile.Entries.Select(e => new ZipNode(e)).ToArray(); for (int index = 0; index < entries.Length; index++) { var node = entries[index]; string parentPath = node.FullName.GetParentPath(); if (!IsRootPath(parentPath)) { //TODO currently, we require the node to have a parent entry if there's path //information that indicates so. According to ZIP specs, this might not necessarily //be the case... node.ParentNode = entries.Single(e => e.FullName == parentPath && e.IsDirectoryNode); node.ParentNode.RegisterChildNode(node); } } //get top level entries var topLevelEntries = entries.Where(e => e.ParentNode == null).ToArray(); //assign root entries to root node foreach (var entry in topLevelEntries) { RootNode.RegisterChildNode(entry); entry.ParentNode = RootNode; } }
/// <summary> /// Removes a given node from the internal <see cref="ChildNodes"/> /// collection. /// </summary> /// <param name="childNode">The node to be removed.</param> /// <returns>True if the node was found and removed. Otherwise false.</returns> public bool RemoveChildNode(ZipNode childNode) { lock (childNodes) { return(childNodes.Remove(childNode)); } }
/// <summary> /// Gets a folder item for a known folder entry within the /// maintained ZIP file. /// </summary> /// <param name="qualifiedName">The qualified name of the ZIP /// entry.</param> /// <returns>A folder item that can be resolved to the requested ZIP /// entry.</returns> /// <exception cref="VirtualResourceNotFoundException">If the submitted /// path cannot be resolved to a maintained folder entry.</exception> public ZipFolderItem GetFolderItem(string qualifiedName) { qualifiedName = qualifiedName.RemoveRootSlash(); var node = TryFindNode(qualifiedName); //if there is no such node, create a virtual one if (node == null) { node = new ZipNode(qualifiedName, true); node.ParentNode = TryFindNode(qualifiedName.GetParentPath()) ?? RootNode; } else if (!node.IsDirectoryNode) { //throw exception if the path is already linked to a directory entry string msg = "Submitted folder path [{0}] refers to a file, not a directory."; msg = String.Format(msg, qualifiedName); throw new ResourceAccessException(msg); } if (node.IsRootNode) { return(CreateRootItem()); } return(new ZipFolderItem(node, node.ToFolderInfo())); }
public static VirtualFileInfo ToFileInfo(this ZipNode node) { Ensure.ArgumentNotNull(node, "node"); if (node.IsDirectoryNode) { string msg = "ZIP entry [{0}] does not represent a file."; msg = String.Format(msg, node.FileEntry.FileName); throw new InvalidOperationException(msg); } var fi = new VirtualFileInfo { Name = Path.GetFileName(node.FullName), ContentType = ContentUtil.ResolveContentType(Path.GetExtension(node.FullName)), }; SetCommonProperties(fi, node); if (node.FileEntry != null) { fi.Length = node.FileEntry.UncompressedSize; } return(fi); }
/// <summary> /// Registers a child node, which will be added to the /// <see cref="ChildNodes"/> collection. /// </summary> /// <param name="childNode">The node to be registered.</param> public void RegisterChildNode(ZipNode childNode) { lock (childNodes) { childNodes.Add(childNode); } }
public static VirtualFolderInfo ToFolderInfo(this ZipNode node) { Ensure.ArgumentNotNull(node, "node"); if (!node.IsDirectoryNode) { string msg = "ZIP entry [{0}] does not represent a directory."; msg = String.Format(msg, node.FullName); throw new InvalidOperationException(msg); } //get local name var fileName = node.FullName; if (fileName.EndsWith("/")) { fileName = fileName.Substring(0, fileName.Length - 1); } fileName = Path.GetFileName(fileName); var fi = new VirtualFolderInfo { Name = fileName, IsRootFolder = node.IsRootNode, IsEmpty = node.ChildNodes.Count() == 0 }; SetCommonProperties(fi, node); return(fi); }
private static void SetCommonProperties(VirtualResourceInfo resourceInfo, ZipNode node) { resourceInfo.FullName = node.FullName; resourceInfo.ParentFolderPath = node.ParentNode == null ? null : node.ParentNode.FullName; var entry = node.FileEntry; if (entry != null) { resourceInfo.Description = entry.Info; resourceInfo.IsHidden = (entry.Attributes & FileAttributes.Hidden) == FileAttributes.Hidden; resourceInfo.IsReadOnly = (entry.Attributes & FileAttributes.ReadOnly) == FileAttributes.ReadOnly; resourceInfo.CreationTime = entry.CreationTime == DateTime.MinValue ? (DateTimeOffset?)null : entry.CreationTime.ToLocalTime(); resourceInfo.LastWriteTime = entry.LastModified == DateTime.MinValue ? (DateTimeOffset?)null : entry.LastModified.ToLocalTime(); } }
/// <summary> /// Recursively copies /// </summary> /// <param name="sourceFolderNode">Represents the folder that needs to copied.</param> /// <param name="targetFolderPath">The path of the target folder that corresponds to the /// submitted <paramref name="sourceFolderNode"/>.</param> protected virtual void CopyFolderContents(ZipNode sourceFolderNode, string targetFolderPath) { //create the target folder NodeRepository.ZipFile.AddDirectoryByName(targetFolderPath); foreach (var childFile in sourceFolderNode.ChildFiles) { //copy file string path = CreateFilePath(targetFolderPath, childFile.GetLocalName()); //create a deferred stream that extracts the file during writing var ds = new DeferredStream(() => Configuration.TempStreamFactory.CreateTempStream()); NodeRepository.ZipFile.AddEntry(path, s => ds, (s, n) => ds.Dispose()); } foreach (ZipNode childFolder in sourceFolderNode.ChildDirectories) { //create new target folder path and recurse string childPath = CreateFolderPath(targetFolderPath, childFolder.GetLocalName()); CopyFolderContents(childFolder, childPath); } }
public ZipFileItem(ZipNode node, VirtualFileInfo virtualFile) { Node = node; ResourceInfo = virtualFile; }
public ZipFolderItem(ZipNode folderEntry, VirtualFolderInfo virtualFolder) { Node = folderEntry; ResourceInfo = virtualFolder; }
/// <summary> /// Gets the local name of a given <see cref="ZipNode"/>. /// </summary> /// <param name="node">The queried node.</param> /// <returns>The non-qualified local file or directory name.</returns> public static string GetLocalName(this ZipNode node) { var fullName = node.FullName.RemoveTrailingSlash(); return(Path.GetFileName(fullName)); }