mirror of
https://github.com/adamhathcock/sharpcompress.git
synced 2026-09-25 16:34:45 +00:00
120 lines
3.4 KiB
C#
120 lines
3.4 KiB
C#
using System;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using SharpCompress.IO;
|
|
|
|
namespace SharpCompress.Common.SevenZip
|
|
{
|
|
internal class SevenZipFilePart : FilePart
|
|
{
|
|
private CompressionType? _type;
|
|
private readonly Stream _stream;
|
|
private readonly ArchiveDatabase _database;
|
|
|
|
internal SevenZipFilePart(
|
|
Stream stream,
|
|
ArchiveDatabase database,
|
|
int index,
|
|
CFileItem fileEntry,
|
|
ArchiveEncoding archiveEncoding
|
|
) : base(archiveEncoding)
|
|
{
|
|
_stream = stream;
|
|
_database = database;
|
|
Index = index;
|
|
Header = fileEntry;
|
|
if (Header.HasStream)
|
|
{
|
|
Folder = database._folders[database._fileIndexToFolderIndexMap[index]];
|
|
}
|
|
}
|
|
|
|
internal CFileItem Header { get; }
|
|
internal CFolder? Folder { get; }
|
|
|
|
internal override string FilePartName => Header.Name;
|
|
|
|
internal override Stream? GetRawStream()
|
|
{
|
|
return null;
|
|
}
|
|
|
|
internal override Stream GetCompressedStream()
|
|
{
|
|
if (!Header.HasStream)
|
|
{
|
|
return null!;
|
|
}
|
|
var folderStream = _database.GetFolderStream(
|
|
_stream,
|
|
Folder!,
|
|
_database.PasswordProvider
|
|
);
|
|
|
|
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;
|
|
}
|
|
if (skipSize > 0)
|
|
{
|
|
folderStream.Skip(skipSize);
|
|
}
|
|
return new ReadOnlySubStream(folderStream, Header.Size);
|
|
}
|
|
|
|
public CompressionType CompressionType
|
|
{
|
|
get
|
|
{
|
|
if (_type is null)
|
|
{
|
|
_type = GetCompression();
|
|
}
|
|
return _type.Value;
|
|
}
|
|
}
|
|
|
|
//copied from DecoderRegistry
|
|
private const uint K_COPY = 0x0;
|
|
private const uint K_DELTA = 3;
|
|
private const uint K_LZMA2 = 0x21;
|
|
private const uint K_LZMA = 0x030101;
|
|
private const uint K_PPMD = 0x030401;
|
|
private const uint K_BCJ = 0x03030103;
|
|
private const uint K_BCJ2 = 0x0303011B;
|
|
private const uint K_DEFLATE = 0x040108;
|
|
private const uint K_B_ZIP2 = 0x040202;
|
|
|
|
internal CompressionType GetCompression()
|
|
{
|
|
var coder = Folder!._coders.First();
|
|
switch (coder._methodId._id)
|
|
{
|
|
case K_LZMA:
|
|
case K_LZMA2:
|
|
{
|
|
return CompressionType.LZMA;
|
|
}
|
|
case K_PPMD:
|
|
{
|
|
return CompressionType.PPMd;
|
|
}
|
|
case K_B_ZIP2:
|
|
{
|
|
return CompressionType.BZip2;
|
|
}
|
|
default:
|
|
throw new NotImplementedException();
|
|
}
|
|
}
|
|
|
|
internal bool IsEncrypted =>
|
|
Folder!._coders.FindIndex(c => c._methodId._id == CMethodId.K_AES_ID) != -1;
|
|
}
|
|
}
|