Made ArchiveEncoding a non-static class that is used with options. (#274)

* Made ArchiveEncoding a non-static class that is used with options.

* Revert some formatting.

* Optional string decoder delegate (#278)
This commit is contained in:
Adam Hathcock
2017-07-17 10:53:20 -04:00
committed by GitHub
parent 231258ef69
commit 310d56fc16
40 changed files with 282 additions and 242 deletions

View File

@@ -181,7 +181,7 @@ namespace SharpCompress.Archives.GZip
protected override IEnumerable<GZipArchiveEntry> LoadEntries(IEnumerable<GZipVolume> volumes)
{
Stream stream = volumes.Single().Stream;
yield return new GZipArchiveEntry(this, new GZipFilePart(stream, ReaderOptions.ForceEncoding));
yield return new GZipArchiveEntry(this, new GZipFilePart(stream, ReaderOptions.ArchiveEncoding));
}
protected override IReader CreateReaderForSolidExtraction()

View File

@@ -106,7 +106,7 @@ namespace SharpCompress.Archives.SevenZip
for (int i = 0; i < database.Files.Count; i++)
{
var file = database.Files[i];
yield return new SevenZipArchiveEntry(this, new SevenZipFilePart(stream, database, i, file));
yield return new SevenZipArchiveEntry(this, new SevenZipFilePart(stream, database, i, file, ReaderOptions.ArchiveEncoding));
}
}

View File

@@ -75,7 +75,7 @@ namespace SharpCompress.Archives.Tar
{
try
{
TarHeader tar = new TarHeader();
TarHeader tar = new TarHeader(new ArchiveEncoding());
tar.Read(new BinaryReader(stream));
return tar.Name.Length > 0 && Enum.IsDefined(typeof(EntryType), tar.EntryType);
}
@@ -127,7 +127,7 @@ namespace SharpCompress.Archives.Tar
{
Stream stream = volumes.Single().Stream;
TarHeader previousHeader = null;
foreach (TarHeader header in TarHeaderFactory.ReadHeader(StreamingMode.Seekable, stream, ReaderOptions.ForceEncoding))
foreach (TarHeader header in TarHeaderFactory.ReadHeader(StreamingMode.Seekable, stream, ReaderOptions.ArchiveEncoding))
{
if (header != null)
{
@@ -152,7 +152,7 @@ namespace SharpCompress.Archives.Tar
memoryStream.Position = 0;
var bytes = memoryStream.ToArray();
header.Name = (ReaderOptions.ForceEncoding ?? ArchiveEncoding.Default).GetString(bytes, 0, bytes.Length).TrimNulls();
header.Name = ReaderOptions.ArchiveEncoding.Decode(bytes).TrimNulls();
}
}

View File

@@ -81,7 +81,7 @@ namespace SharpCompress.Archives.Zip
public static bool IsZipFile(Stream stream, string password = null)
{
StreamingZipHeaderFactory headerFactory = new StreamingZipHeaderFactory(password);
StreamingZipHeaderFactory headerFactory = new StreamingZipHeaderFactory(password, new ArchiveEncoding());
try
{
ZipHeader header =
@@ -112,7 +112,7 @@ namespace SharpCompress.Archives.Zip
internal ZipArchive(FileInfo fileInfo, ReaderOptions readerOptions)
: base(ArchiveType.Zip, fileInfo, readerOptions)
{
headerFactory = new SeekableZipHeaderFactory(readerOptions.Password, readerOptions.ForceEncoding);
headerFactory = new SeekableZipHeaderFactory(readerOptions.Password, readerOptions.ArchiveEncoding);
}
protected override IEnumerable<ZipVolume> LoadVolumes(FileInfo file)
@@ -134,7 +134,7 @@ namespace SharpCompress.Archives.Zip
internal ZipArchive(Stream stream, ReaderOptions readerOptions)
: base(ArchiveType.Zip, stream, readerOptions)
{
headerFactory = new SeekableZipHeaderFactory(readerOptions.Password, readerOptions.ForceEncoding);
headerFactory = new SeekableZipHeaderFactory(readerOptions.Password, readerOptions.ArchiveEncoding);
}
protected override IEnumerable<ZipVolume> LoadVolumes(IEnumerable<Stream> streams)
@@ -163,7 +163,7 @@ namespace SharpCompress.Archives.Zip
case ZipHeaderType.DirectoryEnd:
{
byte[] bytes = (h as DirectoryEndHeader).Comment;
volume.Comment = (ReaderOptions.ForceEncoding ?? ArchiveEncoding.Default).GetString(bytes, 0, bytes.Length);
volume.Comment = ReaderOptions.ArchiveEncoding.Decode(bytes);
yield break;
}
}

View File

@@ -1,23 +1,60 @@
using System.Text;
using System;
using System.Text;
namespace SharpCompress.Common
{
public static class ArchiveEncoding
public class ArchiveEncoding
{
/// <summary>
/// Default encoding to use when archive format doesn't specify one.
/// </summary>
public static Encoding Default { get; set; }
public Encoding Default { get; set; }
/// <summary>
/// Encoding used by encryption schemes which don't comply with RFC 2898.
/// ArchiveEncoding used by encryption schemes which don't comply with RFC 2898.
/// </summary>
public static Encoding Password { get; set; }
public Encoding Password { get; set; }
static ArchiveEncoding()
/// <summary>
/// Set this encoding when you want to force it for all encoding operations.
/// </summary>
public Encoding Forced { get; set; }
/// <summary>
/// Set this when you want to use a custom method for all decoding operations.
/// </summary>
/// <returns>string Func(bytes, index, length)</returns>
public Func<byte[], int, int, string> CustomDecoder { get; set; }
public ArchiveEncoding()
{
Default = Encoding.UTF8;
Password = Encoding.UTF8;
}
public string Decode(byte[] bytes)
{
return Decode(bytes, 0, bytes.Length);
}
public string Decode(byte[] bytes, int start, int length)
{
return GetDecoder().Invoke(bytes, start, length);
}
public byte[] Encode(string str)
{
return GetEncoding().GetBytes(str);
}
public Encoding GetEncoding()
{
return Forced ?? Default ?? Encoding.UTF8;
}
public Func<byte[], int, int, string> GetDecoder()
{
return CustomDecoder ?? ((bytes, index, count) => (Default ?? Encoding.UTF8).GetString(bytes, index, count));
}
}
}

View File

@@ -4,6 +4,13 @@ namespace SharpCompress.Common
{
public abstract class FilePart
{
protected FilePart(ArchiveEncoding archiveEncoding)
{
ArchiveEncoding = archiveEncoding;
}
internal ArchiveEncoding ArchiveEncoding { get; }
internal abstract string FilePartName { get; }
internal abstract Stream GetCompressedStream();

View File

@@ -40,9 +40,9 @@ namespace SharpCompress.Common.GZip
internal override IEnumerable<FilePart> Parts => filePart.AsEnumerable<FilePart>();
internal static IEnumerable<GZipEntry> GetEntries(Stream stream, Encoding forceEncoding)
internal static IEnumerable<GZipEntry> GetEntries(Stream stream, OptionsBase options)
{
yield return new GZipEntry(new GZipFilePart(stream, forceEncoding));
yield return new GZipEntry(new GZipFilePart(stream, options.ArchiveEncoding));
}
}
}

View File

@@ -11,32 +11,31 @@ namespace SharpCompress.Common.GZip
{
internal class GZipFilePart : FilePart
{
private string name;
private readonly Stream stream;
private readonly Encoding forceEncoding;
private string _name;
private readonly Stream _stream;
internal GZipFilePart(Stream stream, Encoding forceEncoding)
internal GZipFilePart(Stream stream, ArchiveEncoding archiveEncoding)
: base(archiveEncoding)
{
ReadAndValidateGzipHeader(stream);
EntryStartPosition = stream.Position;
this.stream = stream;
this.forceEncoding = forceEncoding;
this._stream = stream;
}
internal long EntryStartPosition { get; }
internal DateTime? DateModified { get; private set; }
internal override string FilePartName => name;
internal override string FilePartName => _name;
internal override Stream GetCompressedStream()
{
return new DeflateStream(stream, CompressionMode.Decompress, CompressionLevel.Default, false);
return new DeflateStream(_stream, CompressionMode.Decompress, CompressionLevel.Default, false);
}
internal override Stream GetRawStream()
{
return stream;
return _stream;
}
private void ReadAndValidateGzipHeader(Stream stream)
@@ -78,11 +77,11 @@ namespace SharpCompress.Common.GZip
}
if ((header[3] & 0x08) == 0x08)
{
name = ReadZeroTerminatedString(stream, forceEncoding);
_name = ReadZeroTerminatedString(stream);
}
if ((header[3] & 0x10) == 0x010)
{
ReadZeroTerminatedString(stream, forceEncoding);
ReadZeroTerminatedString(stream);
}
if ((header[3] & 0x02) == 0x02)
{
@@ -90,7 +89,7 @@ namespace SharpCompress.Common.GZip
}
}
private static string ReadZeroTerminatedString(Stream stream, Encoding forceEncoding)
private string ReadZeroTerminatedString(Stream stream)
{
byte[] buf1 = new byte[1];
var list = new List<byte>();
@@ -114,7 +113,7 @@ namespace SharpCompress.Common.GZip
}
while (!done);
byte[] buffer = list.ToArray();
return (forceEncoding ?? ArchiveEncoding.Default).GetString(buffer, 0, buffer.Length);
return ArchiveEncoding.Decode(buffer);
}
}
}

View File

@@ -1,5 +1,4 @@
using System.Text;
namespace SharpCompress.Common
{
public class OptionsBase
@@ -9,6 +8,6 @@ namespace SharpCompress.Common
/// </summary>
public bool LeaveStreamOpen { get; set; } = true;
public Encoding ForceEncoding { get; set; }
public ArchiveEncoding ArchiveEncoding { get; set; } = new ArchiveEncoding();
}
}

