public void BuildEndOffsetBeforeStartOffset()
        {
            IDataBlockBuilder dataBlockBuilder = CreateDataBlockBuilder1();

            dataBlockBuilder.EndOffset = (StartOffset1 - 1);
            dataBlockBuilder.Build();
        }
        public void BuildEndOffsetEqualToStartOffset()
        {
            IDataBlockBuilder dataBlockBuilder = CreateDataBlockBuilder1();

            dataBlockBuilder.EndOffset = StartOffset1;
            dataBlockBuilder.Build();
        }
        public void BuildEndOffsetAfterEndOfFile()
        {
            IDataBlockBuilder dataBlockBuilder = CreateDataBlockBuilder1();

            dataBlockBuilder.EndOffset = (FileLength1 + 1);
            dataBlockBuilder.Build();
        }
        public void EqualsDifferentDetector()
        {
            IDataBlockBuilder dataBlockBuilder = CreateDataBlockBuilder1();

            dataBlockBuilder.Detectors = new[] { _detector2 };
            Assert.IsFalse(_dataBlock1.Equals(dataBlockBuilder.Build()));
        }
        public void EqualsDifferentDataFormat()
        {
            IDataBlockBuilder dataBlockBuilder = CreateDataBlockBuilder1();

            dataBlockBuilder.DataFormat = CodecID.Mpeg1System;
            Assert.IsFalse(_dataBlock1.Equals(dataBlockBuilder.Build()));
        }
        public void BuildInputFileNull()
        {
            IDataBlockBuilder dataBlockBuilder = CreateDataBlockBuilder1();

            dataBlockBuilder.InputFile = null;
            dataBlockBuilder.Build();
        }
        public void BuildEndOffsetNegative()
        {
            IDataBlockBuilder dataBlockBuilder = CreateDataBlockBuilder1();

            dataBlockBuilder.EndOffset = -1;
            dataBlockBuilder.Build();
        }
        public void EqualsDifferentInputFile()
        {
            IDataBlockBuilder dataBlockBuilder = CreateDataBlockBuilder1();

            dataBlockBuilder.InputFile = _inputFile2;
            Assert.IsFalse(_dataBlock1.Equals(dataBlockBuilder.Build()));
        }
        public void BuildDetectorNull()
        {
            IDataBlockBuilder dataBlockBuilder = CreateDataBlockBuilder1();

            dataBlockBuilder.Detectors = null;
            dataBlockBuilder.Build();
        }
        public void EqualsDifferentEndOffset()
        {
            IDataBlockBuilder dataBlockBuilder = CreateDataBlockBuilder1();

            dataBlockBuilder.EndOffset = (EndOffset1 + 1);
            Assert.IsFalse(_dataBlock1.Equals(dataBlockBuilder.Build()));
        }
        public void EqualsDifferentIsFullFile()
        {
            IDataBlockBuilder dataBlockBuilder = CreateDataBlockBuilder1();

            dataBlockBuilder.IsFullFile = true;
            Assert.IsFalse(_dataBlock1.Equals(dataBlockBuilder.Build()));
        }
        private IDataBlock DetectData1(IDataReader dataReader, IDataBlockBuilder dataBlockBuilder, IScanContext context)
        {
            if ((dataReader.Position + 51) > dataReader.Length)
            {
                return(null);
            }

            IResultNode root   = new MockResult(this);
            IResultNode parent = root;
            int         i      = (int)(dataReader.GetDataPacket(0, 1).StartOffset + (dataReader.Position) / 51);

            for (int j = 0; j < 3; j++)
            {
                long       offset = dataReader.Position;
                const long length = 17;
                parent = new MockResult(parent, dataReader, offset, length, "result: " + i + ", " + j);
                dataReader.Position += length;
            }
            context.Results = root;
            var firstChild = ((MockResult)context.Results.Children[0]);

            dataBlockBuilder.StartOffset = firstChild.Offset;
            var lastChild = ((MockResult)context.Results.GetLastDescendant());

            dataBlockBuilder.EndOffset = (lastChild.Offset + lastChild.Length);
            return(dataBlockBuilder.Build());
        }
        override public IDataBlock DetectData(IDataReader dataReader, IDataBlockBuilder dataBlockBuilder, IScanContext context)
        {
            AsfObject root = new AsfObject(context.Detectors);

            // Try to parse a contiguous block of ASF objects
            using (AsfParser parser = new AsfParser(new ByteStreamDataReader(dataReader, Endianness.Little)))
            {
                if (!parser.ParseRoot(root, dataReader.Length))
                {
                    dataReader.Position = dataReader.Length;
                    return(null);
                }

                // Synchronize the position of the data reader
                dataReader.Position = parser.Position;
            }

            // Trim trailing unknown, padding byte or large unparsable ASF objects
            AsfObject lastAsfObject = root.LastHeader;

            while (lastAsfObject.IsUnknown && lastAsfObject.Parent != null)
            {
                if (lastAsfObject.RelativeEndOffset == ((AsfObject)lastAsfObject.Parent).RelativeEndOffset)
                {
                    break;                      // Last child perfectly aligned with parent object
                }

                lastAsfObject.Parent.RemoveChild(lastAsfObject);
                lastAsfObject = root.LastHeader;
            }

            if ((dataReader.State == DataReaderState.Cancelled) ||
                (root.Children.Count == 0) ||
                (root.Children.Count == 1 && !root.FirstChild.HasChildren()))                   // Discard data blocks of only 1 ASF object
            {
                // Rewind data reader
                dataReader.Position = lastAsfObject.Offset + lastAsfObject.Length;                      // != lastHeader.RelativeEndOffset; !!!

                return(null);
            }

            context.Results = root;

            dataBlockBuilder.DataFormat = root.DataFormat;
            var firstChild = ((AsfObject)root.Children[0]);

            dataBlockBuilder.StartOffset = firstChild.Offset;
            var lastChild = ((AsfObject)root.GetLastDescendant());
            var endOffset = (lastChild.Offset + lastChild.Length);

            dataBlockBuilder.EndOffset = endOffset;

            CodecStream codecStream = new CodecStream(root);

            codecStream.CreateCodecStreams(dataBlockBuilder);

            dataReader.Position = endOffset;
            return(dataBlockBuilder.Build());
        }
        public void Equals()
        {
            IDataBlockBuilder dataBlockBuilder = CreateDataBlockBuilder1();

            Assert.IsTrue(_dataBlock1.Equals(dataBlockBuilder.Build()));
            Assert.IsFalse(_dataBlock1.Equals(_dataBlock2));
            Assert.IsFalse(_dataBlock2.Equals(_dataBlock1));
        }
