public IEnumerable <string> GetAsciis(string elementName) { var sig32 = MkvFormat.GetLeafSigVal(elementName); foreach (var node in GetNodes(elementName)) { if (node is EbmlNodeLeaf leaf) { yield return(Encoding.ASCII.GetString(leaf.payload, 0, leaf.payload.Length)); } } }
public Model(Stream stream, string path) { base._data = Data = new MkvFormat(this, stream, path); var bb = new byte[5]; Data.fbs.Position = Data.ValidSize = 4; Data.root = ParseTree(rootSig); Data.layout.Add(Data.root); if (Data.Issues.HasError) { return; } System.Diagnostics.Debug.Assert(Data.ValidSize == Data.fbs.Position); Data.fbs.Position = Data.ValidSize; long SegmentLength = ReadMTF(0x18, 0x53, 0x80, 0x67); if (SegmentLength < 0) { IssueModel.Add("Missing root element.", Severity.Fatal); return; } System.Diagnostics.Debug.Assert(Data.ValidSize == Data.fbs.Position); long segmentStart = Data.ValidSize; var diff = Data.ValidSize + SegmentLength - Data.FileSize; if (diff > 0) { IssueModel.Add($"File appears truncated by {diff} bytes.", Severity.Error); } Data.segment = new EbmlNodeMaster(segmentSig, SegmentLength); Data.layout.Add(Data.segment); Data.fbs.Position = Data.ValidSize; while (Data.ValidSize < segmentStart + SegmentLength) { Data.fbs.Position = Data.ValidSize; int got = Data.fbs.Read(bb, 0, 4); if (got < 3) { break; } if (bb[0] == voidSig.Sig32) { Data.fbs.Position = Data.ValidSize + 1; var voidLenBuf = ReadMTF(Data.fbs, out long voidLen); if (voidLen < 0) { IssueModel.Add("File truncated near void.", Severity.Fatal); return; } Data.ValidSize += 1 + voidLenBuf.Length + voidLen; var voidNode = new EbmlNodeLeaf(voidSig, voidLen); Data.segment.AddNode(voidNode); continue; } if (got < 4) { break; } foreach (var mstr in topSigs) { if (mstr.SigIsStartOf(bb)) { Data.fbs.Position = Data.ValidSize = Data.ValidSize + 4; if ((mstr.Flag & ParseFlag.PrunePayload) != 0) { var payloadLenBuf = ReadMTF(Data.fbs, out long payloadLen); if (payloadLen < 0) { IssueModel.Add("File corrupt or truncated.", Severity.Fatal); return; } Data.ValidSize += payloadLenBuf.Length + payloadLen; Data.segment.AddMaster(mstr, payloadLenBuf.Length + payloadLen); } else { var newNode = ParseTree(mstr); if (IssueModel.Data.HasFatal) { if (newNode != null) { Data.segment.AddNode(newNode); } return; } Data.segment.AddNode(newNode); } goto NEXT_SEG; } } string msg = $"Parse fail at 0x{Data.ValidSize:X} on [{bb[0]:X2}][{bb[1]:X2}][{bb[2]:X2}][{bb[3]:X2}]."; IssueModel.Add(msg, Severity.Fatal); return; NEXT_SEG :; } Data.fbs.Position = Data.ValidSize; var got2 = Data.fbs.Read(bb, 0, 4); if (got2 == 4 && attachSig.SigIsStartOf(bb)) { // By spec, everything should be within a single Segment. Data.HasMisplacedAttachment = true; IssueModel.Add($"Misplaced attachment at {Data.ValidSize:X}", Severity.Warning); } Data.fbs.Position = Data.ValidSize; CalcMark(true); return; }