QEdidParser: optimize the hardcoded EDID vendor table
Instead of using an array of fixed-length strings for the vendor names, use qOffsetStringArray instead. This removes the need of using the longest vendor name length as the size of the fixed-length strings, which results in a massive waste of space. This saves 150KB of (readonly) data. Details: there are 2555 entries, each one hardcoded to be 78 byte long, for a total of 199290 bytes. However the vendor names themselves amount only to 50658 bytes. Making all this data optional on desktop Linux (where the vendor data is present anyhow on the system, in /usr/share/) is left for a future change. Change-Id: I17007865e741e3dab15dd2ab2feffbce4664fb37 Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
This commit is contained in:
parent
8d0283ad2c
commit
6844c70ae9
@ -124,20 +124,20 @@ bool QEdidParser::parse(const QByteArray &blob)
|
||||
|
||||
if (manufacturer.isEmpty()) {
|
||||
// Find the manufacturer from the vendor lookup table
|
||||
const auto compareVendorId = [](const VendorTable &vendor, const char *str)
|
||||
const auto compareVendorId = [](const QEdidVendorId &vendor, const char *str)
|
||||
{
|
||||
return strncmp(vendor.id, str, 3) < 0;
|
||||
};
|
||||
|
||||
const auto b = std::begin(q_edidVendorTable);
|
||||
const auto e = std::end(q_edidVendorTable);
|
||||
const auto b = std::begin(q_edidVendorIds);
|
||||
const auto e = std::end(q_edidVendorIds);
|
||||
auto it = std::lower_bound(b,
|
||||
e,
|
||||
pnpId,
|
||||
compareVendorId);
|
||||
|
||||
if (it != e && strncmp(it->id, pnpId, 3) == 0)
|
||||
manufacturer = QString::fromUtf8(it->name);
|
||||
manufacturer = QString::fromUtf8(q_edidVendorNames + q_edidVendorNamesOffsets[it - b]);
|
||||
}
|
||||
|
||||
// If we don't know the manufacturer, fallback to PNP ID
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -3,14 +3,14 @@
|
||||
# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
import urllib.request
|
||||
import sys
|
||||
|
||||
# The original source for this data used to be
|
||||
# 'https://git.fedorahosted.org/cgit/hwdata.git/plain/pnp.ids'
|
||||
# which is discontinued. For now there seems to be a fork at:
|
||||
url = 'https://github.com/vcrhonek/hwdata/raw/master/pnp.ids'
|
||||
# REUSE-IgnoreStart
|
||||
copyright = """
|
||||
// Copyright (C) 2017 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
|
||||
copyright = """// Copyright (C) 2017 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
||||
"""
|
||||
# REUSE-IgnoreEnd
|
||||
@ -37,43 +37,89 @@ header = """
|
||||
//
|
||||
|
||||
#include <QtCore/private/qglobal_p.h>
|
||||
#include <QtCore/qtypes.h>
|
||||
|
||||
#include <iterator>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
"""
|
||||
|
||||
struct VendorTable {
|
||||
vendorIdHeader = """struct QEdidVendorId {
|
||||
const char id[4];
|
||||
const char name[%d];
|
||||
};
|
||||
|
||||
static const VendorTable q_edidVendorTable[] = {"""
|
||||
static constexpr QEdidVendorId q_edidVendorIds[] = {"""
|
||||
|
||||
footer = """};
|
||||
vendorIdFooter = """};
|
||||
"""
|
||||
|
||||
vendorNameHeader = """static constexpr char q_edidVendorNames[] = {"""
|
||||
|
||||
vendorNameFooter = """};
|
||||
"""
|
||||
|
||||
vendorNameOffsetHeader = """static constexpr %s q_edidVendorNamesOffsets[] = {"""
|
||||
|
||||
vendorNameOffsetFooter = """};
|
||||
"""
|
||||
|
||||
footer = """static_assert(std::size(q_edidVendorIds) == std::size(q_edidVendorNamesOffsets));
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QEDIDVENDORTABLE_P_H"""
|
||||
|
||||
|
||||
# Actual script begins here
|
||||
|
||||
vendors = {}
|
||||
|
||||
max_vendor_length = 0
|
||||
|
||||
vendorNameTotalLength = 0
|
||||
response = urllib.request.urlopen(url)
|
||||
data = response.read().decode('utf-8')
|
||||
for line in data.split('\n'):
|
||||
l = line.split()
|
||||
if line.startswith('#'):
|
||||
continue
|
||||
elif len(l) == 0:
|
||||
elif len(line) == 0:
|
||||
continue
|
||||
else:
|
||||
pnp_id = l[0].upper()
|
||||
vendors[pnp_id] = ' '.join(l[1:])
|
||||
if len(vendors[pnp_id]) > max_vendor_length:
|
||||
max_vendor_length = len(vendors[pnp_id])
|
||||
|
||||
l = line.split('\t', 1)
|
||||
if len(l) == 0:
|
||||
continue
|
||||
|
||||
pnp_id = l[0].upper()
|
||||
if len(pnp_id) != 3:
|
||||
sys.exit("Id '%s' is non-conforming" % pnp_id)
|
||||
vendors[pnp_id] = l[1]
|
||||
vendorNameTotalLength += len(l[1]) + 1
|
||||
|
||||
sortedVendorKeys = sorted(vendors.keys())
|
||||
|
||||
print(copyright)
|
||||
print(notice)
|
||||
print(header % (max_vendor_length + 1))
|
||||
for pnp_id in sorted(vendors.keys()):
|
||||
print(' { "%s", "%s" },' % (pnp_id, vendors[pnp_id]))
|
||||
print(header)
|
||||
|
||||
print(vendorIdHeader)
|
||||
print(*[(' { "%s" }' % pnp_id) for pnp_id in sortedVendorKeys], sep=",\n")
|
||||
print(vendorIdFooter)
|
||||
|
||||
print(vendorNameHeader)
|
||||
print(*[(' "%s\\0"' % vendors[pnp_id]) for pnp_id in sortedVendorKeys], sep="\n")
|
||||
print(vendorNameFooter)
|
||||
|
||||
if vendorNameTotalLength < 2**16:
|
||||
print(vendorNameOffsetHeader % "quint16")
|
||||
elif vendorNameTotalLength < 2**32:
|
||||
print(vendorNameOffsetHeader % "quint32")
|
||||
else:
|
||||
sys.exit("Vendor name table is too big")
|
||||
|
||||
currentOffset = 0
|
||||
for pnp_id in sortedVendorKeys:
|
||||
vendor = vendors[pnp_id]
|
||||
print(' %d,' % currentOffset)
|
||||
currentOffset += len(vendor) + 1
|
||||
|
||||
print(vendorNameOffsetFooter)
|
||||
|
||||
print(footer)
|
||||
|
Loading…
x
Reference in New Issue
Block a user