Пример #15
0
        public IDataBlock Carve(long offsetLimit)
        {
            if ((offsetLimit < 0) || (offsetLimit > _dataReader.Length))
            {
                throw new ArgumentOutOfRangeException("offsetLimit");
            }

            try
            {
                _readerState.Reset();

                // Find possible start of header sequence
                while (!IsCancelled && (Position < offsetLimit) && _dataBlockCarver.Carve(offsetLimit))
                {
                    // Try to construct a valid header sequence
                    long dataBlockStartOffset = Position;
                    long dataBlockEndOffset   = Position;

                    while (_readerState.Valid)
                    {
                        dataBlockEndOffset = Position;

                        _dataBlockCarver.ParseHeader(_readerState);
                    }

                    // Try to create and return valid result!
                    if (!IsCancelled && ValidateDataBlock(dataBlockStartOffset, dataBlockEndOffset))
                    {
                        var dataBlock = _dataBlockBuilder.Build();
                        _resultMetadata.Init(dataBlock);

                        Position = dataBlock.EndOffset;
                        return(dataBlock);
                    }

                    // TODO: The data block carver should be able to skip any number of bytes ... (to avoid O(N^2) performance in some cases)

                    // Not a valid header sequence: Rewind and skip 1 byte
                    // Rewind data reader for incorrect header to avoid skipping correct headers after a dummy start code
                    Position = dataBlockStartOffset + 1;                    // Note: This is slightly inefficient for MPEG-2 (we could skip upto 4 bytes)

                    // Start new block
                    _readerState.Reset();
                }

                // No valid headers found or cancelled
                //Position = Math.Max(Position, offsetLimit);
                return(null);
            }
            finally
            {
                FlushStream();
            }
        }
