PortsModel: don't populate it by doing a lot of weird string-pushing.

When enumerating port-to-name entries, the callback to
wmem_map_foreach() gets passed:

- a key, which is the port number for the entry;
- a value, which is a pointer to a structure containing pointers to port
names for various transport protocols;
- a user data pointer.

That's sufficient (if you work around some C++ annoyances) to append a
row to a PortsModel, if the user data pointer is a pointer to the
PortsModel.

The existing code, instead, appended to a QStringList of lines (in
effect, undoing the effort of the code that read the services file and
filled in the wmem_map, re-generating a set of lines) in the callback,
and then iterated over all the lines, splitting them with blanks and
appending rows.

Looking at that made my eyeballs bleed so badly that I decided not to
spend any time figuring out why it wasn't working.

So I just make the callback just append rows, avoiding all the
string-pushing.

Fixes #17395.


(cherry picked from commit 6e95a0aa47)
This commit is contained in:
Guy Harris 2021-05-18 01:03:04 -07:00
parent 4a5dece155
commit 82b0eac6af
2 changed files with 44 additions and 15 deletions

View File

@ -32,9 +32,16 @@ public:
virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
protected:
//
// This is not protected because we may need to invoke it from
// a wmem_map_foreach() callback implemented as an extern "C"
// static member function of a subclass. wmem_map_foreach() is
// passed, as the user data, a pointer to the class instance to
// which we want to append rows.
//
virtual void appendRow(const QStringList &, const QString & row_tooltip = QString(), const QModelIndex &parent = QModelIndex());
protected:
virtual QStringList headerColumns() const = 0;
private:

View File

@ -20,20 +20,47 @@ extern "C"
{
static void
serv_port_hash_to_qstringlist(gpointer key, gpointer value, gpointer sl_ptr)
serv_port_hash_to_qstringlist(gpointer key, gpointer value, gpointer member_ptr)
{
QStringList *string_list = (QStringList *) sl_ptr;
PortsModel *model = static_cast<PortsModel *>(member_ptr);
serv_port_t *serv_port = (serv_port_t *)value;
guint port = GPOINTER_TO_UINT(key);
QStringList entries;
if (serv_port->tcp_name) {
QStringList entries;
if (serv_port->tcp_name) entries << QString("%1 %2 tcp").arg(serv_port->tcp_name).arg(port);
if (serv_port->udp_name) entries << QString("%1 %2 udp").arg(serv_port->udp_name).arg(port);
if (serv_port->sctp_name) entries << QString("%1 %2 sctp").arg(serv_port->sctp_name).arg(port);
if (serv_port->dccp_name) entries << QString("%1 %2 dccp").arg(serv_port->dccp_name).arg(port);
entries << serv_port->tcp_name;
entries << QString("%1").arg(port);
entries << "tcp";
model->appendRow(entries);
}
if (serv_port->udp_name) {
QStringList entries;
if (!entries.isEmpty()) *string_list << entries.join("\n");
entries = QStringList();
entries << serv_port->udp_name;
entries << QString("%1").arg(port);
entries << "udp";
model->appendRow(entries);
}
if (serv_port->sctp_name) {
QStringList entries;
entries = QStringList();
entries << serv_port->sctp_name;
entries << QString("%1").arg(port);
entries << "sctp";
model->appendRow(entries);
}
if (serv_port->dccp_name) {
QStringList entries;
entries = QStringList();
entries << serv_port->dccp_name;
entries << QString("%1").arg(port);
entries << "dccp";
model->appendRow(entries);
}
}
static void
@ -175,15 +202,10 @@ QStringList PortsModel::headerColumns() const
void PortsModel::populate()
{
QStringList values;
wmem_map_t *serv_port_hashtable = get_serv_port_hashtable();
if (serv_port_hashtable) {
wmem_map_foreach(serv_port_hashtable, serv_port_hash_to_qstringlist, &values);
wmem_map_foreach(serv_port_hashtable, serv_port_hash_to_qstringlist, this);
}
foreach(QString line, values)
appendRow(QStringList() << line.split(" "));
}
/*