### Bug Summary

File: | usr/include/x86_64-linux-gnu/qt6/QtCore/qobjectdefs.h
Warning: | line 646, column 9 Potential leak of memory pointed to by 'callable'

### Annotated Source Code

Press '?' to see keyboard shortcuts

Show analyzer invocation
clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name dis_stream_dialog.cpp -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -fno-delete-null-pointer-checks -mframe-pointer=all -relaxed-aliasing -fmath-errno -ffp-contract=on -fno-rounding-math -ffloat16-excess-precision=fast -fbfloat16-excess-precision=fast -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/builds/wireshark/wireshark/build -fcoverage-compilation-dir=/builds/wireshark/wireshark/build -resource-dir /usr/lib/llvm-22/lib/clang/22 -isystem /usr/include/glib-2.0 -isystem /usr/lib/x86_64-linux-gnu/glib-2.0/include -isystem /builds/wireshark/wireshark/build/ui/qt -isystem /builds/wireshark/wireshark/ui/qt -isystem /builds/wireshark/wireshark/ui/qt/lua_debugger -isystem /usr/include/x86_64-linux-gnu/qt6/QtConcurrent -isystem /usr/include/x86_64-linux-gnu/qt6 -isystem /usr/include/x86_64-linux-gnu/qt6/QtCore -isystem /usr/lib/x86_64-linux-gnu/qt6/mkspecs/linux-g++ -isystem /usr/include/x86_64-linux-gnu/qt6/QtNetwork -isystem /usr/include/x86_64-linux-gnu/qt6/QtPrintSupport -isystem /usr/include/x86_64-linux-gnu/qt6/QtGui -isystem /usr/include/x86_64-linux-gnu/qt6/QtWidgets -isystem /usr/include/x86_64-linux-gnu/qt6/QtSvg -isystem /usr/include/x86_64-linux-gnu/qt6/QtMultimedia -isystem /usr/include/x86_64-linux-gnu/qt6/QtDBus -D CARES_NO_DEPRECATED -D G_DISABLE_DEPRECATED -D G_DISABLE_SINGLE_INCLUDES -D QT_CONCURRENT_LIB -D QT_CORE_LIB -D QT_DBUS_LIB -D QT_GUI_LIB -D QT_MULTIMEDIA_LIB -D QT_NETWORK_LIB -D QT_PRINTSUPPORT_LIB -D QT_SVG_LIB -D QT_WIDGETS_LIB -D WS_DEBUG -D WS_DEBUG_UTF_8 -I /builds/wireshark/wireshark/build/ui/qt/qtui_autogen/include -I /builds/wireshark/wireshark/build -I /builds/wireshark/wireshark -I /builds/wireshark/wireshark/include -D _GLIBCXX_ASSERTIONS -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../include/c++/16 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../include/x86_64-linux-gnu/c++/16 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../include/c++/16/backward -internal-isystem /usr/lib/llvm-22/lib/clang/22/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fmacro-prefix-map=/builds/wireshark/wireshark/= -fmacro-prefix-map=/builds/wireshark/wireshark/build/= -fmacro-prefix-map=../= -Wno-format-nonliteral -std=c++17 -fdeprecated-macro -ferror-limit 19 -fwrapv -fwrapv-pointer -fstrict-flex-arrays=3 -stack-protector 2 -fstack-clash-protection -fcf-protection=full -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fcxx-exceptions -fexceptions -fcolor-diagnostics -analyzer-output=html -faddrsig -fdwarf2-cfi-asm -o /builds/wireshark/wireshark/sbout/2026-09-02-100927-3660-1 -x c++ /builds/wireshark/wireshark/ui/qt/dis_stream_dialog.cpp

Keyboard shortcuts:

- Use 'j/k' keys for keyboard navigation
- Use 'Shift+S' to show/hide relevant lines
- Use '?' to toggle this window

Close
Show only relevant lines Show control flow arrows

#### /builds/wireshark/wireshark/ui/qt/dis_stream_dialog.cpp

→

