System.IO.Compression.ZipArchiveEntry.WriteCrcAndSizesInLocalHeader C# (CSharp) Méthode

WriteCrcAndSizesInLocalHeader() private méthode

private WriteCrcAndSizesInLocalHeader ( bool zip64HeaderUsed ) : void
zip64HeaderUsed bool
Résultat void
        private void WriteCrcAndSizesInLocalHeader(bool zip64HeaderUsed)
        {
            long finalPosition = _archive.ArchiveStream.Position;
            BinaryWriter writer = new BinaryWriter(_archive.ArchiveStream);

            bool zip64Needed = SizesTooLarge()
#if DEBUG_FORCE_ZIP64
 || _archive._forceZip64
#endif
;
            bool pretendStreaming = zip64Needed && !zip64HeaderUsed;

            uint compressedSizeTruncated = zip64Needed ? ZipHelper.Mask32Bit : (uint)_compressedSize;
            uint uncompressedSizeTruncated = zip64Needed ? ZipHelper.Mask32Bit : (uint)_uncompressedSize;

            /* first step is, if we need zip64, but didn't allocate it, pretend we did a stream write, because
             * we can't go back and give ourselves the space that the extra field needs.
             * we do this by setting the correct property in the bit flag */
            if (pretendStreaming)
            {
                _generalPurposeBitFlag |= BitFlagValues.DataDescriptor;

                _archive.ArchiveStream.Seek(_offsetOfLocalHeader + ZipLocalFileHeader.OffsetToBitFlagFromHeaderStart,
                                            SeekOrigin.Begin);
                writer.Write((ushort)_generalPurposeBitFlag);
            }

            /* next step is fill out the 32-bit size values in the normal header. we can't assume that
             * they are correct. we also write the CRC */
            _archive.ArchiveStream.Seek(_offsetOfLocalHeader + ZipLocalFileHeader.OffsetToCrcFromHeaderStart,
                                            SeekOrigin.Begin);
            if (!pretendStreaming)
            {
                writer.Write(_crc32);
                writer.Write(compressedSizeTruncated);
                writer.Write(uncompressedSizeTruncated);
            }
            else //but if we are pretending to stream, we want to fill in with zeroes
            {
                writer.Write((uint)0);
                writer.Write((uint)0);
                writer.Write((uint)0);
            }

            /* next step: if we wrote the 64 bit header initially, a different implementation might
             * try to read it, even if the 32-bit size values aren't masked. thus, we should always put the
             * correct size information in there. note that order of uncomp/comp is switched, and these are
             * 64-bit values
             * also, note that in order for this to be correct, we have to insure that the zip64 extra field
             * is always the first extra field that is written */
            if (zip64HeaderUsed)
            {
                _archive.ArchiveStream.Seek(_offsetOfLocalHeader + ZipLocalFileHeader.SizeOfLocalHeader
                                            + _storedEntryNameBytes.Length + Zip64ExtraField.OffsetToFirstField,
                                            SeekOrigin.Begin);
                writer.Write(_uncompressedSize);
                writer.Write(_compressedSize);

                _archive.ArchiveStream.Seek(finalPosition, SeekOrigin.Begin);
            }

            // now go to the where we were. assume that this is the end of the data
            _archive.ArchiveStream.Seek(finalPosition, SeekOrigin.Begin);

            /* if we are pretending we did a stream write, we want to write the data descriptor out
             * the data descriptor can have 32-bit sizes or 64-bit sizes. In this case, we always use
             * 64-bit sizes */
            if (pretendStreaming)
            {
                writer.Write(_crc32);
                writer.Write(_compressedSize);
                writer.Write(_uncompressedSize);
            }
        }

Usage Example

Exemple #1
0
            protected override void Dispose(bool disposing)
            {
                if (disposing && !_isDisposed)
                {
                    _crcSizeStream.Dispose(); // now we have size/crc info

                    if (!_everWritten)
                    {
                        // write local header, no data, so we use stored
                        _entry.WriteLocalFileHeader(isEmptyFile: true);
                    }
                    else
                    {
                        // go back and finish writing
                        if (_entry._archive.ArchiveStream.CanSeek)
                        {
                            // finish writing local header if we have seek capabilities

                            _entry.WriteCrcAndSizesInLocalHeader(_usedZip64inLH);
                        }
                        else
                        {
                            // write out data descriptor if we don't have seek capabilities
                            _entry.WriteDataDescriptor();
                        }
                    }
                    _canWrite   = false;
                    _isDisposed = true;
                }

                base.Dispose(disposing);
            }