// Write the local file header
        // TODO: ZipHelperStream.WriteLocalHeader is not yet used and needs checking for ZipFile and ZipOuptutStream usage
        void WriteLocalHeader(uZipEntry entry, EntryPatchData patchData)
        {
            CompressionMethod method = entry.CompressionMethod;
            bool headerInfoAvailable = true; // How to get this?
            bool patchEntryHeader = false;

            WriteLEInt(ZipConstants.LocalHeaderSignature);

            WriteLEShort(entry.Version);
            WriteLEShort(entry.Flags);
            WriteLEShort((byte)method);
            WriteLEInt((int)entry.DosTime);

            if (headerInfoAvailable == true) {
                WriteLEInt((int)entry.Crc);
                if ( entry.LocalHeaderRequiresZip64 ) {
                    WriteLEInt(-1);
                    WriteLEInt(-1);
                }
                else {
                    WriteLEInt(entry.IsCrypted ? (int)entry.CompressedSize + ZipConstants.CryptoHeaderSize : (int)entry.CompressedSize);
                    WriteLEInt((int)entry.Size);
                }
            } else {
                if (patchData != null) {
                    patchData.CrcPatchOffset = stream_.Position;
                }
                WriteLEInt(0);	// Crc

                if ( patchData != null ) {
                    patchData.SizePatchOffset = stream_.Position;
                }

                // For local header both sizes appear in Zip64 Extended Information
                if ( entry.LocalHeaderRequiresZip64 && patchEntryHeader ) {
                    WriteLEInt(-1);
                    WriteLEInt(-1);
                }
                else {
                    WriteLEInt(0);	// Compressed size
                    WriteLEInt(0);	// Uncompressed size
                }
            }

            byte[] name = ZipConstants.ConvertToArray(entry.Flags, entry.Name);

            if (name.Length > 0xFFFF) {
                throw new Exception("Entry name too long.");
            }

            ZipExtraData ed = new ZipExtraData(entry.ExtraData);

            if (entry.LocalHeaderRequiresZip64 && (headerInfoAvailable || patchEntryHeader)) {
                ed.StartNewEntry();
                if (headerInfoAvailable) {
                    ed.AddLeLong(entry.Size);
                    ed.AddLeLong(entry.CompressedSize);
                }
                else {
                    ed.AddLeLong(-1);
                    ed.AddLeLong(-1);
                }
                ed.AddNewEntry(1);

                if ( !ed.Find(1) ) {
                    throw new Exception("Internal error cant find extra data");
                }

                if ( patchData != null ) {
                    patchData.SizePatchOffset = ed.CurrentReadIndex;
                }
            }
            else {
                ed.Delete(1);
            }

            byte[] extra = ed.GetEntryData();

            WriteLEShort(name.Length);
            WriteLEShort(extra.Length);

            if ( name.Length > 0 ) {
                stream_.Write(name, 0, name.Length);
            }

            if ( entry.LocalHeaderRequiresZip64 && patchEntryHeader ) {
                patchData.SizePatchOffset += stream_.Position;
            }

            if ( extra.Length > 0 ) {
                stream_.Write(extra, 0, extra.Length);
            }
        }
Пример #2
0
        public uZipEntry(uZipEntry entry)
        {
            if ( entry == null ) {
                throw new ArgumentNullException("entry");
            }

            known                  = entry.known;
            name                   = entry.name;
            size                   = entry.size;
            compressedSize         = entry.compressedSize;
            crc                    = entry.crc;
            dosTime                = entry.dosTime;
            method                 = entry.method;
            comment                = entry.comment;
            versionToExtract       = entry.versionToExtract;
            versionMadeBy          = entry.versionMadeBy;
            externalFileAttributes = entry.externalFileAttributes;
            flags                  = entry.flags;

            zipFileIndex           = entry.zipFileIndex;
            offset                 = entry.offset;

            forceZip64_			   = entry.forceZip64_;

            if ( entry.extra != null ) {
                extra = new byte[entry.extra.Length];
                Array.Copy(entry.extra, 0, extra, 0, entry.extra.Length);
            }
        }
        /// <summary>
        /// Write a data descriptor.
        /// </summary>
        /// <param name="entry">The entry to write a descriptor for.</param>
        /// <returns>Returns the number of descriptor bytes written.</returns>
        public int WriteDataDescriptor(uZipEntry entry)
        {
            if (entry == null) {
                throw new ArgumentNullException("entry");
            }

            int result=0;

            // Add data descriptor if flagged as required
            if ((entry.Flags & (int)GeneralBitFlags.Descriptor) != 0)
            {
                // The signature is not PKZIP originally but is now described as optional
                // in the PKZIP Appnote documenting trhe format.
                WriteLEInt(ZipConstants.DataDescriptorSignature);
                WriteLEInt(unchecked((int)(entry.Crc)));

                result+=8;

                if (entry.LocalHeaderRequiresZip64)
                {
                    WriteLELong(entry.CompressedSize);
                    WriteLELong(entry.Size);
                    result+=16;
                }
                else
                {
                    WriteLEInt((int)entry.CompressedSize);
                    WriteLEInt((int)entry.Size);
                    result+=8;
                }
            }

            return result;
        }