1 | /* dis_stream_dialog.cpp
2 | *
3 | * Wireshark - Network traffic analyzer
4 | * By Gerald Combs <gerald@wireshark.org>
5 | * Copyright 1998 Gerald Combs
6 | *
7 | * SPDX-License-Identifier: GPL-2.0-or-later
8 | */
9 |
10 | #include "dis_stream_dialog.h"
11 |
12 | #include "dis_audio_stream.h"
13 |
14 | #include <QFile>
15 | #include <QFileDialog>
16 | #include <QHeaderView>
17 | #include <QMenu>
18 | #include <QMetaObject>
19 | #include <QMessageBox>
20 | #include <QFormLayout>
21 | #include <QSignalBlocker>
22 | #include <QTextStream>
23 | #include <QVBoxLayout>
24 |
25 | #include "epan/addr_resolv.h"
26 |
27 | #include "main_application.h"
28 |
29 | DisStreamDialog *DisStreamDialog::pinstance_ = nullptr;
30 | std::mutex DisStreamDialog::mutex_;
31 |
32 | enum {
33 | dis_col_start_time = 0,
34 | dis_col_end_time,
35 | dis_col_src_addr,
36 | dis_col_src_port,
37 | dis_col_dst_addr,
38 | dis_col_dst_port,
39 | dis_col_radio,
40 | dis_col_entity,
41 | dis_col_signal_pkts,
42 | dis_col_tx_pkts,
43 | dis_col_lost,
44 | dis_col_max_delta,
45 | dis_col_mean_jitter,
46 | dis_col_max_jitter,
47 | dis_col_problem,
48 | dis_col_count
49 | };
50 |
51 | static constexpr int disstream_ptr_role = Qt::UserRole + 100;
52 |
53 | bool
54 | DisStreamDialog::DisStreamTreeWidgetItem::operator<(const QTreeWidgetItem &other) const
55 | {
56 | int sort_col = treeWidget() ? treeWidget()->sortColumn() : 0;
57 | QVariant lhs = data(sort_col, Qt::UserRole);
58 | QVariant rhs = other.data(sort_col, Qt::UserRole);
59 |
60 | if (lhs.isValid() && rhs.isValid()) {
61 | if (lhs.metaType().id() == QMetaType::Double || rhs.metaType().id() == QMetaType::Double) {
62 | return lhs.toDouble() < rhs.toDouble();
63 | }
64 |
65 | return lhs.toLongLong() < rhs.toLongLong();
66 | }
67 |
68 | return QTreeWidgetItem::operator<(other);
69 | }
70 |
71 | DisStreamDialog *
72 | DisStreamDialog::openDisStreamDialog(QWidget &parent, CaptureFile &cf, QObject *packet_list)
73 | {
74 | std::lock_guard<std::mutex> lock(mutex_);
75 |
76 | if (!pinstance_) {
77 | pinstance_ = new DisStreamDialog(parent, cf, packet_list);
78 | }
79 |
80 | return pinstance_;
81 | }
82 |
83 | DisStreamDialog::DisStreamDialog(QWidget &parent, CaptureFile &cf, QObject *packet_list) :
84 | WiresharkDialog(parent, cf),
85 | stream_tree_(new QTreeWidget(this)),
86 | button_box_(new QDialogButtonBox(QDialogButtonBox::Close, Qt::Horizontal, this)),
87 | filter_button_(nullptr),
88 | play_button_(nullptr),
89 | stop_button_(nullptr),
90 | analyze_button_(nullptr),
91 | need_redraw_(false),
92 | packet_list_(packet_list)
93 | #ifdef QT_MULTIMEDIA_LIB1
94 | , audio_stream_(new DisAudioStream(this))
95 | #endif
96 | {
97 | QVBoxLayout *layout = new QVBoxLayout(this);
98 | QFormLayout *summary_layout = new QFormLayout;
99 |
100 | setWindowSubtitle(tr("DIS Streams"));
101 |
102 | layout->addLayout(summary_layout);
103 |
104 | stream_tree_->setRootIsDecorated(false);
105 | stream_tree_->setAlternatingRowColors(true);
106 | stream_tree_->setSortingEnabled(true);
107 | stream_tree_->setSelectionMode(QAbstractItemView::SingleSelection);
108 | stream_tree_->setUniformRowHeights(true);
109 | stream_tree_->setContextMenuPolicy(Qt::ActionsContextMenu);
110 | stream_tree_->setColumnCount(dis_col_count);
111 | stream_tree_->setHeaderLabels(QStringList()
112 | << tr("Start")
113 | << tr("End")
114 | << tr("Src Address")
115 | << tr("Src Port")
116 | << tr("Dst Address")
117 | << tr("Dst Port")
118 | << tr("Radio")
119 | << tr("Entity")
120 | << tr("Signal")
121 | << tr("Tx")
122 | << tr("Lost")
123 | << tr("Max Delta (ms)")
124 | << tr("Mean Jitter (ms)")
125 | << tr("Max Jitter (ms)")
126 | << tr("Pb"));
127 | stream_tree_->header()->setSortIndicator(dis_col_start_time, Qt::AscendingOrder);
128 | stream_tree_->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
129 |
130 | layout->addWidget(stream_tree_);
131 |
132 | filter_button_ = button_box_->addButton(tr("Prepare Filter"), QDialogButtonBox::ActionRole);
133 | play_button_ = button_box_->addButton(tr("Play"), QDialogButtonBox::ActionRole);
134 | stop_button_ = button_box_->addButton(tr("Stop"), QDialogButtonBox::ActionRole);
135 | analyze_button_ = button_box_->addButton(tr("Analyze"), QDialogButtonBox::ActionRole);
136 | layout->addWidget(button_box_);
137 |
138 | connect(button_box_, &QDialogButtonBox::rejected, this, &DisStreamDialog::reject);
139 | connect(filter_button_, &QPushButton::clicked, this, &DisStreamDialog::onPrepareFilter);
140 | connect(analyze_button_, &QPushButton::clicked, this, &DisStreamDialog::onAnalyzeStream);
141 | #ifdef QT_MULTIMEDIA_LIB1
142 | connect(play_button_, &QPushButton::clicked, this, &DisStreamDialog::onPlayStream);
143 | connect(stop_button_, &QPushButton::clicked, this, &DisStreamDialog::onStopStream);
144 | connect(audio_stream_, &DisAudioStream::playbackStateChanged,
145 | this, &DisStreamDialog::onPlaybackStateChanged);
146 | #endif
147 | connect(stream_tree_, &QTreeWidget::itemSelectionChanged, this, &DisStreamDialog::onStreamSelectionChanged);
148 | connect(stream_tree_, &QTreeWidget::itemDoubleClicked, this, &DisStreamDialog::onStreamItemDoubleClicked);
149 | connect(&cap_file_, &CaptureFile::captureEvent, this, &DisStreamDialog::onCaptureEvent);
150 |
151 | if (packet_list_) {
152 | connect(this, SIGNAL(goToPacket(int))qFlagLocation("2" "goToPacket(int)" "\0" "ui/qt/dis_stream_dialog.cpp" ":" "152"), packet_list_, SLOT(goToPacket(int))qFlagLocation("1" "goToPacket(int)" "\0" "ui/qt/dis_stream_dialog.cpp" ":" "152"));
153 | }
154 | connect(this, SIGNAL(updateFilter(QString, bool))qFlagLocation("2" "updateFilter(QString, bool)" "\0" "ui/qt/dis_stream_dialog.cpp" ":" "154"), &parent, SLOT(filterPackets(QString, bool))qFlagLocation("1" "filterPackets(QString, bool)" "\0" "ui/qt/dis_stream_dialog.cpp" ":" "154"));
155 |
156 | memset(&tapinfo_, 0, sizeof(tapinfo_));
157 | tapinfo_.mode = DISSTREAM_TAP_ANALYSE;
158 | tapinfo_.tap_reset = tapReset;
159 | tapinfo_.tap_draw = tapDraw;
160 |
161 | register_tap_listener_disstream(&tapinfo_, NULL__null, NULL__null);
162 |
163 | if (cap_file_.isValid()) {
164 | cap_file_.delayedRetapPackets();
165 | }
166 |
167 | loadGeometry(parent.width() * 4 / 5, parent.height() * 2 / 3);
168 | updateWidgets();
169 | }
170 |
171 | DisStreamDialog::~DisStreamDialog()
172 | {
173 | std::lock_guard<std::mutex> lock(mutex_);
174 |
175 | #ifdef QT_MULTIMEDIA_LIB1
176 | audio_stream_->stopPlayback();
177 | #endif
178 |
179 | disstream_reset(&tapinfo_);
180 | remove_tap_listener_disstream(&tapinfo_);
181 | pinstance_ = nullptr;
182 | }
183 |
184 | void
185 | DisStreamDialog::captureFileClosing()
186 | {
187 | #ifdef QT_MULTIMEDIA_LIB1
188 | audio_stream_->stopPlayback();
189 | #endif
190 | remove_tap_listener_disstream(&tapinfo_);
191 | disstream_reset(&tapinfo_);
192 | }
193 |
194 | void
195 | DisStreamDialog::captureFileClosed()
196 | {
197 | #ifdef QT_MULTIMEDIA_LIB1
198 | audio_stream_->stopPlayback();
199 | #endif
200 | stream_tree_->clear();
201 | }
202 |
203 | void
204 | DisStreamDialog::tapReset(disstream_tapinfo_t *tapinfo _U___attribute__((unused)))
205 | {
206 | if (!pinstance_) {
207 | return;
208 | }
209 |
210 | pinstance_->need_redraw_ = true;
211 | }
212 |
213 | void
214 | DisStreamDialog::tapDraw(disstream_tapinfo_t *tapinfo _U___attribute__((unused)))
215 | {
216 | if (!pinstance_) {
1 | Assuming 'pinstance_' is non-null | →
2 | ← | Taking false branch | →
217 | return;
218 | }
219 |
220 | pinstance_->need_redraw_ = true;
221 | QMetaObject::invokeMethod(pinstance_, [=]() { pinstance_->updateStreams(); }, Qt::QueuedConnection);
3 | ← | Calling 'QMetaObject::invokeMethod' | →
222 | }
223 |
224 | disstream_info_t *
225 | DisStreamDialog::selectedStream() const
226 | {
227 | QTreeWidgetItem *current = stream_tree_->currentItem();
228 | if (!current) {
229 | return nullptr;
230 | }
231 |
232 | quintptr ptr = current->data(0, disstream_ptr_role).value<quintptr>();
233 | return reinterpret_cast<disstream_info_t *>(ptr);
234 | }
235 |
236 | void
237 | DisStreamDialog::updateStreams()
238 | {
239 | GList *list;
240 | disstream_info_t *previous = selectedStream();
241 | QTreeWidgetItem *item_to_select = nullptr;
242 |
243 | if (!need_redraw_ || fileClosed()) {
244 | updateWidgets();
245 | return;
246 | }
247 |
248 | QSignalBlocker signal_blocker(stream_tree_);
249 |
250 | stream_tree_->setSortingEnabled(false);
251 | stream_tree_->clear();
252 |
253 | list = g_list_first(tapinfo_.strinfo_list);
254 | while (list) {
255 | disstream_info_t *stream_info = (disstream_info_t *)list->data;
256 | DisStreamTreeWidgetItem *item;
257 | char *src_addr;
258 | char *dst_addr;
259 |
260 | item = new DisStreamTreeWidgetItem(stream_tree_);
261 | item->setData(0, disstream_ptr_role, QVariant::fromValue((quintptr)stream_info));
262 | if ((previous && previous == stream_info) || (!previous && !item_to_select)) {
263 | item_to_select = item;
264 | }
265 |
266 | src_addr = address_to_display(NULL__null, &stream_info->id.src_addr);
267 | dst_addr = address_to_display(NULL__null, &stream_info->id.dst_addr);
268 |
269 | item->setText(dis_col_start_time, QString::number(nstime_to_sec(&stream_info->start_rel_time), 'f', 6));
270 | item->setData(dis_col_start_time, Qt::UserRole, nstime_to_sec(&stream_info->start_rel_time));
271 |
272 | item->setText(dis_col_end_time, QString::number(nstime_to_sec(&stream_info->stop_rel_time), 'f', 6));
273 | item->setData(dis_col_end_time, Qt::UserRole, nstime_to_sec(&stream_info->stop_rel_time));
274 |
275 | item->setText(dis_col_src_addr, src_addr);
276 | item->setText(dis_col_src_port, QString::number(stream_info->id.src_port));
277 | item->setData(dis_col_src_port, Qt::UserRole, (int)stream_info->id.src_port);
278 |
279 | item->setText(dis_col_dst_addr, dst_addr);
280 | item->setText(dis_col_dst_port, QString::number(stream_info->id.dst_port));
281 | item->setData(dis_col_dst_port, Qt::UserRole, (int)stream_info->id.dst_port);
282 |
283 | item->setText(dis_col_radio, QStringLiteral("0x%1")(QString(QtPrivate::qMakeStringPrivate(u"" "0x%1"))).arg(stream_info->id.radio_id, 4, 16, QChar('0')));
284 | item->setData(dis_col_radio, Qt::UserRole, (int)stream_info->id.radio_id);
285 |
286 | item->setText(dis_col_entity, QStringLiteral("%1/%2/%3")(QString(QtPrivate::qMakeStringPrivate(u"" "%1/%2/%3")))
287 | .arg(stream_info->id.entity_id_site)
288 | .arg(stream_info->id.entity_id_appl)
289 | .arg(stream_info->id.entity_id_entity));
290 |
291 | item->setText(dis_col_signal_pkts, QString::number(stream_info->signal_packet_count));
292 | item->setData(dis_col_signal_pkts, Qt::UserRole, (int)stream_info->signal_packet_count);
293 |
294 | item->setText(dis_col_tx_pkts, QString::number(stream_info->transmitter_packet_count));
295 | item->setData(dis_col_tx_pkts, Qt::UserRole, (int)stream_info->transmitter_packet_count);
296 |
297 | item->setText(dis_col_lost, QString::number(stream_info->estimated_lost_packets));
298 | item->setData(dis_col_lost, Qt::UserRole, (int)stream_info->estimated_lost_packets);
299 |
300 | item->setText(dis_col_max_delta, QString::number(stream_info->max_delta_ms, 'f', 3));
301 | item->setData(dis_col_max_delta, Qt::UserRole, stream_info->max_delta_ms);
302 |
303 | item->setText(dis_col_mean_jitter, QString::number(stream_info->mean_jitter_ms, 'f', 3));
304 | item->setData(dis_col_mean_jitter, Qt::UserRole, stream_info->mean_jitter_ms);
305 |
306 | item->setText(dis_col_max_jitter, QString::number(stream_info->max_jitter_ms, 'f', 3));
307 | item->setData(dis_col_max_jitter, Qt::UserRole, stream_info->max_jitter_ms);
308 |
309 | item->setText(dis_col_problem, stream_info->problem ? tr("X") : QString());
310 | item->setTextAlignment(dis_col_problem, Qt::AlignCenter);
311 |
312 | wmem_free(NULL__null, src_addr);
313 | wmem_free(NULL__null, dst_addr);
314 |
315 | list = g_list_next(list)((list) ? (((GList *)(list))->next) : __null);
316 | }
317 |
318 | stream_tree_->setSortingEnabled(true);
319 | stream_tree_->sortByColumn(stream_tree_->header()->sortIndicatorSection(),
320 | stream_tree_->header()->sortIndicatorOrder());
321 | if (item_to_select) {
322 | stream_tree_->setCurrentItem(item_to_select);
323 | }
324 |
325 | need_redraw_ = false;
326 | updateWidgets();
327 | }
328 |
329 | void
330 | DisStreamDialog::updateWidgets()
331 | {
332 | bool has_capture = cap_file_.isValid() && !fileClosed();
333 | disstream_info_t *stream_info = selectedStream();
334 | bool has_selection = stream_info != nullptr;
335 | bool has_audio_data = has_selection && stream_info->signal_packets && stream_info->signal_packets->len > 0;
336 |
337 | stream_tree_->setEnabled(has_capture);
338 | filter_button_->setEnabled(has_capture && has_selection);
339 | play_button_->setEnabled(has_capture && has_audio_data);
340 | analyze_button_->setEnabled(has_capture && has_selection);
341 | #ifdef QT_MULTIMEDIA_LIB1
342 | stop_button_->setEnabled(audio_stream_->isPlaying());
343 | #else
344 | stop_button_->setEnabled(false);
345 | #endif
346 | }
347 |
348 | void
349 | DisStreamDialog::onStreamSelectionChanged()
350 | {
351 | #ifdef QT_MULTIMEDIA_LIB1
352 | disstream_info_t *stream_info = selectedStream();
353 |
354 | if (audio_stream_->currentStream() != nullptr &&
355 | audio_stream_->currentStream() != stream_info &&
356 | (audio_stream_->isPlaying() || audio_stream_->isPaused())) {
357 | audio_stream_->stopPlayback();
358 | }
359 | #endif
360 | updateWidgets();
361 | }
362 |
363 | void
364 | DisStreamDialog::onStreamItemDoubleClicked(QTreeWidgetItem *item, int column _U___attribute__((unused)))
365 | {
366 | quintptr ptr;
367 | disstream_info_t *stream_info;
368 |
369 | if (!item) {
370 | return;
371 | }
372 |
373 | ptr = item->data(0, disstream_ptr_role).value<quintptr>();
374 | stream_info = reinterpret_cast<disstream_info_t *>(ptr);
375 | if (stream_info && stream_info->first_packet_num > 0) {
376 | emit goToPacket((int)stream_info->first_packet_num);
377 | }
378 | }
379 |
380 | void
381 | DisStreamDialog::onPrepareFilter()
382 | {
383 | disstream_info_t *stream_info = selectedStream();
384 | QString filter;
385 |
386 | if (!stream_info) {
387 | return;
388 | }
389 |
390 | filter = QStringLiteral((QString(QtPrivate::qMakeStringPrivate(u"" "dis && udp.srcport==%1 && udp.dstport==%2 && " "dis.radio.radio_id==%3 && dis.entity_id_site==%4 && " "dis.entity_id_application==%5 && dis.entity_id_entity==%6" )))
391 | "dis && udp.srcport==%1 && udp.dstport==%2 && "(QString(QtPrivate::qMakeStringPrivate(u"" "dis && udp.srcport==%1 && udp.dstport==%2 && " "dis.radio.radio_id==%3 && dis.entity_id_site==%4 && " "dis.entity_id_application==%5 && dis.entity_id_entity==%6" )))
392 | "dis.radio.radio_id==%3 && dis.entity_id_site==%4 && "(QString(QtPrivate::qMakeStringPrivate(u"" "dis && udp.srcport==%1 && udp.dstport==%2 && " "dis.radio.radio_id==%3 && dis.entity_id_site==%4 && " "dis.entity_id_application==%5 && dis.entity_id_entity==%6" )))
393 | "dis.entity_id_application==%5 && dis.entity_id_entity==%6")(QString(QtPrivate::qMakeStringPrivate(u"" "dis && udp.srcport==%1 && udp.dstport==%2 && " "dis.radio.radio_id==%3 && dis.entity_id_site==%4 && " "dis.entity_id_application==%5 && dis.entity_id_entity==%6" )))
394 | .arg(stream_info->id.src_port)
395 | .arg(stream_info->id.dst_port)
396 | .arg(stream_info->id.radio_id)
397 | .arg(stream_info->id.entity_id_site)
398 | .arg(stream_info->id.entity_id_appl)
399 | .arg(stream_info->id.entity_id_entity);
400 |
401 | emit updateFilter(filter, true);
402 | }
403 |
404 | void
405 | DisStreamDialog::onAnalyzeStream()
406 | {
407 | disstream_info_t *stream_info = selectedStream();
408 | QWidget *parent_widget = qobject_cast<QWidget *>(parent());
409 |
410 | if (!stream_info) {
411 | return;
412 | }
413 |
414 | if (!parent_widget) {
415 | parent_widget = this;
416 | }
417 |
418 | DisStreamAnalysisDialog *dialog = DisStreamAnalysisDialog::openDisStreamAnalysisDialog(
419 | *parent_widget, cap_file_, packet_list_);
420 | dialog->selectStream(stream_info);
421 | dialog->show();
422 | dialog->raise();
423 | dialog->activateWindow();
424 | }
425 |
426 | #ifdef QT_MULTIMEDIA_LIB1
427 | void
428 | DisStreamDialog::onPlayStream()
429 | {
430 | disstream_info_t *stream_info = selectedStream();
431 | QString error_message;
432 |
433 | if (!audio_stream_->playDisStream(stream_info, error_message)) {
434 | QMessageBox::warning(this, tr("DIS Playback"), error_message);
435 | return;
436 | }
437 | updateWidgets();
438 | }
439 |
440 | void
441 | DisStreamDialog::onStopStream()
442 | {
443 | audio_stream_->stopPlayback();
444 | updateWidgets();
445 | }
446 |
447 | void
448 | DisStreamDialog::onPlaybackStateChanged(QAudio::State state _U___attribute__((unused)))
449 | {
450 | updateWidgets();
451 | }
452 | #endif
453 |
454 | void
455 | DisStreamDialog::onCaptureEvent(CaptureEvent e)
456 | {
457 | if (e.captureContext() == CaptureEvent::Retap) {
458 | need_redraw_ = true;
459 | }
460 |
461 | updateStreams();
462 | }

