summaryrefslogtreecommitdiffstats
path: root/src/corelib
diff options
context:
space:
mode:
authorOswald Buddenhagen <oswald.buddenhagen@nokia.com>2011-04-28 10:53:14 +0200
committerOlivier Goffart <olivier.goffart@nokia.com>2011-05-10 12:54:52 +0200
commit9ff8d1c34a74bd852a7eb2016b46ab2904340b05 (patch)
tree923330e5d529a8b616c4d4ecbf6c42d48f14a5b9 /src/corelib
parent299d10549f5aff50cd6211eb3d3e58c17f13be81 (diff)
make QProcessEnvironment on Unix cache converted variable names
the converted keys also cache their hash, as they are used only for the purpose of looking up in a qhash. Reviewed-by: thiago Reviewed-by: dt (cherry picked from commit 18f1613aa8ece72d24ac10e28f06e3db1d8ce400)
Diffstat (limited to 'src/corelib')
-rw-r--r--src/corelib/io/qprocess.cpp17
-rw-r--r--src/corelib/io/qprocess_p.h40
-rw-r--r--src/corelib/io/qprocess_unix.cpp4
3 files changed, 50 insertions, 11 deletions
diff --git a/src/corelib/io/qprocess.cpp b/src/corelib/io/qprocess.cpp
index ffd5ff0ff8..80e0b0f36f 100644
--- a/src/corelib/io/qprocess.cpp
+++ b/src/corelib/io/qprocess.cpp
@@ -202,12 +202,19 @@ QStringList QProcessEnvironmentPrivate::keys() const
return result;
}
-void QProcessEnvironmentPrivate::insert(const Hash &h)
+void QProcessEnvironmentPrivate::insert(const QProcessEnvironmentPrivate &other)
{
- Hash::ConstIterator it = h.constBegin(),
- end = h.constEnd();
+ Hash::ConstIterator it = other.hash.constBegin(),
+ end = other.hash.constEnd();
for ( ; it != end; ++it)
hash.insert(it.key(), it.value());
+
+#ifdef Q_OS_UNIX
+ QHash<QString, Key>::ConstIterator nit = other.nameMap.constBegin(),
+ nend = other.nameMap.constEnd();
+ for ( ; nit != nend; ++nit)
+ nameMap.insert(nit.key(), nit.value());
+#endif
}
/*!
@@ -288,6 +295,8 @@ void QProcessEnvironment::clear()
{
if (d)
d->hash.clear();
+ // Unix: Don't clear d->nameMap, as the environment is likely to be
+ // re-populated with the same keys again.
}
/*!
@@ -409,7 +418,7 @@ void QProcessEnvironment::insert(const QProcessEnvironment &e)
return;
// d detaches from null
- d->insert(e.d->hash);
+ d->insert(*e.d);
}
void QProcessPrivate::Channel::clear()
diff --git a/src/corelib/io/qprocess_p.h b/src/corelib/io/qprocess_p.h
index 14fc9f32ce..9a9981efda 100644
--- a/src/corelib/io/qprocess_p.h
+++ b/src/corelib/io/qprocess_p.h
@@ -101,11 +101,33 @@ public:
inline Value prepareValue(const QString &value) const { return value; }
inline QString valueToString(const Value &value) const { return value; }
#else
- typedef QByteArray Key;
+ class Key
+ {
+ public:
+ Key() : hash(0) {}
+ explicit Key(const QByteArray &other) : key(other), hash(qHash(key)) {}
+ Key(const Key &other) { *this = other; }
+ bool operator==(const Key &other) const { return key == other.key; }
+
+ QByteArray key;
+ uint hash;
+ };
+
typedef QByteArray Value;
- inline Key prepareName(const QString &name) const { return name.toLocal8Bit(); }
- inline QString nameToString(const Key &name) const { return QString::fromLocal8Bit(name); }
+ inline Key prepareName(const QString &name) const
+ {
+ Key &ent = nameMap[name];
+ if (ent.key.isEmpty())
+ ent = Key(name.toLocal8Bit());
+ return ent;
+ }
+ inline QString nameToString(const Key &name) const
+ {
+ const QString sname = QString::fromLocal8Bit(name.key);
+ nameMap[sname] = name;
+ return sname;
+ }
inline Value prepareValue(const QString &value) const { return value.toLocal8Bit(); }
inline QString valueToString(const Value &value) const { return QString::fromLocal8Bit(value); }
#endif
@@ -113,14 +135,22 @@ public:
typedef QHash<Key, Value> Hash;
Hash hash;
+#ifdef Q_OS_UNIX
+ typedef QHash<QString, Key> NameHash;
+ mutable NameHash nameMap;
+#endif
+
static QProcessEnvironment fromList(const QStringList &list);
QStringList toList() const;
QStringList keys() const;
- void insert(const Hash &hash);
+ void insert(const QProcessEnvironmentPrivate &other);
};
-#ifdef Q_OS_WIN
Q_DECLARE_TYPEINFO(QProcessEnvironmentPrivate::Key, Q_MOVABLE_TYPE);
+
+#ifdef Q_OS_WIN
inline uint qHash(const QProcessEnvironmentPrivate::Key &key) { return qHash(key.toCaseFolded()); }
+#else
+inline uint qHash(const QProcessEnvironmentPrivate::Key &key) { return key.hash; }
#endif
class QProcessPrivate : public QIODevicePrivate
diff --git a/src/corelib/io/qprocess_unix.cpp b/src/corelib/io/qprocess_unix.cpp
index 7ee66ec955..7edefd3820 100644
--- a/src/corelib/io/qprocess_unix.cpp
+++ b/src/corelib/io/qprocess_unix.cpp
@@ -483,7 +483,7 @@ static char **_q_dupEnvironment(const QProcessEnvironmentPrivate::Hash &environm
#endif
const QByteArray envLibraryPath = qgetenv(libraryPath);
bool needToAddLibraryPath = !envLibraryPath.isEmpty() &&
- !environment.contains(libraryPath);
+ !environment.contains(QProcessEnvironmentPrivate::Key(QByteArray(libraryPath)));
char **envp = new char *[environment.count() + 2];
envp[environment.count()] = 0;
@@ -492,7 +492,7 @@ static char **_q_dupEnvironment(const QProcessEnvironmentPrivate::Hash &environm
QProcessEnvironmentPrivate::Hash::ConstIterator it = environment.constBegin();
const QProcessEnvironmentPrivate::Hash::ConstIterator end = environment.constEnd();
for ( ; it != end; ++it) {
- QByteArray key = it.key();
+ QByteArray key = it.key().key;
QByteArray value = it.value();
key.reserve(key.length() + 1 + value.length());
key.append('=');