Coverage Report

Created: 2025-08-25 07:17

/src/vlc/modules/demux/mkv/Ebml_dispatcher.hpp
Line
Count
Source (jump to first uncovered line)
1
/*****************************************************************************
2
 * Ebml_dispatcher.hpp : matroska demuxer
3
 *****************************************************************************
4
 * Copyright (C) 2016 VLC authors, VideoLAN, Videolabs SAS
5
 *
6
 * Authors: Filip Roseen <filip@videolabs.io>
7
 *
8
 * This program is free software; you can redistribute it and/or modify it
9
 * under the terms of the GNU Lesser General Public License as published by
10
 * the Free Software Foundation; either version 2.1 of the License, or
11
 * (at your option) any later version.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
 * GNU Lesser General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Lesser General Public License
19
 * along with this program; if not, write to the Free Software Foundation,
20
 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
21
 *****************************************************************************/
22
#ifndef VLC_MKV_EBML_DISPATCHER_HPP_
23
#define VLC_MKV_EBML_DISPATCHER_HPP_
24
25
#include "dispatcher.hpp"
26
27
#include <ebml/EbmlElement.h>
28
#include <ebml/EbmlId.h>
29
30
#include <algorithm>
31
#include <typeinfo>
32
#include <vector>
33
34
namespace {
35
  struct EbmlProcessorEntry {
36
    typedef void (*EbmlProcessor) (EbmlElement*, void*);
37
38
    EbmlId         const* p_ebmlid;
39
    EbmlProcessor         callback;
40
41
    EbmlProcessorEntry (EbmlId const& id, EbmlProcessor cb)
42
4.59k
      : p_ebmlid (&id), callback (cb)
43
4.59k
    { }
matroska_segment.cpp:(anonymous namespace)::EbmlProcessorEntry::EbmlProcessorEntry(libebml::EbmlId const&, void (*)(libebml::EbmlElement*, void*))
Line
Count
Source
42
4.05k
      : p_ebmlid (&id), callback (cb)
43
4.05k
    { }
matroska_segment_parse.cpp:(anonymous namespace)::EbmlProcessorEntry::EbmlProcessorEntry(libebml::EbmlId const&, void (*)(libebml::EbmlElement*, void*))
Line
Count
Source
42
539
      : p_ebmlid (&id), callback (cb)
43
539
    { }
44
45
  };
46
47
  bool operator<( EbmlProcessorEntry const& lhs, EbmlProcessorEntry const& rhs )
48
14.6k
  {
49
14.6k
      EbmlId const& lid = *lhs.p_ebmlid;
50
14.6k
      EbmlId const& rid = *rhs.p_ebmlid;
51
52
14.6k
      return lid.GetLength() < rid.GetLength() || (
53
14.4k
        !( rid.GetLength() < lid.GetLength() ) && lid.GetValue() < rid.GetValue()
54
14.4k
      );
55
14.6k
  }
matroska_segment.cpp:(anonymous namespace)::operator<((anonymous namespace)::EbmlProcessorEntry const&, (anonymous namespace)::EbmlProcessorEntry const&)
Line
Count
Source
48
11.4k
  {
49
11.4k
      EbmlId const& lid = *lhs.p_ebmlid;
50
11.4k
      EbmlId const& rid = *rhs.p_ebmlid;
51
52
11.4k
      return lid.GetLength() < rid.GetLength() || (
53
11.4k
        !( rid.GetLength() < lid.GetLength() ) && lid.GetValue() < rid.GetValue()
54
11.4k
      );
55
11.4k
  }
matroska_segment_parse.cpp:(anonymous namespace)::operator<((anonymous namespace)::EbmlProcessorEntry const&, (anonymous namespace)::EbmlProcessorEntry const&)
Line
Count
Source
48
3.20k
  {
49
3.20k
      EbmlId const& lid = *lhs.p_ebmlid;
50
3.20k
      EbmlId const& rid = *rhs.p_ebmlid;
51
52
3.20k
      return lid.GetLength() < rid.GetLength() || (
53
2.94k
        !( rid.GetLength() < lid.GetLength() ) && lid.GetValue() < rid.GetValue()
54
2.94k
      );
55
3.20k
  }
Unexecuted instantiation: matroska_segment_seeker.cpp:(anonymous namespace)::operator<((anonymous namespace)::EbmlProcessorEntry const&, (anonymous namespace)::EbmlProcessorEntry const&)
56
57
  class EbmlTypeDispatcher : public Dispatcher<EbmlTypeDispatcher, EbmlProcessorEntry::EbmlProcessor> {
58
    protected:
59
      typedef std::vector<EbmlProcessorEntry> ProcessorContainer;
60
61
    public:
62
117
      void insert (EbmlProcessorEntry const& data) {
63
117
        _processors.push_back (data);
64
117
      }
matroska_segment.cpp:(anonymous namespace)::EbmlTypeDispatcher::insert((anonymous namespace)::EbmlProcessorEntry const&)
Line
Count
Source
62
26
      void insert (EbmlProcessorEntry const& data) {
63
26
        _processors.push_back (data);
64
26
      }
matroska_segment_parse.cpp:(anonymous namespace)::EbmlTypeDispatcher::insert((anonymous namespace)::EbmlProcessorEntry const&)
Line
Count
Source
62
91
      void insert (EbmlProcessorEntry const& data) {
63
91
        _processors.push_back (data);
64
91
      }
Unexecuted instantiation: matroska_segment_seeker.cpp:(anonymous namespace)::EbmlTypeDispatcher::insert((anonymous namespace)::EbmlProcessorEntry const&)
65
66
10
      void on_create () {
67
10
        std::sort (_processors.begin(), _processors.end());
68
10
      }
matroska_segment.cpp:(anonymous namespace)::EbmlTypeDispatcher::on_create()
Line
Count
Source
66
7
      void on_create () {
67
7
        std::sort (_processors.begin(), _processors.end());
68
7
      }
matroska_segment_parse.cpp:(anonymous namespace)::EbmlTypeDispatcher::on_create()
Line
Count
Source
66
3
      void on_create () {
67
3
        std::sort (_processors.begin(), _processors.end());
68
3
      }
Unexecuted instantiation: matroska_segment_seeker.cpp:(anonymous namespace)::EbmlTypeDispatcher::on_create()
69
70
      bool send (EbmlElement * const& element, void* payload) const
71
4.48k
      {
72
4.48k
        if ( element == nullptr )
73
0
            return false;
74
75
4.48k
        EbmlProcessorEntry eb(static_cast<EbmlId const&> (*element), NULL);
76
77
        // --------------------------------------------------------------
78
        // Find the appropriate callback for the received EbmlElement
79
        // --------------------------------------------------------------
80
81
4.48k
        auto cit_end = _processors.cend();
82
4.48k
        auto cit     = std::lower_bound(_processors.cbegin(), cit_end, eb);
83
84
        /* Check that the processor is valid and unique. */
85
4.48k
        if (cit != cit_end &&
86
4.48k
            cit->p_ebmlid == eb.p_ebmlid &&
87
4.48k
            (*cit->p_ebmlid == *eb.p_ebmlid))
88
3.94k
        {
89
3.94k
            cit->callback (element, payload);
90
3.94k
            return true;
91
3.94k
        }
92
93
531
        if (_default_handler == NULL)
94
37
            return false;
95
96
494
        _default_handler (element, payload);
97
494
        return true;
98
531
      }
matroska_segment.cpp:(anonymous namespace)::EbmlTypeDispatcher::send(libebml::EbmlElement* const&, void*) const
Line
Count
Source
71
4.03k
      {
72
4.03k
        if ( element == nullptr )
73
0
            return false;
74
75
4.03k
        EbmlProcessorEntry eb(static_cast<EbmlId const&> (*element), NULL);
76
77
        // --------------------------------------------------------------
78
        // Find the appropriate callback for the received EbmlElement
79
        // --------------------------------------------------------------
80
81
4.03k
        auto cit_end = _processors.cend();
82
4.03k
        auto cit     = std::lower_bound(_processors.cbegin(), cit_end, eb);
83
84
        /* Check that the processor is valid and unique. */
85
4.03k
        if (cit != cit_end &&
86
4.03k
            cit->p_ebmlid == eb.p_ebmlid &&
87
4.03k
            (*cit->p_ebmlid == *eb.p_ebmlid))
88
3.51k
        {
89
3.51k
            cit->callback (element, payload);
90
3.51k
            return true;
91
3.51k
        }
92
93
521
        if (_default_handler == NULL)
94
37
            return false;
95
96
484
        _default_handler (element, payload);
97
484
        return true;
98
521
      }
matroska_segment_parse.cpp:(anonymous namespace)::EbmlTypeDispatcher::send(libebml::EbmlElement* const&, void*) const
Line
Count
Source
71
448
      {
72
448
        if ( element == nullptr )
73
0
            return false;
74
75
448
        EbmlProcessorEntry eb(static_cast<EbmlId const&> (*element), NULL);
76
77
        // --------------------------------------------------------------
78
        // Find the appropriate callback for the received EbmlElement
79
        // --------------------------------------------------------------
80
81
448
        auto cit_end = _processors.cend();
82
448
        auto cit     = std::lower_bound(_processors.cbegin(), cit_end, eb);
83
84
        /* Check that the processor is valid and unique. */
85
448
        if (cit != cit_end &&
86
448
            cit->p_ebmlid == eb.p_ebmlid &&
87
448
            (*cit->p_ebmlid == *eb.p_ebmlid))
88
438
        {
89
438
            cit->callback (element, payload);
90
438
            return true;
91
438
        }
92
93
10
        if (_default_handler == NULL)
94
0
            return false;
95
96
10
        _default_handler (element, payload);
97
10
        return true;
98
10
      }
Unexecuted instantiation: matroska_segment_seeker.cpp:(anonymous namespace)::EbmlTypeDispatcher::send(libebml::EbmlElement* const&, void*) const
99
100
    public:
101
      ProcessorContainer _processors;
102
  };
103
104
} /* end-of-namespace */
105
106
#define EBML_ELEMENT_CASE_DEF(EbmlType_, ClassName_, VariableName_, InitializationExpr_) \
107
    MKV_SWITCH_CASE_DEFINITION( ClassName_, EbmlType_, EbmlElement*, VariableName_, vars,          \
108
      InitializationExpr_, static_cast<EbmlType_&> (*data)                            \
109
    )
110
111
#define E_CASE(EbmlType_, VariableName_)            \
112
    EBML_ELEMENT_CASE_DEF(EbmlType_, EbmlType_, VariableName_, \
113
      (dispatcher.insert( EbmlProcessorEntry( EBML_ID(EbmlType_), &EbmlType_ ## _callback) ) ) \
114
    )
115
116
#define E_CASE_DEFAULT(VariableName_)                    \
117
    EBML_ELEMENT_CASE_DEF(EbmlElement, ebml_default, VariableName_, \
118
      dispatcher.set_default_handler (&ebml_default_callback)    \
119
    )
120
121
#endif