Exemple #1
0
        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));
                }
            }
        }
Exemple #2
0
            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;
            }