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)); }
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(); } }
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()); }
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); }
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); }