Пример #16
0
        internal static IDataBlock CreateDataBlock(IDetector detector, IDataPacket data, bool isFullFile, IDataBlock lastDataBlock)
        {
            IDataBlockBuilder dataBlockBuilder = CreateDataBlockBuilder();

            dataBlockBuilder.DataFormat   = CodecID.Unknown;
            dataBlockBuilder.Detectors    = new[] { detector };
            dataBlockBuilder.InputFile    = data.InputFile;
            dataBlockBuilder.StartOffset  = data.StartOffset;
            dataBlockBuilder.EndOffset    = data.EndOffset;
            dataBlockBuilder.IsFullFile   = isFullFile;
            dataBlockBuilder.IsFragmented = false;
            return(dataBlockBuilder.Build());
        }
        private static IDataBlock Carve(IDataReader dataReader, IDataBlockBuilder dataBlockBuilder, IScanContext context)
        {
            // Try to parse a contiguous block of headers
            using (var parser = new Mpeg4Parser(new BitStreamDataReader(dataReader)))
            {
                if (context.ReferenceHeader is Dictionary <IDataPacket, VideoObjectLayer> )
                {
                    parser.ReferenceHeaders = context.ReferenceHeader as Dictionary <IDataPacket, VideoObjectLayer>;
                }

                Mpeg4Header root;
                while (parser.ParseRoot(root = new Mpeg4Header(context.Detectors), dataReader.Length))
                {
                    Mpeg4Header lastHeader = root.LastHeader;
                    if (lastHeader.ZeroByteStuffing > 0)
                    {
                        lastHeader.TrimZeroByteStuffing(parser);
                    }

                    // Discard results that do not contain a VOP, short video VOP or VOL.
                    // Discard data blocks of only one header that is not a H.263 Short Header VOP.
                    // The Short Header VOP counts for two headers because it is hard to correctly
                    // parse a Short Header VOP from random bits.
                    var requiredMpeg4Headers = new[] { Mpeg4HeaderName.VideoObjectLayer, Mpeg4HeaderName.Vop, Mpeg4HeaderName.VopWithShortHeader };
                    if (RequiredHeaderCount(root) && root.ContainsChildren(requiredMpeg4Headers, true) && RequiredShortHeaderCount(root))
                    {
                        context.Results = root;

                        dataBlockBuilder.DataFormat = root.DataFormat;
                        var firstChild = ((Mpeg4Header)root.Children[0]);
                        dataBlockBuilder.StartOffset = firstChild.Offset;
                        var lastChild = ((Mpeg4Header)root.GetLastDescendant());
                        var endOffset = (lastChild.Offset + lastChild.Length);
                        dataBlockBuilder.EndOffset = endOffset;
                        dataReader.Position        = endOffset;
                        if (parser.ReferenceHeader != null)
                        {
                            dataBlockBuilder.ReferenceHeaderOffset = parser.ReferenceHeaderPosition - firstChild.Offset;
                            dataBlockBuilder.ReferenceHeader       = parser.ReferenceHeader;
                        }
                        return(dataBlockBuilder.Build());
                    }

                    RewindParser(parser, lastHeader);
                }
            }

            dataReader.Position = dataReader.Length;
            return(null);            // Nothing detected!
        }
        private void FixAndReportDataBlock(IDataBlock dataBlock)
        {
            IDataBlockBuilder dataBlockBuilder = _createDataBlockBuilder();

            dataBlockBuilder.DataFormat            = dataBlock.DataFormat;
            dataBlockBuilder.Detectors             = dataBlock.Detectors;
            dataBlockBuilder.StartOffset           = dataBlock.StartOffset + _fixedDataBlockStartOffset;
            dataBlockBuilder.EndOffset             = dataBlock.EndOffset + _fixedDataBlockStartOffset;
            dataBlockBuilder.InputFile             = dataBlock.InputFile;
            dataBlockBuilder.IsFullFile            = dataBlock.IsFullFile;
            dataBlockBuilder.PreviousFragment      = _fixedDataBlock;
            dataBlockBuilder.ReferenceHeaderOffset = dataBlock.ReferenceHeaderOffset;
            dataBlockBuilder.ReferenceHeader       = dataBlock.ReferenceHeader;
            _fixedDataBlock = dataBlockBuilder.Build();

            ReportDataBlock(_fixedDataBlock);
        }
        private IDataBlock DetectData3(IDataReader dataReader, IDataBlockBuilder dataBlockBuilder, IScanContext context)
        {
            IResultNode root = new MockResult(this);

            for (int i = 0; i < 17; i++)
            {
                long       offset = i * 15;
                const long length = 15;
                new MockResult(root, dataReader, offset, length, "result: " + i);
            }
            context.Results = root;
            var firstChild = ((MockResult)context.Results.Children[0]);

            dataBlockBuilder.StartOffset = firstChild.Offset;
            var lastChild = ((MockResult)context.Results.GetLastDescendant());

            dataBlockBuilder.EndOffset = (lastChild.Offset + lastChild.Length);
            return(dataBlockBuilder.Build());
        }
