mirror of
https://github.com/adamhathcock/sharpcompress.git
synced 2026-09-22 23:15:20 +00:00
Merge branch 'master' into dnx
This commit is contained in:
@@ -202,7 +202,7 @@ namespace SharpCompress.Test
|
||||
{
|
||||
FileInfo fi1 = new FileInfo(file1);
|
||||
FileInfo fi2 = new FileInfo(file2);
|
||||
Assert.AreEqual(fi1.LastWriteTime, fi2.LastWriteTime);
|
||||
Assert.AreNotEqual(fi1.LastWriteTime, fi2.LastWriteTime);
|
||||
Assert.AreEqual(fi1.Attributes, fi2.Attributes);
|
||||
}
|
||||
|
||||
|
||||
@@ -90,7 +90,7 @@ namespace SharpCompress.Archive
|
||||
FileInfo nf = new FileInfo(destinationFileName);
|
||||
if (nf.Exists)
|
||||
{
|
||||
if (options.HasFlag(ExtractOptions.PreserveAttributes))
|
||||
if (options.HasFlag(ExtractOptions.PreserveFileTime))
|
||||
{
|
||||
if (entry.CreatedTime.HasValue)
|
||||
{
|
||||
|
||||
@@ -116,7 +116,7 @@ namespace SharpCompress.Archive.Zip
|
||||
try
|
||||
{
|
||||
ZipHeader header =
|
||||
headerFactory.ReadStreamHeader(stream).FirstOrDefault(x => x.ZipHeaderType != ZipHeaderType.Split);
|
||||
headerFactory.ReadStreamHeader(stream).FirstOrDefault(x => x != null && x.ZipHeaderType != ZipHeaderType.Split);
|
||||
if (header == null)
|
||||
{
|
||||
return false;
|
||||
|
||||
@@ -5,26 +5,26 @@ namespace SharpCompress.Common
|
||||
[Flags]
|
||||
public enum ExtractOptions
|
||||
{
|
||||
None,
|
||||
None = 0,
|
||||
|
||||
/// <summary>
|
||||
/// overwrite target if it exists
|
||||
/// </summary>
|
||||
Overwrite,
|
||||
Overwrite = 1 << 0,
|
||||
|
||||
/// <summary>
|
||||
/// extract with internal directory structure
|
||||
/// </summary>
|
||||
ExtractFullPath,
|
||||
ExtractFullPath = 1 << 1,
|
||||
|
||||
/// <summary>
|
||||
/// preserve file time
|
||||
/// </summary>
|
||||
PreserveFileTime,
|
||||
PreserveFileTime = 1 << 2,
|
||||
|
||||
/// <summary>
|
||||
/// preserve windows file attributes
|
||||
/// </summary>
|
||||
PreserveAttributes,
|
||||
PreserveAttributes = 1 << 3,
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,7 @@ namespace SharpCompress.Common.Zip
|
||||
{
|
||||
internal class SeekableZipHeaderFactory : ZipHeaderFactory
|
||||
{
|
||||
private const int MAX_ITERATIONS_FOR_DIRECTORY_HEADER = 1000;
|
||||
private const int MAX_ITERATIONS_FOR_DIRECTORY_HEADER = 4096;
|
||||
|
||||
internal SeekableZipHeaderFactory(string password)
|
||||
: base(StreamingMode.Seekable, password)
|
||||
|
||||
@@ -45,18 +45,17 @@ namespace SharpCompress.Common.Zip
|
||||
lastEntryHeader = null;
|
||||
uint headerBytes = reader.ReadUInt32();
|
||||
header = ReadHeader(headerBytes, reader);
|
||||
|
||||
//entry could be zero bytes so we need to know that.
|
||||
if (header.ZipHeaderType == ZipHeaderType.LocalEntry)
|
||||
{
|
||||
bool isRecording = rewindableStream.IsRecording;
|
||||
if (!isRecording)
|
||||
{
|
||||
rewindableStream.StartRecording();
|
||||
if (header != null) {
|
||||
// entry could be zero bytes so we need to know that.
|
||||
if(header.ZipHeaderType == ZipHeaderType.LocalEntry) {
|
||||
bool isRecording = rewindableStream.IsRecording;
|
||||
if (!isRecording) {
|
||||
rewindableStream.StartRecording();
|
||||
}
|
||||
uint nextHeaderBytes = reader.ReadUInt32();
|
||||
header.HasData = !IsHeader(nextHeaderBytes);
|
||||
rewindableStream.Rewind(!isRecording);
|
||||
}
|
||||
uint nextHeaderBytes = reader.ReadUInt32();
|
||||
header.HasData = !IsHeader(nextHeaderBytes);
|
||||
rewindableStream.Rewind(!isRecording);
|
||||
}
|
||||
yield return header;
|
||||
}
|
||||
|
||||
@@ -87,7 +87,7 @@ namespace SharpCompress.Common.Zip
|
||||
return entry;
|
||||
}
|
||||
default:
|
||||
throw new NotSupportedException("Unknown header: " + headerBytes);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -677,10 +677,10 @@ namespace SharpCompress.Compressor.Deflate
|
||||
{
|
||||
if (bi_valid > (int) Buf_size - len)
|
||||
{
|
||||
//int val = value;
|
||||
// bi_buf |= (val << bi_valid);
|
||||
int x = (value << bi_valid) & 0xffff;
|
||||
bi_buf = (short)((int)bi_buf | x);
|
||||
|
||||
bi_buf |= (short) ((value << bi_valid) & 0xffff);
|
||||
//put_short(bi_buf);
|
||||
pending[pendingCount++] = (byte) bi_buf;
|
||||
pending[pendingCount++] = (byte) (bi_buf >> 8);
|
||||
@@ -691,8 +691,10 @@ namespace SharpCompress.Compressor.Deflate
|
||||
}
|
||||
else
|
||||
{
|
||||
// bi_buf |= (value) << bi_valid;
|
||||
bi_buf |= (short) ((value << bi_valid) & 0xffff);
|
||||
// bi_buf |= (val << bi_valid);
|
||||
int x = (value << bi_valid) & 0xffff;
|
||||
bi_buf = (short)((int)bi_buf | x);
|
||||
|
||||
bi_valid += len;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -321,6 +321,7 @@
|
||||
<Compile Include="Writer\Tar\TarWriter.cs" />
|
||||
<Compile Include="Writer\WriterFactory.cs" />
|
||||
<Compile Include="Writer\Zip\ZipCentralDirectoryEntry.cs" />
|
||||
<Compile Include="Writer\Zip\ZipCompressionInfo.cs" />
|
||||
<Compile Include="Writer\Zip\ZipWriter.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
||||
@@ -371,6 +371,7 @@
|
||||
<Compile Include="Writer\Tar\TarWriter.cs" />
|
||||
<Compile Include="Writer\WriterFactory.cs" />
|
||||
<Compile Include="Writer\Zip\ZipCentralDirectoryEntry.cs" />
|
||||
<Compile Include="Writer\Zip\ZipCompressionInfo.cs" />
|
||||
<Compile Include="Writer\Zip\ZipWriter.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
||||
@@ -359,6 +359,7 @@
|
||||
<Compile Include="Writer\Tar\TarWriter.cs" />
|
||||
<Compile Include="Writer\WriterFactory.cs" />
|
||||
<Compile Include="Writer\Zip\ZipCentralDirectoryEntry.cs" />
|
||||
<Compile Include="Writer\Zip\ZipCompressionInfo.cs" />
|
||||
<Compile Include="Writer\Zip\ZipWriter.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
||||
@@ -306,6 +306,7 @@
|
||||
<Compile Include="Writer\Tar\TarWriter.cs" />
|
||||
<Compile Include="Writer\WriterFactory.cs" />
|
||||
<Compile Include="Writer\Zip\ZipCentralDirectoryEntry.cs" />
|
||||
<Compile Include="Writer\Zip\ZipCompressionInfo.cs" />
|
||||
<Compile Include="Writer\Zip\ZipWriter.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
||||
@@ -359,6 +359,7 @@
|
||||
<Compile Include="Writer\Tar\TarWriter.cs" />
|
||||
<Compile Include="Writer\WriterFactory.cs" />
|
||||
<Compile Include="Writer\Zip\ZipCentralDirectoryEntry.cs" />
|
||||
<Compile Include="Writer\Zip\ZipCompressionInfo.cs" />
|
||||
<Compile Include="Writer\Zip\ZipWriter.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
||||
@@ -202,6 +202,10 @@ namespace SharpCompress
|
||||
public static void WriteLittleEndian(byte[] array, int pos, short value)
|
||||
{
|
||||
byte[] newBytes = BitConverter.GetBytes(value);
|
||||
|
||||
if (!BitConverter.IsLittleEndian)
|
||||
Array.Reverse(newBytes);
|
||||
|
||||
Array.Copy(newBytes, 0, array, pos, newBytes.Length);
|
||||
}
|
||||
|
||||
@@ -234,6 +238,10 @@ namespace SharpCompress
|
||||
public static void WriteLittleEndian(byte[] array, int pos, int value)
|
||||
{
|
||||
byte[] newBytes = BitConverter.GetBytes(value);
|
||||
|
||||
if (!BitConverter.IsLittleEndian)
|
||||
Array.Reverse(newBytes);
|
||||
|
||||
Array.Copy(newBytes, 0, array, pos, newBytes.Length);
|
||||
}
|
||||
|
||||
|
||||
@@ -11,5 +11,5 @@ using System.Runtime.InteropServices;
|
||||
[assembly: AssemblyCopyright("Copyright © Adam Hathcock")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
[assembly: AssemblyVersion("0.10.3.0")]
|
||||
[assembly: AssemblyFileVersion("0.10.3.0")]
|
||||
[assembly: AssemblyVersion("0.11.2.0")]
|
||||
[assembly: AssemblyFileVersion("0.11.2.0")]
|
||||
47
SharpCompress/Writer/Zip/ZipCompressionInfo.cs
Normal file
47
SharpCompress/Writer/Zip/ZipCompressionInfo.cs
Normal file
@@ -0,0 +1,47 @@
|
||||
using SharpCompress.Common;
|
||||
using SharpCompress.Common.Zip;
|
||||
using SharpCompress.Compressor.Deflate;
|
||||
|
||||
namespace SharpCompress.Writer.Zip
|
||||
{
|
||||
internal class ZipCompressionInfo
|
||||
{
|
||||
internal CompressionLevel DeflateCompressionLevel { get; private set; }
|
||||
internal ZipCompressionMethod Compression { get; private set; }
|
||||
|
||||
public ZipCompressionInfo(CompressionInfo compressionInfo)
|
||||
{
|
||||
switch (compressionInfo.Type)
|
||||
{
|
||||
case CompressionType.None:
|
||||
{
|
||||
this.Compression = ZipCompressionMethod.None;
|
||||
}
|
||||
break;
|
||||
case CompressionType.Deflate:
|
||||
{
|
||||
this.DeflateCompressionLevel = compressionInfo.DeflateCompressionLevel;
|
||||
this.Compression = ZipCompressionMethod.Deflate;
|
||||
}
|
||||
break;
|
||||
case CompressionType.BZip2:
|
||||
{
|
||||
this.Compression = ZipCompressionMethod.BZip2;
|
||||
}
|
||||
break;
|
||||
case CompressionType.LZMA:
|
||||
{
|
||||
this.Compression = ZipCompressionMethod.LZMA;
|
||||
}
|
||||
break;
|
||||
case CompressionType.PPMd:
|
||||
{
|
||||
this.Compression = ZipCompressionMethod.PPMd;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new InvalidFormatException("Invalid compression method: " + compressionInfo.Type);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -17,52 +17,18 @@ namespace SharpCompress.Writer.Zip
|
||||
{
|
||||
public class ZipWriter : AbstractWriter
|
||||
{
|
||||
private readonly ZipCompressionMethod compression;
|
||||
private readonly CompressionLevel deflateCompressionLevel;
|
||||
|
||||
private readonly ZipCompressionInfo zipCompressionInfo;
|
||||
private readonly PpmdProperties ppmdProperties = new PpmdProperties(); // Caching properties to speed up PPMd
|
||||
private readonly List<ZipCentralDirectoryEntry> entries = new List<ZipCentralDirectoryEntry>();
|
||||
private readonly string zipComment;
|
||||
private long streamPosition;
|
||||
|
||||
private readonly PpmdProperties ppmdProperties; // Caching properties to speed up PPMd.
|
||||
|
||||
public ZipWriter(Stream destination, CompressionInfo compressionInfo, string zipComment)
|
||||
: base(ArchiveType.Zip)
|
||||
{
|
||||
this.zipComment = zipComment ?? string.Empty;
|
||||
|
||||
switch (compressionInfo.Type)
|
||||
{
|
||||
case CompressionType.None:
|
||||
{
|
||||
compression = ZipCompressionMethod.None;
|
||||
}
|
||||
break;
|
||||
case CompressionType.Deflate:
|
||||
{
|
||||
compression = ZipCompressionMethod.Deflate;
|
||||
deflateCompressionLevel = compressionInfo.DeflateCompressionLevel;
|
||||
}
|
||||
break;
|
||||
case CompressionType.BZip2:
|
||||
{
|
||||
compression = ZipCompressionMethod.BZip2;
|
||||
}
|
||||
break;
|
||||
case CompressionType.LZMA:
|
||||
{
|
||||
compression = ZipCompressionMethod.LZMA;
|
||||
}
|
||||
break;
|
||||
case CompressionType.PPMd:
|
||||
{
|
||||
ppmdProperties = new PpmdProperties();
|
||||
compression = ZipCompressionMethod.PPMd;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new InvalidFormatException("Invalid compression method: " + compressionInfo.Type);
|
||||
}
|
||||
this.zipCompressionInfo = new ZipCompressionInfo(compressionInfo);
|
||||
InitalizeStream(destination, false);
|
||||
}
|
||||
|
||||
@@ -73,7 +39,7 @@ namespace SharpCompress.Writer.Zip
|
||||
uint size = 0;
|
||||
foreach (ZipCentralDirectoryEntry entry in entries)
|
||||
{
|
||||
size += entry.Write(OutputStream, compression);
|
||||
size += entry.Write(OutputStream, zipCompressionInfo.Compression);
|
||||
}
|
||||
WriteEndRecord(size);
|
||||
}
|
||||
@@ -85,15 +51,15 @@ namespace SharpCompress.Writer.Zip
|
||||
Write(entryPath, source, modificationTime, null);
|
||||
}
|
||||
|
||||
public void Write(string entryPath, Stream source, DateTime? modificationTime, string comment)
|
||||
public void Write(string entryPath, Stream source, DateTime? modificationTime, string comment, CompressionInfo compressionInfo = null)
|
||||
{
|
||||
using (Stream output = WriteToStream(entryPath, modificationTime, comment))
|
||||
using (Stream output = WriteToStream(entryPath, modificationTime, comment, compressionInfo))
|
||||
{
|
||||
source.TransferTo(output);
|
||||
}
|
||||
}
|
||||
|
||||
public Stream WriteToStream(string entryPath, DateTime? modificationTime, string comment)
|
||||
public Stream WriteToStream(string entryPath, DateTime? modificationTime, string comment, CompressionInfo compressionInfo = null)
|
||||
{
|
||||
entryPath = NormalizeFilename(entryPath);
|
||||
modificationTime = modificationTime ?? DateTime.Now;
|
||||
@@ -105,7 +71,8 @@ namespace SharpCompress.Writer.Zip
|
||||
ModificationTime = modificationTime,
|
||||
HeaderOffset = (uint) streamPosition,
|
||||
};
|
||||
var headersize = (uint) WriteHeader(entryPath, modificationTime);
|
||||
|
||||
var headersize = (uint)WriteHeader(entryPath, modificationTime, compressionInfo);
|
||||
streamPosition += headersize;
|
||||
return new ZipWritingStream(this, OutputStream, entry);
|
||||
}
|
||||
@@ -121,8 +88,9 @@ namespace SharpCompress.Writer.Zip
|
||||
return filename.Trim('/');
|
||||
}
|
||||
|
||||
private int WriteHeader(string filename, DateTime? modificationTime)
|
||||
private int WriteHeader(string filename, DateTime? modificationTime, CompressionInfo compressionInfo = null)
|
||||
{
|
||||
var explicitZipCompressionInfo = compressionInfo != null ? new ZipCompressionInfo(compressionInfo) : this.zipCompressionInfo;
|
||||
byte[] encodedFilename = ArchiveEncoding.Default.GetBytes(filename);
|
||||
|
||||
OutputStream.Write(BitConverter.GetBytes(ZipHeaderFactory.ENTRY_HEADER_BYTES), 0, 4);
|
||||
@@ -131,13 +99,13 @@ namespace SharpCompress.Writer.Zip
|
||||
if (!OutputStream.CanSeek)
|
||||
{
|
||||
flags |= HeaderFlags.UsePostDataDescriptor;
|
||||
if (compression == ZipCompressionMethod.LZMA)
|
||||
if (explicitZipCompressionInfo.Compression == ZipCompressionMethod.LZMA)
|
||||
{
|
||||
flags |= HeaderFlags.Bit1; // eos marker
|
||||
}
|
||||
}
|
||||
OutputStream.Write(BitConverter.GetBytes((ushort) flags), 0, 2);
|
||||
OutputStream.Write(BitConverter.GetBytes((ushort) compression), 0, 2); // zipping method
|
||||
OutputStream.Write(BitConverter.GetBytes((ushort)explicitZipCompressionInfo.Compression), 0, 2); // zipping method
|
||||
OutputStream.Write(BitConverter.GetBytes(modificationTime.DateTimeToDosTime()), 0, 4);
|
||||
// zipping date and time
|
||||
OutputStream.Write(new byte[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 0, 12);
|
||||
@@ -220,7 +188,7 @@ namespace SharpCompress.Writer.Zip
|
||||
{
|
||||
counting = new CountingWritableSubStream(writeStream);
|
||||
Stream output = counting;
|
||||
switch (writer.compression)
|
||||
switch (writer.zipCompressionInfo.Compression)
|
||||
{
|
||||
case ZipCompressionMethod.None:
|
||||
{
|
||||
@@ -228,7 +196,7 @@ namespace SharpCompress.Writer.Zip
|
||||
}
|
||||
case ZipCompressionMethod.Deflate:
|
||||
{
|
||||
return new DeflateStream(counting, CompressionMode.Compress, writer.deflateCompressionLevel,
|
||||
return new DeflateStream(counting, CompressionMode.Compress, writer.zipCompressionInfo.DeflateCompressionLevel,
|
||||
true);
|
||||
}
|
||||
case ZipCompressionMethod.BZip2:
|
||||
@@ -254,7 +222,7 @@ namespace SharpCompress.Writer.Zip
|
||||
}
|
||||
default:
|
||||
{
|
||||
throw new NotSupportedException("CompressionMethod: " + writer.compression);
|
||||
throw new NotSupportedException("CompressionMethod: " + writer.zipCompressionInfo.Compression);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user