Exemplo n.º 1
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>
		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");
			}

			ZipFile result = new ZipFile();
			result.baseStream_ = outStream;
			return result;
		}
Exemplo n.º 2
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)
		{
		}
Exemplo n.º 3
0
		/// <summary>
		/// Create a new <see cref="ZipFile"/> whose data will be stored in a file.
		/// </summary>
		/// <param name="fileName">The name of the archive to create.</param>
		/// <returns>Returns the newly created <see cref="ZipFile"/></returns>
		public static ZipFile Create(string fileName)
		{
			if (fileName == null)
			{
				throw new ArgumentNullException("fileName");
			}

			FileStream fs = File.Create(fileName);

			ZipFile result = new ZipFile();
			result.name_ = fileName;
			result.baseStream_ = fs;
			result.isStreamOwner = true;
			return result;
		}
Exemplo n.º 4
0
		private void CopyEntry(ZipFile workFile, ZipUpdate update)
		{
			workFile.WriteLocalEntryHeader(update);

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

				long 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_);
		}
Exemplo n.º 5
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;
		}
Exemplo n.º 6
0
		private void CopyEntryDirect(ZipFile workFile, ZipUpdate update, ref long destinationPosition)
		{
			bool skipOver = false;
			if (update.Entry.Offset == destinationPosition)
			{
				skipOver = true;
			}

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

			long sourcePosition = 0;

			const int NameLengthOffset = 26;

			// TODO: Add base for SFX friendly handling
			long 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();

			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);
			}
		}
Exemplo n.º 7
0
		private void ModifyEntry(ZipFile workFile, ZipUpdate update)
		{
			workFile.WriteLocalEntryHeader(update);
			long dataStart = workFile.baseStream_.Position;

			// TODO: This is slow if the changes don't effect the data!!
			if (update.Entry.IsFile && (update.Filename != null))
			{
				using (Stream output = workFile.GetOutputStream(update.OutEntry))
				{
					using (Stream source = this.GetInputStream(update.Entry))
					{
						CopyBytes(update, output, source, source.Length, true);
					}
				}
			}

			long dataEnd = workFile.baseStream_.Position;
			update.Entry.CompressedSize = dataEnd - dataStart;
		}
Exemplo n.º 8
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, update.Filename);
				}
			}

			if (source != null)
			{
				using (source)
				{
					long 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);

					long dataStart = workFile.baseStream_.Position;

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

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

					if ((update.OutEntry.Flags & (int) GeneralBitFlags.Descriptor) == (int) GeneralBitFlags.Descriptor)
					{
						ZipHelperStream helper = new ZipHelperStream(workFile.baseStream_);
						helper.WriteDataDescriptor(update.OutEntry);
					}
				}
			}
			else
			{
				workFile.WriteLocalEntryHeader(update);
				update.OutEntry.CompressedSize = 0;
			}
		}
Exemplo n.º 9
0
		/// <summary>
		/// Initialise a new instance of <see cref="TestStatus"/>
		/// </summary>
		/// <param name="file">The <see cref="ZipFile"/> this status applies to.</param>
		public TestStatus(ZipFile file)
		{
			file_ = file;
		}
Exemplo n.º 10
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,
		                       Overwrite overwrite, ConfirmOverwriteDelegate confirmDelegate,
		                       string fileFilter, string directoryFilter, bool restoreDateTime)
		{
			if ((overwrite == Overwrite.Prompt) && (confirmDelegate == null))
			{
				throw new ArgumentNullException("confirmDelegate");
			}

			continueRunning_ = true;
			overwrite_ = overwrite;
			confirmDelegate_ = confirmDelegate;
			targetDirectory_ = targetDirectory;
			fileFilter_ = new NameFilter(fileFilter);
			directoryFilter_ = new NameFilter(directoryFilter);
			restoreDateTimeOnExtract_ = restoreDateTime;

			using (zipFile_ = new ZipFile(zipFileName))
			{
#if !NETCF_1_0
				if (password_ != null)
				{
					zipFile_.Password = password_;
				}
#endif

				IEnumerator enumerator = zipFile_.GetEnumerator();
				while (continueRunning_ && enumerator.MoveNext())
				{
					ZipEntry entry = (ZipEntry) enumerator.Current;
					if (entry.IsFile)
					{
						if (directoryFilter_.IsMatch(Path.GetDirectoryName(entry.Name)) && fileFilter_.IsMatch(entry.Name))
						{
							ExtractEntry(entry);
						}
					}
					else if (entry.IsDirectory)
					{
						if (directoryFilter_.IsMatch(entry.Name) && CreateEmptyDirectories)
						{
							ExtractEntry(entry);
						}
					}
					else
					{
						// Do nothing for volume labels etc...
					}
				}
			}
		}