Пример #1
0
 internal SevenZipStreamsExtractor(Stream stream, SevenZipHeader.StreamsInfo streamsInfo, string password = null)
 {
     this.password    = password;
     this.stream      = stream;
     this.streamsInfo = streamsInfo;
 }
Пример #2
0
        private void writeHeaders()
        {
            // current position is defined as end of packed streams and beginning of header
            long endOfPackedStreamsPosition = stream.Position;

            // write headers in temporary stream
            var headerStream = new MemoryStream();

            header.Write(headerStream);

            // go through compressing again for headers
            if (CompressHeader)
            {
                // get compressor and default codec
                var sc = new SevenZipStreamsCompressor(stream);
                sc.Method = Compression.Registry.Method.LZMA;

                // compress
                headerStream.Position = 0;
                SevenZipStreamsCompressor.PackedStream cs = sc.Compress(headerStream, null);

                // create encoded header
                SevenZipHeader.StreamsInfo headerStreamsInfo = new SevenZipHeader.StreamsInfo()
                {
                    PackInfo = new SevenZipHeader.PackInfo()
                    {
                        NumPackStreams = cs.NumStreams,
                        PackPos        = (ulong)(endOfPackedStreamsPosition - Marshal.SizeOf(typeof(SevenZipArchive.SignatureHeader))),
                        Sizes          = cs.Sizes,
                        Digests        = new SevenZipHeader.Digests(1)
                        {
                            CRCs = cs.CRCs
                        }
                    },
                    UnPackInfo = new SevenZipHeader.UnPackInfo()
                    {
                        Folders = new SevenZipHeader.Folder[1] {
                            cs.Folder
                        },
                        NumFolders = 1
                    }
                };

                // bait and switch
                header.RawHeader     = null;
                header.EncodedHeader = headerStreamsInfo;

                // write new header in headerStream
                headerStream.Dispose();
                headerStream = new MemoryStream();
                header.Write(headerStream);

                // update new end of packed position for encoded header
                endOfPackedStreamsPosition = stream.Position;
            }

            // create start header and calculate header crc
            headerStream.Position = 0;
            var startHeader = new SevenZipArchive.StartHeader()
            {
                NextHeaderOffset = (ulong)(endOfPackedStreamsPosition - Marshal.SizeOf(typeof(SevenZipArchive.SignatureHeader))),
                NextHeaderSize   = (ulong)headerStream.Length,
                NextHeaderCRC    = CRC.Calculate(headerStream)
            };

            // write headers at the end of output stream
            headerStream.Position = 0;
            headerStream.CopyTo(stream);
            headerStream.Dispose();

            // regenerate signature header with positions and crcs
            var signatureHeader = new SevenZipArchive.SignatureHeader()
            {
                Signature      = SevenZipArchive.kSignature.ToArray(),
                ArchiveVersion = new SevenZipArchive.ArchiveVersion()
                {
                    Major = 0,
                    Minor = 2,
                },
                StartHeaderCRC = CRC.Calculate(startHeader.GetByteArray()),
                StartHeader    = startHeader
            };

            // write start header and flush all pending writes
            stream.Position = 0;
            stream.Write(signatureHeader.GetByteArray(), 0, Marshal.SizeOf(signatureHeader));
            stream.Flush();
        }