File: | builds/wireshark/wireshark/ui/qt/models/supported_protocols_model.cpp |
Warning: | line 185, column 5 Potential leak of memory pointed to by 'fieldItem' |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* supported_protocols_model.cpp | |||
2 | * | |||
3 | * Wireshark - Network traffic analyzer | |||
4 | * By Gerald Combs <[email protected]> | |||
5 | * Copyright 1998 Gerald Combs | |||
6 | * | |||
7 | * SPDX-License-Identifier: GPL-2.0-or-later | |||
8 | */ | |||
9 | ||||
10 | #include <QSortFilterProxyModel> | |||
11 | #include <QStringList> | |||
12 | #include <QPalette> | |||
13 | #include <QApplication> | |||
14 | #include <QBrush> | |||
15 | #include <QRegularExpression> | |||
16 | ||||
17 | #include <ui/qt/models/supported_protocols_model.h> | |||
18 | ||||
19 | SupportedProtocolsItem::SupportedProtocolsItem(protocol_t* proto, const char *name, const char* filter, ftenum_t ftype, const char* descr, SupportedProtocolsItem* parent) | |||
20 | : ModelHelperTreeItem<SupportedProtocolsItem>(parent), | |||
21 | proto_(proto), | |||
22 | name_(name), | |||
23 | filter_(filter), | |||
24 | ftype_(ftype), | |||
25 | descr_(descr) | |||
26 | { | |||
27 | } | |||
28 | ||||
29 | SupportedProtocolsItem::~SupportedProtocolsItem() | |||
30 | { | |||
31 | } | |||
32 | ||||
33 | ||||
34 | SupportedProtocolsModel::SupportedProtocolsModel(QObject *parent) : | |||
35 | QAbstractItemModel(parent), | |||
36 | root_(new SupportedProtocolsItem(NULL__null, NULL__null, NULL__null, FT_NONE, NULL__null, NULL__null)), | |||
37 | field_count_(0) | |||
38 | { | |||
39 | } | |||
40 | ||||
41 | SupportedProtocolsModel::~SupportedProtocolsModel() | |||
42 | { | |||
43 | delete root_; | |||
44 | } | |||
45 | ||||
46 | int SupportedProtocolsModel::rowCount(const QModelIndex &parent) const | |||
47 | { | |||
48 | SupportedProtocolsItem *parent_item; | |||
49 | if (parent.column() > 0) | |||
50 | return 0; | |||
51 | ||||
52 | if (!parent.isValid()) | |||
53 | parent_item = root_; | |||
54 | else | |||
55 | parent_item = static_cast<SupportedProtocolsItem*>(parent.internalPointer()); | |||
56 | ||||
57 | if (parent_item == NULL__null) | |||
58 | return 0; | |||
59 | ||||
60 | return parent_item->childCount(); | |||
61 | } | |||
62 | ||||
63 | int SupportedProtocolsModel::columnCount(const QModelIndex&) const | |||
64 | { | |||
65 | return colLast; | |||
66 | } | |||
67 | ||||
68 | QVariant SupportedProtocolsModel::headerData(int section, Qt::Orientation orientation, int role) const | |||
69 | { | |||
70 | if (orientation == Qt::Horizontal && role == Qt::DisplayRole) { | |||
71 | ||||
72 | switch ((enum SupportedProtocolsColumn)section) { | |||
73 | case colName: | |||
74 | return tr("Name"); | |||
75 | case colFilter: | |||
76 | return tr("Filter"); | |||
77 | case colType: | |||
78 | return tr("Type"); | |||
79 | case colDescription: | |||
80 | return tr("Description"); | |||
81 | default: | |||
82 | break; | |||
83 | } | |||
84 | } | |||
85 | return QVariant(); | |||
86 | } | |||
87 | ||||
88 | QModelIndex SupportedProtocolsModel::parent(const QModelIndex& index) const | |||
89 | { | |||
90 | if (!index.isValid()) | |||
91 | return QModelIndex(); | |||
92 | ||||
93 | SupportedProtocolsItem* item = static_cast<SupportedProtocolsItem*>(index.internalPointer()); | |||
94 | if (item != NULL__null) { | |||
95 | SupportedProtocolsItem* parent_item = item->parentItem(); | |||
96 | if (parent_item != NULL__null) { | |||
97 | if (parent_item == root_) | |||
98 | return QModelIndex(); | |||
99 | ||||
100 | return createIndex(parent_item->row(), 0, parent_item); | |||
101 | } | |||
102 | } | |||
103 | ||||
104 | return QModelIndex(); | |||
105 | } | |||
106 | ||||
107 | QModelIndex SupportedProtocolsModel::index(int row, int column, const QModelIndex& parent) const | |||
108 | { | |||
109 | if (!hasIndex(row, column, parent)) | |||
110 | return QModelIndex(); | |||
111 | ||||
112 | SupportedProtocolsItem *parent_item, *child_item; | |||
113 | ||||
114 | if (!parent.isValid()) | |||
115 | parent_item = root_; | |||
116 | else | |||
117 | parent_item = static_cast<SupportedProtocolsItem*>(parent.internalPointer()); | |||
118 | ||||
119 | Q_ASSERT(parent_item)((parent_item) ? static_cast<void>(0) : qt_assert("parent_item" , "ui/qt/models/supported_protocols_model.cpp", 119)); | |||
120 | ||||
121 | child_item = parent_item->child(row); | |||
122 | if (child_item) { | |||
123 | return createIndex(row, column, child_item); | |||
124 | } | |||
125 | ||||
126 | return QModelIndex(); | |||
127 | } | |||
128 | ||||
129 | QVariant SupportedProtocolsModel::data(const QModelIndex &index, int role) const | |||
130 | { | |||
131 | if (!index.isValid() || role != Qt::DisplayRole) | |||
132 | return QVariant(); | |||
133 | ||||
134 | SupportedProtocolsItem* item = static_cast<SupportedProtocolsItem*>(index.internalPointer()); | |||
135 | if (item == NULL__null) | |||
136 | return QVariant(); | |||
137 | ||||
138 | switch ((enum SupportedProtocolsColumn)index.column()) { | |||
139 | case colName: | |||
140 | return item->name(); | |||
141 | case colFilter: | |||
142 | return item->filter(); | |||
143 | case colType: | |||
144 | if (index.parent().isValid()) | |||
145 | return QString(ftype_pretty_name(item->type())); | |||
146 | ||||
147 | return QVariant(); | |||
148 | case colDescription: | |||
149 | return item->description(); | |||
150 | default: | |||
151 | break; | |||
152 | } | |||
153 | ||||
154 | return QVariant(); | |||
155 | } | |||
156 | ||||
157 | void SupportedProtocolsModel::populate() | |||
158 | { | |||
159 | void *proto_cookie; | |||
160 | void *field_cookie; | |||
161 | ||||
162 | beginResetModel(); | |||
163 | ||||
164 | SupportedProtocolsItem *protoItem, *fieldItem; | |||
165 | protocol_t *protocol; | |||
166 | ||||
167 | for (int proto_id = proto_get_first_protocol(&proto_cookie); proto_id != -1; | |||
| ||||
168 | proto_id = proto_get_next_protocol(&proto_cookie)) { | |||
169 | ||||
170 | protocol = find_protocol_by_id(proto_id); | |||
171 | protoItem = new SupportedProtocolsItem(protocol, proto_get_protocol_short_name(protocol), proto_get_protocol_filter_name(proto_id), FT_PROTOCOL, proto_get_protocol_long_name(protocol), root_); | |||
172 | root_->prependChild(protoItem); | |||
173 | ||||
174 | for (header_field_info *hfinfo = proto_get_first_protocol_field(proto_id, &field_cookie); hfinfo != NULL__null; | |||
175 | hfinfo = proto_get_next_protocol_field(proto_id, &field_cookie)) { | |||
176 | if (hfinfo->same_name_prev_id != -1) | |||
177 | continue; | |||
178 | ||||
179 | fieldItem = new SupportedProtocolsItem(protocol, hfinfo->name, hfinfo->abbrev, hfinfo->type, hfinfo->blurb, protoItem); | |||
180 | protoItem->prependChild(fieldItem); | |||
181 | field_count_++; | |||
182 | } | |||
183 | } | |||
184 | ||||
185 | endResetModel(); | |||
| ||||
186 | } | |||
187 | ||||
188 | ||||
189 | ||||
190 | SupportedProtocolsProxyModel::SupportedProtocolsProxyModel(QObject * parent) | |||
191 | : QSortFilterProxyModel(parent), | |||
192 | filter_() | |||
193 | { | |||
194 | } | |||
195 | ||||
196 | bool SupportedProtocolsProxyModel::lessThan(const QModelIndex &left, const QModelIndex &right) const | |||
197 | { | |||
198 | //Use SupportedProtocolsItem directly for better performance | |||
199 | SupportedProtocolsItem* left_item = static_cast<SupportedProtocolsItem*>(left.internalPointer()); | |||
200 | SupportedProtocolsItem* right_item = static_cast<SupportedProtocolsItem*>(right.internalPointer()); | |||
201 | ||||
202 | if ((left_item != NULL__null) && (right_item != NULL__null)) { | |||
203 | int compare_ret = QString::compare(left_item->name(), right_item->name(), Qt::CaseInsensitive); | |||
204 | if (compare_ret < 0) | |||
205 | return true; | |||
206 | } | |||
207 | ||||
208 | return false; | |||
209 | } | |||
210 | ||||
211 | bool SupportedProtocolsProxyModel::filterAcceptItem(SupportedProtocolsItem& item) const | |||
212 | { | |||
213 | QRegularExpression regex(filter_, QRegularExpression::CaseInsensitiveOption); | |||
214 | if (! regex.isValid()) | |||
215 | return false; | |||
216 | ||||
217 | if (item.name().contains(regex)) | |||
218 | return true; | |||
219 | ||||
220 | if (item.filter().contains(regex)) | |||
221 | return true; | |||
222 | ||||
223 | if (item.description().contains(regex)) | |||
224 | return true; | |||
225 | ||||
226 | return false; | |||
227 | } | |||
228 | ||||
229 | bool SupportedProtocolsProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const | |||
230 | { | |||
231 | QModelIndex nameIdx = sourceModel()->index(sourceRow, SupportedProtocolsModel::colName, sourceParent); | |||
232 | SupportedProtocolsItem* item = static_cast<SupportedProtocolsItem*>(nameIdx.internalPointer()); | |||
233 | if (item == NULL__null) | |||
234 | return true; | |||
235 | ||||
236 | if (!filter_.isEmpty()) { | |||
237 | if (filterAcceptItem(*item)) | |||
238 | return true; | |||
239 | ||||
240 | if (!nameIdx.parent().isValid()) | |||
241 | { | |||
242 | SupportedProtocolsItem* child_item; | |||
243 | for (int row = 0; row < item->childCount(); row++) | |||
244 | { | |||
245 | child_item = item->child(row); | |||
246 | if ((child_item != NULL__null) && (filterAcceptItem(*child_item))) | |||
247 | return true; | |||
248 | } | |||
249 | } | |||
250 | ||||
251 | return false; | |||
252 | } | |||
253 | ||||
254 | return true; | |||
255 | } | |||
256 | ||||
257 | void SupportedProtocolsProxyModel::setFilter(const QString& filter) | |||
258 | { | |||
259 | filter_ = filter; | |||
260 | invalidateFilter(); | |||
261 | } |