public ZipReturn ZipFileOpenWriteStream(bool raw, bool trrntzip, string filename, ulong uncompressedSize, ushort compressionMethod, out Stream stream, TimeStamps dateTime) { // check if we are writing a directory if (uncompressedSize == 0 && filename.Substring(filename.Length - 1, 1) == "/") { ZipFileAddDirectory(filename); stream = null; return(ZipReturn.ZipGood); } SevenZipLocalFile localFile = new() { Filename = filename, UncompressedSize = uncompressedSize }; _localFiles.Add(localFile); if (uncompressedSize == 0) { unpackedStreamInfo = null; stream = null; return(ZipReturn.ZipGood); } unpackedStreamInfo = new UnpackedStreamInfo { UnpackedSize = uncompressedSize }; _packedOutStreams[_packedOutStreams.Count - 1].unpackedStreams.Add(unpackedStreamInfo); stream = _compressStream; return(ZipReturn.ZipGood); }
public ZipReturn ZipFileOpenWriteStream(bool raw, bool trrntzip, string filename, ulong uncompressedSize, ushort compressionMethod, out Stream stream, TimeStamps dateTime) { // check if we are writing a directory if (uncompressedSize == 0 && filename.Substring(filename.Length - 1, 1) == "/") { ZipFileAddDirectory(filename); stream = null; return(ZipReturn.ZipGood); } SevenZipLocalFile localFile = new() { Filename = filename, UncompressedSize = uncompressedSize }; _localFiles.Add(localFile); if (uncompressedSize == 0) { unpackedStreamInfo = null; stream = null; return(ZipReturn.ZipGood); } #if !solid outStreams newStream = new() { packedStart = (ulong)_zipFs.Position, compType = _compType, packedSize = 0, unpackedStreams = new List <UnpackedStreamInfo>() }; switch (_compType) { case SevenZipCompressType.lzma: LzmaEncoderProperties ep = new(true, GetDictionarySizeFromUncompressedSize(uncompressedSize), 64); LzmaStream lzs = new(ep, false, _zipFs); newStream.Method = new byte[] { 3, 1, 1 }; newStream.Properties = lzs.Properties; _compressStream = lzs; break; case SevenZipCompressType.zstd: ZstdSharp.CompressionStream zss = new(_zipFs, 19); newStream.Method = new byte[] { 4, 247, 17, 1 }; newStream.Properties = new byte[] { 1, 5, 19, 0, 0 }; _compressStream = zss; break; case SevenZipCompressType.uncompressed: newStream.Method = new byte[] { 0 }; newStream.Properties = null; _compressStream = _zipFs; break; } _packedOutStreams.Add(newStream); #endif unpackedStreamInfo = new UnpackedStreamInfo { UnpackedSize = uncompressedSize }; _packedOutStreams[_packedOutStreams.Count - 1].unpackedStreams.Add(unpackedStreamInfo); stream = _compressStream; return(ZipReturn.ZipGood); } public ZipReturn ZipFileCloseWriteStream(byte[] crc32) { SevenZipLocalFile localFile = _localFiles[_localFiles.Count - 1]; localFile.CRC = new[] { crc32[3], crc32[2], crc32[1], crc32[0] }; if (unpackedStreamInfo != null) { unpackedStreamInfo.Crc = Util.BytesToUint(localFile.CRC); } #if !solid if (unpackedStreamInfo != null) { if (_packedOutStreams[_packedOutStreams.Count - 1].compType != SevenZipCompressType.uncompressed) { _compressStream.Flush(); _compressStream.Close(); } _packedOutStreams[_packedOutStreams.Count - 1].packedSize = (ulong)_zipFs.Position - _packedOutStreams[_packedOutStreams.Count - 1].packedStart; } #endif return(ZipReturn.ZipGood); }
private void Create7ZStructure() { int fileCount = _localFiles.Count; //FileInfo _header.FileInfo = new Structure.FileInfo { Names = new string[fileCount] }; ulong emptyStreamCount = 0; ulong emptyFileCount = 0; for (int i = 0; i < fileCount; i++) { _header.FileInfo.Names[i] = _localFiles[i].FileName; if (_localFiles[i].UncompressedSize != 0) { continue; } if (!_localFiles[i].IsDirectory) { emptyFileCount += 1; } emptyStreamCount += 1; } ulong outFileCount = (ulong)_localFiles.Count - emptyStreamCount; _header.FileInfo.EmptyStreamFlags = null; _header.FileInfo.EmptyFileFlags = null; _header.FileInfo.Attributes = null; if (emptyStreamCount > 0) { if (emptyStreamCount != emptyFileCount) //then we found directories and need to set the attributes { _header.FileInfo.Attributes = new uint[fileCount]; } if (emptyFileCount > 0) { _header.FileInfo.EmptyFileFlags = new bool[emptyStreamCount]; } emptyStreamCount = 0; _header.FileInfo.EmptyStreamFlags = new bool[fileCount]; for (int i = 0; i < fileCount; i++) { if (_localFiles[i].UncompressedSize != 0) { continue; } if (_localFiles[i].IsDirectory) { if (_header.FileInfo.Attributes != null) { _header.FileInfo.Attributes[i] = 0x10; // set attributes to directory } } else { if (_header.FileInfo.EmptyFileFlags != null) { _header.FileInfo.EmptyFileFlags[emptyStreamCount] = true; // set empty file flag } } _header.FileInfo.EmptyStreamFlags[i] = true; emptyStreamCount += 1; } } //StreamsInfo _header.StreamsInfo = new StreamsInfo { PackPosition = 0 }; //StreamsInfo.PackedStreamsInfo if (_compressed) { _header.StreamsInfo.PackedStreams = new PackedStreamInfo[1]; _header.StreamsInfo.PackedStreams[0] = new PackedStreamInfo { PackedSize = _packStreamSize }; } else { _header.StreamsInfo.PackedStreams = new PackedStreamInfo[outFileCount]; int fileIndex = 0; for (int i = 0; i < fileCount; i++) { if (_localFiles[i].UncompressedSize == 0) { continue; } _header.StreamsInfo.PackedStreams[fileIndex++] = new PackedStreamInfo { PackedSize = _localFiles[i].UncompressedSize }; } } //StreamsInfo.PackedStreamsInfo, no CRC or StreamPosition required if (_compressed) { //StreamsInfo.Folders _header.StreamsInfo.Folders = new Folder[1]; Folder folder = new Folder { Coders = new Coder[1] }; //StreamsInfo.Folders.Coder // flags 0x23 folder.Coders[0] = new Coder { Method = new byte[] { 3, 1, 1 }, NumInStreams = 1, NumOutStreams = 1, Properties = _codeMSbytes }; folder.BindPairs = null; folder.PackedStreamIndices = new[] { (ulong)0 }; folder.UnpackedStreamSizes = new[] { _unpackedStreamSize }; folder.UnpackCRC = null; folder.UnpackedStreamInfo = new UnpackedStreamInfo[outFileCount]; int fileIndex = 0; for (int i = 0; i < fileCount; i++) { if (_localFiles[i].UncompressedSize == 0) { continue; } UnpackedStreamInfo unpackedStreamInfo = new UnpackedStreamInfo { UnpackedSize = _localFiles[i].UncompressedSize, Crc = Util.bytestouint(_localFiles[i].CRC) }; folder.UnpackedStreamInfo[fileIndex++] = unpackedStreamInfo; } _header.StreamsInfo.Folders[0] = folder; } else { _header.StreamsInfo.Folders = new Folder[outFileCount]; int fileIndex = 0; for (int i = 0; i < fileCount; i++) { if (_localFiles[i].UncompressedSize == 0) { continue; } Folder folder = new Folder { Coders = new Coder[1] }; //StreamsInfo.Folders.Coder // flags 0x01 folder.Coders[0] = new Coder { Method = new byte[] { 0 }, NumInStreams = 1, NumOutStreams = 1, Properties = null }; folder.BindPairs = null; folder.PackedStreamIndices = new[] { (ulong)i }; folder.UnpackedStreamSizes = new[] { _localFiles[i].UncompressedSize }; folder.UnpackCRC = null; folder.UnpackedStreamInfo = new UnpackedStreamInfo[1]; UnpackedStreamInfo unpackedStreamInfo = new UnpackedStreamInfo { UnpackedSize = _localFiles[i].UncompressedSize, Crc = Util.bytestouint(_localFiles[i].CRC) }; folder.UnpackedStreamInfo[0] = unpackedStreamInfo; _header.StreamsInfo.Folders[fileIndex++] = folder; } } }