Hello everybody,
I've run into one problem, but first of all I'll describe what I tried to achieve. I'm writing a multiuser client app with server-side authentication. This app has to store some user's settings on his computer. This settings need to be encrypted with a key, which is stored on the server-side and is sent after user's authentication. Every user has its own unique key.
I came up with the following solution: I've created a wrapper class that contains a QSettings object, an encryption key, setValue(), value(), sync(), writeFile() and readFile() methods. The methods setValue(), value() and sync() are calling the corresponding QSettings's methods. writeFile() and readFile() are declared according to QSettings::WriteFunc and QSettings::ReadFunc and do writing/reading settings to/from the file. They also encrypt/decrypt the file if the encryption key is not NULL.
The class is inside a namespace as all other app stuff.
Now the stripped down header file:
namespace CLIENT {
{
Q_OBJECT
public:
void sync();
~Settings();
private:
Key key;
};
}
namespace CLIENT {
class Settings: public QObject
{
Q_OBJECT
public:
Settings(const QString &user, const Key &k, QObject *parent = 0);
void setValue(const QString &key, const QVariant &value);
void sync();
QVariant value(const QString &key, const QVariant &defaultValue = QVariant()) const;
~Settings();
private:
QSettings::Format f;
QSettings *s;
Key key;
bool readFile(QIODevice &device, QSettings::SettingsMap &map);
bool writeFile(QIODevice &device, const QSettings::SettingsMap &map);
};
}
To copy to clipboard, switch view to plain text mode
And source file:
namespace CLIENT {
Settings
::Settings(const QString &user,
const Key
&k,
QObject *parent
){
if (!user.isEmpty())
appname.append(".").append(user);
}
{
s->setValue(key, value);
}
void Settings::sync()
{
s->sync();
}
{
return s->value(key, defaultValue);
}
Settings::~Settings()
{
delete s;
}
{
// Reads data from device, decrypts it with the key and saves to map
}
{
#ifdef DEBUG
qDebug() << Q_FUNC_INFO << endl << "Writing map:" << map;
#endif // DEBUG
// Saves map to QByteArray, encrypts it with the key and writes to device
}
}
namespace CLIENT {
Settings::Settings(const QString &user, const Key &k, QObject *parent)
: QObject(parent), key(k)
{
f = QSettings::registerFormat("settings", (QSettings::ReadFunc)&Settings::readFile, (QSettings::WriteFunc)&Settings::writeFile);
QString appname = QCoreApplication::applicationName();
if (!user.isEmpty())
appname.append(".").append(user);
s = new QSettings(f, QSettings::UserScope, QCoreApplication::organizationName(), appname, parent);
}
void Settings::setValue(const QString &key, const QVariant &value)
{
s->setValue(key, value);
}
void Settings::sync()
{
s->sync();
}
QVariant Settings::value(const QString &key, const QVariant &defaultValue) const
{
return s->value(key, defaultValue);
}
Settings::~Settings()
{
delete s;
}
bool Settings::readFile(QIODevice &device, QSettings::SettingsMap &map)
{
// Reads data from device, decrypts it with the key and saves to map
}
bool Settings::writeFile(QIODevice &device, const QSettings::SettingsMap &map)
{
#ifdef DEBUG
qDebug() << Q_FUNC_INFO << endl << "Writing map:" << map;
#endif // DEBUG
// Saves map to QByteArray, encrypts it with the key and writes to device
}
}
To copy to clipboard, switch view to plain text mode
Now about the problem:
I get a segfault at line 350 in qmap.h:
inline const_iterator constBegin() const { return const_iterator(e->forward[0]); }
inline const_iterator constBegin() const { return const_iterator(e->forward[0]); }
To copy to clipboard, switch view to plain text mode
which traces back to the line 43 of my code (the first access to map).
The debugger tells me that the map is <not in scope>, the device seems to be <not in scope> too.
Am I doing something wrong?
Is there any way I can get my class working with QSettings or do I have to write it from scratch?
I'm using Qt 4.6.2 (minGW).
Bookmarks