/// <summary>
        /// Handles validation and stream preparation of a given transfer in order to read
        /// a given block of data. The actual reading (either into a buffer, or a returned
        /// stream) is being delegated via the <paramref name="dataReaderFunc"/>.
        /// </summary>
        /// <typeparam name="T">The type of <see cref="IDataBlock"/> that is being returned.</typeparam>
        /// <param name="transfer">The processed transfer.</param>
        /// <param name="blockNumber">The block number to be read.</param>
        /// <param name="dataReaderFunc">A function that receives the designated stream offset,
        /// and returns the required <see cref="IDataBlock"/> that provides the block's data.</param>
        /// <returns>The <see cref="IDataBlock"/> that is being created by the <paramref name="dataReaderFunc"/>.</returns>
        private static T PrepareAndRunBlockReading <T>(ZipDownloadTransfer transfer, long blockNumber,
                                                       Func <Stream, long, T> dataReaderFunc) where T : IDataBlock
        {
            DownloadToken token    = transfer.Token;
            long          position = blockNumber * token.DownloadBlockSize;

            //in case of an invalid position, throw error
            if (position > token.ResourceLength)
            {
                string msg = "Cannot deliver block {0} - invalid block number (beyond actual file size).";
                msg = String.Format(msg, blockNumber);
                throw new DataBlockException(msg);
            }

            ZipNode node = transfer.FileItem.Node;

            //TODO cache stream or even use temp file - this needs heavy optimization
            //open and position stream
            var stream = node.FileEntry.OpenReader();

            stream.Position = position;

            T dataBlock = dataReaderFunc(stream, position);

            return(dataBlock);
        }
Example #2
0
        public async Task GetFilters()
        {
            using (var temp = new TempFile())
            {
                using (var stream = temp.OpenWrite())
                {
                    using (var zip = StreamHelper.CreateZipArchive(stream, ZipArchiveMode.Create))
                    {
                        StreamHelper.CreateZipArchiveEntry(zip, "binary.txt", TestFilterData.TextWithMixedBinary);
                        StreamHelper.CreateZipArchiveEntry(zip, "text.txt", TestFilterData.TextWithBlankLines);
                        StreamHelper.CreateZipArchiveEntry(zip, "text2.txt", TestFilterData.TextMixedLineEndings);
                    }
                }

                var context = new Mock <FilterContext>();
                context.Setup(x => x.CancellationToken).Returns(CancellationToken.None);
                var visitor = new Mock <INodeVisitor>();
                visitor.Setup(x => x.Context).Returns(context.Object);
                visitor.Setup(x => x.Visit(It.IsAny <FileNode>())).Returns(Task.FromResult(1));

                var node = new ZipNode(temp.File);

                await node.Accept(visitor.Object);

                visitor.Verify(x => x.Visit(It.IsAny <FileNode>()), Times.Exactly(3));
            }
        }
Example #3
0
    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();
      }
    }
Example #4
0
        /// <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);
            }
        }
Example #5
0
 public ZipFolderItem(ZipNode folderEntry, VirtualFolderInfo virtualFolder)
 {
   Node = folderEntry;
   ResourceInfo = virtualFolder;
 }
    /// <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>
    /// Gets a file item for a known file entry within the
    /// maintained ZIP file.
    /// </summary>
    /// <param name="qualifiedName">The qualified name of the ZIP
    /// entry.</param>
    /// <returns>A file item that can be resolved to the requested ZIP
    /// entry.</returns>
    /// <exception cref="VirtualResourceNotFoundException">If the submitted
    /// path cannot be resolved to a maintained file entry.</exception>
    public ZipFileItem GetFileItem(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, false);
        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 file path [{0}] refers to a directory, not a file.";
        msg = String.Format(msg, qualifiedName);
        throw new ResourceAccessException(msg);
      }

      return new ZipFileItem(node, node.ToFileInfo());
    }
Example #8
0
 public ZipFileItem(ZipNode node, VirtualFileInfo virtualFile)
 {
   Node = node;
   ResourceInfo = virtualFile;
 }