From 7b879241728da85c7b8dbfdf2f9ec343c5fccb67 Mon Sep 17 00:00:00 2001 From: Adam Hathcock Date: Sun, 28 Nov 2021 10:11:54 +0000 Subject: [PATCH] Add zstd classes for initial work --- src/SharpCompress/Common/ArchiveType.cs | 3 +- src/SharpCompress/Common/CompressionType.cs | 3 +- .../Common/ZStandard/ZStandardEntry.cs | 50 +++++++++++++++ .../Common/ZStandard/ZStandardFilePart.cs | 37 +++++++++++ .../Common/ZStandard/ZStandardVolume.cs | 23 +++++++ .../Readers/ZStandard/ZStandardReader.cs | 32 ++++++++++ .../Writers/ZStandard/ZStandardWriter.cs | 61 +++++++++++++++++++ .../ZStandard/ZStandardWriterOptions.cs | 28 +++++++++ 8 files changed, 235 insertions(+), 2 deletions(-) create mode 100644 src/SharpCompress/Common/ZStandard/ZStandardEntry.cs create mode 100644 src/SharpCompress/Common/ZStandard/ZStandardFilePart.cs create mode 100644 src/SharpCompress/Common/ZStandard/ZStandardVolume.cs create mode 100644 src/SharpCompress/Readers/ZStandard/ZStandardReader.cs create mode 100644 src/SharpCompress/Writers/ZStandard/ZStandardWriter.cs create mode 100644 src/SharpCompress/Writers/ZStandard/ZStandardWriterOptions.cs diff --git a/src/SharpCompress/Common/ArchiveType.cs b/src/SharpCompress/Common/ArchiveType.cs index a0d3097a..df28ca93 100644 --- a/src/SharpCompress/Common/ArchiveType.cs +++ b/src/SharpCompress/Common/ArchiveType.cs @@ -6,6 +6,7 @@ Zip, Tar, SevenZip, - GZip + GZip, + ZStandard } } \ No newline at end of file diff --git a/src/SharpCompress/Common/CompressionType.cs b/src/SharpCompress/Common/CompressionType.cs index 23ed354f..e29e9b0c 100644 --- a/src/SharpCompress/Common/CompressionType.cs +++ b/src/SharpCompress/Common/CompressionType.cs @@ -14,6 +14,7 @@ LZip, Xz, Unknown, - Deflate64 + Deflate64, + ZStandard, } } \ No newline at end of file diff --git a/src/SharpCompress/Common/ZStandard/ZStandardEntry.cs b/src/SharpCompress/Common/ZStandard/ZStandardEntry.cs new file mode 100644 index 00000000..a82c93d6 --- /dev/null +++ b/src/SharpCompress/Common/ZStandard/ZStandardEntry.cs @@ -0,0 +1,50 @@ +using System; +using System.Collections.Generic; +using System.IO; +using SharpCompress.Common.GZip; + +namespace SharpCompress.Common.ZStandard +{ + public class ZStandardEntry : Entry + { + private readonly ZStandardFilePart _filePart; + + internal ZStandardEntry(ZStandardFilePart filePart) + { + _filePart = filePart; + } + + public override CompressionType CompressionType => CompressionType.GZip; + + public override long Crc => _filePart.Crc ?? 0; + + public override string Key => _filePart.FilePartName; + + public override string? LinkTarget => null; + + public override long CompressedSize => 0; + + public override long Size => _filePart.UncompressedSize ?? 0; + + public override DateTime? LastModifiedTime => _filePart.DateModified; + + public override DateTime? CreatedTime => null; + + public override DateTime? LastAccessedTime => null; + + public override DateTime? ArchivedTime => null; + + public override bool IsEncrypted => false; + + public override bool IsDirectory => false; + + public override bool IsSplitAfter => false; + + internal override IEnumerable Parts => _filePart.AsEnumerable(); + + internal static IEnumerable GetEntries(Stream stream, OptionsBase options) + { + yield return new GZipEntry(new GZipFilePart(stream, options.ArchiveEncoding)); + } + } +} \ No newline at end of file diff --git a/src/SharpCompress/Common/ZStandard/ZStandardFilePart.cs b/src/SharpCompress/Common/ZStandard/ZStandardFilePart.cs new file mode 100644 index 00000000..25a0a750 --- /dev/null +++ b/src/SharpCompress/Common/ZStandard/ZStandardFilePart.cs @@ -0,0 +1,37 @@ +using System; +using System.IO; +using ZstdSharp; + +namespace SharpCompress.Common.ZStandard +{ + internal sealed class ZStandardFilePart : FilePart + { + private string _name = ""; + private readonly Stream _stream; + + internal ZStandardFilePart(Stream stream, ArchiveEncoding archiveEncoding) + : base(archiveEncoding) + { + _stream = stream; + EntryStartPosition = stream.Position; + } + + internal long EntryStartPosition { get; } + + internal DateTime? DateModified { get; private set; } + internal int? Crc { get; private set; } + internal int? UncompressedSize { get; private set; } + + internal override string FilePartName => _name!; + + internal override Stream GetCompressedStream() + { + return new DecompressionStream(_stream); + } + + internal override Stream GetRawStream() + { + return _stream; + } + } +} diff --git a/src/SharpCompress/Common/ZStandard/ZStandardVolume.cs b/src/SharpCompress/Common/ZStandard/ZStandardVolume.cs new file mode 100644 index 00000000..39398372 --- /dev/null +++ b/src/SharpCompress/Common/ZStandard/ZStandardVolume.cs @@ -0,0 +1,23 @@ +using System.IO; +using SharpCompress.Readers; + +namespace SharpCompress.Common.ZStandard +{ + public class ZStandardVolume : Volume + { + public ZStandardVolume(Stream stream, ReaderOptions options) + : base(stream, options) + { + } + + public ZStandardVolume(FileInfo fileInfo, ReaderOptions options) + : base(fileInfo.OpenRead(), options) + { + options.LeaveStreamOpen = false; + } + + public override bool IsFirstVolume => true; + + public override bool IsMultiVolume => true; + } +} \ No newline at end of file diff --git a/src/SharpCompress/Readers/ZStandard/ZStandardReader.cs b/src/SharpCompress/Readers/ZStandard/ZStandardReader.cs new file mode 100644 index 00000000..099f21b6 --- /dev/null +++ b/src/SharpCompress/Readers/ZStandard/ZStandardReader.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; +using System.IO; +using SharpCompress.Common; +using SharpCompress.Common.ZStandard; + +namespace SharpCompress.Readers.Tar +{ + public class ZStandardReader : AbstractReader + { + private readonly CompressionType compressionType; + + internal ZStandardReader(Stream stream, ReaderOptions options, CompressionType compressionType) + : base(options, ArchiveType.Tar) + { + this.compressionType = compressionType; + Volume = new ZStandardVolume(stream, options); + } + + public override ZStandardVolume Volume { get; } + + protected override Stream RequestInitialStream() + { + throw new NotImplementedException(); + } + + protected override IEnumerable GetEntries(Stream stream) + { + throw new NotImplementedException(); + } + } +} diff --git a/src/SharpCompress/Writers/ZStandard/ZStandardWriter.cs b/src/SharpCompress/Writers/ZStandard/ZStandardWriter.cs new file mode 100644 index 00000000..133edd64 --- /dev/null +++ b/src/SharpCompress/Writers/ZStandard/ZStandardWriter.cs @@ -0,0 +1,61 @@ +using System; +using System.IO; +using SharpCompress.Common; +using SharpCompress.Compressors.Deflate; +using SharpCompress.IO; +using ZstdSharp; + +namespace SharpCompress.Writers.ZStandard +{ + public static class ZStandard + { + public static readonly byte[] Magic = { 0xFD, 0x2F, 0xB5, 0x28}; + } + + [Flags] + public enum FrameHeaderDescriptor + { + Dictionary_ID_Flag = 0, + Dictionary_ID_Flag2 = 1, + Content_Checksum_Flag = 2, + Single_Segment_Flag = 5, + Frame_Content_Size_Flag = 6, + Frame_Content_Size_Flag2 = 7 + + } + + public class FrameHeader + { + //private byte Descriptor = 0x0; + } + public sealed class ZStandardWriter : AbstractWriter + { + + public ZStandardWriter(Stream destination, ZStandardWriterOptions? options = null) + : base(ArchiveType.ZStandard, options ?? new ZStandardWriterOptions()) + { + if (WriterOptions.LeaveStreamOpen) + { + destination = new NonDisposingStream(destination); + } + InitalizeStream(new CompressionStream(destination)); + } + + protected override void Dispose(bool isDisposing) + { + if (isDisposing) + { + OutputStream.Dispose(); + } + base.Dispose(isDisposing); + } + + public override void Write(string filename, Stream source, DateTime? modificationTime) + { + GZipStream stream = (GZipStream)OutputStream; + stream.FileName = filename; + stream.LastModified = modificationTime; + source.TransferTo(stream); + } + } +} \ No newline at end of file diff --git a/src/SharpCompress/Writers/ZStandard/ZStandardWriterOptions.cs b/src/SharpCompress/Writers/ZStandard/ZStandardWriterOptions.cs new file mode 100644 index 00000000..66c2cc43 --- /dev/null +++ b/src/SharpCompress/Writers/ZStandard/ZStandardWriterOptions.cs @@ -0,0 +1,28 @@ +using SharpCompress.Common; +using SharpCompress.Compressors.Deflate; + +namespace SharpCompress.Writers.ZStandard +{ + public class ZStandardWriterOptions : WriterOptions + { + public ZStandardWriterOptions() + : base(CompressionType.ZStandard) + { + } + + internal ZStandardWriterOptions(WriterOptions options) + : base(options.CompressionType) + { + LeaveStreamOpen = options.LeaveStreamOpen; + ArchiveEncoding = options.ArchiveEncoding; + + var writerOptions = options as ZStandardWriterOptions; + if (writerOptions != null) + { + CompressionLevel = writerOptions.CompressionLevel; + } + } + + public CompressionLevel CompressionLevel { get; set; } = CompressionLevel.Default; + } +} \ No newline at end of file