示例#1
0
        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);
        }
示例#2
0
        internal MasterBlockWriter(EbmlWriter writer, VInt elementId)
            : base(new MemoryStream())
        {
            var flushed = false;
            _flushImpl = () =>
                {
                    if (flushed) return;
                    var data = ((MemoryStream) _stream).ToArray();
                    writer.Write(elementId, data);

                    flushed = true;
                    _stream.Close();
                };
        }
示例#3
0
        public void ReusesNextFiller()
        {
            var stream = new MemoryStream();
            var writer = new EbmlWriter(stream);

            writer.Write(VInt.MakeId(122), 321);
            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");
                }

                // write some dummy data
                segment.Write(StandardDtd.Void.Identifier, new byte[1000]);
                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());
        }
示例#4
0
        internal MasterBlockWriter(EbmlWriter writer, VInt elementId)
            : base(new MemoryStream())
        {
            var flushed = false;

            _flushImpl = () =>
            {
                if (flushed)
                {
                    return;
                }
                var data = ((MemoryStream)_stream).ToArray();
                writer.Write(elementId, data);

                flushed = true;
                _stream.Close();
            };
        }
示例#5
0
        private void WriteData()
        {
            var reader = new EbmlReader(new MemoryStream(_oldSegmentInfoData), _oldSegmentInfoData.Length);

            // prepare writing part
            var infoStream= new MemoryStream();
            var infoWriter = new EbmlWriter(infoStream);

            var writeMap = new[]
                {
                    new {Id = MatroskaDtd.Segment.Info.Title.Identifier, Value = _title},
                    new {Id = MatroskaDtd.Segment.Info.WritingApp.Identifier, Value = _writingApp},
                };

            // enter the Segment block
            reader.ReadNext();
            reader.EnterContainer();

            while (reader.ReadNext())
            {
                if (!writeMap.Any(arg => arg.Id == reader.ElementId))
                {
                    // copying data as is
                    var buffer = new byte[reader.ElementSize];
                    reader.ReadBinary(buffer, 0, (int) reader.ElementSize);
                    infoWriter.Write(reader.ElementId, buffer);
                }
            }

            // write title/app in case it was not present!
            foreach (var e in writeMap.Where(arg => !string.IsNullOrEmpty(arg.Value)))
            {
                infoWriter.WriteUtf(e.Id, e.Value);
            }

            var outStream = new MemoryStream(_dataLength);
            var writer = new EbmlWriter(outStream);

            writer.Write(MatroskaDtd.Segment.Info.Identifier, infoStream.ToArray());
            var extraByteCount = _dataLength - outStream.Position;

            if (extraByteCount != 0)
            {
                var extraHLen = StandardDtd.Void.Identifier.Length + 2;

                var blankDataLen = (int) (extraByteCount - extraHLen);
                if (blankDataLen < 0)
                {
                    throw new InvalidOperationException(string.Format("Not enough space to put the new data, {0} bytes to feet", -blankDataLen));
                }

                writer.WriteElementHeader(StandardDtd.Void.Identifier, VInt.EncodeSize((ulong)blankDataLen, 2));
                writer.Write(new byte[blankDataLen], 0, blankDataLen);
            }

            if (outStream.Length != _dataLength)
                throw new InvalidOperationException("Failed to prepare modified data - block length mismatch");

            _stream.Position = _dataStart;
            _stream.Write(outStream.ToArray(), 0, _dataLength);
        }