Пример #1
0
        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);
        }
Пример #2
0
        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);
        }
Пример #3
0
        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;
                }
            }
        }