summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarc Mutz <marc.mutz@kdab.com>2016-05-17 13:05:26 +0200
committerMarc Mutz <marc.mutz@kdab.com>2019-07-22 10:54:51 +0300
commit9b91d68df0a812b2fa0dd3da3f06ff0724033a46 (patch)
treebf09cf336aaf367830976cabaea19ce53aea7364
parent7c5f56277cd0c7450a168af6188ee4753655ca31 (diff)
assimp plugin: replace QMap with a C array
The keys are statically known, short, and few, so replace the QMap<QByteArray, OpenMode> with a C array of a {char[2]; OpenMode} struct, which occupies just 40B in read-only memory. We don't even need to sort the list, as binary search in a list of ten entries is slower than linear search (five comparisons each, on average, with the linear scan having a predictable memory access pattern. This is a port of dd1d8f51e67ec93031fdd7f7930d63761d1238e6 to the other copy of this code, which shows that arguments like 'this is just a tool, not a library' are ill-advised. Code _will_ be copied. Change-Id: Ie04137f94e487ce998ec077daf655b09bcbbcfc7 Reviewed-by: Paul Lemire <paul.lemire@kdab.com>
-rw-r--r--src/plugins/sceneparsers/assimp/assimphelpers.cpp57
-rw-r--r--src/plugins/sceneparsers/assimp/assimphelpers.h6
2 files changed, 28 insertions, 35 deletions
diff --git a/src/plugins/sceneparsers/assimp/assimphelpers.cpp b/src/plugins/sceneparsers/assimp/assimphelpers.cpp
index ce6619541..77209a7a9 100644
--- a/src/plugins/sceneparsers/assimp/assimphelpers.cpp
+++ b/src/plugins/sceneparsers/assimp/assimphelpers.cpp
@@ -157,29 +157,29 @@ void AssimpIOStream::Flush()
*
*/
-/*!
- * Builds a new instance of AssimpIOSystem.
- */
-AssimpIOSystem::AssimpIOSystem() :
- Assimp::IOSystem()
-{
- m_openModeMaps[QByteArrayLiteral("r")] = QIODevice::ReadOnly;
- m_openModeMaps[QByteArrayLiteral("r+")] = QIODevice::ReadWrite;
- m_openModeMaps[QByteArrayLiteral("w")] = QIODevice::WriteOnly | QIODevice::Truncate;
- m_openModeMaps[QByteArrayLiteral("w+")] = QIODevice::ReadWrite | QIODevice::Truncate;
- m_openModeMaps[QByteArrayLiteral("a")] = QIODevice::WriteOnly | QIODevice::Append;
- m_openModeMaps[QByteArrayLiteral("a+")] = QIODevice::ReadWrite | QIODevice::Append;
- m_openModeMaps[QByteArrayLiteral("wb")] = QIODevice::WriteOnly;
- m_openModeMaps[QByteArrayLiteral("wt")] = QIODevice::WriteOnly | QIODevice::Text;
- m_openModeMaps[QByteArrayLiteral("rb")] = QIODevice::ReadOnly;
- m_openModeMaps[QByteArrayLiteral("rt")] = QIODevice::ReadOnly | QIODevice::Text;
-}
-
-/*!
- * Clears an AssimpIOSystem instance before deletion.
- */
-AssimpIOSystem::~AssimpIOSystem()
+static QIODevice::OpenMode openModeFromText(const char *name) noexcept
{
+ static const struct OpenModeMapping {
+ char name[2];
+ ushort mode;
+ } openModeMapping[] = {
+ { { 'r', 0 }, QIODevice::ReadOnly },
+ { { 'r', '+' }, QIODevice::ReadWrite },
+ { { 'w', 0 }, QIODevice::WriteOnly | QIODevice::Truncate },
+ { { 'w', '+' }, QIODevice::ReadWrite | QIODevice::Truncate },
+ { { 'a', 0 }, QIODevice::WriteOnly | QIODevice::Append },
+ { { 'a', '+' }, QIODevice::ReadWrite | QIODevice::Append },
+ { { 'w', 'b' }, QIODevice::WriteOnly },
+ { { 'w', 't' }, QIODevice::WriteOnly | QIODevice::Text },
+ { { 'r', 'b' }, QIODevice::ReadOnly },
+ { { 'r', 't' }, QIODevice::ReadOnly | QIODevice::Text },
+ };
+
+ for (auto e : openModeMapping) {
+ if (qstrncmp(e.name, name, sizeof(OpenModeMapping::name)) == 0)
+ return static_cast<QIODevice::OpenMode>(e.mode);
+ }
+ return QIODevice::NotOpen;
}
/*!
@@ -205,14 +205,13 @@ char AssimpIOSystem::getOsSeparator() const
Assimp::IOStream *AssimpIOSystem::Open(const char *pFile, const char *pMode)
{
const QString fileName(QString::fromUtf8(pFile));
- const QByteArray cleanedMode(QByteArray(pMode).trimmed());
-
- const QIODevice::OpenMode openMode = m_openModeMaps.value(cleanedMode, QIODevice::NotOpen);
-
- QScopedPointer<QFile> file(new QFile(fileName));
- if (file->open(openMode))
- return new AssimpIOStream(file.take());
+ const QLatin1String cleanedMode = QLatin1String{pMode}.trimmed();
+ if (const QIODevice::OpenMode openMode = openModeFromText(cleanedMode.data())) {
+ QScopedPointer<QFile> file(new QFile(fileName));
+ if (file->open(openMode))
+ return new AssimpIOStream(file.take());
+ }
return nullptr;
}
diff --git a/src/plugins/sceneparsers/assimp/assimphelpers.h b/src/plugins/sceneparsers/assimp/assimphelpers.h
index 0db22ce7b..fd102213c 100644
--- a/src/plugins/sceneparsers/assimp/assimphelpers.h
+++ b/src/plugins/sceneparsers/assimp/assimphelpers.h
@@ -55,7 +55,6 @@
#include <assimp/IOStream.hpp>
#include <assimp/IOSystem.hpp>
#include <QtCore/QIODevice>
-#include <QtCore/QMap>
QT_BEGIN_NAMESPACE
@@ -84,15 +83,10 @@ private:
class AssimpIOSystem : public Assimp::IOSystem
{
public :
- AssimpIOSystem();
- ~AssimpIOSystem();
bool Exists(const char *pFile) const override;
char getOsSeparator() const override;
Assimp::IOStream *Open(const char *pFile, const char *pMode) override;
void Close(Assimp::IOStream *pFile) override;
-
-private:
- QMap<QByteArray, QIODevice::OpenMode> m_openModeMaps;
};
} // namespace AssimpHelper