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)
This commit is contained in:
parent
299d10549f
commit
9ff8d1c34a
@ -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()
|
||||
|
@ -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
|
||||
|
@ -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('=');
|
||||
|
Loading…
Reference in New Issue
Block a user