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

WriteLocalFileHeader() private méthode

private WriteLocalFileHeader ( bool isEmptyFile ) : bool
isEmptyFile bool
Résultat bool
        private bool WriteLocalFileHeader(bool isEmptyFile)
        {
            BinaryWriter writer = new BinaryWriter(_archive.ArchiveStream);

            //_entryname only gets set when we read in or call moveTo. MoveTo does a check, and
            //reading in should not be able to produce a entryname longer than ushort.MaxValue
            Debug.Assert(_storedEntryNameBytes.Length <= ushort.MaxValue);

            //decide if we need the Zip64 extra field:
            Zip64ExtraField zip64ExtraField = new Zip64ExtraField();
            bool zip64Used = false;
            uint compressedSizeTruncated, uncompressedSizeTruncated;

            //if we already know that we have an empty file don't worry about anything, just do a straight shot of the header
            if (isEmptyFile)
            {
                CompressionMethod = CompressionMethodValues.Stored;
                compressedSizeTruncated = 0;
                uncompressedSizeTruncated = 0;
                Debug.Assert(_compressedSize == 0);
                Debug.Assert(_uncompressedSize == 0);
                Debug.Assert(_crc32 == 0);
            }
            else
            {
                //if we have a non-seekable stream, don't worry about sizes at all, and just set the right bit
                //if we are using the data descriptor, then sizes and crc should be set to 0 in the header
                if (_archive.Mode == ZipArchiveMode.Create && _archive.ArchiveStream.CanSeek == false && !isEmptyFile)
                {
                    _generalPurposeBitFlag |= BitFlagValues.DataDescriptor;
                    zip64Used = false;
                    compressedSizeTruncated = 0;
                    uncompressedSizeTruncated = 0;
                    //the crc should not have been set if we are in create mode, but clear it just to be sure
                    Debug.Assert(_crc32 == 0);
                }
                else //if we are not in streaming mode, we have to decide if we want to write zip64 headers
                {
                    if (SizesTooLarge()
#if DEBUG_FORCE_ZIP64
 || (_archive._forceZip64 && _archive.Mode == ZipArchiveMode.Update)
#endif
)
                    {
                        zip64Used = true;
                        compressedSizeTruncated = ZipHelper.Mask32Bit;
                        uncompressedSizeTruncated = ZipHelper.Mask32Bit;

                        //prepare Zip64 extra field object. If we have one of the sizes, the other must go in there
                        zip64ExtraField.CompressedSize = _compressedSize;
                        zip64ExtraField.UncompressedSize = _uncompressedSize;

                        VersionToExtractAtLeast(ZipVersionNeededValues.Zip64);
                    }
                    else
                    {
                        zip64Used = false;
                        compressedSizeTruncated = (uint)_compressedSize;
                        uncompressedSizeTruncated = (uint)_uncompressedSize;
                    }
                }
            }

            //save offset
            _offsetOfLocalHeader = writer.BaseStream.Position;

            //calculate extra field. if zip64 stuff + original extraField aren't going to fit, dump the original extraField, because this is more important
            int bigExtraFieldLength = (zip64Used ? zip64ExtraField.TotalSize : 0)
                                      + (_lhUnknownExtraFields != null ? ZipGenericExtraField.TotalSize(_lhUnknownExtraFields) : 0);
            ushort extraFieldLength;
            if (bigExtraFieldLength > ushort.MaxValue)
            {
                extraFieldLength = (ushort)(zip64Used ? zip64ExtraField.TotalSize : 0);
                _lhUnknownExtraFields = null;
            }
            else
            {
                extraFieldLength = (ushort)bigExtraFieldLength;
            }

            //write header
            writer.Write(ZipLocalFileHeader.SignatureConstant);
            writer.Write((ushort)_versionToExtract);
            writer.Write((ushort)_generalPurposeBitFlag);
            writer.Write((ushort)CompressionMethod);
            writer.Write(ZipHelper.DateTimeToDosTime(_lastModified.DateTime)); //uint
            writer.Write(_crc32);               //uint
            writer.Write(compressedSizeTruncated);  //uint
            writer.Write(uncompressedSizeTruncated); //uint
            writer.Write((ushort)_storedEntryNameBytes.Length);
            writer.Write(extraFieldLength);    //ushort

            writer.Write(_storedEntryNameBytes);

            if (zip64Used)
                zip64ExtraField.WriteBlock(_archive.ArchiveStream);
            if (_lhUnknownExtraFields != null)
                ZipGenericExtraField.WriteAllBlocks(_lhUnknownExtraFields, _archive.ArchiveStream);

            return zip64Used;
        }

Usage Example

Exemple #1
0
            // careful: assumes that write is the only way to write to the stream, if writebyte/beginwrite are implemented
            // they must set _everWritten, etc.
            public override void Write(byte[] buffer, int offset, int count)
            {
                //we can't pass the argument checking down a level
                if (buffer == null)
                {
                    throw new ArgumentNullException(nameof(buffer));
                }
                if (offset < 0)
                {
                    throw new ArgumentOutOfRangeException(nameof(offset));
                }
                if (count < 0)
                {
                    throw new ArgumentOutOfRangeException(nameof(count));
                }
                if ((buffer.Length - offset) < count)
                {
                    throw new ArgumentException();
                }

                ThrowIfDisposed();
                Debug.Assert(CanWrite);

                // if we're not actually writing anything, we don't want to trigger the header
                if (count == 0)
                {
                    return;
                }

                if (!_everWritten)
                {
                    _everWritten = true;
                    // write local header, we are good to go
                    _usedZip64inLH = _entry.WriteLocalFileHeader(isEmptyFile: false);
                }

                _crcSizeStream.Write(buffer, offset, count);
                _position += count;
            }