System.IO.Compression.ZipHelper.SeekBackwardsToSignature C# (CSharp) Méthode

SeekBackwardsToSignature() static private méthode

static private SeekBackwardsToSignature ( Stream stream, uint signatureToFind ) : bool
stream Stream
signatureToFind uint
Résultat bool
        internal static bool SeekBackwardsToSignature(Stream stream, uint signatureToFind)
        {
            int bufferPointer = 0;
            uint currentSignature = 0;
            byte[] buffer = new byte[BackwardsSeekingBufferSize];

            bool outOfBytes = false;
            bool signatureFound = false;

            while (!signatureFound && !outOfBytes)
            {
                outOfBytes = SeekBackwardsAndRead(stream, buffer, out bufferPointer);

                Debug.Assert(bufferPointer < buffer.Length);

                while (bufferPointer >= 0 && !signatureFound)
                {
                    currentSignature = (currentSignature << 8) | ((uint)buffer[bufferPointer]);
                    if (currentSignature == signatureToFind)
                    {
                        signatureFound = true;
                    }
                    else
                    {
                        bufferPointer--;
                    }
                }
            }

            if (!signatureFound)
            {
                return false;
            }
            else
            {
                stream.Seek(bufferPointer, SeekOrigin.Current);
                return true;
            }
        }

Usage Example

Exemple #1
0
        //This function reads all the EOCD stuff it needs to find the offset to the start of the central directory
        //This offset gets put in _centralDirectoryStart and the number of this disk gets put in _numberOfThisDisk
        //Also does some verification that this isn't a split/spanned archive
        //Also checks that offset to CD isn't out of bounds
        private void ReadEndOfCentralDirectory()
        {
            try
            {
                //this seeks to the start of the end of central directory record
                _archiveStream.Seek(-ZipEndOfCentralDirectoryBlock.SizeOfBlockWithoutSignature, SeekOrigin.End);
                if (!ZipHelper.SeekBackwardsToSignature(_archiveStream, ZipEndOfCentralDirectoryBlock.SignatureConstant))
                {
                    throw new InvalidDataException(SR.EOCDNotFound);
                }

                long eocdStart = _archiveStream.Position;

                //read the EOCD
                ZipEndOfCentralDirectoryBlock eocd;
                bool eocdProper = ZipEndOfCentralDirectoryBlock.TryReadBlock(_archiveReader, out eocd);
                Debug.Assert(eocdProper); //we just found this using the signature finder, so it should be okay

                if (eocd.NumberOfThisDisk != eocd.NumberOfTheDiskWithTheStartOfTheCentralDirectory)
                {
                    throw new InvalidDataException(SR.SplitSpanned);
                }

                _numberOfThisDisk      = eocd.NumberOfThisDisk;
                _centralDirectoryStart = eocd.OffsetOfStartOfCentralDirectoryWithRespectToTheStartingDiskNumber;
                if (eocd.NumberOfEntriesInTheCentralDirectory != eocd.NumberOfEntriesInTheCentralDirectoryOnThisDisk)
                {
                    throw new InvalidDataException(SR.SplitSpanned);
                }
                _expectedNumberOfEntries = eocd.NumberOfEntriesInTheCentralDirectory;

                //only bother saving the comment if we are in update mode
                if (_mode == ZipArchiveMode.Update)
                {
                    _archiveComment = eocd.ArchiveComment;
                }

                //only bother looking for zip64 EOCD stuff if we suspect it is needed because some value is FFFFFFFFF
                //because these are the only two values we need, we only worry about these
                //if we don't find the zip64 EOCD, we just give up and try to use the original values
                if (eocd.NumberOfThisDisk == ZipHelper.Mask16Bit ||
                    eocd.OffsetOfStartOfCentralDirectoryWithRespectToTheStartingDiskNumber == ZipHelper.Mask32Bit ||
                    eocd.NumberOfEntriesInTheCentralDirectory == ZipHelper.Mask16Bit)
                {
                    //we need to look for zip 64 EOCD stuff
                    //seek to the zip 64 EOCD locator
                    _archiveStream.Seek(eocdStart - Zip64EndOfCentralDirectoryLocator.SizeOfBlockWithoutSignature, SeekOrigin.Begin);
                    //if we don't find it, assume it doesn't exist and use data from normal eocd
                    if (ZipHelper.SeekBackwardsToSignature(_archiveStream, Zip64EndOfCentralDirectoryLocator.SignatureConstant))
                    {
                        //use locator to get to Zip64EOCD
                        Zip64EndOfCentralDirectoryLocator locator;
                        bool zip64eocdLocatorProper = Zip64EndOfCentralDirectoryLocator.TryReadBlock(_archiveReader, out locator);
                        Debug.Assert(zip64eocdLocatorProper); //we just found this using the signature finder, so it should be okay

                        if (locator.OffsetOfZip64EOCD > (ulong)long.MaxValue)
                        {
                            throw new InvalidDataException(SR.FieldTooBigOffsetToZip64EOCD);
                        }
                        long zip64EOCDOffset = (long)locator.OffsetOfZip64EOCD;

                        _archiveStream.Seek(zip64EOCDOffset, SeekOrigin.Begin);

                        //read Zip64EOCD
                        Zip64EndOfCentralDirectoryRecord record;
                        if (!Zip64EndOfCentralDirectoryRecord.TryReadBlock(_archiveReader, out record))
                        {
                            throw new InvalidDataException(SR.Zip64EOCDNotWhereExpected);
                        }

                        _numberOfThisDisk = record.NumberOfThisDisk;

                        if (record.NumberOfEntriesTotal > (ulong)long.MaxValue)
                        {
                            throw new InvalidDataException(SR.FieldTooBigNumEntries);
                        }
                        if (record.OffsetOfCentralDirectory > (ulong)long.MaxValue)
                        {
                            throw new InvalidDataException(SR.FieldTooBigOffsetToCD);
                        }
                        if (record.NumberOfEntriesTotal != record.NumberOfEntriesOnThisDisk)
                        {
                            throw new InvalidDataException(SR.SplitSpanned);
                        }

                        _expectedNumberOfEntries = (long)record.NumberOfEntriesTotal;
                        _centralDirectoryStart   = (long)record.OffsetOfCentralDirectory;
                    }
                }

                if (_centralDirectoryStart > _archiveStream.Length)
                {
                    throw new InvalidDataException(SR.FieldTooBigOffsetToCD);
                }
            }
            catch (EndOfStreamException ex)
            {
                throw new InvalidDataException(SR.CDCorrupt, ex);
            }
            catch (IOException ex)
            {
                throw new InvalidDataException(SR.CDCorrupt, ex);
            }
        }
All Usage Examples Of System.IO.Compression.ZipHelper::SeekBackwardsToSignature