Beispiel #1
0
 /// <summary>
 ///   Initializes a new instance of the <see cref="DiskArchiveStorage" /> class.
 /// </summary>
 /// <param name="file">The file.</param>
 public DiskArchiveStorage(ZipFile file)
   : this(file, FileUpdateMode.Safe) {}
Beispiel #2
0
    /// <summary>
    ///   Extract the contents of a zip file.
    /// </summary>
    /// <param name="zipFileName">The zip file to extract from.</param>
    /// <param name="targetDirectory">The directory to save extracted information in.</param>
    /// <param name="overwrite">The style of <see cref="Overwrite">overwriting</see> to apply.</param>
    /// <param name="confirmDelegate">A delegate to invoke when confirming overwriting.</param>
    /// <param name="fileFilter">A filter to apply to files.</param>
    /// <param name="directoryFilter">A filter to apply to directories.</param>
    /// <param name="restoreDateTime">Flag indicating wether to restore the date and time for extracted files.</param>
    public void ExtractZip(string zipFileName, string targetDirectory, string fileFilter, string directoryFilter)
    {
      continueRunning_ = true;
      extractNameTransform_ = new WindowsNameTransform(targetDirectory);

      fileFilter_ = new NameFilter(fileFilter);
      directoryFilter_ = new NameFilter(directoryFilter);

      using (zipFile_ = new ZipFile(zipFileName))
      {
        var enumerator = zipFile_.GetEnumerator();
        while (continueRunning_ && enumerator.MoveNext())
        {
          var entry = (ZipEntry) enumerator.Current;
          if (entry.IsFile)
          {
            // TODO Path.GetDirectory can fail here on invalid characters.
            if (directoryFilter_.IsMatch(Path.GetDirectoryName(entry.Name)) && fileFilter_.IsMatch(entry.Name))
            {
              ExtractEntry(entry);
            }
          }
        }
      }
    }
Beispiel #3
0
      /// <summary>
      ///   Initialise a new instance of the <see cref="PartialInputStream" /> class.
      /// </summary>
      /// <param name="zipFile">The <see cref="ZipFile" /> containing the underlying stream to use for IO.</param>
      /// <param name="start">The start of the partial data.</param>
      /// <param name="length">The length of the partial data.</param>
      public PartialInputStream(ZipFile zipFile, long start, long length)
      {
        start_ = start;
        length_ = length;

        // Although this is the only time the zipfile is used
        // keeping a reference here prevents premature closure of
        // this zip file and thus the baseStream_.

        // Code like this will cause apparently random failures depending
        // on the size of the files and when garbage is collected.
        //
        // ZipFile z = new ZipFile (stream);
        // Stream reader = z.GetInputStream(0);
        // uses reader here....
        baseStream_ = zipFile.baseStream_;
        readPos_ = start;
        end_ = start + length;
      }
Beispiel #4
0
    /// <summary>
    ///   Initializes a new instance of the <see cref="DiskArchiveStorage" /> class.
    /// </summary>
    /// <param name="file">The file.</param>
    /// <param name="updateMode">The update mode.</param>
    public DiskArchiveStorage(ZipFile file, FileUpdateMode updateMode)
      : base(updateMode)
    {
      if (file.Name == null)
      {
        throw new ZipException("Cant handle non file archives");
      }

      fileName_ = file.Name;
    }
Beispiel #5
0
    /// <summary>
    ///   Create a new <see cref="ZipFile" /> whose data will be stored on a stream.
    /// </summary>
    /// <param name="outStream">The stream providing data storage.</param>
    /// <returns>Returns the newly created <see cref="ZipFile" /></returns>
    /// <exception cref="ArgumentNullException">
    ///   <paramref name="outStream"> is null</paramref>
    /// </exception>
    /// <exception cref="ArgumentException">
    ///   <paramref name="outStream"> doesnt support writing.</paramref>
    /// </exception>
    public static ZipFile Create(Stream outStream)
    {
      if (outStream == null)
      {
        throw new ArgumentNullException("outStream");
      }

      if (!outStream.CanWrite)
      {
        throw new ArgumentException("Stream is not writeable", "outStream");
      }

      if (!outStream.CanSeek)
      {
        throw new ArgumentException("Stream is not seekable", "outStream");
      }

      var result = new ZipFile();
      result.baseStream_ = outStream;
      return result;
    }
