X-Git-Url: https://vaikene.ee/gitweb/pswgen11.html?a=blobdiff_plain;ds=sidebyside;f=www%2Fpswgen03.html;h=a4bd834943764d8cafe13ea8ab079a7af815e152;hb=3f5d9725a23f25ee623123160dd11cea11adb063;hp=056da8e42145a4b3c1f15656e206c67b8cb92497;hpb=368818c22af812ac35f5ff69423522dbd54d37ed;p=evaf diff --git a/www/pswgen03.html b/www/pswgen03.html index 056da8e..a4bd834 100644 --- a/www/pswgen03.html +++ b/www/pswgen03.html @@ -13,6 +13,7 @@
+Next: 04 - Generator Module, Previous: 02 - Preparations
We start by defining the interface for the module. For this create the file igenerator.h in the - src/apps/pswGen/Generator directory:
+We start by defining the interface for the module and create the file igenerator.h in the + src/apps/PswGen/Generator directory:
/** * @file src/apps/PswGen/Generator/igenerator.h @@ -34,8 +35,8 @@ #endif // igenerator.h-
The interface class needs to be derived from QObject and we also need QString for input - data and generated passwords:
+We need to include some Qt header files -- QObject is almost always needed and QString we need for input data and generated + passwords:
#include <QObject> #include <QString>@@ -49,23 +50,15 @@ } // namespace eVaf::PswGen } // namespace eVaf -
We call the interface class iGenerator: +
We call the interface class iGenerator. For pure abstract classes I personally prefer using the struct keyword, but + class works as well if you remember to add the public keyword to make methods in the class public.
-class iGenerator : public QObject +-struct iGenerator { - Q_OBJECT -public: -};- -All the interface classes need a default constructor and an empty virtual destructor. Do not perform any actions - in these constructors and destructors. Instead, leave it up to the class that implements the interface.
-/// Interface constructor -iGenerator() : QObject() {} -/// Empty virtual destructor -virtual ~iGenerator() {}+};
Now we add the functionality to the interface and according to the specification we need two functions -- one that +
We add functionality to the interface and according to the specification we need two functions -- one that generates passwords and another that returns the maximum length of the password:
virtual QString generatePassword(QString const & name, QString const & masterPassword, int length, uint flags = 0) const = 0; @@ -74,29 +67,10 @@+Q_DECLARE_INTERFACE(eVaf::PswGen::iGenerator, "eVaf.PswGen.iGenerator/1.0") + +#endif // igenerator.hI am training myself to use the style of writing declarations like "QString const &", which refers to a non-mutable QString object similar to "int maxLength() const", which is a function that does not modify the object's data members. Feel free to use the traditional way of writing "const QString &" if this looks weird to you.
-The iGenerator interface needs to be visible for other modules and marked for export. We do this by creating the src/apps/PswGen/Generator/lib.h file, which defines the PSWGEN_GENERATOR_EXPORT macro:
-/** - * @file src/apps/PswGen/Generator/lib.h - */ -#ifndef __PSWGEN_GENERATOR_LIB_H -# define __PSWGEN_GENERATOR_LIB_H - -#include <QtCore/qglobal.h> +- -We use the Q_DECLARE_INTERFACE macro to add Qt meta-data to the interface. eVaf interfaces are type-casted using the qobject_cast<>() template function and it requires meta-data to verify type and version of the interface. The Q_DECLARE_INTERFACE macro has to be + outside of any namespaces and we add it to the end of the file:
-#if defined(PSWGEN_GENERATOR_LIBRARY) -# define PSWGEN_GENERATOR_EXPORT Q_DECL_EXPORT -#else -# define PSWGEN_GENERATOR_EXPORT Q_DECL_IMPORT -#endif -#endif // libgen.hThen we include this new header file in our interface header file and modify the iGenerator class definition by adding - the PSWGEN_GENERATOR_EXPORT macro to it:
-#include "lib.h" - -/// ... - -class PSWGEN_GENERATOR_EXPORT iGenerator : public QObject+Q_DECLARE_INTERFACE(eVaf::PswGen::iGenerator, "eVaf.PswGen.iGenerator/1.0")This is pretty much all we need to add to the iGenerator interface and here is the final file:
@@ -107,8 +81,6 @@ #ifndef __PSWGEN_GENERATOR_IGENERATOR_H # define __PSWGEN_GENERATOR_IGENERATOR_H -#include "lib.h" - #include <QObject> #include <QString> @@ -116,18 +88,8 @@ namespace PswGen { /// Password generator interface. -class PSWGEN_GENERATOR_EXPORT iGenerator : public QObject +struct iGenerator { - Q_OBJECT - -public: - - /// Interface constructor - iGenerator() : QObject() {} - - /// Empty virtual destructor - virtual ~iGenerator() {} - /// Generates a strong password virtual QString generatePassword(QString const & name, QString const & masterPassword, int length, uint flags = 0) const = 0; @@ -139,8 +101,9 @@ } // namespace eVaf::PswGen } // namespace eVaf -#endif // igenerator.h -
As a final touch, we create a file called iGenerator with the following content:
#include "igenerator.h"@@ -191,8 +154,7 @@ } // namespace eVaf
We call the class that implements the module simply Module. This is a public class and goes into the - eVaf::PswGen::Generator namespace. We however, do not need to export it as we did with the iGenerator - interface class, as this will be done by Qt.
+ eVaf::PswGen::Generator namespace.class Module : public Plugins::iPlugin { @@ -206,8 +168,8 @@ }-
The iPlugin interface has three abstract methods that we need to implement in our class -- init(), - done() and isReady(). Since this simple module is always ready, we can return true in the +
The iPlugin interface has three pure virtual methods that we need to implement in our class -- init(), + done() and isReady(). Since this simple module is always ready, we can return always true in the isReady() function. More complex modules can use a private mReady variable, which they set to true once all the initialization is done. @@ -232,11 +194,15 @@ } // namespace eVaf::PswGen::Generator::Internal
Then we can move forward and implement the iGenerator interface, which we already happened to call - GeneratorImpl. This class goes into the eVaf::PswGen::Generator::Internal namespace:
+ GeneratorImpl. This class goes into the eVaf::PswGen::Generator::Internal namespace. + +The GeneratorImpl class needs to be derived both from QObject and from iGenerator. We also have to use the + Q_INTERFACES macro to include Qt meta-data for the iGenerator interface:
-class GeneratorImpl : public iGenerator +class GeneratorImpl : public QObject, public iGenerator { - Q_OBJECT + Q_OBJECT + Q_INTERFACES(eVaf::PswGen::iGenerator) public: @@ -276,10 +242,10 @@ class GeneratorImpl; } // namespace eVaf::PswGen::Generator::Internal -/// Plugins/iPlugin interface implementation. +/// Plugins::iPlugin interface implementation. class Module : public Plugins::iPlugin { - Q_OBJECT + Q_OBJECT public: @@ -293,20 +259,19 @@ virtual bool isReady() const { return true; } - private: // Members /// iGenerator interface instance Internal::GeneratorImpl * mGenerator; - }; namespace Internal { - /// iGenerator interface implementation. -class GeneratorImpl : public iGenerator +/// iGenerator interface implementation. +class GeneratorImpl : public QObject, public iGenerator { - Q_OBJECT + Q_OBJECT + Q_INTERFACES(eVaf::PswGen::iGenerator) public: @@ -316,11 +281,11 @@ virtual QString generatePassword(QString const & name, QString const & masterPassword, int length, uint flags = 0) const; - virtual int maxLength() const; - + virtual int maxLength() const { return 24; } }; } // namespace eVaf::PswGen::Generator::Internal + } // namespace eVaf::PswGen::Generator } // namespace eVaf::PswGen } // namespace eVaf