]> vaikene.ee Git - evaf/blob - www/pswgen04.html
Warning fixes and copyright update.
[evaf] / www / pswgen04.html
1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
2 <html lang="et" xmlns="http://www.w3.org/1999/xhtml" xml:lang="et">
3
4 <head>
5 <meta http-equiv="CONTENT-TYPE" content="text/html; charset=utf-8" />
6 <title>eVaf Tutorial - 04 - Generator Module</title>
7 <meta name="Author" content="Enar Väikene" />
8 <meta name="description" content="eVaf Tutorial" />
9 <meta name="keywords" content="evaf c++ application development framework tutorial password generator" />
10 <link rel="StyleSheet" href="evaf.css" type="text/css" media="all" />
11 <link rel="StyleSheet" href="highlight.css" type="text/css" media="all" />
12 </head>
13
14 <body>
15
16 <p>Next: <a href="pswgen05.html">05 - Building Generator Module</a>, Previous: <a href="pswgen03.html">03 - Generator Module</a></p>
17
18 <h1>eVaf Tutorial</h1>
19
20 <h2>04 - Generator Module</h2>
21
22 <p>Now we are going to implement all the classes declared in the <tt>module.h</tt>. Create the <tt>module.cpp</tt> file
23 in the <tt>src/apps/PswGen/Generator</tt> directory. We obviously include the <tt>module.h</tt> header file, but also
24 the <tt>QtCore</tt> header file for any non-GUI Qt classes.</p>
25
26 <pre class="hl"><span class="hl com">/**</span>
27 <span class="hl com"> * &#64;file src/apps/PswGen/Generator/module.cpp</span>
28 <span class="hl com"> */</span>
29
30 <span class="hl ppc">#include</span> <span class="hl pps">&quot;module.h&quot;</span><span class="hl ppc"></span>
31
32 <span class="hl ppc">#include &lt;QtCore&gt;</span></pre>
33
34 <p>All the eVaf modules need to include version information. This is common for all the modules and we can simply
35 copy existing version info files from another eVaf module:</p>
36
37 <pre>evaf/src/apps/PswGen/Generator $ <code>cp ../../../plugins/SdiWindow/version.{h,rc} .</code></pre>
38
39 <p>The <tt>version.h</tt> file contains version information for the module. The <tt>version.rc</tt> is for Windows
40 builds only and embeds the same version information into the dll or exe file. Modify the copied <tt>version.h</tt>
41 file for our new module. The <tt>version.rc</tt> file uses the values from the <tt>version.h</tt> and does not
42 need to be touched.</p>
43
44 <pre class="hl"><span class="hl com">/**</span>
45 <span class="hl com"> * &#64;file src/apps/PswGen/Generator/version.h</span>
46 <span class="hl com"> */</span>
47 <span class="hl ppc">#ifndef __PSWGEN_GENERATOR_VERSION_H</span>
48 <span class="hl ppc">#define __PSWGEN_GENERATOR_VERSION_H</span>
49
50 <span class="hl ppc">#include &lt;version_rc.h&gt;</span>
51
52 <span class="hl com">/**</span>
53 <span class="hl com"> * Module/library version number in the form major,minor,release,build</span>
54 <span class="hl com"> */</span>
55 <span class="hl ppc">#define VER_FILE_VERSION 0,1,1,1</span>
56
57 <span class="hl com">/**</span>
58 <span class="hl com"> * Module/library version number in the string format (shall end with \0)</span>
59 <span class="hl com"> */</span>
60 <span class="hl ppc">#define VER_FILE_VERSION_STR</span> <span class="hl pps">&quot;0.1.1.1\0&quot;</span><span class="hl ppc"></span>
61
62 <span class="hl com">/**</span>
63 <span class="hl com"> * Module/library name (shall end with \0)</span>
64 <span class="hl com"> */</span>
65 <span class="hl ppc">#define VER_MODULE_NAME_STR</span> <span class="hl pps">&quot;PswGen\0&quot;</span><span class="hl ppc"></span>
66
67 <span class="hl com">/**</span>
68 <span class="hl com"> * Module type (see version_rc.h for all the types)</span>
69 <span class="hl com"> */</span>
70 <span class="hl ppc">#define VER_MODULE_TYPE MT_GENERIC</span>
71
72 <span class="hl com">/**</span>
73 <span class="hl com"> * Module type in the string format (see version_rc for all the types)</span>
74 <span class="hl com"> */</span>
75 <span class="hl ppc">#define VER_MODULE_TYPE_STR MT_GENERIC</span>
76
77 <span class="hl com">/**</span>
78 <span class="hl com"> * Original file name for windows (shall end with \0)</span>
79 <span class="hl com"> */</span>
80 <span class="hl ppc">#define VER_ORIGINAL_FILE_NAME_STR</span> <span class="hl pps">&quot;PswGen.dll\0&quot;</span><span class="hl ppc"></span>
81
82 <span class="hl com">/**</span>
83 <span class="hl com"> * Description of the module/library (shall end with \0)</span>
84 <span class="hl com"> */</span>
85 <span class="hl ppc">#define VER_FILE_DESCRIPTION_STR</span> <span class="hl pps">&quot;Module that generates strong passwords using MD5 hashes.\0&quot;</span><span class="hl ppc"></span>
86
87 <span class="hl ppc">#endif</span> <span class="hl slc">// version.h</span><span class="hl ppc"></span></pre>
88
89 <p>Then include the version info file in the <tt>module.cpp</tt> file and use the <tt>VER_EXPORT_VERSION_INFO()</tt> macro
90 to export version information from the module. This macro defines a public function that all the eVaf modules export and
91 is used to collect version information from them. In your modules you only need to modify the <tt>version.h</tt> file and then
92 use the <tt>VER_EXPORT_VERSION_INFO()</tt> macro once somewhere in your code.</p>
93
94 <pre class="hl"><span class="hl ppc">#include</span> <span class="hl pps">&quot;version.h&quot;</span><span class="hl ppc"></span>
95
96 <span class="hl kwd">VER_EXPORT_VERSION_INFO</span><span class="hl opt">()</span></pre>
97
98 <p>To make the <tt>Module</tt> class a proper Qt plugin, we use the <tt>Q_EXPORT_PLUGIN2</tt> macro. The name of the module is already
99 defined in the <tt>version.h</tt> header file as <tt>VER_MODULE_NAME_STR</tt>.
100
101 <pre class="hl"><span class="hl kwd">Q_EXPORT_PLUGIN2</span><span class="hl opt">(</span>VER_MODULE_NAME_STR<span class="hl opt">,</span> eVaf<span class="hl opt">::</span>PswGen<span class="hl opt">::</span>Generator<span class="hl opt">::</span>Module<span class="hl opt">)</span></pre>
102
103 <p>We make our life easier with several <tt>using namespace</tt> keywords:</p>
104
105 <pre class="hl"><span class="hl kwa">using namespace</span> eVaf<span class="hl opt">;</span>
106 <span class="hl kwa">using namespace</span> eVaf<span class="hl opt">::</span>PswGen<span class="hl opt">;</span>
107 <span class="hl kwa">using namespace</span> eVaf<span class="hl opt">::</span>PswGen<span class="hl opt">::</span>Generator<span class="hl opt">;</span></pre>
108
109 <p>The Module class needs to instantiate the <tt>iGenerator</tt> interface in the constructor. We also need to set
110 the QObject's name property to the name of the plugin by combining the name of the module with the name of the class.
111 While the application would work without the name property, it makes our life much easier if the name property is set.</p>
112
113 <p>Finally, we output an info message telling that the object was created. Every eVaf module and class is expected to
114 output info messages when they are created, destroyed, initialized or destroyed.</p>
115
116 <pre class="hl">Module<span class="hl opt">::</span><span class="hl kwd">Module</span><span class="hl opt">()</span>
117 <span class="hl opt">:</span> Plugins<span class="hl opt">::</span><span class="hl kwd">iPlugin</span><span class="hl opt">()</span>
118 <span class="hl opt">{</span>
119 <span class="hl kwd">setObjectName</span><span class="hl opt">(</span><span class="hl kwd">QString</span><span class="hl opt">(</span><span class="hl str">&quot;%1.%2&quot;</span><span class="hl opt">).</span><span class="hl kwd">arg</span><span class="hl opt">(</span>VER_MODULE_NAME_STR<span class="hl opt">).</span><span class="hl kwd">arg</span><span class="hl opt">(</span>__FUNCTION__<span class="hl opt">));</span>
120
121 mGenerator <span class="hl opt">=</span> <span class="hl kwa">new</span> Internal<span class="hl opt">::</span>GeneratorImpl<span class="hl opt">;</span>
122
123 <span class="hl kwd">EVAF_INFO</span><span class="hl opt">(</span><span class="hl str">&quot;%s created&quot;</span><span class="hl opt">,</span> <span class="hl kwd">qPrintable</span><span class="hl opt">(</span><span class="hl kwd">objectName</span><span class="hl opt">()));</span>
124 <span class="hl opt">}</span></pre>
125
126 <p>The <tt>EVAF_INFO</tt> macro comes from the <tt>Common/iLogger</tt> header file ane we need to include it:</p>
127
128 <pre class="hl"><span class="hl ppc">#include &lt;Common/iLogger&gt;</span></pre>
129
130 <p>The destructor should delete the <tt>iGenerator</tt> interface object, which we created in the constructor. The common
131 rule is that any resources allocated in the constructor shall be released in the destructor, preferrably in the opposite
132 order, ie. the first resource allocated in the constructor is released last in the destructor.</tt>
133
134 <pre class="hl">Module<span class="hl opt">::~</span><span class="hl kwd">Module</span><span class="hl opt">()</span>
135 <span class="hl opt">{</span>
136 <span class="hl kwa">delete</span> mGenerator<span class="hl opt">;</span>
137
138 <span class="hl kwd">EVAF_INFO</span><span class="hl opt">(</span><span class="hl str">&quot;%s destroyed&quot;</span><span class="hl opt">,</span> <span class="hl kwd">qPrintable</span><span class="hl opt">(</span><span class="hl kwd">objectName</span><span class="hl opt">()));</span>
139 <span class="hl opt">}</span></pre>
140
141 <p>We also need to implement <tt>init()</tt> and <tt>done()</tt> functions, which are used to initialize and finalize modules.
142 They are similar to the constructor and destructor with two major differences:</p>
143 <ol>
144 <li>The <tt>init()</tt> function can fail and return <tt>false</tt> to indicate a failure. eVaf does not use exceptions and
145 this is the only way for a module to fail without terminating the whole application. A failed module will be disabled
146 and the rest of the application can still run if it can.</li>
147 <li>eVaf modules are loaded in two steps. At first, all the modules are created, which means that all the objects
148 are constructed. Only then will eVaf call <tt>init()</tt> functions meaning that when the <tt>init()</tt> function is
149 called, all the modules are already loaded and instantiated. Interfaces and resources from other modules that might be not
150 available when the object is created, are available when the <tt>init()</tt> function is called.</li>
151 </ol>
152
153 <p>The rule for <tt>init()</tt> and <tt>done()</tt> functions is the same than for constructors and destructors -- any resource
154 allocated in the <tt>init()</tt> function shall be released in the <tt>done()</tt> function and preferrably in the opposite
155 order.</p>
156
157 <p>This simple module needs no extra resources to be allocated and our <tt>init()</tt> and <tt>done()</tt> functions can be
158 the following:</p>
159
160 <pre class="hl"><span class="hl kwb">bool</span> Module<span class="hl opt">::</span><span class="hl kwd">init</span><span class="hl opt">(</span>QString <span class="hl kwb">const</span> <span class="hl opt">&amp;</span> args<span class="hl opt">)</span>
161 <span class="hl opt">{</span>
162 <span class="hl kwd">Q_UNUSED</span><span class="hl opt">(</span>args<span class="hl opt">);</span>
163
164 <span class="hl kwd">EVAF_INFO</span><span class="hl opt">(</span><span class="hl str">&quot;%s initialized&quot;</span><span class="hl opt">,</span> <span class="hl kwd">qPrintable</span><span class="hl opt">(</span><span class="hl kwd">objectName</span><span class="hl opt">()));</span>
165
166 <span class="hl kwa">return true</span><span class="hl opt">;</span>
167 <span class="hl opt">}</span>
168
169 <span class="hl kwb">void</span> Module<span class="hl opt">::</span><span class="hl kwd">done</span><span class="hl opt">()</span>
170 <span class="hl opt">{</span>
171 <span class="hl kwd">EVAF_INFO</span><span class="hl opt">(</span><span class="hl str">&quot;%s finalized&quot;</span><span class="hl opt">,</span> <span class="hl kwd">qPrintable</span><span class="hl opt">(</span><span class="hl kwd">objectName</span><span class="hl opt">()));</span>
172 <span class="hl opt">}</span></pre>
173
174 <p>We continue by implementing the <tt>iGenerator</tt> interface. There are no resources to be allocated in the constructor
175 and we just set the QObject's name property and output the info message.</p>
176
177 <p>We also register the <tt>iGenerator</tt> interface in the global registry so that other modules can query for it and
178 use our interface. This is done by using the <tt>Common::iRegistry</tt> interface, which we need to include:</p>
179
180 <pre class="hl"><span class="hl ppc">#include &lt;Common/iRegistry&gt;</span></pre>
181
182 <p>The <tt>GeneratorImpl</tt> class was declared in the <tt>eVaf::PswGen::Generator::Internal</tt> namespace, so we need
183 another <tt>using namespace</tt> keyword before the implementation of the class:</p>
184
185 <pre class="hl"><span class="hl kwa">using namespace</span> eVaf<span class="hl opt">::</span>PswGen<span class="hl opt">::</span>Generator<span class="hl opt">::</span>Internal<span class="hl opt">;</span>
186
187 GeneratorImpl<span class="hl opt">::</span><span class="hl kwd">GeneratorImpl</span><span class="hl opt">()</span>
188 <span class="hl opt">:</span> <span class="hl kwd">iGenerator</span><span class="hl opt">()</span>
189 <span class="hl opt">{</span>
190 <span class="hl kwd">setObjectName</span><span class="hl opt">(</span><span class="hl kwd">QString</span><span class="hl opt">(</span><span class="hl str">&quot;%1.iGenerator&quot;</span><span class="hl opt">).</span><span class="hl kwd">arg</span><span class="hl opt">(</span>VER_MODULE_NAME_STR<span class="hl opt">));</span>
191
192 Common<span class="hl opt">::</span>iRegistry<span class="hl opt">::</span><span class="hl kwd">instance</span><span class="hl opt">()-&gt;</span><span class="hl kwd">registerInterface</span><span class="hl opt">(</span><span class="hl str">&quot;iGenerator&quot;</span><span class="hl opt">,</span> <span class="hl kwa">this</span><span class="hl opt">);</span>
193
194 <span class="hl kwd">EVAF_INFO</span><span class="hl opt">(</span><span class="hl str">&quot;%s created&quot;</span><span class="hl opt">,</span> <span class="hl kwd">qPrintable</span><span class="hl opt">(</span><span class="hl kwd">objectName</span><span class="hl opt">()));</span>
195 <span class="hl opt">}</span>
196
197 GeneratorImpl<span class="hl opt">::~</span><span class="hl kwd">GeneratorImpl</span><span class="hl opt">()</span>
198 <span class="hl opt">{</span>
199 <span class="hl kwd">EVAF_INFO</span><span class="hl opt">(</span><span class="hl str">&quot;%s destroyed&quot;</span><span class="hl opt">,</span> <span class="hl kwd">qPrintable</span><span class="hl opt">(</span><span class="hl kwd">objectName</span><span class="hl opt">()));</span>
200 <span class="hl opt">}</span></pre>
201
202 <p>Finally, we write the <tt>generatePassword</tt> function that does the actual job of the module.</p>
203
204 <p>We use the MD5 cryptographic hash function to calculate a hash value over the <tt>name</tt> and <tt>masterPassword</tt> values.
205 The result, which is a binary blob, needs to be convert into something that can be used as a password and we use base 64 encoding
206 for this and cut the result to the requested length:</p>
207
208 <pre class="hl">QString GeneratorImpl<span class="hl opt">::</span><span class="hl kwd">generatePassword</span><span class="hl opt">(</span>QString <span class="hl kwb">const</span> <span class="hl opt">&amp;</span> name<span class="hl opt">,</span> QString <span class="hl kwb">const</span> <span class="hl opt">&amp;</span> masterPassword<span class="hl opt">,</span> <span class="hl kwb">int</span> length<span class="hl opt">,</span> uint flags<span class="hl opt">)</span> <span class="hl kwb">const</span>
209 <span class="hl opt">{</span>
210 <span class="hl kwd">Q_UNUSED</span><span class="hl opt">(</span>flags<span class="hl opt">);</span>
211
212 QByteArray inputString <span class="hl opt">=</span> <span class="hl kwd">QString</span><span class="hl opt">(</span><span class="hl str">&quot;%1%2&quot;</span><span class="hl opt">).</span><span class="hl kwd">arg</span><span class="hl opt">(</span>name<span class="hl opt">).</span><span class="hl kwd">arg</span><span class="hl opt">(</span>masterPassword<span class="hl opt">).</span><span class="hl kwd">toLatin1</span><span class="hl opt">();</span>
213 QCryptographicHash <span class="hl kwd">hash</span><span class="hl opt">(</span>QCryptographicHash<span class="hl opt">::</span>Md5<span class="hl opt">);</span>
214 hash<span class="hl opt">.</span><span class="hl kwd">addData</span><span class="hl opt">(</span>inputString<span class="hl opt">);</span>
215 QByteArray result <span class="hl opt">=</span> hash<span class="hl opt">.</span><span class="hl kwd">result</span><span class="hl opt">().</span><span class="hl kwd">toBase64</span><span class="hl opt">();</span>
216 <span class="hl kwa">if</span> <span class="hl opt">(</span>length <span class="hl opt">&gt;</span> <span class="hl num">0</span><span class="hl opt">)</span>
217 <span class="hl kwa">return</span> result<span class="hl opt">.</span><span class="hl kwd">left</span><span class="hl opt">(</span>length<span class="hl opt">);</span>
218 <span class="hl kwa">else</span>
219 <span class="hl kwa">return</span> result<span class="hl opt">;</span>
220 <span class="hl opt">}</span></pre>
221
222 <p>We also know now the maximum length of the generated password, which is 24. Go back to the <tt>module.h</tt> header file and
223 modify the <tt>GeneratorImpl::maxLength()</tt> function:</p>
224
225 <pre class="hl"><span class="hl kwc">virtual</span> <span class="hl kwb">int</span> <span class="hl kwd">maxLength</span><span class="hl opt">()</span> <span class="hl kwb">const</span> <span class="hl opt">{</span> <span class="hl kwa">return</span> <span class="hl num">24</span><span class="hl opt">; }</span></pre>
226
227 <p>Here is the final <tt>module.cpp</tt> file:</p>
228
229 <pre class="hl"><span class="hl com">/**</span>
230 <span class="hl com"> * &#64;file src/apps/PswGen/Generator/module.cpp</span>
231 <span class="hl com"> */</span>
232
233 <span class="hl ppc">#include</span> <span class="hl pps">&quot;module.h&quot;</span><span class="hl ppc"></span>
234 <span class="hl ppc">#include</span> <span class="hl pps">&quot;version.h&quot;</span><span class="hl ppc"></span>
235
236 <span class="hl ppc">#include &lt;Common/iLogger&gt;</span>
237 <span class="hl ppc">#include &lt;Common/iRegistry&gt;</span>
238
239 <span class="hl ppc">#include &lt;QtCore&gt;</span>
240
241 <span class="hl kwd">VER_EXPORT_VERSION_INFO</span><span class="hl opt">()</span>
242 <span class="hl kwd">Q_EXPORT_PLUGIN2</span><span class="hl opt">(</span>VER_MODULE_NAME_STR<span class="hl opt">,</span> eVaf<span class="hl opt">::</span>PswGen<span class="hl opt">::</span>Generator<span class="hl opt">::</span>Module<span class="hl opt">)</span>
243
244 <span class="hl kwa">using namespace</span> eVaf<span class="hl opt">;</span>
245 <span class="hl kwa">using namespace</span> eVaf<span class="hl opt">::</span>PswGen<span class="hl opt">;</span>
246 <span class="hl kwa">using namespace</span> eVaf<span class="hl opt">::</span>PswGen<span class="hl opt">::</span>Generator<span class="hl opt">;</span>
247
248 Module<span class="hl opt">::</span><span class="hl kwd">Module</span><span class="hl opt">()</span>
249 <span class="hl opt">:</span> Plugins<span class="hl opt">::</span><span class="hl kwd">iPlugin</span><span class="hl opt">()</span>
250 <span class="hl opt">{</span>
251 <span class="hl kwd">setObjectName</span><span class="hl opt">(</span><span class="hl kwd">QString</span><span class="hl opt">(</span><span class="hl str">&quot;%1.%2&quot;</span><span class="hl opt">).</span><span class="hl kwd">arg</span><span class="hl opt">(</span>VER_MODULE_NAME_STR<span class="hl opt">).</span><span class="hl kwd">arg</span><span class="hl opt">(</span>__FUNCTION__<span class="hl opt">));</span>
252
253 mGenerator <span class="hl opt">=</span> <span class="hl kwa">new</span> Internal<span class="hl opt">::</span>GeneratorImpl<span class="hl opt">;</span>
254
255 <span class="hl kwd">EVAF_INFO</span><span class="hl opt">(</span><span class="hl str">&quot;%s created&quot;</span><span class="hl opt">,</span> <span class="hl kwd">qPrintable</span><span class="hl opt">(</span><span class="hl kwd">objectName</span><span class="hl opt">()));</span>
256 <span class="hl opt">}</span>
257
258 Module<span class="hl opt">::~</span><span class="hl kwd">Module</span><span class="hl opt">()</span>
259 <span class="hl opt">{</span>
260 <span class="hl kwa">delete</span> mGenerator<span class="hl opt">;</span>
261
262 <span class="hl kwd">EVAF_INFO</span><span class="hl opt">(</span><span class="hl str">&quot;%s destroyed&quot;</span><span class="hl opt">,</span> <span class="hl kwd">qPrintable</span><span class="hl opt">(</span><span class="hl kwd">objectName</span><span class="hl opt">()));</span>
263 <span class="hl opt">}</span>
264
265 <span class="hl kwb">bool</span> Module<span class="hl opt">::</span><span class="hl kwd">init</span><span class="hl opt">(</span>QString <span class="hl kwb">const</span> <span class="hl opt">&amp;</span> args<span class="hl opt">)</span>
266 <span class="hl opt">{</span>
267 <span class="hl kwd">Q_UNUSED</span><span class="hl opt">(</span>args<span class="hl opt">);</span>
268
269 <span class="hl kwd">EVAF_INFO</span><span class="hl opt">(</span><span class="hl str">&quot;%s initialized&quot;</span><span class="hl opt">,</span> <span class="hl kwd">qPrintable</span><span class="hl opt">(</span><span class="hl kwd">objectName</span><span class="hl opt">()));</span>
270
271 <span class="hl kwa">return true</span><span class="hl opt">;</span>
272 <span class="hl opt">}</span>
273
274 <span class="hl kwb">void</span> Module<span class="hl opt">::</span><span class="hl kwd">done</span><span class="hl opt">()</span>
275 <span class="hl opt">{</span>
276 <span class="hl kwd">EVAF_INFO</span><span class="hl opt">(</span><span class="hl str">&quot;%s finalized&quot;</span><span class="hl opt">,</span> <span class="hl kwd">qPrintable</span><span class="hl opt">(</span><span class="hl kwd">objectName</span><span class="hl opt">()));</span>
277 <span class="hl opt">}</span>
278
279 <span class="hl kwa">using namespace</span> eVaf<span class="hl opt">::</span>PswGen<span class="hl opt">::</span>Generator<span class="hl opt">::</span>Internal<span class="hl opt">;</span>
280
281 GeneratorImpl<span class="hl opt">::</span><span class="hl kwd">GeneratorImpl</span><span class="hl opt">()</span>
282 <span class="hl opt">:</span> <span class="hl kwd">iGenerator</span><span class="hl opt">()</span>
283 <span class="hl opt">{</span>
284 <span class="hl kwd">setObjectName</span><span class="hl opt">(</span><span class="hl kwd">QString</span><span class="hl opt">(</span><span class="hl str">&quot;%1.iGenerator&quot;</span><span class="hl opt">).</span><span class="hl kwd">arg</span><span class="hl opt">(</span>VER_MODULE_NAME_STR<span class="hl opt">));</span>
285
286 Common<span class="hl opt">::</span>iRegistry<span class="hl opt">::</span><span class="hl kwd">instance</span><span class="hl opt">()-&gt;</span><span class="hl kwd">registerInterface</span><span class="hl opt">(</span><span class="hl str">&quot;iGenerator&quot;</span><span class="hl opt">,</span> <span class="hl kwa">this</span><span class="hl opt">);</span>
287
288 <span class="hl kwd">EVAF_INFO</span><span class="hl opt">(</span><span class="hl str">&quot;%s created&quot;</span><span class="hl opt">,</span> <span class="hl kwd">qPrintable</span><span class="hl opt">(</span><span class="hl kwd">objectName</span><span class="hl opt">()));</span>
289 <span class="hl opt">}</span>
290
291 GeneratorImpl<span class="hl opt">::~</span><span class="hl kwd">GeneratorImpl</span><span class="hl opt">()</span>
292 <span class="hl opt">{</span>
293 <span class="hl kwd">EVAF_INFO</span><span class="hl opt">(</span><span class="hl str">&quot;%s destroyed&quot;</span><span class="hl opt">,</span> <span class="hl kwd">qPrintable</span><span class="hl opt">(</span><span class="hl kwd">objectName</span><span class="hl opt">()));</span>
294 <span class="hl opt">}</span>
295
296 QString GeneratorImpl<span class="hl opt">::</span><span class="hl kwd">generatePassword</span><span class="hl opt">(</span>QString <span class="hl kwb">const</span> <span class="hl opt">&amp;</span> name<span class="hl opt">,</span> QString <span class="hl kwb">const</span> <span class="hl opt">&amp;</span> masterPassword<span class="hl opt">,</span> <span class="hl kwb">int</span> length<span class="hl opt">,</span> uint flags<span class="hl opt">)</span> <span class="hl kwb">const</span>
297 <span class="hl opt">{</span>
298 <span class="hl kwd">Q_UNUSED</span><span class="hl opt">(</span>flags<span class="hl opt">);</span>
299
300 QByteArray inputString <span class="hl opt">=</span> <span class="hl kwd">QString</span><span class="hl opt">(</span><span class="hl str">&quot;%1%2&quot;</span><span class="hl opt">).</span><span class="hl kwd">arg</span><span class="hl opt">(</span>name<span class="hl opt">).</span><span class="hl kwd">arg</span><span class="hl opt">(</span>masterPassword<span class="hl opt">).</span><span class="hl kwd">toLatin1</span><span class="hl opt">();</span>
301 QCryptographicHash <span class="hl kwd">hash</span><span class="hl opt">(</span>QCryptographicHash<span class="hl opt">::</span>Md5<span class="hl opt">);</span>
302 hash<span class="hl opt">.</span><span class="hl kwd">addData</span><span class="hl opt">(</span>inputString<span class="hl opt">);</span>
303 QByteArray result <span class="hl opt">=</span> hash<span class="hl opt">.</span><span class="hl kwd">result</span><span class="hl opt">().</span><span class="hl kwd">toBase64</span><span class="hl opt">();</span>
304 <span class="hl kwa">if</span> <span class="hl opt">(</span>length <span class="hl opt">&gt;</span> <span class="hl num">0</span><span class="hl opt">)</span>
305 <span class="hl kwa">return</span> result<span class="hl opt">.</span><span class="hl kwd">left</span><span class="hl opt">(</span>length<span class="hl opt">);</span>
306 <span class="hl kwa">else</span>
307 <span class="hl kwa">return</span> result<span class="hl opt">;</span>
308 <span class="hl opt">}</span></pre>
309
310 <p>Next -- <a href="pswgen05.html">05 - Building Generator Module</a>.</p>
311
312 </body>
313 </html>