View File

@@ -68,12 +68,12 @@ namespace SharpCompress.Common.Rar.Headers
}
else
{
FileName = DecodeString(fileNameBytes);
FileName = ArchiveEncoding.Decode(fileNameBytes);
}
}
else
{
FileName = DecodeString(fileNameBytes);
FileName = ArchiveEncoding.Decode(fileNameBytes);
}
FileName = ConvertPath(FileName, HostOS);
}
@@ -118,12 +118,6 @@ namespace SharpCompress.Common.Rar.Headers
}
}
//only the full .net framework will do other code pages than unicode/utf8
private string DecodeString(byte[] bytes)
{
return (ForceEncoding ?? ArchiveEncoding.Default).GetString(bytes, 0, bytes.Length);
}
private long UInt32To64(uint x, uint y)
{
long l = x;

View File

@@ -18,14 +18,16 @@ namespace SharpCompress.Common.Rar.Headers
HeaderSize = baseHeader.HeaderSize;
AdditionalSize = baseHeader.AdditionalSize;
ReadBytes = baseHeader.ReadBytes;
ArchiveEncoding = baseHeader.ArchiveEncoding;
}
internal static RarHeader Create(RarCrcBinaryReader reader)
internal static RarHeader Create(RarCrcBinaryReader reader, ArchiveEncoding archiveEncoding)
{
try
{
RarHeader header = new RarHeader();
header.ArchiveEncoding = archiveEncoding;
reader.Mark();
header.ReadStartFromReader(reader);
header.ReadBytes += reader.CurrentReadByteCount;
@@ -109,7 +111,7 @@ namespace SharpCompress.Common.Rar.Headers
protected short HeaderSize { get; private set; }
internal Encoding ForceEncoding { get; set; }
internal ArchiveEncoding ArchiveEncoding { get; private set; }
/// <summary>
/// This additional size of the header could be file data

View File

@@ -30,8 +30,6 @@ namespace SharpCompress.Common.Rar.Headers
RarHeader header;
while ((header = ReadNextHeader(stream)) != null)
{
header.ForceEncoding = Options.ForceEncoding;
yield return header;
if (header.HeaderType == HeaderType.EndArchiveHeader)
{
@@ -135,7 +133,7 @@ namespace SharpCompress.Common.Rar.Headers
#endif
RarHeader header = RarHeader.Create(reader);
RarHeader header = RarHeader.Create(reader, Options.ArchiveEncoding);
if (header == null)
{
return null;

View File

@@ -9,6 +9,7 @@ namespace SharpCompress.Common.Rar
internal abstract class RarFilePart : FilePart
{
internal RarFilePart(MarkHeader mh, FileHeader fh)
: base(fh.ArchiveEncoding)
{
MarkHeader = mh;
FileHeader = fh;

View File

@@ -7,14 +7,15 @@ namespace SharpCompress.Common.SevenZip
{
internal class SevenZipFilePart : FilePart
{
private CompressionType? type;
private readonly Stream stream;
private readonly ArchiveDatabase database;
private CompressionType? _type;
private readonly Stream _stream;
private readonly ArchiveDatabase _database;
internal SevenZipFilePart(Stream stream, ArchiveDatabase database, int index, CFileItem fileEntry)
internal SevenZipFilePart(Stream stream, ArchiveDatabase database, int index, CFileItem fileEntry, ArchiveEncoding archiveEncoding)
: base(archiveEncoding)
{
this.stream = stream;
this.database = database;
this._stream = stream;
this._database = database;
Index = index;
Header = fileEntry;
if (Header.HasStream)
@@ -41,14 +42,14 @@ namespace SharpCompress.Common.SevenZip
{
return null;
}
var folderStream = database.GetFolderStream(stream, Folder, null);
var folderStream = _database.GetFolderStream(_stream, Folder, null);
int firstFileIndex = database.FolderStartFileIndex[database.Folders.IndexOf(Folder)];
int firstFileIndex = _database.FolderStartFileIndex[_database.Folders.IndexOf(Folder)];
int skipCount = Index - firstFileIndex;
long skipSize = 0;
for (int i = 0; i < skipCount; i++)
{
skipSize += database.Files[firstFileIndex + i].Size;
skipSize += _database.Files[firstFileIndex + i].Size;
}
if (skipSize > 0)
{
@@ -61,11 +62,11 @@ namespace SharpCompress.Common.SevenZip
{
get
{
if (type == null)
if (_type == null)
{
type = GetCompression();
_type = GetCompression();
}
return type.Value;
return _type.Value;
}
}
@@ -84,7 +85,7 @@ namespace SharpCompress.Common.SevenZip
{
var coder = Folder.Coders.First();
switch (coder.MethodId.Id)
{
{
case k_LZMA:
case k_LZMA2:
{

View File

@@ -9,6 +9,11 @@ namespace SharpCompress.Common.Tar.Headers
{
internal static readonly DateTime Epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
public TarHeader(ArchiveEncoding archiveEncoding)
{
ArchiveEncoding = archiveEncoding;
}
internal string Name { get; set; }
//internal int Mode { get; set; }
@@ -20,7 +25,7 @@ namespace SharpCompress.Common.Tar.Headers
internal DateTime LastModifiedTime { get; set; }
internal EntryType EntryType { get; set; }
internal Stream PackedStream { get; set; }
internal Encoding ForceEncoding { get; set; }
internal ArchiveEncoding ArchiveEncoding { get; }
internal const int BlockSize = 512;
@@ -32,7 +37,7 @@ namespace SharpCompress.Common.Tar.Headers
WriteOctalBytes(0, buffer, 108, 8); // owner ID
WriteOctalBytes(0, buffer, 116, 8); // group ID
//Encoding.UTF8.GetBytes("magic").CopyTo(buffer, 257);
//ArchiveEncoding.UTF8.GetBytes("magic").CopyTo(buffer, 257);
if (Name.Length > 100)
{
// Set mock filename and filetype to indicate the next block is the actual name of the file
@@ -73,7 +78,7 @@ namespace SharpCompress.Common.Tar.Headers
private void WriteLongFilenameHeader(Stream output)
{
byte[] nameBytes = (ForceEncoding ?? ArchiveEncoding.Default).GetBytes(Name);
byte[] nameBytes = ArchiveEncoding.Encode(Name);
output.Write(nameBytes, 0, nameBytes.Length);
// pad to multiple of BlockSize bytes, and make sure a terminating null is added
@@ -100,7 +105,7 @@ namespace SharpCompress.Common.Tar.Headers
}
else
{
Name = (ForceEncoding ?? ArchiveEncoding.Default).GetString(buffer, 0, 100).TrimNulls();
Name = ArchiveEncoding.Decode(buffer, 0, 100).TrimNulls();
}
EntryType = ReadEntryType(buffer);
@@ -112,12 +117,12 @@ namespace SharpCompress.Common.Tar.Headers
long unixTimeStamp = ReadASCIIInt64Base8(buffer, 136, 11);
LastModifiedTime = Epoch.AddSeconds(unixTimeStamp).ToLocalTime();
Magic = (ForceEncoding ?? ArchiveEncoding.Default).GetString(buffer, 257, 6).TrimNulls();
Magic = ArchiveEncoding.Decode(buffer, 257, 6).TrimNulls();
if (!string.IsNullOrEmpty(Magic)
&& "ustar".Equals(Magic))
{
string namePrefix = (ForceEncoding ?? ArchiveEncoding.Default).GetString(buffer, 345, 157);
string namePrefix = ArchiveEncoding.Decode(buffer, 345, 157);
namePrefix = namePrefix.TrimNulls();
if (!string.IsNullOrEmpty(namePrefix))
{
@@ -144,7 +149,7 @@ namespace SharpCompress.Common.Tar.Headers
{
reader.ReadBytes(remainingBytesToRead);
}
return (ForceEncoding ?? ArchiveEncoding.Default).GetString(nameBytes, 0, nameBytes.Length).TrimNulls();
return ArchiveEncoding.Decode(nameBytes, 0, nameBytes.Length).TrimNulls();
}
private static EntryType ReadEntryType(byte[] buffer)

View File

@@ -44,9 +44,9 @@ namespace SharpCompress.Common.Tar
internal override IEnumerable<FilePart> Parts => filePart.AsEnumerable<FilePart>();
internal static IEnumerable<TarEntry> GetEntries(StreamingMode mode, Stream stream,
CompressionType compressionType, Encoding forceEncoding)
CompressionType compressionType, ArchiveEncoding archiveEncoding)
{
foreach (TarHeader h in TarHeaderFactory.ReadHeader(mode, stream, forceEncoding))
foreach (TarHeader h in TarHeaderFactory.ReadHeader(mode, stream, archiveEncoding))
{
if (h != null)
{

View File

@@ -6,11 +6,12 @@ namespace SharpCompress.Common.Tar
{
internal class TarFilePart : FilePart
{
private readonly Stream seekableStream;
private readonly Stream _seekableStream;
internal TarFilePart(TarHeader header, Stream seekableStream)
: base(header.ArchiveEncoding)
{
this.seekableStream = seekableStream;
this._seekableStream = seekableStream;
Header = header;
}
@@ -20,10 +21,10 @@ namespace SharpCompress.Common.Tar
internal override Stream GetCompressedStream()
{
if (seekableStream != null)
if (_seekableStream != null)
{
seekableStream.Position = Header.DataStartPosition.Value;
return new ReadOnlySubStream(seekableStream, Header.Size);
_seekableStream.Position = Header.DataStartPosition.Value;
return new ReadOnlySubStream(_seekableStream, Header.Size);
}
return Header.PackedStream;
}

View File

@@ -8,7 +8,7 @@ namespace SharpCompress.Common.Tar
{
internal static class TarHeaderFactory
{
internal static IEnumerable<TarHeader> ReadHeader(StreamingMode mode, Stream stream, Encoding forceEncoding)
internal static IEnumerable<TarHeader> ReadHeader(StreamingMode mode, Stream stream, ArchiveEncoding archiveEncoding)
{
while (true)
{
@@ -16,10 +16,7 @@ namespace SharpCompress.Common.Tar
try
{
BinaryReader reader = new BinaryReader(stream);
header = new TarHeader()
{
ForceEncoding = forceEncoding
};
header = new TarHeader(archiveEncoding);
if (!header.Read(reader))
{

View File

@@ -6,8 +6,8 @@ namespace SharpCompress.Common.Zip.Headers
{
internal class DirectoryEntryHeader : ZipFileEntry
{
public DirectoryEntryHeader()
: base(ZipHeaderType.DirectoryEntry)
public DirectoryEntryHeader(ArchiveEncoding archiveEncoding)
: base(ZipHeaderType.DirectoryEntry, archiveEncoding)
{
}
@@ -31,10 +31,10 @@ namespace SharpCompress.Common.Zip.Headers
RelativeOffsetOfEntryHeader = reader.ReadUInt32();
byte[] name = reader.ReadBytes(nameLength);
Name = DecodeString(name);
Name = ArchiveEncoding.Decode(name);
byte[] extra = reader.ReadBytes(extraLength);
byte[] comment = reader.ReadBytes(commentLength);
Comment = DecodeString(comment);
Comment = ArchiveEncoding.Decode(comment);
LoadExtra(extra);
var unicodePathExtra = Extra.FirstOrDefault(u => u.Type == ExtraDataType.UnicodePathExtraField);

View File

@@ -6,8 +6,8 @@ namespace SharpCompress.Common.Zip.Headers
{
internal class LocalEntryHeader : ZipFileEntry
{
public LocalEntryHeader()
: base(ZipHeaderType.LocalEntry)
public LocalEntryHeader(ArchiveEncoding archiveEncoding)
: base(ZipHeaderType.LocalEntry, archiveEncoding)
{
}
@@ -25,7 +25,7 @@ namespace SharpCompress.Common.Zip.Headers
ushort extraLength = reader.ReadUInt16();
byte[] name = reader.ReadBytes(nameLength);
byte[] extra = reader.ReadBytes(extraLength);
Name = DecodeString(name);
Name = ArchiveEncoding.Decode(name);
LoadExtra(extra);
var unicodePathExtra = Extra.FirstOrDefault(u => u.Type == ExtraDataType.UnicodePathExtraField);

View File

@@ -8,10 +8,11 @@ namespace SharpCompress.Common.Zip.Headers
{
internal abstract class ZipFileEntry : ZipHeader
{
protected ZipFileEntry(ZipHeaderType type)
protected ZipFileEntry(ZipHeaderType type, ArchiveEncoding archiveEncoding)
: base(type)
{
Extra = new List<ExtraData>();
ArchiveEncoding = archiveEncoding;
}
internal bool IsDirectory
@@ -29,40 +30,10 @@ namespace SharpCompress.Common.Zip.Headers
&& Name.EndsWith("\\");
}
}
protected string DecodeString(byte[] str)
{
if (ForceEncoding != null)
{
return ForceEncoding.GetString(str, 0, str.Length);
}
if (FlagUtility.HasFlag(Flags, HeaderFlags.UTF8))
{
return Encoding.UTF8.GetString(str, 0, str.Length);
}
return ArchiveEncoding.Default.GetString(str, 0, str.Length);
}
protected byte[] EncodeString(string str)
{
if (ForceEncoding != null)
{
return ForceEncoding.GetBytes(str);
}
if (FlagUtility.HasFlag(Flags, HeaderFlags.UTF8))
{
return Encoding.UTF8.GetBytes(str);
}
return ArchiveEncoding.Default.GetBytes(str);
}
internal Stream PackedStream { get; set; }
internal Encoding ForceEncoding { get; set; }
internal ArchiveEncoding ArchiveEncoding { get; }
internal string Name { get; set; }

View File

@@ -9,9 +9,11 @@ namespace SharpCompress.Common.Zip
{
private static readonly CRC32 crc32 = new CRC32();
private readonly UInt32[] _Keys = {0x12345678, 0x23456789, 0x34567890};
private readonly ArchiveEncoding _archiveEncoding;
private PkwareTraditionalEncryptionData(string password)
private PkwareTraditionalEncryptionData(string password, ArchiveEncoding archiveEncoding)
{
_archiveEncoding = archiveEncoding;
Initialize(password);
}
@@ -27,7 +29,7 @@ namespace SharpCompress.Common.Zip
public static PkwareTraditionalEncryptionData ForRead(string password, ZipFileEntry header,
byte[] encryptionHeader)
{
var encryptor = new PkwareTraditionalEncryptionData(password);
var encryptor = new PkwareTraditionalEncryptionData(password, header.ArchiveEncoding);
byte[] plainTextHeader = encryptor.Decrypt(encryptionHeader, encryptionHeader.Length);
if (plainTextHeader[11] != (byte)((header.Crc >> 24) & 0xff))
{
@@ -93,17 +95,12 @@ namespace SharpCompress.Common.Zip
}
}
internal static byte[] StringToByteArray(string value, Encoding encoding)
internal byte[] StringToByteArray(string value)
{
byte[] a = encoding.GetBytes(value);
byte[] a = _archiveEncoding.Password.GetBytes(value);
return a;
}
internal static byte[] StringToByteArray(string value)
{
return StringToByteArray(value, ArchiveEncoding.Password);
}
private void UpdateKeys(byte byteValue)
{
_Keys[0] = (UInt32)crc32.ComputeCrc32((int)_Keys[0], byteValue);

View File

@@ -5,21 +5,21 @@ namespace SharpCompress.Common.Zip
{
internal class SeekableZipFilePart : ZipFilePart
{
private bool isLocalHeaderLoaded;
private readonly SeekableZipHeaderFactory headerFactory;
private bool _isLocalHeaderLoaded;
private readonly SeekableZipHeaderFactory _headerFactory;
internal SeekableZipFilePart(SeekableZipHeaderFactory headerFactory, DirectoryEntryHeader header, Stream stream)
: base(header, stream)
{
this.headerFactory = headerFactory;
this._headerFactory = headerFactory;
}
internal override Stream GetCompressedStream()
{
if (!isLocalHeaderLoaded)
if (!_isLocalHeaderLoaded)
{
LoadLocalHeader();
isLocalHeaderLoaded = true;
_isLocalHeaderLoaded = true;
}
return base.GetCompressedStream();
}
@@ -29,7 +29,7 @@ namespace SharpCompress.Common.Zip
private void LoadLocalHeader()
{
bool hasData = Header.HasData;
Header = headerFactory.GetLocalHeader(BaseStream, Header as DirectoryEntryHeader);
Header = _headerFactory.GetLocalHeader(BaseStream, Header as DirectoryEntryHeader);
Header.HasData = hasData;
}

View File

@@ -10,10 +10,10 @@ namespace SharpCompress.Common.Zip
internal class SeekableZipHeaderFactory : ZipHeaderFactory
{
private const int MAX_ITERATIONS_FOR_DIRECTORY_HEADER = 4096;
private bool zip64;
private bool _zip64;
internal SeekableZipHeaderFactory(string password, Encoding forceEncoding)
: base(StreamingMode.Seekable, password, forceEncoding)
internal SeekableZipHeaderFactory(string password, ArchiveEncoding archiveEncoding)
: base(StreamingMode.Seekable, password, archiveEncoding)
{
}
@@ -27,7 +27,7 @@ namespace SharpCompress.Common.Zip
if (entry.IsZip64)
{
zip64 = true;
_zip64 = true;
SeekBackToHeader(stream, reader, ZIP64_END_OF_CENTRAL_DIRECTORY_LOCATOR);
var zip64Locator = new Zip64DirectoryEndLocatorHeader();
zip64Locator.Read(reader);
@@ -51,7 +51,7 @@ namespace SharpCompress.Common.Zip
{
stream.Position = position;
uint signature = reader.ReadUInt32();
var directoryEntryHeader = ReadHeader(signature, reader, zip64) as DirectoryEntryHeader;
var directoryEntryHeader = ReadHeader(signature, reader, _zip64) as DirectoryEntryHeader;
position = stream.Position;
if (directoryEntryHeader == null)
{
@@ -92,7 +92,7 @@ namespace SharpCompress.Common.Zip
stream.Seek(directoryEntryHeader.RelativeOffsetOfEntryHeader, SeekOrigin.Begin);
BinaryReader reader = new BinaryReader(stream);
uint signature = reader.ReadUInt32();
var localEntryHeader = ReadHeader(signature, reader, zip64) as LocalEntryHeader;
var localEntryHeader = ReadHeader(signature, reader, _zip64) as LocalEntryHeader;
if (localEntryHeader == null)
{
throw new InvalidOperationException();

View File

@@ -8,8 +8,8 @@ namespace SharpCompress.Common.Zip
{
internal class StreamingZipHeaderFactory : ZipHeaderFactory
{
internal StreamingZipHeaderFactory(string password, Encoding forceEncoding = null)
: base(StreamingMode.Streaming, password, forceEncoding)
internal StreamingZipHeaderFactory(string password, ArchiveEncoding archiveEncoding)
: base(StreamingMode.Streaming, password, archiveEncoding)
{
}

View File

@@ -15,6 +15,7 @@ namespace SharpCompress.Common.Zip
internal abstract class ZipFilePart : FilePart
{
internal ZipFilePart(ZipFileEntry header, Stream stream)
: base(header.ArchiveEncoding)
{
Header = header;
header.Part = this;

View File

@@ -24,13 +24,13 @@ namespace SharpCompress.Common.Zip
protected LocalEntryHeader lastEntryHeader;
private readonly string password;
private readonly StreamingMode mode;
private readonly Encoding forceEncoding;
private readonly ArchiveEncoding archiveEncoding;
protected ZipHeaderFactory(StreamingMode mode, string password, Encoding forceEncoding)
protected ZipHeaderFactory(StreamingMode mode, string password, ArchiveEncoding archiveEncoding)
{
this.mode = mode;
this.password = password;
this.forceEncoding = forceEncoding;
this.archiveEncoding = archiveEncoding;
}
protected ZipHeader ReadHeader(uint headerBytes, BinaryReader reader, bool zip64 = false)
@@ -38,26 +38,20 @@ namespace SharpCompress.Common.Zip
switch (headerBytes)
{
case ENTRY_HEADER_BYTES:
{
var entryHeader = new LocalEntryHeader()
{
ForceEncoding = forceEncoding
};
entryHeader.Read(reader);
LoadHeader(entryHeader, reader.BaseStream);
{
var entryHeader = new LocalEntryHeader(archiveEncoding);
entryHeader.Read(reader);
LoadHeader(entryHeader, reader.BaseStream);
lastEntryHeader = entryHeader;
return entryHeader;
}
lastEntryHeader = entryHeader;
return entryHeader;
}
case DIRECTORY_START_HEADER_BYTES:
{
var entry = new DirectoryEntryHeader()
{
ForceEncoding = forceEncoding
};
entry.Read(reader);
return entry;
}
{
var entry = new DirectoryEntryHeader(archiveEncoding);
entry.Read(reader);
return entry;
}
case POST_DATA_DESCRIPTOR:
{
if (FlagUtility.HasFlag(lastEntryHeader.Flags, HeaderFlags.UsePostDataDescriptor))

View File

@@ -36,39 +36,39 @@ namespace SharpCompress.Compressors.Deflate
{
public class GZipStream : Stream
{
internal static readonly DateTime UnixEpoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
internal static readonly DateTime UNIX_EPOCH = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
public DateTime? LastModified { get; set; }
private string comment;
private string fileName;
private string _comment;
private string _fileName;
internal ZlibBaseStream BaseStream;
private bool disposed;
private bool firstReadDone;
private int headerByteCount;
private bool _disposed;
private bool _firstReadDone;
private int _headerByteCount;
private readonly Encoding forceEncoding;
private readonly Encoding _encoding;
public GZipStream(Stream stream, CompressionMode mode)
: this(stream, mode, CompressionLevel.Default, false)
: this(stream, mode, CompressionLevel.Default, false, Encoding.UTF8)
{
}
public GZipStream(Stream stream, CompressionMode mode, CompressionLevel level)
: this(stream, mode, level, false)
: this(stream, mode, level, false, Encoding.UTF8)
{
}
public GZipStream(Stream stream, CompressionMode mode, bool leaveOpen)
: this(stream, mode, CompressionLevel.Default, leaveOpen)
: this(stream, mode, CompressionLevel.Default, leaveOpen, Encoding.UTF8)
{
}
public GZipStream(Stream stream, CompressionMode mode, CompressionLevel level, bool leaveOpen, Encoding forceEncoding = null)
public GZipStream(Stream stream, CompressionMode mode, CompressionLevel level, bool leaveOpen, Encoding encoding)
{
BaseStream = new ZlibBaseStream(stream, mode, level, ZlibStreamFlavor.GZIP, leaveOpen, forceEncoding);
this.forceEncoding = forceEncoding;
BaseStream = new ZlibBaseStream(stream, mode, level, ZlibStreamFlavor.GZIP, leaveOpen, encoding);
_encoding = encoding;
}
#region Zlib properties
@@ -78,7 +78,7 @@ namespace SharpCompress.Compressors.Deflate
get => (BaseStream._flushMode);
set
{
if (disposed)
if (_disposed)
{
throw new ObjectDisposedException("GZipStream");
}
@@ -91,7 +91,7 @@ namespace SharpCompress.Compressors.Deflate
get => BaseStream._bufferSize;
set
{
if (disposed)
if (_disposed)
{
throw new ObjectDisposedException("GZipStream");
}
@@ -127,7 +127,7 @@ namespace SharpCompress.Compressors.Deflate
{
get
{
if (disposed)
if (_disposed)
{
throw new ObjectDisposedException("GZipStream");
}
@@ -153,7 +153,7 @@ namespace SharpCompress.Compressors.Deflate
{
get
{
if (disposed)
if (_disposed)
{
throw new ObjectDisposedException("GZipStream");
}
@@ -183,7 +183,7 @@ namespace SharpCompress.Compressors.Deflate
{
if (BaseStream._streamMode == ZlibBaseStream.StreamMode.Writer)
{
return BaseStream._z.TotalBytesOut + headerByteCount;
return BaseStream._z.TotalBytesOut + _headerByteCount;
}
if (BaseStream._streamMode == ZlibBaseStream.StreamMode.Reader)
{
@@ -206,14 +206,14 @@ namespace SharpCompress.Compressors.Deflate
{
try
{
if (!disposed)
if (!_disposed)
{
if (disposing && (BaseStream != null))
{
BaseStream.Dispose();
Crc32 = BaseStream.Crc32;
}
disposed = true;
_disposed = true;
}
}
finally
@@ -227,7 +227,7 @@ namespace SharpCompress.Compressors.Deflate
/// </summary>
public override void Flush()
{
if (disposed)
if (_disposed)
{
throw new ObjectDisposedException("GZipStream");
}
@@ -267,7 +267,7 @@ namespace SharpCompress.Compressors.Deflate
/// <returns>the number of bytes actually read</returns>
public override int Read(byte[] buffer, int offset, int count)
{
if (disposed)
if (_disposed)
{
throw new ObjectDisposedException("GZipStream");
}
@@ -276,9 +276,9 @@ namespace SharpCompress.Compressors.Deflate
// Console.WriteLine("GZipStream::Read(buffer, off({0}), c({1}) = {2}", offset, count, n);
// Console.WriteLine( Util.FormatByteArray(buffer, offset, n) );
if (!firstReadDone)
if (!_firstReadDone)
{
firstReadDone = true;
_firstReadDone = true;
FileName = BaseStream._GzipFileName;
Comment = BaseStream._GzipComment;
}
@@ -329,7 +329,7 @@ namespace SharpCompress.Compressors.Deflate
/// <param name="count">the number of bytes to write.</param>
public override void Write(byte[] buffer, int offset, int count)
{
if (disposed)
if (_disposed)
{
throw new ObjectDisposedException("GZipStream");
}
@@ -339,7 +339,7 @@ namespace SharpCompress.Compressors.Deflate
if (BaseStream._wantCompress)
{
// first write in compression, therefore, emit the GZIP header
headerByteCount = EmitHeader();
_headerByteCount = EmitHeader();
}
else
{
@@ -354,52 +354,52 @@ namespace SharpCompress.Compressors.Deflate
public String Comment
{
get => comment;
get => _comment;
set
{
if (disposed)
if (_disposed)
{
throw new ObjectDisposedException("GZipStream");
}
comment = value;
_comment = value;
}
}
public string FileName
{
get => fileName;
get => _fileName;
set
{
if (disposed)
if (_disposed)
{
throw new ObjectDisposedException("GZipStream");
}
fileName = value;
if (fileName == null)
_fileName = value;
if (_fileName == null)
{
return;
}
if (fileName.IndexOf("/") != -1)
if (_fileName.IndexOf("/") != -1)
{
fileName = fileName.Replace("/", "\\");
_fileName = _fileName.Replace("/", "\\");
}
if (fileName.EndsWith("\\"))
if (_fileName.EndsWith("\\"))
{
throw new InvalidOperationException("Illegal filename");
}
var index = fileName.IndexOf("\\");
var index = _fileName.IndexOf("\\");
if (index != -1)
{
// trim any leading path
int length = fileName.Length;
int length = _fileName.Length;
int num = length;
while (--num >= 0)
{
char c = fileName[num];
char c = _fileName[num];
if (c == '\\')
{
fileName = fileName.Substring(num + 1, length - num - 1);
_fileName = _fileName.Substring(num + 1, length - num - 1);
}
}
}
@@ -411,9 +411,9 @@ namespace SharpCompress.Compressors.Deflate
private int EmitHeader()
{
byte[] commentBytes = (Comment == null) ? null
: (forceEncoding ?? ArchiveEncoding.Default).GetBytes(Comment);
: _encoding.GetBytes(Comment);
byte[] filenameBytes = (FileName == null) ? null
: (forceEncoding ?? ArchiveEncoding.Default).GetBytes(FileName);
: _encoding.GetBytes(FileName);
int cbLength = (Comment == null) ? 0 : commentBytes.Length + 1;
int fnLength = (FileName == null) ? 0 : filenameBytes.Length + 1;
@@ -446,7 +446,7 @@ namespace SharpCompress.Compressors.Deflate
{
LastModified = DateTime.Now;
}
TimeSpan delta = LastModified.Value - UnixEpoch;
TimeSpan delta = LastModified.Value - UNIX_EPOCH;
var timet = (Int32)delta.TotalSeconds;
DataConverter.LittleEndian.PutBytes(header, i, timet);
i += 4;

View File

@@ -65,7 +65,7 @@ namespace SharpCompress.Compressors.Deflate
protected internal DateTime _GzipMtime;
protected internal int _gzipHeaderByteCount;
private readonly Encoding forceEncoding;
private readonly Encoding _encoding;
internal int Crc32
{
@@ -84,7 +84,7 @@ namespace SharpCompress.Compressors.Deflate
CompressionLevel level,
ZlibStreamFlavor flavor,
bool leaveOpen,
Encoding forceEncoding)
Encoding encoding)
{
_flushMode = FlushType.None;
@@ -95,7 +95,7 @@ namespace SharpCompress.Compressors.Deflate
_flavor = flavor;
_level = level;
this.forceEncoding = forceEncoding;
_encoding = encoding;
// workitem 7159
if (flavor == ZlibStreamFlavor.GZIP)
@@ -425,7 +425,7 @@ namespace SharpCompress.Compressors.Deflate
}
while (!done);
byte[] buffer = list.ToArray();
return (forceEncoding ?? ArchiveEncoding.Default).GetString(buffer, 0, buffer.Length);
return _encoding.GetString(buffer, 0, buffer.Length);
}
private int _ReadAndValidateGzipHeader()

View File

@@ -37,23 +37,23 @@ namespace SharpCompress.Compressors.Deflate
private bool _disposed;
public ZlibStream(Stream stream, CompressionMode mode)
: this(stream, mode, CompressionLevel.Default, false)
: this(stream, mode, CompressionLevel.Default, false, Encoding.UTF8)
{
}
public ZlibStream(Stream stream, CompressionMode mode, CompressionLevel level)
: this(stream, mode, level, false)
: this(stream, mode, level, false, Encoding.UTF8)
{
}
public ZlibStream(Stream stream, CompressionMode mode, bool leaveOpen)
: this(stream, mode, CompressionLevel.Default, leaveOpen)
: this(stream, mode, CompressionLevel.Default, leaveOpen, Encoding.UTF8)
{
}
public ZlibStream(Stream stream, CompressionMode mode, CompressionLevel level, bool leaveOpen, Encoding forceEncoding = null)
public ZlibStream(Stream stream, CompressionMode mode, CompressionLevel level, bool leaveOpen, Encoding encoding)
{
_baseStream = new ZlibBaseStream(stream, mode, level, ZlibStreamFlavor.ZLIB, leaveOpen, forceEncoding);
_baseStream = new ZlibBaseStream(stream, mode, level, ZlibStreamFlavor.ZLIB, leaveOpen, encoding);
}
#region Zlib properties

View File

@@ -33,7 +33,7 @@ namespace SharpCompress.Readers.GZip
internal override IEnumerable<GZipEntry> GetEntries(Stream stream)
{
return GZipEntry.GetEntries(stream, Options.ForceEncoding);
return GZipEntry.GetEntries(stream, Options);
}
}
}

View File

@@ -118,7 +118,7 @@ namespace SharpCompress.Readers.Tar
internal override IEnumerable<TarEntry> GetEntries(Stream stream)
{
return TarEntry.GetEntries(StreamingMode.Streaming, stream, compressionType, Options.ForceEncoding);
return TarEntry.GetEntries(StreamingMode.Streaming, stream, compressionType, Options.ArchiveEncoding);
}
}
}

View File

@@ -8,13 +8,13 @@ namespace SharpCompress.Readers.Zip
{
public class ZipReader : AbstractReader<ZipEntry, ZipVolume>
{
private readonly StreamingZipHeaderFactory headerFactory;
private readonly StreamingZipHeaderFactory _headerFactory;
internal ZipReader(Stream stream, ReaderOptions options)
: base(options, ArchiveType.Zip)
{
Volume = new ZipVolume(stream, options);
headerFactory = new StreamingZipHeaderFactory(options.Password, options.ForceEncoding);
_headerFactory = new StreamingZipHeaderFactory(options.Password, options.ArchiveEncoding);
}
public override ZipVolume Volume { get; }
@@ -37,7 +37,7 @@ namespace SharpCompress.Readers.Zip
internal override IEnumerable<ZipEntry> GetEntries(Stream stream)
{
foreach (ZipHeader h in headerFactory.ReadStreamHeader(stream))
foreach (ZipHeader h in _headerFactory.ReadStreamHeader(stream))
{
if (h != null)
{

View File

@@ -8,12 +8,15 @@ namespace SharpCompress.Writers.GZip
{
public class GZipWriter : AbstractWriter
{
private bool wroteToStream;
private bool _wroteToStream;
public GZipWriter(Stream destination, bool leaveOpen = false)
: base(ArchiveType.GZip, new WriterOptions(CompressionType.GZip))
public GZipWriter(Stream destination, GZipWriterOptions options = null)
: base(ArchiveType.GZip, options ?? new GZipWriterOptions())
{
InitalizeStream(new GZipStream(destination, CompressionMode.Compress, leaveOpen), !leaveOpen);
InitalizeStream(new GZipStream(destination, CompressionMode.Compress,
options?.CompressionLevel ?? CompressionLevel.Default,
WriterOptions.LeaveStreamOpen,
WriterOptions.ArchiveEncoding.GetEncoding()), !WriterOptions.LeaveStreamOpen);
}
protected override void Dispose(bool isDisposing)
@@ -28,7 +31,7 @@ namespace SharpCompress.Writers.GZip
public override void Write(string filename, Stream source, DateTime? modificationTime)
{
if (wroteToStream)
if (_wroteToStream)
{
throw new ArgumentException("Can only write a single stream to a GZip file.");
}
@@ -36,7 +39,7 @@ namespace SharpCompress.Writers.GZip
stream.FileName = filename;
stream.LastModified = modificationTime;
source.TransferTo(stream);
wroteToStream = true;
_wroteToStream = true;
}
}
}

View File

@@ -0,0 +1,28 @@
using SharpCompress.Common;
using SharpCompress.Compressors.Deflate;
namespace SharpCompress.Writers.GZip
{
public class GZipWriterOptions : WriterOptions
{
public GZipWriterOptions()
: base(CompressionType.GZip)
{
}
internal GZipWriterOptions(WriterOptions options)
: base(options.CompressionType)
{
LeaveStreamOpen = options.LeaveStreamOpen;
ArchiveEncoding = options.ArchiveEncoding;
var writerOptions = options as GZipWriterOptions;
if (writerOptions != null)
{
CompressionLevel = writerOptions.CompressionLevel;
}
}
public CompressionLevel CompressionLevel { get; set; } = CompressionLevel.Default;
}
}

View File

@@ -72,10 +72,7 @@ namespace SharpCompress.Writers.Tar
long realSize = size ?? source.Length;
TarHeader header = new TarHeader()
{
ForceEncoding = WriterOptions.ForceEncoding
};
TarHeader header = new TarHeader(WriterOptions.ArchiveEncoding);
header.LastModifiedTime = modificationTime ?? TarHeader.Epoch;
header.Name = NormalizeFilename(filename);

View File

@@ -19,7 +19,7 @@ namespace SharpCompress.Writers
{
throw new InvalidFormatException("GZip archives only support GZip compression type.");
}
return new GZipWriter(stream, writerOptions.LeaveStreamOpen);
return new GZipWriter(stream, new GZipWriterOptions(writerOptions));
}
case ArchiveType.Zip:
{

View File

@@ -1,6 +1,7 @@
using System;
using System.IO;
using System.Text;
using SharpCompress.Common;
using SharpCompress.Common.Zip;
using SharpCompress.Common.Zip.Headers;
using SharpCompress.Converters;
@@ -11,14 +12,14 @@ namespace SharpCompress.Writers.Zip
{
private readonly ZipCompressionMethod compression;
private readonly string fileName;
private readonly Encoding forceEncoding;
private readonly ArchiveEncoding archiveEncoding;
public ZipCentralDirectoryEntry(ZipCompressionMethod compression, string fileName, ulong headerOffset, Encoding forceEncoding)
public ZipCentralDirectoryEntry(ZipCompressionMethod compression, string fileName, ulong headerOffset, ArchiveEncoding archiveEncoding)
{
this.compression = compression;
this.fileName = fileName;
HeaderOffset = headerOffset;
this.forceEncoding = forceEncoding;
this.archiveEncoding = archiveEncoding;
}
internal DateTime? ModificationTime { get; set; }
@@ -31,8 +32,8 @@ namespace SharpCompress.Writers.Zip
internal uint Write(Stream outputStream)
{
byte[] encodedFilename = (forceEncoding ?? Encoding.UTF8).GetBytes(fileName);
byte[] encodedComment = (forceEncoding ?? Encoding.UTF8).GetBytes(Comment);
byte[] encodedFilename = archiveEncoding.Encode(fileName);
byte[] encodedComment = archiveEncoding.Encode(Comment);
var zip64_stream = Compressed >= uint.MaxValue || Decompressed >= uint.MaxValue;
var zip64 = zip64_stream || HeaderOffset >= uint.MaxValue || Zip64HeaderOffset != 0;
@@ -43,7 +44,7 @@ namespace SharpCompress.Writers.Zip
var extralength = zip64 ? (2 + 2 + 8 + 8 + 8 + 4) : 0;
var version = (byte)(zip64 ? 45 : 20); // Version 20 required for deflate/encryption
HeaderFlags flags = (forceEncoding ?? Encoding.UTF8) == Encoding.UTF8 ? HeaderFlags.UTF8 : HeaderFlags.None;
HeaderFlags flags = Equals(archiveEncoding.GetEncoding(), Encoding.UTF8) ? HeaderFlags.UTF8 : HeaderFlags.None;
if (!outputStream.CanSeek)
{
// Cannot use data descriptors with zip64:

View File

@@ -118,7 +118,7 @@ namespace SharpCompress.Writers.Zip
entryPath = NormalizeFilename(entryPath);
options.ModificationDateTime = options.ModificationDateTime ?? DateTime.Now;
options.EntryComment = options.EntryComment ?? string.Empty;
var entry = new ZipCentralDirectoryEntry(compression, entryPath, (ulong)streamPosition, WriterOptions.ForceEncoding)
var entry = new ZipCentralDirectoryEntry(compression, entryPath, (ulong)streamPosition, WriterOptions.ArchiveEncoding)
{
Comment = options.EntryComment,
ModificationTime = options.ModificationDateTime
@@ -155,7 +155,7 @@ namespace SharpCompress.Writers.Zip
throw new NotSupportedException("Zip64 extensions are not supported on non-seekable streams");
var explicitZipCompressionInfo = ToZipCompressionMethod(zipWriterEntryOptions.CompressionType ?? compressionType);
byte[] encodedFilename = (WriterOptions.ForceEncoding ?? ArchiveEncoding.Default).GetBytes(filename);
byte[] encodedFilename = WriterOptions.ArchiveEncoding.Encode(filename);
OutputStream.Write(DataConverter.LittleEndian.GetBytes(ZipHeaderFactory.ENTRY_HEADER_BYTES), 0, 4);
if (explicitZipCompressionInfo == ZipCompressionMethod.Deflate)
@@ -169,7 +169,7 @@ namespace SharpCompress.Writers.Zip
{
OutputStream.Write(new byte[] { 63, 0 }, 0, 2); //version says we used PPMd or LZMA
}
HeaderFlags flags = (WriterOptions.ForceEncoding ?? ArchiveEncoding.Default) == Encoding.UTF8 ? HeaderFlags.UTF8 : 0;
HeaderFlags flags = Equals(WriterOptions.ArchiveEncoding.GetEncoding(), Encoding.UTF8) ? HeaderFlags.UTF8 : 0;
if (!OutputStream.CanSeek)
{
flags |= HeaderFlags.UsePostDataDescriptor;
@@ -214,7 +214,7 @@ namespace SharpCompress.Writers.Zip
private void WriteEndRecord(ulong size)
{
byte[] encodedComment = (WriterOptions.ForceEncoding ?? ArchiveEncoding.Default).GetBytes(zipComment);
byte[] encodedComment = WriterOptions.ArchiveEncoding.Encode(zipComment);
var zip64 = isZip64 || entries.Count > ushort.MaxValue || streamPosition >= uint.MaxValue || size >= uint.MaxValue;
var sizevalue = size >= uint.MaxValue ? uint.MaxValue : (uint)size;

View File

@@ -15,8 +15,15 @@ namespace SharpCompress.Writers.Zip
: base(options.CompressionType)
{
LeaveStreamOpen = options.LeaveStreamOpen;
if (options is ZipWriterOptions)
UseZip64 = ((ZipWriterOptions)options).UseZip64;
ArchiveEncoding = options.ArchiveEncoding;
var writerOptions = options as ZipWriterOptions;
if (writerOptions != null)
{
UseZip64 = writerOptions.UseZip64;
DeflateCompressionLevel = writerOptions.DeflateCompressionLevel;
ArchiveComment = writerOptions.ArchiveComment;
}
}
/// <summary>
/// When CompressionType.Deflate is used, this property is referenced. Defaults to CompressionLevel.Default.