Results 1 to 7 of 7

Thread: QSettings, custom format and class methods as read/write functions.

  1. #1
    Join Date
    Mar 2010
    Location
    Berlin, Germany
    Posts
    2
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows Symbian S60 Maemo/MeeGo

    Default QSettings, custom format and class methods as read/write functions.

    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:
    Qt Code:
    1. namespace CLIENT {
    2.  
    3. class Settings: public QObject
    4. {
    5. Q_OBJECT
    6.  
    7. public:
    8. Settings(const QString &user, const Key &k, QObject *parent = 0);
    9. void setValue(const QString &key, const QVariant &value);
    10. void sync();
    11. QVariant value(const QString &key, const QVariant &defaultValue = QVariant()) const;
    12. ~Settings();
    13.  
    14. private:
    15. QSettings::Format f;
    16. Key key;
    17.  
    18. bool readFile(QIODevice &device, QSettings::SettingsMap &map);
    19. bool writeFile(QIODevice &device, const QSettings::SettingsMap &map);
    20. };
    21.  
    22. }
    To copy to clipboard, switch view to plain text mode 
    And source file:
    Qt Code:
    1. namespace CLIENT {
    2.  
    3. Settings::Settings(const QString &user, const Key &k, QObject *parent)
    4. : QObject(parent), key(k)
    5. {
    6. f = QSettings::registerFormat("settings", (QSettings::ReadFunc)&Settings::readFile, (QSettings::WriteFunc)&Settings::writeFile);
    7.  
    8. QString appname = QCoreApplication::applicationName();
    9. if (!user.isEmpty())
    10. appname.append(".").append(user);
    11.  
    12. s = new QSettings(f, QSettings::UserScope, QCoreApplication::organizationName(), appname, parent);
    13. }
    14.  
    15. void Settings::setValue(const QString &key, const QVariant &value)
    16. {
    17. s->setValue(key, value);
    18. }
    19.  
    20. void Settings::sync()
    21. {
    22. s->sync();
    23. }
    24.  
    25. QVariant Settings::value(const QString &key, const QVariant &defaultValue) const
    26. {
    27. return s->value(key, defaultValue);
    28. }
    29.  
    30. Settings::~Settings()
    31. {
    32. delete s;
    33. }
    34.  
    35. bool Settings::readFile(QIODevice &device, QSettings::SettingsMap &map)
    36. {
    37. // Reads data from device, decrypts it with the key and saves to map
    38. }
    39.  
    40. bool Settings::writeFile(QIODevice &device, const QSettings::SettingsMap &map)
    41. {
    42. #ifdef DEBUG
    43. qDebug() << Q_FUNC_INFO << endl << "Writing map:" << map;
    44. #endif // DEBUG
    45. // Saves map to QByteArray, encrypts it with the key and writes to device
    46. }
    47.  
    48. }
    To copy to clipboard, switch view to plain text mode 

    Now about the problem:
    I get a segfault at line 350 in qmap.h:
    Qt Code:
    1. 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).
    Last edited by leppa; 31st March 2010 at 12:44. Reason: corrected a little typo
    With best regards,
    Oleksii Serdiuk <contacts[at]oleksii[dot]name>

  2. #2
    Join Date
    Mar 2010
    Location
    Berlin, Germany
    Posts
    2
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows Symbian S60 Maemo/MeeGo

    Default Re: QSettings, custom format and class methods as read/write functions.

    Forgot to mention. If I move writeFile() and readFile() out of the class, i.e., make them regular functions like this:
    Qt Code:
    1. bool readFile(QIODevice &device, QSettings::SettingsMap &map);
    2. bool writeFile(QIODevice &device, const QSettings::SettingsMap &map);
    To copy to clipboard, switch view to plain text mode 
    and change line 6 of source file to
    Qt Code:
    1. f = QSettings::registerFormat("settings", readFile, writeFile);
    To copy to clipboard, switch view to plain text mode 
    everything starts working as expected. But then I'm unable to use per-instance encryption key as there is no way to determine an instance of QSettings that calls writeFile() and readFile() in this case.

    PS: It would be much easier if QSettings class provided oveloadable reading and writing methods.
    With best regards,
    Oleksii Serdiuk <contacts[at]oleksii[dot]name>

  3. #3
    Join Date
    Sep 2008
    Posts
    54
    Thanks
    3
    Thanked 10 Times in 5 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows
    Wiki edits
    2

    Default Re: QSettings, custom format and class methods as read/write functions.

    Qt Code:
    1. Settings::Settings(const QString &user, const Key &k, QObject *parent)
    2. : QObject(parent), key(k)
    3. {
    4. f = QSettings::registerFormat("settings", (QSettings::ReadFunc)&Settings::readFile, (QSettings::WriteFunc)&Settings::writeFile);
    5.  
    6. QString appname = QCoreApplication::applicationName();
    7. if (!user.isEmpty())
    8. appname.append(".").append(user);
    9.  
    10. s = new QSettings(f, QSettings::UserScope, QCoreApplication::organizationName(), appname, parent);
    11. }
    To copy to clipboard, switch view to plain text mode 

    I can image that you will have problems with object not being created if you use it in the constructor.

    I think this should work:
    Qt Code:
    1. f = QSettings::registerFormat("settings", readFile, writeFile);
    To copy to clipboard, switch view to plain text mode 

    But than you can not call the QSetting constructor unless your Settings object is created:
    Qt Code:
    1. s = new QSettings(f, QSettings::UserScope, QCoreApplication::organizationName(), appname, parent);
    To copy to clipboard, switch view to plain text mode 

    Thus try putting the last code segment in an initialize function instead of the constructor. readFile and writeFile might not exists.

  4. #4
    Join Date
    Jan 2006
    Location
    Munich, Germany
    Posts
    4,714
    Thanks
    21
    Thanked 418 Times in 411 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default Re: QSettings, custom format and class methods as read/write functions.

    Qt Code:
    1. f = QSettings::registerFormat("settings", (QSettings::ReadFunc)&Settings::readFile, (QSettings::WriteFunc)&Settings::writeFile);
    To copy to clipboard, switch view to plain text mode 
    Why are you using this at all like that? (function pointers??)
    Why not just define and implement your methods normally?

    But if you do, you probably mean to do:
    Qt Code:
    1. typedef void (QSettings::*pReadFunc)(QIODevice &, QSettings::SettingsMap &);
    2. pReadFunc = &Settings::writeFile;
    3. //Same for pWriteFunc;
    4. f = QSettings::registerFormat("settings",pReadFunc,pWriteFunc);
    To copy to clipboard, switch view to plain text mode 

    I didn't test my code here for compilation, it should be regarded as pseudo code.
    The idea is that you didn't fully described your function signature.
    EDIT:
    Actually much more is missing - object initialization, and then assigning the function pointer from that object.

    Again, this is complicating things WAAAAY more than needed.
    Last edited by high_flyer; 6th December 2010 at 17:50.
    ==========================signature=============== ==================
    S.O.L.I.D principles (use them!):
    https://en.wikipedia.org/wiki/SOLID_...iented_design)

    Do you write clean code? - if you are TDD'ing then maybe, if not, your not writing clean code.

  5. #5
    Join Date
    Sep 2010
    Posts
    145
    Thanks
    1
    Thanked 18 Times in 17 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QSettings, custom format and class methods as read/write functions.

    You don't need a typedef or variable assignment to pass a function pointer. His prototype is already available to the compiler from his class header. Also, how else do you use a callback in c++ without passing a functor?

  6. #6
    Join Date
    Jan 2006
    Location
    Munich, Germany
    Posts
    4,714
    Thanks
    21
    Thanked 418 Times in 411 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default Re: QSettings, custom format and class methods as read/write functions.

    You don't need a typedef or variable assignment to pass a function pointer.
    No one said you did.
    Its just more readable this way, when you don't put the whole definition as parameter - that was not the point I was making.

    His prototype is already available to the compiler from his class header.
    true.
    Was to quick to write, before thought through.

    Also, how else do you use a callback in c++ without passing a functor?
    I was on the wrong path.
    I thought he was trying to do something else than what I see now he does, and thought the whole approach was complicating things.
    But I think I understand the problem now.
    Will have to think to see if I can see what can be wrong.
    ==========================signature=============== ==================
    S.O.L.I.D principles (use them!):
    https://en.wikipedia.org/wiki/SOLID_...iented_design)

    Do you write clean code? - if you are TDD'ing then maybe, if not, your not writing clean code.

  7. #7
    Join Date
    Sep 2010
    Posts
    145
    Thanks
    1
    Thanked 18 Times in 17 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QSettings, custom format and class methods as read/write functions.

    No one said you did.
    Its just more readable this way, when you don't put the whole definition as parameter - that was not the point I was making.
    You don't have to define anything, you are simply passing the address of the function. The "definition" aka prototype is already supplied for his function in his class header, and the receiver has a specification for it in the parameter of the function he is calling. Do you seriously think that
    Qt Code:
    1. passFuncPointer(someFunc);
    To copy to clipboard, switch view to plain text mode 
    must look like
    Qt Code:
    1. /*seriously?*/
    2. passFuncPointer(someFunc(int,int,float));
    To copy to clipboard, switch view to plain text mode 
    without a typedef?

    Here's some code to show you what I mean.
    Qt Code:
    1. #include <QDebug>
    2. void someFunc(int p)
    3. {
    4. qDebug() << p;
    5. }
    6. void call_ftor(void(*func)(int))
    7. {
    8. func(13);
    9. }
    10. int main(int argc, char* argv[])
    11. {
    12. /*passing the function pointer*/
    13. call_ftor(someFunc);
    14. }
    To copy to clipboard, switch view to plain text mode 

Similar Threads

  1. cannot access QLineEdit text in other methods of the class...
    By Leoha_Zveri in forum Qt Programming
    Replies: 2
    Last Post: 29th September 2009, 13:07
  2. Opendocument format read/write *.odt
    By patrik08 in forum Qt Programming
    Replies: 7
    Last Post: 17th September 2008, 01:48
  3. QSettings , read only avaiable?
    By patrik08 in forum Qt Programming
    Replies: 5
    Last Post: 18th November 2007, 16:21
  4. QSettings, my own format of config-file
    By IPFreely in forum Qt Programming
    Replies: 2
    Last Post: 14th November 2007, 21:07
  5. Replies: 4
    Last Post: 1st February 2006, 18:17

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.