←

#### /usr/include/x86_64-linux-gnu/qt6/QtCore/qobjectdefs.h

1 | // Copyright (C) 2022 The Qt Company Ltd.
2 | // Copyright (C) 2019 Intel Corporation.
3 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
4 |
5 | #ifndef QOBJECTDEFS_H
6 | #define QOBJECTDEFS_H
7 |
8 | #if defined(__OBJC__) && !defined(__cplusplus201703L)
9 | # warning "File built in Objective-C mode (.m), but using Qt requires Objective-C++ (.mm)"
10 | #endif
11 |
12 | #include <QtCore/qnamespace.h>
13 | #include <QtCore/qobjectdefs_impl.h>
14 | #include <QtCore/qtcoreexports.h>
15 | #include <QtCore/qtmetamacros.h>
16 |
17 | QT_BEGIN_NAMESPACE
18 |
19 | class QByteArray;
20 | struct QArrayData;
21 |
22 | class QString;
23 |
24 | #ifndef QT_NO_META_MACROS
25 | // macro for onaming members
26 | #ifdef METHOD
27 | #undef METHOD
28 | #endif
29 | #ifdef SLOT
30 | #undef SLOT
31 | #endif
32 | #ifdef SIGNAL
33 | #undef SIGNAL
34 | #endif
35 | #endif // QT_NO_META_MACROS
36 |
37 | Q_CORE_EXPORT__attribute__((visibility("default"))) const char *qFlagLocation(const char *method);
38 |
39 | #ifndef QT_NO_META_MACROS
40 | # define QMETHOD_CODE0 0 // member type codes
41 | # define QSLOT_CODE1 1
42 | # define QSIGNAL_CODE2 2
43 | # define QT_PREFIX_CODE(code, a)"code" "a" QT_STRINGIFY(code)"code" #a
44 | # define QT_STRINGIFY_METHOD(a)"0" "a" QT_PREFIX_CODE(QMETHOD_CODE, a)"0" "a"
45 | # define QT_STRINGIFY_SLOT(a)"1" "a" QT_PREFIX_CODE(QSLOT_CODE, a)"1" "a"
46 | # define QT_STRINGIFY_SIGNAL(a)"2" "a" QT_PREFIX_CODE(QSIGNAL_CODE, a)"2" "a"
47 | # ifndef QT_NO_DEBUG
48 | # define QLOCATION"\0" "/usr/include/x86_64-linux-gnu/qt6/QtCore/qobjectdefs.h" ":" "48" "\0" __FILE__"/usr/include/x86_64-linux-gnu/qt6/QtCore/qobjectdefs.h" ":" QT_STRINGIFY(__LINE__)"48"
49 | # ifndef QT_NO_KEYWORDS
50 | # define METHOD(a)qFlagLocation("0" "a" "\0" "/usr/include/x86_64-linux-gnu/qt6/QtCore/qobjectdefs.h" ":" "50") qFlagLocation(QT_STRINGIFY_METHOD(a)"0" "a" QLOCATION"\0" "/usr/include/x86_64-linux-gnu/qt6/QtCore/qobjectdefs.h" ":" "50")
51 | # endif
52 | # define SLOT(a)qFlagLocation("1" "a" "\0" "/usr/include/x86_64-linux-gnu/qt6/QtCore/qobjectdefs.h" ":" "52") qFlagLocation(QT_STRINGIFY_SLOT(a)"1" "a" QLOCATION"\0" "/usr/include/x86_64-linux-gnu/qt6/QtCore/qobjectdefs.h" ":" "52")
53 | # define SIGNAL(a)qFlagLocation("2" "a" "\0" "/usr/include/x86_64-linux-gnu/qt6/QtCore/qobjectdefs.h" ":" "53") qFlagLocation(QT_STRINGIFY_SIGNAL(a)"2" "a" QLOCATION"\0" "/usr/include/x86_64-linux-gnu/qt6/QtCore/qobjectdefs.h" ":" "53")
54 | # else
55 | # ifndef QT_NO_KEYWORDS
56 | # define METHOD(a)qFlagLocation("0" "a" "\0" "/usr/include/x86_64-linux-gnu/qt6/QtCore/qobjectdefs.h" ":" "56") QT_STRINGIFY_METHOD(a)"0" "a"
57 | # endif
58 | # define SLOT(a)qFlagLocation("1" "a" "\0" "/usr/include/x86_64-linux-gnu/qt6/QtCore/qobjectdefs.h" ":" "58") QT_STRINGIFY_SLOT(a)"1" "a"
59 | # define SIGNAL(a)qFlagLocation("2" "a" "\0" "/usr/include/x86_64-linux-gnu/qt6/QtCore/qobjectdefs.h" ":" "59") QT_STRINGIFY_SIGNAL(a)"2" "a"
60 | # endif
61 | #endif // QT_NO_META_MACROS
62 |
63 | #define Q_ARG(Type, data)QtPrivate::Invoke::argument<Type>("Type", data) QtPrivate::Invoke::argument<Type>(QT_STRINGIFY(Type)"Type", data)
64 | #define Q_RETURN_ARG(Type, data)QtPrivate::Invoke::returnArgument<Type>("Type", data) QtPrivate::Invoke::returnArgument<Type>(QT_STRINGIFY(Type)"Type", data)
65 |
66 | class QObject;
67 | class QMetaMethod;
68 | class QMetaEnum;
69 | class QMetaProperty;
70 | class QMetaClassInfo;
71 |
72 | namespace QtPrivate {
73 | class QMetaTypeInterface;
74 | template<typename T> constexpr const QMetaTypeInterface *qMetaTypeInterfaceForType();
75 | }
76 |
77 | struct QMethodRawArguments
78 | {
79 | void **arguments;
80 | };
81 |
82 | #if QT_VERSION((6<<16)|(10<<8)|(2)) < QT_VERSION_CHECK(7, 0, 0)((7<<16)|(0<<8)|(0))
83 | class Q_CORE_EXPORT__attribute__((visibility("default"))) QGenericArgument
84 | {
85 | public:
86 | inline QGenericArgument(const char *aName = nullptr, const void *aData = nullptr)
87 | : _data(aData), _name(aName) {}
88 | inline void *data() const { return const_cast<void *>(_data); }
89 | inline const char *name() const { return _name; }
90 |
91 | private:
92 | const void *_data;
93 | const char *_name;
94 | };
95 |
96 | class Q_CORE_EXPORT__attribute__((visibility("default"))) QGenericReturnArgument: public QGenericArgument
97 | {
98 | public:
99 | inline QGenericReturnArgument(const char *aName = nullptr, void *aData = nullptr)
100 | : QGenericArgument(aName, aData)
101 | {}
102 | };
103 |
104 | template <class T>
105 | class QArgument: public QGenericArgument
106 | {
107 | public:
108 | inline QArgument(const char *aName, const T &aData)
109 | : QGenericArgument(aName, static_cast<const void *>(&aData))
110 | {}
111 | };
112 | template <class T>
113 | class QArgument<T &>: public QGenericArgument
114 | {
115 | public:
116 | inline QArgument(const char *aName, T &aData)
117 | : QGenericArgument(aName, static_cast<const void *>(&aData))
118 | {}
119 | };
120 |
121 |
122 | template <typename T>
123 | class QReturnArgument: public QGenericReturnArgument
124 | {
125 | public:
126 | inline QReturnArgument(const char *aName, T &aData)
127 | : QGenericReturnArgument(aName, static_cast<void *>(&aData))
128 | {}
129 | };
130 | #endif
131 |
132 | struct QMetaMethodArgument
133 | {
134 | const QtPrivate::QMetaTypeInterface *metaType;
135 | const char *name;
136 | const void *data;
137 | };
138 |
139 | struct QMetaMethodReturnArgument
140 | {
141 | const QtPrivate::QMetaTypeInterface *metaType;
142 | const char *name;
143 | void *data;
144 | };
145 |
146 | template <typename T>
147 | struct QTemplatedMetaMethodReturnArgument : QMetaMethodReturnArgument
148 | {
149 | using Type = T;
150 | };
151 |
152 | namespace QtPrivate {
153 | namespace Invoke {
154 | #if QT_VERSION((6<<16)|(10<<8)|(2)) <= QT_VERSION_CHECK(7, 0, 0)((7<<16)|(0<<8)|(0))
155 | template <typename... Args>
156 | using AreOldStyleArgs = std::disjunction<std::is_base_of<QGenericArgument, Args>...>;
157 |
158 | template <typename T, typename... Args> using IfNotOldStyleArgs =
159 | std::enable_if_t<!AreOldStyleArgs<Args...>::value, T>;
160 | #else
161 | template <typename T, typename... Args> using IfNotOldStyleArgs = T;
162 | #endif
163 |
164 | template <typename T> inline QMetaMethodArgument argument(const char *name, const T &t)
165 | {
166 | if constexpr ((std::is_lvalue_reference_v<T> && std::is_const_v<std::remove_reference_t<T>>) ||
167 | !std::is_reference_v<T>) {
168 | return { qMetaTypeInterfaceForType<T>(), name, std::addressof(t) };
169 | } else {
170 | return { nullptr, name, std::addressof(t) };
171 | }
172 | }
173 |
174 | template <typename T>
175 | inline QTemplatedMetaMethodReturnArgument<T> returnArgument(const char *name, T &t)
176 | {
177 | return { qMetaTypeInterfaceForType<T>(), name, std::addressof(t) };
178 | }
179 |
180 | template <typename T> inline const char *typenameHelper(const T &)
181 | {
182 | return nullptr;
183 | }
184 | template <typename T> inline const void *dataHelper(const T &t)
185 | {
186 | return std::addressof(t);
187 | }
188 | template <typename T> inline const QMetaTypeInterface *metaTypeHelper(const T &)
189 | {
190 | return qMetaTypeInterfaceForType<T>();
191 | }
192 |
193 | inline const char *typenameHelper(QMetaMethodArgument a)
194 | { return a.name; }
195 | inline const void *dataHelper(QMetaMethodArgument a)
196 | { return a.data; }
197 | inline const QMetaTypeInterface *metaTypeHelper(QMetaMethodArgument a)
198 | { return a.metaType; }
199 |
200 | inline const char *typenameHelper(const char *) = delete;
201 | template <typename T> inline const void *dataHelper(const char *) = delete;
202 | inline const QMetaTypeInterface *metaTypeHelper(const char *) = delete;
203 | inline const char *typenameHelper(const char16_t *) = delete;
204 | template <typename T> inline const void *dataHelper(const char16_t *) = delete;
205 | inline const QMetaTypeInterface *metaTypeHelper(const char16_t *) = delete;
206 |
207 | } // namespace QtPrivate::Invoke
208 |
209 | template <typename... Args> inline auto invokeMethodHelper(QMetaMethodReturnArgument r, const Args &... arguments)
210 | {
211 | std::array params = { const_cast<const void *>(r.data), Invoke::dataHelper(arguments)... };
212 | std::array names = { r.name, Invoke::typenameHelper(arguments)... };
213 | std::array types = { r.metaType, Invoke::metaTypeHelper(arguments)... };
214 | static_assert(params.size() == types.size());
215 | static_assert(params.size() == names.size());
216 |
217 | struct R {
218 | decltype(params) parameters;
219 | decltype(names) typeNames;
220 | decltype(types) metaTypes;
221 | constexpr qsizetype parameterCount() const { return qsizetype(parameters.size()); }
222 | };
223 | return R { params, names, types };
224 | }
225 | } // namespace QtPrivate
226 |
227 | template <typename T> void qReturnArg(const T &&) = delete;
228 | template <typename T> inline QTemplatedMetaMethodReturnArgument<T> qReturnArg(T &data)
229 | {
230 | return QtPrivate::Invoke::returnArgument(nullptr, data);
231 | }
232 |
233 | struct Q_CORE_EXPORT__attribute__((visibility("default"))) QMetaObject
234 | {
235 | class Connection;
236 | const char *className() const;
237 | const QMetaObject *superClass() const;
238 |
239 | bool inherits(const QMetaObject *metaObject) const noexcept;
240 | QObject *cast(QObject *obj) const
241 | { return const_cast<QObject *>(cast(const_cast<const QObject *>(obj))); }
242 | const QObject *cast(const QObject *obj) const;
243 |
244 | #if !defined(QT_NO_TRANSLATION) || defined(Q_QDOC)
245 | QString tr(const char *s, const char *c, int n = -1) const;
246 | #endif // QT_NO_TRANSLATION
247 |
248 | QMetaType metaType() const;
249 |
250 | int methodOffset() const;
251 | int enumeratorOffset() const;
252 | int propertyOffset() const;
253 | int classInfoOffset() const;
254 |
255 | int constructorCount() const;
256 | int methodCount() const;
257 | int enumeratorCount() const;
258 | int propertyCount() const;
259 | int classInfoCount() const;
260 |
261 | int indexOfConstructor(const char *constructor) const;
262 | int indexOfMethod(const char *method) const;
263 | int indexOfSignal(const char *signal) const;
264 | int indexOfSlot(const char *slot) const;
265 | int indexOfEnumerator(const char *name) const;
266 |
267 | int indexOfProperty(const char *name) const;
268 | int indexOfClassInfo(const char *name) const;
269 |
270 | QMetaMethod constructor(int index) const;
271 | QMetaMethod method(int index) const;
272 | QMetaEnum enumerator(int index) const;
273 | QMetaProperty property(int index) const;
274 | QMetaClassInfo classInfo(int index) const;
275 | QMetaProperty userProperty() const;
276 |
277 | static bool checkConnectArgs(const char *signal, const char *method);
278 | static bool checkConnectArgs(const QMetaMethod &signal,
279 | const QMetaMethod &method);
280 | static QByteArray normalizedSignature(const char *method);
281 | static QByteArray normalizedType(const char *type);
282 |
283 | // internal index-based connect
284 | static Connection connect(const QObject *sender, int signal_index,
285 | const QObject *receiver, int method_index,
286 | int type = 0, int *types = nullptr);
287 | // internal index-based disconnect
288 | static bool disconnect(const QObject *sender, int signal_index,
289 | const QObject *receiver, int method_index);
290 | static bool disconnectOne(const QObject *sender, int signal_index,
291 | const QObject *receiver, int method_index);
292 | // internal slot-name based connect
293 | static void connectSlotsByName(QObject *o);
294 |
295 | #ifdef Q_QDOC
296 | template<typename PointerToMemberFunction>
297 | static QMetaObject::Connection connect(const QObject *sender, const QMetaMethod &signal, const QObject *receiver, PointerToMemberFunction method, Qt::ConnectionType type = Qt::AutoConnection);
298 | template<typename Functor>
299 | static QMetaObject::Connection connect(const QObject *sender, const QMetaMethod &signal, const QObject *context, Functor functor, Qt::ConnectionType type = Qt::AutoConnection);
300 | #else
301 | template <typename Func>
302 | static inline Connection
303 | connect(const QObject *sender, const QMetaMethod &signal,
304 | const typename QtPrivate::ContextTypeForFunctor<Func>::ContextType *context, Func &&slot,
305 | Qt::ConnectionType type = Qt::AutoConnection);
306 | #endif // Q_QDOC
307 |
308 | // internal index-based signal activation
309 | static void activate(QObject *sender, int signal_index, void **argv);
310 | static void activate(QObject *sender, const QMetaObject *, int local_signal_index, void **argv);
311 | static void activate(QObject *sender, int signal_offset, int local_signal_index, void **argv);
312 | template <typename Ret, typename... Args> static inline void
313 | activate(QObject *sender, const QMetaObject *mo, int local_signal_index, Ret *ret, const Args &... args)
314 | {
315 | void *_a[] = {
316 | const_cast<void *>(reinterpret_cast<const volatile void *>(ret)),
317 | const_cast<void *>(reinterpret_cast<const volatile void *>(std::addressof(args)))...
318 | };
319 | activate(sender, mo, local_signal_index, _a);
320 | }
321 |
322 | #if QT_VERSION((6<<16)|(10<<8)|(2)) <= QT_VERSION_CHECK(7, 0, 0)((7<<16)|(0<<8)|(0))
323 | static bool invokeMethod(QObject *obj, const char *member,
324 | Qt::ConnectionType,
325 | QGenericReturnArgument ret,
326 | QGenericArgument val0 = QGenericArgument(nullptr),
327 | QGenericArgument val1 = QGenericArgument(),
328 | QGenericArgument val2 = QGenericArgument(),
329 | QGenericArgument val3 = QGenericArgument(),
330 | QGenericArgument val4 = QGenericArgument(),
331 | QGenericArgument val5 = QGenericArgument(),
332 | QGenericArgument val6 = QGenericArgument(),
333 | QGenericArgument val7 = QGenericArgument(),
334 | QGenericArgument val8 = QGenericArgument(),
335 | QGenericArgument val9 = QGenericArgument());
336 |
337 | static inline bool invokeMethod(QObject *obj, const char *member,
338 | QGenericReturnArgument ret,
339 | QGenericArgument val0 = QGenericArgument(nullptr),
340 | QGenericArgument val1 = QGenericArgument(),
341 | QGenericArgument val2 = QGenericArgument(),
342 | QGenericArgument val3 = QGenericArgument(),
343 | QGenericArgument val4 = QGenericArgument(),
344 | QGenericArgument val5 = QGenericArgument(),
345 | QGenericArgument val6 = QGenericArgument(),
346 | QGenericArgument val7 = QGenericArgument(),
347 | QGenericArgument val8 = QGenericArgument(),
348 | QGenericArgument val9 = QGenericArgument())
349 | {
350 | return invokeMethod(obj, member, Qt::AutoConnection, ret, val0, val1, val2, val3,
351 | val4, val5, val6, val7, val8, val9);
352 | }
353 |
354 | static inline bool invokeMethod(QObject *obj, const char *member,
355 | Qt::ConnectionType type,
356 | QGenericArgument val0,
357 | QGenericArgument val1 = QGenericArgument(),
358 | QGenericArgument val2 = QGenericArgument(),
359 | QGenericArgument val3 = QGenericArgument(),
360 | QGenericArgument val4 = QGenericArgument(),
361 | QGenericArgument val5 = QGenericArgument(),
362 | QGenericArgument val6 = QGenericArgument(),
363 | QGenericArgument val7 = QGenericArgument(),
364 | QGenericArgument val8 = QGenericArgument(),
365 | QGenericArgument val9 = QGenericArgument())
366 | {
367 | return invokeMethod(obj, member, type, QGenericReturnArgument(), val0, val1, val2,
368 | val3, val4, val5, val6, val7, val8, val9);
369 | }
370 |
371 | static inline bool invokeMethod(QObject *obj, const char *member,
372 | QGenericArgument val0,
373 | QGenericArgument val1 = QGenericArgument(),
374 | QGenericArgument val2 = QGenericArgument(),
375 | QGenericArgument val3 = QGenericArgument(),
376 | QGenericArgument val4 = QGenericArgument(),
377 | QGenericArgument val5 = QGenericArgument(),
378 | QGenericArgument val6 = QGenericArgument(),
379 | QGenericArgument val7 = QGenericArgument(),
380 | QGenericArgument val8 = QGenericArgument(),
381 | QGenericArgument val9 = QGenericArgument())
382 | {
383 | return invokeMethod(obj, member, Qt::AutoConnection, QGenericReturnArgument(), val0,
384 | val1, val2, val3, val4, val5, val6, val7, val8, val9);
385 | }
386 | #endif // Qt < 7.0
387 |
388 | template <typename ReturnArg, typename... Args> static
389 | #ifdef Q_QDOC
390 | bool
391 | #else
392 | QtPrivate::Invoke::IfNotOldStyleArgs<bool, Args...>
393 | #endif
394 | invokeMethod(QObject *obj, const char *member, Qt::ConnectionType c,
395 | QTemplatedMetaMethodReturnArgument<ReturnArg> r, Args &&... arguments)
396 | {
397 | auto h = QtPrivate::invokeMethodHelper(r, std::forward<Args>(arguments)...);
398 | return invokeMethodImpl(obj, member, c, h.parameterCount(), h.parameters.data(),
399 | h.typeNames.data(), h.metaTypes.data());
400 | }
401 |
402 | template <typename... Args> static
403 | #ifdef Q_QDOC
404 | bool
405 | #else
406 | QtPrivate::Invoke::IfNotOldStyleArgs<bool, Args...>
407 | #endif
408 | invokeMethod(QObject *obj, const char *member, Qt::ConnectionType c, Args &&... arguments)
409 | {
410 | QTemplatedMetaMethodReturnArgument<void> r = {};
411 | return invokeMethod(obj, member, c, r, std::forward<Args>(arguments)...);
412 | }
413 |
414 | template <typename ReturnArg, typename... Args> static
415 | #ifdef Q_QDOC
416 | bool
417 | #else
418 | QtPrivate::Invoke::IfNotOldStyleArgs<bool, Args...>
419 | #endif
420 | invokeMethod(QObject *obj, const char *member, QTemplatedMetaMethodReturnArgument<ReturnArg> r,
421 | Args &&... arguments)
422 | {
423 | return invokeMethod(obj, member, Qt::AutoConnection, r, std::forward<Args>(arguments)...);
424 | }
425 |
426 | template <typename... Args> static
427 | #ifdef Q_QDOC
428 | bool
429 | #else
430 | QtPrivate::Invoke::IfNotOldStyleArgs<bool, Args...>
431 | #endif
432 | invokeMethod(QObject *obj, const char *member, Args &&... arguments)
433 | {
434 | QTemplatedMetaMethodReturnArgument<void> r = {};
435 | return invokeMethod(obj, member, Qt::AutoConnection, r, std::forward<Args>(arguments)...);
436 | }
437 |
438 | #ifdef Q_QDOC
439 | template<typename Functor, typename FunctorReturnType>
440 | static bool invokeMethod(QObject *context, Functor &&function, Qt::ConnectionType type = Qt::AutoConnection, FunctorReturnType *ret = nullptr);
441 | template<typename Functor, typename FunctorReturnType>
442 | static bool invokeMethod(QObject *context, Functor &&function, FunctorReturnType *ret);
443 |
444 | template<typename Functor, typename FunctorReturnType, typename... Args>
445 | static bool invokeMethod(QObject *context, Functor &&function, Qt::ConnectionType type, QTemplatedMetaMethodReturnArgument<FunctorReturnType> ret, Args &&...arguments);
446 | template<typename Functor, typename FunctorReturnType, typename... Args>
447 | static bool invokeMethod(QObject *context, Functor &&function, QTemplatedMetaMethodReturnArgument<FunctorReturnType> ret, Args &&...arguments);
448 | template<typename Functor, typename... Args>
449 | static bool invokeMethod(QObject *context, Functor &&function, Qt::ConnectionType type, Args &&...arguments);
450 | template<typename Functor, typename... Args>
451 | static bool invokeMethod(QObject *context, Functor &&function, Args &&...arguments);
452 | #else
453 | template <typename Func>
454 | static std::enable_if_t<!std::disjunction_v<std::is_convertible<Func, const char *>,
455 | QtPrivate::Invoke::AreOldStyleArgs<Func>>,
456 | bool>
457 | invokeMethod(typename QtPrivate::ContextTypeForFunctor<Func>::ContextType *object,
458 | Func &&function, Qt::ConnectionType type,
459 | typename QtPrivate::Callable<Func>::ReturnType *ret)
460 | {
461 | using R = typename QtPrivate::Callable<Func>::ReturnType;
462 | const auto getReturnArg = [ret]() -> QTemplatedMetaMethodReturnArgument<R> {
463 | if constexpr (std::is_void_v<R>)
464 | return {};
465 | else
466 | return ret ? qReturnArg(*ret) : QTemplatedMetaMethodReturnArgument<R>{};
467 | };
468 | return invokeMethod(object, std::forward<Func>(function), type, getReturnArg());
469 | }
470 | template <typename Func>
471 | static std::enable_if_t<!std::disjunction_v<std::is_convertible<Func, const char *>,
472 | QtPrivate::Invoke::AreOldStyleArgs<Func>>,
473 | bool>
474 | invokeMethod(typename QtPrivate::ContextTypeForFunctor<Func>::ContextType *object,
475 | Func &&function, typename QtPrivate::Callable<Func>::ReturnType *ret)
476 | {
477 | return invokeMethod(object, std::forward<Func>(function), Qt::AutoConnection, ret);
478 | }
479 |
480 | template <typename Func, typename... Args>
481 | static std::enable_if_t<!std::disjunction_v<std::is_convertible<Func, const char *>,
482 | QtPrivate::Invoke::AreOldStyleArgs<Args...>>,
483 | bool>
484 | invokeMethod(typename QtPrivate::ContextTypeForFunctor<Func>::ContextType *object,
485 | Func &&function, Qt::ConnectionType type,
486 | QTemplatedMetaMethodReturnArgument<
487 | typename QtPrivate::Callable<Func, Args...>::ReturnType>
488 | ret,
489 | Args &&...args)
490 | {
491 | return invokeMethodCallableHelper(object, std::forward<Func>(function), type, ret,
5 | ← | Calling 'QMetaObject::invokeMethodCallableHelper' | →
492 | std::forward<Args>(args)...);
493 | }
494 |
495 | template <typename Func, typename... Args>
496 | static std::enable_if_t<!std::disjunction_v<std::is_convertible<Func, const char *>,
497 | QtPrivate::Invoke::AreOldStyleArgs<Args...>>,
498 | bool>
499 | invokeMethod(typename QtPrivate::ContextTypeForFunctor<Func>::ContextType *object,
500 | Func &&function, Qt::ConnectionType type, Args &&...args)
501 | {
502 | using R = typename QtPrivate::Callable<Func, Args...>::ReturnType;
503 | QTemplatedMetaMethodReturnArgument<R> r{ QtPrivate::qMetaTypeInterfaceForType<R>(), nullptr,
504 | nullptr };
505 | return invokeMethod(object, std::forward<Func>(function), type, r,
4 | ← | Calling 'QMetaObject::invokeMethod' | →
506 | std::forward<Args>(args)...);
507 | }
508 |
509 | template <typename Func, typename... Args>
510 | static std::enable_if_t<!std::disjunction_v<std::is_convertible<Func, const char *>,
511 | QtPrivate::Invoke::AreOldStyleArgs<Args...>>,
512 | bool>
513 | invokeMethod(typename QtPrivate::ContextTypeForFunctor<Func>::ContextType *object,
514 | Func &&function,
515 | QTemplatedMetaMethodReturnArgument<
516 | typename QtPrivate::Callable<Func, Args...>::ReturnType>
517 | ret,
518 | Args &&...args)
519 | {
520 | return invokeMethod(object, std::forward<Func>(function), Qt::AutoConnection, ret,
521 | std::forward<Args>(args)...);
522 | }
523 |
524 | template <typename Func, typename... Args>
525 | static std::enable_if_t<!std::disjunction_v<std::is_convertible<Func, const char *>,
526 | QtPrivate::Invoke::AreOldStyleArgs<Args...>>,
527 | bool>
528 | invokeMethod(typename QtPrivate::ContextTypeForFunctor<Func>::ContextType *object,
529 | Func &&function, Args &&...args)
530 | {
531 | using R = typename QtPrivate::Callable<Func, Args...>::ReturnType;
532 | QTemplatedMetaMethodReturnArgument<R> r{ QtPrivate::qMetaTypeInterfaceForType<R>(), nullptr,
533 | nullptr };
534 | return invokeMethod(object, std::forward<Func>(function), Qt::AutoConnection, r,
535 | std::forward<Args>(args)...);
536 | }
537 |
538 | #endif
539 |
540 | #if QT_VERSION((6<<16)|(10<<8)|(2)) < QT_VERSION_CHECK(7, 0, 0)((7<<16)|(0<<8)|(0))
541 | QObject *newInstance(QGenericArgument val0,
542 | QGenericArgument val1 = QGenericArgument(),
543 | QGenericArgument val2 = QGenericArgument(),
544 | QGenericArgument val3 = QGenericArgument(),
545 | QGenericArgument val4 = QGenericArgument(),
546 | QGenericArgument val5 = QGenericArgument(),
547 | QGenericArgument val6 = QGenericArgument(),
548 | QGenericArgument val7 = QGenericArgument(),
549 | QGenericArgument val8 = QGenericArgument(),
550 | QGenericArgument val9 = QGenericArgument()) const;
551 | #endif
552 |
553 | template <typename... Args>
554 | #ifdef Q_QDOC
555 | QObject *
556 | #else
557 | QtPrivate::Invoke::IfNotOldStyleArgs<QObject *, Args...>
558 | #endif
559 | newInstance(Args &&... arguments) const
560 | {
561 | auto h = QtPrivate::invokeMethodHelper(QMetaMethodReturnArgument{}, std::forward<Args>(arguments)...);
562 | return newInstanceImpl(this, h.parameterCount(), h.parameters.data(),
563 | h.typeNames.data(), h.metaTypes.data());
564 | }
565 |
566 | enum Call {
567 | InvokeMetaMethod,
568 | ReadProperty,
569 | WriteProperty,
570 | ResetProperty,
571 | CreateInstance,
572 | IndexOfMethod,
573 | RegisterPropertyMetaType,
574 | RegisterMethodArgumentMetaType,
575 | BindableProperty,
576 | CustomCall,
577 | ConstructInPlace,
578 | };
579 |
580 | int static_metacall(Call, int, void **) const;
581 | static int metacall(QObject *, Call, int, void **);
582 |
583 | template <const QMetaObject &MO> static constexpr const QMetaObject *staticMetaObject()
584 | {
585 | return &MO;
586 | }
587 |
588 | struct SuperData {
589 | using Getter = const QMetaObject *(*)();
590 | const QMetaObject *direct;
591 | SuperData() = default;
592 | constexpr SuperData(std::nullptr_t) : direct(nullptr) {}
593 | constexpr SuperData(const QMetaObject *mo) : direct(mo) {}
594 |
595 | constexpr const QMetaObject *operator->() const { return operator const QMetaObject *(); }
596 |
597 | #ifdef QT_NO_DATA_RELOCATION
598 | Getter indirect = nullptr;
599 | constexpr SuperData(Getter g) : direct(nullptr), indirect(g) {}
600 | constexpr operator const QMetaObject *() const
601 | { return indirect ? indirect() : direct; }
602 | template <const QMetaObject &MO> static constexpr SuperData link()
603 | { return SuperData(QMetaObject::staticMetaObject<MO>); }
604 | #else
605 | constexpr SuperData(Getter g) : direct(g()) {}
606 | constexpr operator const QMetaObject *() const
607 | { return direct; }
608 | template <const QMetaObject &MO> static constexpr SuperData link()
609 | { return SuperData(QMetaObject::staticMetaObject<MO>()); }
610 | #endif
611 | };
612 |
613 | struct Data { // private data
614 | SuperData superdata;
615 | const uint *stringdata;
616 | const uint *data;
617 | typedef void (*StaticMetacallFunction)(QObject *, QMetaObject::Call, int, void **);
618 | StaticMetacallFunction static_metacall;
619 | const SuperData *relatedMetaObjects;
620 | const QtPrivate::QMetaTypeInterface *const *metaTypes;
621 | void *extradata; //reserved for future use
622 | } d;
623 |
624 | private:
625 | // Just need to have this here with a separate name so the other inline
626 | // functions can call this without any ambiguity
627 | template <typename Func, typename... Args>
628 | static bool
629 | invokeMethodCallableHelper(typename QtPrivate::ContextTypeForFunctor<Func>::ContextType *object,
630 | Func &&function, Qt::ConnectionType type, const QMetaMethodReturnArgument &ret,
631 | Args &&...args)
632 | {
633 | using Callable = QtPrivate::Callable<Func, Args...>;
634 | using ExpectedArguments = typename Callable::Arguments;
635 | static_assert(sizeof...(Args) <= ExpectedArguments::size, "Too many arguments");
636 | using ActualArguments = QtPrivate::List<Args...>;
637 | static_assert(QtPrivate::CheckCompatibleArguments<ActualArguments,
638 | ExpectedArguments>::value,
639 | "Incompatible arguments");
640 |
641 | auto h = QtPrivate::invokeMethodHelper(ret, std::forward<Args>(args)...);
642 |
643 | // NOLINTBEGIN(clang-analyzer-cplusplus.NewDeleteLeaks)
644 | auto callable = new QtPrivate::QCallableObject<std::decay_t<Func>, ActualArguments,
6 | ← | Memory is allocated | →
645 | typename Callable::ReturnType>(std::forward<Func>(function));
646 | return invokeMethodImpl(object, callable, type, h.parameterCount(), h.parameters.data(),
7 | ← | Potential leak of memory pointed to by 'callable'
647 | h.typeNames.data(), h.metaTypes.data());
648 | // NOLINTEND(clang-analyzer-cplusplus.NewDeleteLeaks)
649 | }
650 |
651 | static bool invokeMethodImpl(QObject *object, const char *member, Qt::ConnectionType type,
652 | qsizetype parameterCount, const void *const *parameters, const char *const *names,
653 | const QtPrivate::QMetaTypeInterface * const *metaTypes);
654 | static bool invokeMethodImpl(QObject *object, QtPrivate::QSlotObjectBase *slotObj,
655 | Qt::ConnectionType type, qsizetype parameterCount,
656 | const void *const *params, const char *const *names,
657 | const QtPrivate::QMetaTypeInterface *const *metaTypes);
658 | #if QT_CORE_REMOVED_SINCE(6, 7)0
659 | static bool invokeMethodImpl(QObject *object, QtPrivate::QSlotObjectBase *slot, Qt::ConnectionType type, void *ret);
660 | #endif
661 | static QObject *newInstanceImpl(const QMetaObject *mobj, qsizetype parameterCount,
662 | const void **parameters, const char **typeNames,
663 | const QtPrivate::QMetaTypeInterface **metaTypes);
664 |
665 | static QMetaObject::Connection connectImpl(const QObject *sender, const QMetaMethod& signal,
666 | const QObject *receiver, void **slotPtr,
667 | QtPrivate::QSlotObjectBase *slot, Qt::ConnectionType type);
668 |
669 | friend class QTimer;
670 | friend class QChronoTimer;
671 | };
672 |
673 | class Q_CORE_EXPORT__attribute__((visibility("default"))) QMetaObject::Connection {
674 | void *d_ptr; //QObjectPrivate::Connection*
675 | explicit Connection(void *data) : d_ptr(data) { }
676 | friend class QObject;
677 | friend class QObjectPrivate;
678 | friend struct QMetaObject;
679 | bool isConnected_helper() const;
680 | public:
681 | ~Connection();
682 | Connection();
683 | Connection(const Connection &other);
684 | Connection &operator=(const Connection &other);
685 | #ifdef Q_QDOC
686 | operator bool() const;
687 | #else
688 | // still using the restricted bool trick here, in order to support
689 | // code using copy-init (e.g. `bool ok = connect(...)`)
690 | typedef void *Connection::*RestrictedBool;
691 | operator RestrictedBool() const { return d_ptr && isConnected_helper() ? &Connection::d_ptr : nullptr; }
692 | #endif
693 |
694 | Connection(Connection &&other) noexcept : d_ptr(std::exchange(other.d_ptr, nullptr)) {}
695 | QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_PURE_SWAP(Connection)Connection &operator=(Connection &&other) noexcept { swap(other); return *this; }
696 | void swap(Connection &other) noexcept { qt_ptr_swap(d_ptr, other.d_ptr); }
697 | };
698 |
699 | template <typename Func>
700 | QMetaObject::Connection
701 | QMetaObject::connect(const QObject *sender, const QMetaMethod &signal,
702 | const typename QtPrivate::ContextTypeForFunctor<Func>::ContextType *context, Func &&slot,
703 | Qt::ConnectionType type)
704 | {
705 | using Slot = std::decay_t<Func>;
706 | using FunctionSlotType = QtPrivate::FunctionPointer<Slot>;
707 | void **pSlot = nullptr;
708 | QtPrivate::QSlotObjectBase *slotObject;
709 | if constexpr (FunctionSlotType::ArgumentCount != -1) {
710 | slotObject = new QtPrivate::QCallableObject<Slot, typename FunctionSlotType::Arguments, typename FunctionSlotType::ReturnType>(std::forward<Func>(slot));
711 | if constexpr (FunctionSlotType::IsPointerToMemberFunction) {
712 | pSlot = const_cast<void **>(reinterpret_cast<void *const *>(&slot));
713 | } else {
714 | Q_ASSERT_X((type & Qt::UniqueConnection) == 0, "",(((type & Qt::UniqueConnection) == 0) ? static_cast<void >(0) : ::qt_assert_x("", "QObject::connect: Unique connection requires the slot to be a pointer to " "a member function of a QObject subclass.", "/usr/include/x86_64-linux-gnu/qt6/QtCore/qobjectdefs.h" , 716))
715 | "QObject::connect: Unique connection requires the slot to be a pointer to "(((type & Qt::UniqueConnection) == 0) ? static_cast<void >(0) : ::qt_assert_x("", "QObject::connect: Unique connection requires the slot to be a pointer to " "a member function of a QObject subclass.", "/usr/include/x86_64-linux-gnu/qt6/QtCore/qobjectdefs.h" , 716))
716 | "a member function of a QObject subclass.")(((type & Qt::UniqueConnection) == 0) ? static_cast<void >(0) : ::qt_assert_x("", "QObject::connect: Unique connection requires the slot to be a pointer to " "a member function of a QObject subclass.", "/usr/include/x86_64-linux-gnu/qt6/QtCore/qobjectdefs.h" , 716));
717 | }
718 | } else {
719 | using FunctorSlotType = QtPrivate::FunctionPointer<decltype(&Slot::operator())>;
720 | slotObject = new QtPrivate::QCallableObject<Slot, typename FunctorSlotType::Arguments, typename FunctorSlotType::ReturnType>(std::forward<Func>(slot));
721 | }
722 | return QMetaObject::connectImpl(sender, signal, context, pSlot, slotObject, type);
723 | }
724 |
725 | inline void swap(QMetaObject::Connection &lhs, QMetaObject::Connection &rhs) noexcept
726 | {
727 | lhs.swap(rhs);
728 | }
729 |
730 | inline const QMetaObject *QMetaObject::superClass() const
731 | { return d.superdata; }
732 |
733 | namespace QtPrivate {
734 | // Trait that tells if a QObject has a Q_OBJECT macro
735 | template <typename Object> struct HasQ_OBJECT_Macro {
736 | template <typename T>
737 | static char test(int (T::*)(QMetaObject::Call, int, void **));
738 | static int test(int (Object::*)(QMetaObject::Call, int, void **));
739 | enum { Value = sizeof(test(&Object::qt_metacall)) == sizeof(int) };
740 | };
741 |
742 | template <class TgtType, class SrcType>
743 | inline TgtType qobject_cast_helper(SrcType *object)
744 | {
745 | using ObjType = std::remove_cv_t<std::remove_pointer_t<TgtType>> ;
746 | static_assert(std::is_pointer_v<TgtType>,
747 | "qobject_cast requires to cast towards a pointer type");
748 | static_assert(HasQ_OBJECT_Macro<ObjType>::Value,
749 | "qobject_cast requires the type to have a Q_OBJECT macro");
750 |
751 | if constexpr (std::is_final_v<ObjType>) {
752 | if (object && object->metaObject() == &ObjType::staticMetaObject)
753 | return static_cast<TgtType>(object);
754 | return nullptr;
755 | } else {
756 | return static_cast<TgtType>(ObjType::staticMetaObject.cast(object));
757 | }
758 | }
759 | }
760 |
761 | QT_END_NAMESPACE
762 |
763 | #endif // QOBJECTDEFS_H