Пример #20
0
        public IDataBlock DetectData(IDataReader dataReader, IDataBlockBuilder dataBlockBuilder, IScanContext context)
        {
            long startOffset = dataReader.Position;
            long endOffset   = dataReader.Length;

            IMetadata          metadata          = new Metadata(CodecID.Unknown, context.Detectors);
            IResultNode        root              = new RootResult(metadata, dataReader.GetDataPacket(0, 1).InputFile);
            IResultNodeBuilder resultNodeBuilder = new ResultNodeBuilder
            {
                Name       = "Data",
                Metadata   = metadata,
                DataPacket = dataReader.GetDataPacket(startOffset, (endOffset - startOffset))
            };

            root.AddChild(resultNodeBuilder.Build());
            context.Results = root;

            dataBlockBuilder.DataFormat  = CodecID.Unknown;
            dataBlockBuilder.StartOffset = startOffset;
            dataBlockBuilder.EndOffset   = endOffset;
            dataReader.Position          = endOffset;
            return(dataBlockBuilder.Build());
        }
        private void ScanCodecStreams(DataBlockDetectedEventArgs e, IDataBlock dataBlock)
        {
            IProgressReporter dataBlockProgressReporter = _createSubProgressReporter(_codecProgressReporter, dataBlock.StartOffset, dataBlock.Length, dataBlock.InputFile.Length);
            long      totalStreamBytes       = dataBlock.CodecStreams.Sum(x => x.Length);
            long      streamBytesScanned     = 0L;
            bool      hasCompleteCodecStream = false;
            IDetector detector = null;

            IDataBlockBuilder dataBlockBuilder = _createDataBlockBuilder();

            dataBlockBuilder.DataFormat            = dataBlock.DataFormat;
            dataBlockBuilder.Detectors             = dataBlock.Detectors;
            dataBlockBuilder.InputFile             = dataBlock.InputFile;
            dataBlockBuilder.IsFullFile            = dataBlock.IsFullFile;
            dataBlockBuilder.IsFragmented          = dataBlock.IsFragmented;
            dataBlockBuilder.PreviousFragment      = LastDataBlock;
            dataBlockBuilder.StartOffset           = dataBlock.StartOffset;
            dataBlockBuilder.EndOffset             = dataBlock.EndOffset;
            dataBlockBuilder.ReferenceHeaderOffset = dataBlock.ReferenceHeaderOffset;
            dataBlockBuilder.ReferenceHeader       = dataBlock.ReferenceHeader;

            foreach (ICodecStream completeCodecStream in dataBlock.CodecStreams)
            {
                IProgressReporter codecStreamProgressReporter = _createSubProgressReporter(dataBlockProgressReporter, streamBytesScanned, completeCodecStream.Length, totalStreamBytes);
                var completeCodecStreamScanner = new CompleteCodecStreamScanner(_codecStreamDataScanner, dataBlockBuilder, completeCodecStream, codecStreamProgressReporter);

                // Note: The container detector that was used is not available to the codec detector!

                // NOTE: We assume that a file never uses multiple codec formats that are supported by Defraser.
                //       So, if at any time for example audio codecs will be supported, this code should be revised!
                using (IDataReader dataReader = _dataReaderPool.CreateDataReader(completeCodecStream, completeCodecStreamScanner))
                {
                    if (detector != null)
                    {
                        // Only scan other streams with the detector that already produced a valid and complete result
                        if (!completeCodecStreamScanner.ScanForNearlyCompleteCodecStream(dataReader))
                        {
                            AddUnknownCodecStream(dataBlockBuilder, completeCodecStream);
                        }
                    }
                    else
                    {
                        detector = completeCodecStreamScanner.ScanDetectForNearlyCompleteCodecStream(dataReader, CodecDetectors);

                        if (detector == null)
                        {
                            AddUnknownCodecStream(dataBlockBuilder, completeCodecStream);
                        }
                    }

                    hasCompleteCodecStream |= completeCodecStreamScanner.HasCompleteCodecStream;
                }

                streamBytesScanned += completeCodecStream.Length;
            }

            if (!hasCompleteCodecStream)
            {
                e.DoubleScanPayload = true;
            }

            LastDataBlock = dataBlockBuilder.Build();

            ReportDataBlock(LastDataBlock);
        }
