public IDataBlock DetectData(IDataReader dataReader, IDataBlockBuilder dataBlockBuilder, IScanContext context)
        {
            if (dataReader.State != DataReaderState.Ready)
            {
                return(null);
            }

            try
            {
                long       startPosition = dataReader.Position;
                IDataBlock dataBlock     = _detector.DetectData(dataReader, dataBlockBuilder, context);

                if (dataReader.State == DataReaderState.Cancelled)
                {
                    dataReader.Position = dataReader.Length;
                }
                else if (dataReader.Position <= startPosition)
                {
                    // Force advance stream reader one byte
                    Log.Error(string.Format("Detector {0} did not advance the stream reader position.", _detector.Name));
                    dataReader.Position = startPosition + 1;
                }

                return(dataBlock);
            }
            catch (OutOfMemoryException)
            {
                // TODO improve out of memory exception handling and remove reference to System.Windows.Forms
                System.Windows.Forms.MessageBox.Show("There is not enough memory available to continue scanning current data block (2); Position: " + dataReader.Position + "; Detector: " + _detector.Name + "; Header count: ?", "Out Of Memory");

                // Skip rest of the stream
                dataReader.Position = dataReader.Length;
                return(null);
            }
        }
        /// <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));
        }
Esempio n. 3
0
        private bool GetNextDataBlock(IInputFile file, IDataReader dataReader, IScanContext scanContext, out IDataBlock volBlock, out IDataBlockBuilder volBuilder)
        {
            IDataBlock        volBlockAttempt        = null;
            IDataBlockBuilder volBlockAttemptBuilder = null;

            while (volBlockAttempt == null && dataReader.State == DataReaderState.Ready)
            {
                volBlockAttemptBuilder = CreateBuilder(file);
                scanContext.Detectors  = new[] { _detector };
                volBlockAttempt        = _detector.DetectData(dataReader, volBlockAttemptBuilder, scanContext);
            }
            volBlock   = volBlockAttempt;
            volBuilder = volBlockAttemptBuilder;
            return(volBlock != null);
        }
Esempio n. 4
0
        private IDataBlock ScanDataBlock(byte[] byteStream, IScanContext scanContext)
        {
            scanContext.Detectors = new[] { _videoDetector };
            IDataBlockBuilder builder = TestFramework.CreateDataBlockBuilder();

            builder.Detectors = scanContext.Detectors;
            var inputFile = _mockRepository.StrictMock <IInputFile>();

            With.Mocks(_mockRepository).Expecting(delegate
            {
                SetupResult.For(inputFile.Name).Return("<ByteArrayDataReader>");
                SetupResult.For(inputFile.Length).Return(byteStream.Length);
            });
            builder.InputFile = inputFile;
            var        mockDataReader = new MockDataReader(byteStream, inputFile);
            IDataBlock dataBlock      = _videoDetector.DetectData(mockDataReader, builder, scanContext);

            Assert.IsNotNull(dataBlock);
            return(dataBlock);
        }
 public void TestDetectData()
 {
     using (IDataReader dataReader = new MockDataReader(new byte[DataFileLength], _inputFile))
     {
         IScanContext scanContext = TestFramework.CreateScanContext(_project);
         scanContext.Detectors = new[] { _detector };
         IDataBlockBuilder builder = TestFramework.CreateDataBlockBuilder();
         builder.Detectors = scanContext.Detectors;
         builder.InputFile = _inputFile;
         IDataBlock dataBlock = _detector.DetectData(dataReader, builder, scanContext);
         Assert.IsNotNull(dataBlock, "Unknown format detector (DetectData not null)");
         IResultNode results = scanContext.Results;
         Assert.IsNotNull(results, "Unknown format detector (Results not null)");
         Assert.AreEqual(_detector, dataBlock.Detectors.First(), "Detector of data block");
         Assert.AreEqual(1, results.Children.Count, "One child 'Data'");
         IResultNode data = results.Children[0];
         Assert.IsEmpty((ICollection)data.Children, "Data has no children");
         Assert.AreEqual(0, data.StartOffset, "");
         Assert.AreEqual(DataFileLength, data.Length, "");
         Assert.IsFalse(data.IsFragmented(), "Single fragment");
         Assert.AreEqual(_inputFile, data.InputFile, "Input file");
         Assert.IsFalse(dataBlock.IsFullFile, "Does not produce full files");
     }
 }
        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);
        }