コード例 #1
0
        /// <summary>
        /// Gets the data for the given <paramref name="codecStream"/> and
        /// reports progress to the given <paramref name="progressReporter"/>.
        /// This rescans the parent (container) of the codecStream to determine
        /// the data of codecStream.
        /// </summary>
        /// <param name="codecStream">the codec stream to retrieve the data for</param>
        /// <param name="progressReporter">the progress reporter</param>
        /// <param name="dataReaderPool">The shared pool of file data readers</param>
        /// <returns>the root node of the results</returns>
        public IDataPacket GetData(ICodecStream codecStream, IProgressReporter progressReporter, IDataReaderPool dataReaderPool)
        {
            IDataPacket data;

            if (_dataCache.TryGetValue(codecStream, out data))
            {
                return(new RescannedCodecStream(codecStream, data));
            }

            IDataBlock containerStreamDataBlock = codecStream.DataBlock;

            using (IDataReader dataReader = new ProgressDataReader(new FragmentedDataReader(containerStreamDataBlock, dataReaderPool), progressReporter))
            {
                IDetector    containerDetector = containerStreamDataBlock.Detectors.FirstOrDefault();
                IScanContext scanContext       = _createScanContext(containerStreamDataBlock.InputFile.Project);
                scanContext.Detectors = new[] { containerDetector };
                IDataBlockBuilder containerStreamDataBlockBuilder = _createDataBlockBuilder();
                containerStreamDataBlockBuilder.Detectors = scanContext.Detectors;
                containerStreamDataBlockBuilder.InputFile = containerStreamDataBlock.InputFile;
                IDataBlock newContainerStream = containerDetector.DetectData(dataReader, containerStreamDataBlockBuilder, scanContext);

                // Check cancellation request
                if (progressReporter.CancellationPending)
                {
                    return(null);
                }

                // Check results / container stream
                if (newContainerStream == null)
                {
                    RetrievedDetectableIsDifferentThanTheOneRetrievedDuringTheInitialScan();
                    return(null);
                }

                data = newContainerStream.CodecStreams.Where(c => c.StreamNumber == codecStream.StreamNumber).FirstOrDefault();

                if ((data == null) || (data.Length < codecStream.EndOffset))
                {
                    RetrievedDetectableIsDifferentThanTheOneRetrievedDuringTheInitialScan();
                    return(null);
                }

                data = data.GetSubPacket(codecStream.StartOffset, codecStream.Length);
            }

            CacheData(codecStream, data);

            return(new RescannedCodecStream(codecStream, data));
        }
コード例 #2
0
        private IResultNode RescanDetectable(IFragment detectable, IProgressReporter progressReporter, IDataReaderPool dataReaderPool)
        {
            IDataPacket data = detectable;

            if (detectable is ICodecStream)
            {
                // Data is specified relative to the codec stream (see IDetectable.Data)
                data = GetData(detectable as ICodecStream, progressReporter, dataReaderPool);

                if (progressReporter.CancellationPending)
                {
                    return(null);                                                      // The rescan is cancelled
                }
                var codecStream = detectable as ICodecStream;
                if (codecStream.ReferenceHeader != null)
                {
                    long off = codecStream.ReferenceHeaderOffset;
                    if (off == 0L)
                    {
                        data = codecStream.ReferenceHeader.Append(data);
                    }
                    else
                    {
                        data = data.GetSubPacket(0, off).Append(codecStream.ReferenceHeader).Append(data.GetSubPacket(off, data.Length - off));
                    }
                }
            }
            if (detectable is IDataBlock)
            {
                IDataBlock dataBlock = detectable as IDataBlock;
                if (dataBlock.ReferenceHeader != null)
                {
                    long off = dataBlock.ReferenceHeaderOffset;
                    if (off == 0L)
                    {
                        data = dataBlock.ReferenceHeader.Append(detectable);
                    }
                    else
                    {
                        data = detectable.GetSubPacket(0, off).Append(dataBlock.ReferenceHeader).Append(detectable.GetSubPacket(off, detectable.Length - off));
                    }
                }
            }

            IResultNode results;

            using (IDataReader dataReader = new ProgressDataReader(new FragmentedDataReader(data, dataReaderPool), progressReporter))
            {
                IScanContext scanContext = _createScanContext(detectable.InputFile.Project);
                scanContext.Detectors = detectable.Detectors;

                IDataBlockBuilder dataBlockBuilder = _createDataBlockBuilder();
                dataBlockBuilder.Detectors = scanContext.Detectors;
                dataBlockBuilder.InputFile = detectable.InputFile;

                IDetector  detector = GetDetector(detectable);
                IDataBlock newDataBlock;

                var codecDetector = (detector as ICodecDetector);
                if (codecDetector == null)
                {
                    newDataBlock = detector.DetectData(dataReader, dataBlockBuilder, scanContext);
                }
                else
                {
                    var referenceHeaders = codecDetector.ReferenceHeaders;
                    try
                    {
                        // Disable reference headers during rescan
                        codecDetector.ReferenceHeaders = null;
                        newDataBlock = detector.DetectData(dataReader, dataBlockBuilder, scanContext);
                    }
                    finally
                    {
                        // Restore reference headers
                        codecDetector.ReferenceHeaders = referenceHeaders;
                    }
                }

                if (!progressReporter.CancellationPending && newDataBlock == null)
                {
                    RetrievedDetectableIsDifferentThanTheOneRetrievedDuringTheInitialScan();
                    return(null);
                }

                results = scanContext.Results;

                // Check cancellation request and results / data block
                if (!progressReporter.CancellationPending && (detectable is IDataBlock) && !IsDataBlockCorrect(detectable as IDataBlock, newDataBlock))
                {
                    //RetrievedDetectableIsDifferentThanTheOneRetrievedDuringTheInitialScan();
                    //return null;
                }
            }
            return(results);
        }