Пример #22
0
        override public IDataBlock DetectData(IDataReader dataReader, IDataBlockBuilder dataBlockBuilder, IScanContext context)
        {
            QtAtom root = new QtAtom(context.Detectors);

            // Try to parse a contiguous block of headers
            using (QtParser parser = new QtParser(new ByteStreamDataReader(dataReader)))
            {
                if (!parser.ParseRoot(root, dataReader.Length))
                {
                    dataReader.Position = dataReader.Length;
                    return(null);
                }

                // Synchronize the position of the data reader
                dataReader.Position = parser.Position;
            }

            // Trim trailing unknown or large unparsable atoms
            QtAtom lastHeader        = root.LastHeader;
            long   firstHeaderOffset = ((QtAtom)root.Children[0]).Offset;

            while (lastHeader.IsUnknown && lastHeader.Parent != null)
            {
                if (lastHeader.RelativeEndOffset == ((QtAtom)lastHeader.Parent).RelativeEndOffset)
                {
                    break;                      // Last child perfectly aligned with parent atom
                }

                lastHeader.Parent.RemoveChild(lastHeader);
                lastHeader = root.LastHeader;
            }

            // Discard data blocks of only 1 atom
            if ((dataReader.State == DataReaderState.Cancelled) ||
                (root.Children.Count == 0) ||
                ((root.Children.Count == 1) && !root.FirstChild.HasChildren()))
            {
                // Rewind data reader
                dataReader.Position = firstHeaderOffset + 1; // lastHeader.Offset + lastHeader.Length; // != lastHeader.RelativeEndOffset; !!!

                return(null);
            }

            context.Results = root;

            var  codecStream    = new CodecStream(dataReader, dataBlockBuilder, root);
            long?rescanPosition = codecStream.CreateCodecStreams();

            // TODO: check for (complete) mdat block (for IsFullFile)

            // Note: For consistency, always report the name of the detector itself, not a specific data format!
            //dataBlockBuilder.DataFormat = root.DataFormat;
            dataBlockBuilder.IsFullFile = IsFullFile(root);
            var firstChild = ((QtAtom)root.Children[0]);

            dataBlockBuilder.StartOffset = firstChild.Offset;
            var lastChild = ((QtAtom)root.GetLastDescendant());
            var endOffset = (lastChild.Offset + lastChild.Length);

            dataBlockBuilder.EndOffset = endOffset;
            dataReader.Position        = rescanPosition ?? endOffset;

            // If the last atom is an 'mdat' atom that was truncated for rescan to its minimum size, truncate the actual result!
            if ((rescanPosition == (lastChild.Offset + 8)) && (lastChild == root.FindChild(AtomName.MediaData)))
            {
                dataBlockBuilder.EndOffset = rescanPosition.Value;
            }
            return(dataBlockBuilder.Build());
        }
        /// This method looks for the beginning of an AviHeader and if one is found it will parse it
        /// by calling Parser.Parse().
        /// </summary>
        override public IDataBlock DetectData(IDataReader dataReader, IDataBlockBuilder dataBlockBuilder, IScanContext context)
        {
            AviChunk root = new AviChunk(context.Detectors);

            // Try to parse a contiguous block of headers
            using (AviParser parser = new AviParser(new ByteStreamDataReader(dataReader, Endianness.Little)))
            {
                if (!parser.ParseRoot(root, dataReader.Length))
                {
                    dataReader.Position = dataReader.Length;
                    return(null);
                }

                // Synchronize the position of the data reader
                dataReader.Position = parser.Position;
            }

            // The content of a Movie Entry can not be parsed by the avi detector.
            // When a Movie Entry is the last header of a data block,
            // we can't be sure that its correct (not overwritten).
            // Because of this, the content of this last Movie Entry
            // will be fed to other detectors to check its content.
            long?    removedLastMovieEntryOffset = null;
            AviChunk lastHeader = root.LastHeader;

            if (lastHeader.HeaderName == AviChunkName.MovieEntry &&
                lastHeader.RelativeEndOffset != (ulong)dataReader.Length)
            {
                removedLastMovieEntryOffset = lastHeader.Offset;
                lastHeader.Parent.RemoveChild(lastHeader);
            }

            // Trim trailing unknown, padding byte or large unparsable chunks
            lastHeader = root.LastHeader;
            while ((lastHeader.IsUnknown || lastHeader.HeaderName == AviChunkName.PaddingByte) && lastHeader.Parent != null)
            {
                // Note: ALWAYS strip padding bytes, to avoid a 'retrieved detectable is different...' error on rescan!
                if (lastHeader.HeaderName != AviChunkName.PaddingByte)
                {
                    if (lastHeader.RelativeEndOffset == ((AviChunk)lastHeader.Parent).RelativeEndOffset)
                    {
                        break;                         // Last child perfectly aligned with parent chunk
                    }
                }

                removedLastMovieEntryOffset = null;
                lastHeader.Parent.RemoveChild(lastHeader);
                lastHeader = root.LastHeader;
            }

            // Discard data blocks of only 1 chunk
            if ((dataReader.State == DataReaderState.Cancelled) ||
                (root.Children.Count == 0) ||
                ((root.Children.Count == 1) && !root.FirstChild.HasChildren()))
            {
                // Rewind data reader
                if (removedLastMovieEntryOffset != null)
                {
                    // If the last header was a movie entry;
                    // proceed just after the 4CC and size bytes of that header.
                    dataReader.Position = removedLastMovieEntryOffset.Value + 1;
                }
                else
                {
                    dataReader.Position = lastHeader.Offset + lastHeader.Length;                     // != lastHeader.RelativeEndOffset; !!!
                }
                return(null);
            }

            // Set properties and return result
            context.Results = root;

            dataBlockBuilder.DataFormat = root.DataFormat;
            var firstChild = ((AviChunk)root.Children[0]);

            dataBlockBuilder.StartOffset = firstChild.Offset;
            var lastChild = ((AviChunk)root.GetLastDescendant());
            var endOffset = (lastChild.Offset + lastChild.Length);

            dataBlockBuilder.EndOffset = endOffset;

            // TODO properties.IsFullFile = (root.FirstChild.HeaderName == AviChunkName.FileType) && (movie != null) && (mediaData != null);
            CodecStream codecStream = new CodecStream(root);

            codecStream.CreateCodecStreams(dataBlockBuilder);

            // TODO: check for (complete) mdat block (for IsFullFile)

            dataReader.Position = endOffset;
            return(dataBlockBuilder.Build());
        }
        override public IDataBlock DetectData(IDataReader dataReader, IDataBlockBuilder dataBlockBuilder, IScanContext context)
        {
            IResultNode          root = new MockResult(this);
            ByteStreamDataReader byteStreamDataReader = new ByteStreamDataReader(dataReader);

            dataReader = byteStreamDataReader;

            long dataReaderOffset = dataReader.GetDataPacket(0, 1).StartOffset;
            long initialPosition  = dataReader.Position + dataReaderOffset;

            if (initialPosition == 0 && dataReader.Length >= 268)
            {
                dataReader.Position = 0;
                long        offset = 0L;
                long        length;
                IResultNode parent = root;
                if (byteStreamDataReader.GetByte() == 69)
                {
                    offset = 0L;
                    length = 1L;
                    parent = new MockResult1(parent, dataReader, offset, length);
                }
                long firstDataBlockOffset = offset;

                dataReader.Position = 255;
                if (byteStreamDataReader.GetByte() == 255)
                {
                    offset = 255L;
                    length = 2L;
                    parent = new MockResult2(parent, dataReader, offset, length);
                }

                dataReader.Position = 260;
                if (byteStreamDataReader.GetByte() == 78)
                {
                    offset = 260L;
                    length = 3L;
                    new MockResult1(parent, dataReader, offset, length);
                }

                offset = 264;
                length = 4;
                dataReader.Position = 264;
                if (byteStreamDataReader.GetByte() == 5)
                {
                    new MockResult2(parent, dataReader, offset, length);
                }

                context.Results = root;

                var firstChild = ((MockResult)root.Children[0]);
                dataBlockBuilder.StartOffset = firstChild.Offset;
                var lastChild = ((MockResult)root.GetLastDescendant());
                dataBlockBuilder.EndOffset  = (lastChild.Offset + lastChild.Length);
                dataBlockBuilder.IsFullFile = false;
                return(dataBlockBuilder.Build());
            }

            if (initialPosition <= 517 && (initialPosition + dataReader.Length) >= 518)
            {
                long       offset = 517L - dataReaderOffset;
                const long length = 1L;

                dataReader.Position = offset;
                if (byteStreamDataReader.GetByte() == 2)
                {
                    new MockResult1(root, dataReader, offset, length);
                }

                context.Results = root;

                var firstChild = ((MockResult)root.Children[0]);
                dataBlockBuilder.StartOffset = firstChild.Offset;
                var lastChild = ((MockResult)root.GetLastDescendant());
                dataBlockBuilder.EndOffset  = (lastChild.Offset + lastChild.Length);
                dataBlockBuilder.IsFullFile = (root.Children.Count == 1);
                return(dataBlockBuilder.Build());
            }
            return(null);
        }
        public void SerializeProject()
        {
            IProject project = TestFramework.ProjectManager.CreateProject(ProjectPath, ProjectInvestigator, DateTime.Now, ProjectDescription);

            IDetector  systemDetector = TestFramework.DetectorFactory.ContainerDetectors.Single(x => x.Name == "MPEG-1/2 Systems");
            IDetector  videoDetector  = TestFramework.DetectorFactory.CodecDetectors.Single(x => x.Name == Mpeg2VideoDetector.DetectorName);
            IInputFile inputFile1     = project.AddFile(FileName1, new[] { systemDetector, videoDetector });
            IInputFile inputFile2     = project.AddFile(FileName2, new[] { videoDetector });

            IDataBlockBuilder dataBlockBuilder1 = TestFramework.CreateDataBlockBuilder();

            dataBlockBuilder1.DataFormat  = CodecID.Mpeg2System;
            dataBlockBuilder1.Detectors   = new[] { systemDetector };
            dataBlockBuilder1.InputFile   = inputFile1;
            dataBlockBuilder1.StartOffset = 0L;
            dataBlockBuilder1.EndOffset   = 20480L;
            dataBlockBuilder1.IsFullFile  = true;
            ICodecStreamBuilder codecStreamBuilder = dataBlockBuilder1.AddCodecStream();

            codecStreamBuilder.Name       = "Video Stream #1";
            codecStreamBuilder.DataFormat = CodecID.Mpeg2Video;
            codecStreamBuilder.Detector   = videoDetector;
            codecStreamBuilder.Data       = TestFramework.CreateDataPacket(inputFile1, 0L, 3033L);
            IDataBlock dataBlock1 = dataBlockBuilder1.Build();

            IDataBlockBuilder dataBlockBuilder2 = TestFramework.CreateDataBlockBuilder();

            dataBlockBuilder2.DataFormat  = CodecID.Mpeg2Video;
            dataBlockBuilder2.Detectors   = new[] { videoDetector };
            dataBlockBuilder2.InputFile   = inputFile1;
            dataBlockBuilder2.StartOffset = 130303L;
            dataBlockBuilder2.EndOffset   = 130327L;
            dataBlockBuilder2.IsFullFile  = false;
            IDataBlock dataBlock2 = dataBlockBuilder2.Build();

            IDataBlockBuilder dataBlockBuilder3 = TestFramework.CreateDataBlockBuilder();

            dataBlockBuilder3.DataFormat  = CodecID.Mpeg2Video;
            dataBlockBuilder3.Detectors   = new[] { videoDetector };
            dataBlockBuilder3.InputFile   = inputFile2;
            dataBlockBuilder3.StartOffset = 0L;
            dataBlockBuilder3.EndOffset   = FileLength2;
            dataBlockBuilder3.IsFullFile  = true;
            IDataBlock dataBlock3 = dataBlockBuilder3.Build();

            project.AddDataBlock(dataBlock1);
            project.AddDataBlock(dataBlock2);
            project.AddDataBlock(dataBlock3);
            project.SetMetadata(_fullMetadata);
//			project.SetVisibleColumns(systemDetector, TwoColumns);

            IProject deserializedProject;

            using (FileStream fileStream = new FileStream(_project.FileName, FileMode.Create))
            {
                TestFramework.CreateXmlObjectSerializer().WriteObject(fileStream, project);
            }
            using (FileStream fileStream = new FileStream(ProjectPath, FileMode.Open))
            {
                deserializedProject = TestFramework.CreateXmlObjectSerializer().ReadObject(fileStream) as IProject;
            }

            IList <IInputFile> inputFiles = deserializedProject.GetInputFiles();

            Assert.AreEqual(2, inputFiles.Count, "Serialization, input files (2 files)");
            AreEqual(inputFile1, inputFiles[0], "1");
            AreEqual(inputFile2, inputFiles[1], "2");

            IList <IDataBlock> dataBlocks = deserializedProject.GetDataBlocks(inputFiles[0]);

            Assert.AreEqual(2, dataBlocks.Count, "Serialization, data blocks (file 1, 2 blocks)");
            AreEqual(dataBlock1, dataBlocks[0], "1", "1");
            AreEqual(dataBlock2, dataBlocks[1], "1", "2");
            dataBlocks = deserializedProject.GetDataBlocks(inputFiles[1]);
            Assert.AreEqual(1, dataBlocks.Count, "Serialization, data blocks (file 2, 1 block)");
            AreEqual(dataBlock3, dataBlocks[0], "2", "1");

            IDictionary <ProjectMetadataKey, string> metadata = deserializedProject.GetMetadata();

            Assert.AreEqual(5, metadata.Count, "Serialization, metadata (5 entries)");
            Assert.IsTrue(metadata.ContainsKey(ProjectMetadataKey.FileVersion), "Serialization, metadata (FileVersion)");
            Assert.AreEqual("1.0.0.4", metadata[ProjectMetadataKey.FileVersion], "Serialization, metadata (FileVersion)");
            Assert.IsTrue(metadata.ContainsKey(ProjectMetadataKey.ProjectDescription), "Serialization, metadata (ProjectDescription)");
            Assert.AreEqual(ProjectDescription, metadata[ProjectMetadataKey.ProjectDescription], "Serialization, metadata (ProjectDescription)");
            Assert.IsTrue(metadata.ContainsKey(ProjectMetadataKey.InvestigatorName), "Serialization, metadata (InvestigatorName)");
            Assert.AreEqual(ProjectInvestigator, metadata[ProjectMetadataKey.InvestigatorName], "Serialization, metadata (InvestigatorName)");
            Assert.IsTrue(metadata.ContainsKey(ProjectMetadataKey.DateCreated), "Serialization, metadata (DateCreated)");
            Assert.AreEqual(ProjectCreationDate, metadata[ProjectMetadataKey.DateCreated], "Serialization, metadata (DateCreated)");
            Assert.IsTrue(metadata.ContainsKey(ProjectMetadataKey.DateLastModified), "Serialization, metadata (DateLastModified)");
            Assert.AreEqual(ProjectModificationDate, metadata[ProjectMetadataKey.DateLastModified], "Serialization, metadata (DateLastModified)");

            //IList<IColumnInfo> visibleColumns = deserializedProject.GetVisibleColumns(systemDetector);
            //Assert.AreEqual(2, visibleColumns.Count, "Serialization, visible columns (2 columns)");
            //Assert.IsTrue(visibleColumns.Contains(_columnInfo1), "Serialization, visible columns (column 1)");
            //Assert.IsTrue(visibleColumns.Contains(_columnInfo2), "Serialization, visible columns (column 2)");

            TestFramework.ProjectManager.CloseProject(project);
        }