Beispiel #6
0
    private void CopyEntry(ZipFile workFile, ZipUpdate update)
    {
      workFile.WriteLocalEntryHeader(update);

      if (update.Entry.CompressedSize > 0)
      {
        const int NameLengthOffset = 26;

        var entryDataOffset = update.Entry.Offset + NameLengthOffset;

        // TODO: This wont work for SFX files!
        baseStream_.Seek(entryDataOffset, SeekOrigin.Begin);

        uint nameLength = ReadLEUshort();
        uint extraLength = ReadLEUshort();

        baseStream_.Seek(nameLength + extraLength, SeekOrigin.Current);

        CopyBytes(update, workFile.baseStream_, baseStream_, update.Entry.CompressedSize, false);
      }
      CopyDescriptorBytes(update, workFile.baseStream_, baseStream_);
    }
Beispiel #7
0
    private void CopyEntryDirect(ZipFile workFile, ZipUpdate update, ref long destinationPosition)
    {
      var skipOver = false;
      if (update.Entry.Offset == destinationPosition)
      {
        skipOver = true;
      }

      if (!skipOver)
      {
        baseStream_.Position = destinationPosition;
        workFile.WriteLocalEntryHeader(update);
        destinationPosition = baseStream_.Position;
      }

      const int NameLengthOffset = 26;

      // TODO: Add base for SFX friendly handling
      var entryDataOffset = update.Entry.Offset + NameLengthOffset;

      baseStream_.Seek(entryDataOffset, SeekOrigin.Begin);

      // Clumsy way of handling retrieving the original name and extra data length for now.
      // TODO: Stop re-reading name and data length in CopyEntryDirect.
      uint nameLength = ReadLEUshort();
      uint extraLength = ReadLEUshort();

      var sourcePosition = baseStream_.Position + nameLength + extraLength;

      if (skipOver)
      {
        destinationPosition +=
          (sourcePosition - entryDataOffset) + NameLengthOffset + // Header size
          update.Entry.CompressedSize + GetDescriptorSize(update);
      }
      else
      {
        if (update.Entry.CompressedSize > 0)
        {
          CopyEntryDataDirect(update, baseStream_, false, ref destinationPosition, ref sourcePosition);
        }
        CopyDescriptorBytesDirect(update, baseStream_, ref destinationPosition, sourcePosition);
      }
    }
Beispiel #8
0
    private static void ModifyEntry(ZipFile workFile, ZipUpdate update)
    {
      workFile.WriteLocalEntryHeader(update);
      var dataStart = workFile.baseStream_.Position;

      var dataEnd = workFile.baseStream_.Position;
      update.Entry.CompressedSize = dataEnd - dataStart;
    }
Beispiel #9
0
    private void AddEntry(ZipFile workFile, ZipUpdate update)
    {
      Stream source = null;

      if (update.Entry.IsFile)
      {
        source = update.GetSource();

        if (source == null)
        {
          source = updateDataSource_.GetSource(update.Entry, null);
        }
      }

      if (source != null)
      {
        using (source)
        {
          var sourceStreamLength = source.Length;
          if (update.OutEntry.Size < 0)
          {
            update.OutEntry.Size = sourceStreamLength;
          }
          else
          {
            // Check for errant entries.
            if (update.OutEntry.Size != sourceStreamLength)
            {
              throw new ZipException("Entry size/stream size mismatch");
            }
          }

          workFile.WriteLocalEntryHeader(update);

          var dataStart = workFile.baseStream_.Position;

          using (var output = workFile.GetOutputStream(update.OutEntry))
          {
            CopyBytes(update, output, source, sourceStreamLength, true);
          }

          var dataEnd = workFile.baseStream_.Position;
          update.OutEntry.CompressedSize = dataEnd - dataStart;

          if ((update.OutEntry.Flags & (int) GeneralBitFlags.Descriptor) == (int) GeneralBitFlags.Descriptor)
          {
            var helper = new ZipHelperStream(workFile.baseStream_);
            helper.WriteDataDescriptor(update.OutEntry);
          }
        }
      }
      else
      {
        workFile.WriteLocalEntryHeader(update);
        update.OutEntry.CompressedSize = 0;
      }
    }