public void ReadWriteContainer() { var innerdata = new MemoryStream(); var container = new EbmlWriter(innerdata); container.WriteAscii(VInt.MakeId(1), "Hello"); container.Write(VInt.MakeId(2), 12345); container.Write(VInt.MakeId(3), 123.45); _writer.Write(VInt.MakeId(5), innerdata.ToArray()); _writer.WriteAscii(VInt.MakeId(6), "end"); _stream.Position = 0; var reader = new EbmlReader(_stream); Assert.IsTrue(reader.ReadNext()); Assert.AreEqual(VInt.MakeId(5), reader.ElementId); reader.EnterContainer(); // reading inner data AssertRead(reader, 1, "Hello", r => r.ReadAscii()); AssertRead(reader, 2, 12345, r => r.ReadInt()); AssertRead(reader, 3, 123.45, r => r.ReadFloat()); reader.LeaveContainer(); // back to main stream AssertRead(reader, 6, "end", r => r.ReadAscii()); }
public void ReadsSegmentInfo() { var stream = new MemoryStream(); var writer = new EbmlWriter(stream); using (var segment = writer.StartMasterElement(MatroskaDtd.Segment.Identifier)) { using (var segmentInfo = segment.StartMasterElement(MatroskaDtd.Segment.Info.Identifier)) { segmentInfo.WriteUtf(MatroskaDtd.Segment.Info.Title.Identifier, "Test data"); segmentInfo.WriteUtf(MatroskaDtd.Segment.Info.WritingApp.Identifier, "writing app"); segmentInfo.WriteUtf(MatroskaDtd.Segment.Info.MuxingApp.Identifier, "mux app"); segmentInfo.Write(MatroskaDtd.Segment.Info.Duration.Identifier, 1234f); } // write some dummy data segment.Write(VInt.MakeId(123), 0); } stream.Position = 0; var infoReader = new SegmentInfoUpdater(); infoReader.Open(stream); Assert.AreEqual("Test data", infoReader.Title); Assert.AreEqual("writing app", infoReader.WritingApp); Assert.AreEqual("mux app", infoReader.MuxingApp); Assert.AreEqual(TimeSpan.FromMilliseconds(1234), infoReader.Duration); }
public void ReusesPriorFiller() { var stream = new MemoryStream(); var writer = new EbmlWriter(stream); writer.Write(VInt.MakeId(122), 321); using (var segment = writer.StartMasterElement(MatroskaDtd.Segment.Identifier)) { segment.Write(StandardDtd.Void.Identifier, new byte[1000]); using (var segmentInfo = segment.StartMasterElement(MatroskaDtd.Segment.Info.Identifier)) { segmentInfo.WriteUtf(MatroskaDtd.Segment.Info.Title.Identifier, "Test data"); } // write some dummy data segment.Write(VInt.MakeId(123), 123); // marker } stream.Position = 0; // act var infoReader = new SegmentInfoUpdater(); infoReader.Open(stream); infoReader.Title = new string('a', 500); infoReader.Write(); // verify the stream is correct stream.Position = 0; var reader = new EbmlReader(stream); reader.ReadNext(); Assert.AreEqual(122, reader.ElementId.Value, "start marker"); Assert.AreEqual(321, reader.ReadInt()); reader.ReadNext(); Assert.AreEqual(MatroskaDtd.Segment.Identifier, reader.ElementId); reader.EnterContainer(); reader.ReadNext(); Assert.AreEqual(MatroskaDtd.Segment.Info.Identifier, reader.ElementId); Assert.Greater(reader.ElementSize, 500); reader.ReadNext(); Assert.AreEqual(StandardDtd.Void.Identifier, reader.ElementId); reader.ReadNext(); Assert.AreEqual(123, reader.ElementId.Value, "end data marker"); Assert.AreEqual(123, reader.ReadInt()); }
private static void AssertRead <T>(EbmlReader reader, uint elementId, T value, Func <EbmlReader, T> read) { Assert.IsTrue(reader.ReadNext()); Assert.AreEqual(VInt.MakeId(elementId), reader.ElementId); Assert.AreEqual(value, read(reader)); }
private void ReadData(Stream src) { var reader = new EbmlReader(src); var readMap = new[] { new { Element = MatroskaDtd.Segment.Info.Title, Code = new Action(() => _title = reader.ReadUtf()) }, new { Element = MatroskaDtd.Segment.Info.WritingApp, Code = new Action(() => _writingApp = reader.ReadUtf()) }, new { Element = MatroskaDtd.Segment.Info.MuxingApp, Code = new Action(() => MuxingApp = reader.ReadUtf()) }, new { Element = MatroskaDtd.Segment.Info.Duration, Code = new Action(() => Duration = TimeSpan.FromMilliseconds(reader.ReadFloat())) }, }; if (!reader.LocateElement(MatroskaDtd.Segment)) { throw new InvalidDataException("Failed to locate Segment"); } reader.EnterContainer(); var segmentInfoIdentifier = MatroskaDtd.Segment.Info.Identifier; // support for Void block right before SegmentInfo var priorElementId = VInt.MakeId(0); var priorElementStart = -1l; // locate SegmentInfo and track its predesessor while (reader.ReadNext()) { if (reader.ElementId == segmentInfoIdentifier) { break; } priorElementId = reader.ElementId; priorElementStart = reader.ElementPosition; } if (reader.ElementId != segmentInfoIdentifier) { throw new InvalidDataException("Failed to locate Segment"); } _dataStart = priorElementId == StandardDtd.Void.Identifier ? priorElementStart : reader.ElementPosition; var oldDataStart = reader.ElementPosition; reader.EnterContainer(); while (reader.ReadNext()) { var entry = readMap.FirstOrDefault(arg => arg.Element.Identifier == reader.ElementId); if (entry != null) { entry.Code(); } } reader.LeaveContainer(); // getting start of the next element reader.ReadNext(); if (reader.ElementId == StandardDtd.Void.Identifier) { reader.ReadNext(); } _dataLength = (int)(reader.ElementPosition - _dataStart); var oldDataLen = (int)(reader.ElementPosition - oldDataStart); _oldSegmentInfoData = new byte[oldDataLen]; _stream.Seek(oldDataStart, SeekOrigin.Begin); _stream.Read(_oldSegmentInfoData, 0, oldDataLen); }