8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-02-02 10:00:38 +01:00

Fixed docs - thanks to Martin

This commit is contained in:
AlexPeshkoff 2016-09-05 13:23:30 +03:00
parent 8d423b6225
commit 3c4062c092

View File

@ -7,12 +7,12 @@
<META NAME="AUTHOR" CONTENT="alex "> <META NAME="AUTHOR" CONTENT="alex ">
<META NAME="CREATED" CONTENT="20130531;10003100"> <META NAME="CREATED" CONTENT="20130531;10003100">
<META NAME="CHANGEDBY" CONTENT="Alex Peshkoff"> <META NAME="CHANGEDBY" CONTENT="Alex Peshkoff">
<META NAME="CHANGED" CONTENT="20160407;18553100"> <META NAME="CHANGED" CONTENT="20160905;13142600">
<META NAME="CHANGEDBY" CONTENT="Alex Peshkoff">
<META NAME="CHANGEDBY" CONTENT="Alex Peshkoff"> <META NAME="CHANGEDBY" CONTENT="Alex Peshkoff">
<STYLE TYPE="text/css"> <STYLE TYPE="text/css">
<!-- <!--
@page { size: 8.5in 11in; margin: 0.79in } @page { size: 8.5in 11in; margin: 0.79in }
TD P { margin-bottom: 0.08in; color: #000000 }
H1 { color: #000000 } H1 { color: #000000 }
P { margin-bottom: 0.08in; color: #000000 } P { margin-bottom: 0.08in; color: #000000 }
--> -->
@ -519,7 +519,7 @@ cycle:</FONT></P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>while <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>while
(curs-&gt;fetchNext(&amp;status, buffer) == IStatus::RESULT_OK)</I></FONT></P> (curs-&gt;fetchNext(&amp;status, buffer) == IStatus::RESULT_OK)</I></FONT></P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>{</I></FONT></P> <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>{</I></FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>// row processing</I></FONT></P> <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>// row processing</I></FONT></P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>}</I></FONT></P> <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>}</I></FONT></P>
<P STYLE="margin-bottom: 0in"><BR> <P STYLE="margin-bottom: 0in"><BR>
</P> </P>
@ -587,43 +587,43 @@ namespace Firebird), timestamp with class FbTimestamp, containing
two public data members date and time of appropriate class, char - two public data members date and time of appropriate class, char -
with struct <A HREF="#FbChar">FbChar</A> and varchar with struct with struct <A HREF="#FbChar">FbChar</A> and varchar with struct
<A HREF="#FbVarChar">FbVarChar</A>. For each field preprocessor <A HREF="#FbVarChar">FbVarChar</A>. For each field preprocessor
creates two data members in the message <I>name</I> for creates two data members in the message </FONT><FONT SIZE=4><I>name</I></FONT><FONT SIZE=4>
field/parameter value and <I>nameNull</I> for NULL indicator. Message for field/parameter value and </FONT><FONT SIZE=4><I>nameNull</I></FONT><FONT SIZE=4>
constructor has 2 parameters pointer to status wrapper and master for NULL indicator. Message constructor has 2 parameters pointer
interface:</FONT></P> to status wrapper and master interface:</FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>FB_MESSAGE(Output, <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>FB_MESSAGE(Output,
ThrowStatusWrapper,</I></FONT></P> ThrowStatusWrapper,</I></FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>(FB_SMALLINT, <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>(FB_SMALLINT,
relationId)</I></FONT></P> relationId)</I></FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>(FB_CHAR(31), <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>(FB_CHAR(31),
relationName)</I></FONT></P> relationName)</I></FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>(FB_VARCHAR(100), <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>(FB_VARCHAR(100),
description)</I></FONT></P> description)</I></FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>) <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>) output(&amp;status,
output(&amp;status, master);</I></FONT></P> master);</I></FONT></P>
<P STYLE="margin-bottom: 0in"><BR> <P STYLE="margin-bottom: 0in"><BR>
</P> </P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>For static messages use of <P STYLE="margin-bottom: 0in"><FONT SIZE=4>For static messages use of
FB_MESSAGE is sooner of all the best choice they can be at the FB_MESSAGE is sooner of all the best choice they can be at the
same time easily passed to execute, openCursor and fetch methods:</FONT></P> same time easily passed to execute, openCursor and fetch methods:</FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>rs = <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>rs =
att-&gt;openCursor(&amp;status, tra, 0, sqlText,</I></FONT></P> att-&gt;openCursor(&amp;status, tra, 0, sqlText,</I></FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>SQL_DIALECT_V6, <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>SQL_DIALECT_V6, NULL,
NULL, NULL, output.getMetadata(), NULL, 0);</I></FONT></P> NULL, output.getMetadata(), NULL, 0);</I></FONT></P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>and used to work with <P STYLE="margin-bottom: 0in"><FONT SIZE=4>and used to work with
values of individual fields:</FONT></P> values of individual fields:</FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>while <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>while
(rs-&gt;fetchNext(&amp;status, output.getData()) == (rs-&gt;fetchNext(&amp;status, output.getData()) ==
IStatus::RESULT_OK)</I></FONT></P> IStatus::RESULT_OK)</I></FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>{</I></FONT></P> <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>{</I></FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>printf(&quot;%4d <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>printf(&quot;%4d
%31.31s %*.*s\n&quot;, output-&gt;relationId, %31.31s %*.*s\n&quot;, output-&gt;relationId,
output-&gt;relationName.str,</I></FONT></P> output-&gt;relationName.str,</I></FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>output-&gt;descriptionNull <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>output-&gt;descriptionNull
? 0 : output-&gt;description.length,</I></FONT></P> ? 0 : output-&gt;description.length,</I></FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>output-&gt;descriptionNull <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>output-&gt;descriptionNull
? 0 : output-&gt;description.length, output-&gt;description.str);</I></FONT></P> ? 0 : output-&gt;description.length, output-&gt;description.str);</I></FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>}</I></FONT></P> <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>}</I></FONT></P>
<P STYLE="margin-bottom: 0in"><BR> <P STYLE="margin-bottom: 0in"><BR>
</P> </P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>An example of using macro <P STYLE="margin-bottom: 0in"><FONT SIZE=4>An example of using macro
@ -663,9 +663,8 @@ blobFieldNumber)];</I></FONT></P>
and FB_MESSAGE macro blob field is declared as having FB_BLOB type:</FONT></P> and FB_MESSAGE macro blob field is declared as having FB_BLOB type:</FONT></P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>FB_MESSAGE(Msg, <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>FB_MESSAGE(Msg,
ThrowStatusWrapper,</I></FONT></P> ThrowStatusWrapper,</I></FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>(FB_BLOB, <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>(FB_BLOB, b)</I></FONT></P>
b)</I></FONT></P> <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>) message(&amp;status,
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>) message(&amp;status,
master);</I></FONT></P> master);</I></FONT></P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>ISC_QUAD* blobPtr = <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>ISC_QUAD* blobPtr =
&amp;message-&gt;b;</I></FONT></P> &amp;message-&gt;b;</I></FONT></P>
@ -687,7 +686,7 @@ engine:</FONT></P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>unsigned segmentLength;</I></FONT></P> <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>unsigned segmentLength;</I></FONT></P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>while <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>while
(userFunctionProvidingBlobData(&amp;segmentData, &amp;segmentLength))</I></FONT></P> (userFunctionProvidingBlobData(&amp;segmentData, &amp;segmentLength))</I></FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>blob-&gt;putSegment(&amp;status, <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>blob-&gt;putSegment(&amp;status,
segmentLength, segmentData);</I></FONT></P> segmentLength, segmentData);</I></FONT></P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>After sending some data to <P STYLE="margin-bottom: 0in"><FONT SIZE=4>After sending some data to
blob do not forget to close blob interface:</FONT></P> blob do not forget to close blob interface:</FONT></P>
@ -707,32 +706,30 @@ may be done using fetch() or execute() methods. After it use
openBlob() attachment's method:</FONT></P> openBlob() attachment's method:</FONT></P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I><A HREF="#Blob">IBlob</A>* <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I><A HREF="#Blob">IBlob</A>*
blob = att-&gt;openBlob(status, tra, blobPtr, 0, NULL);</I></FONT></P> blob = att-&gt;openBlob(status, tra, blobPtr, 0, NULL);</I></FONT></P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>Blob interface is ready <P STYLE="margin-bottom: 0in"><FONT SIZE=4>Blob interface is ready to
to provide blob data. Use getSegment() method to receive data from provide blob data. Use getSegment() method to receive data from
engine:</FONT></P> engine:</FONT></P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>char buffer[BUFSIZE];</I></FONT></P> <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>char buffer[BUFSIZE];</I></FONT></P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>unsigned actualLength;</I></FONT></P> <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>unsigned actualLength;</I></FONT></P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>for(;;)</I></FONT></P> <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>for(;;)</I></FONT></P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>{</I></FONT></P> <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>{</I></FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>switch <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>switch
(blob-&gt;getSegment(&amp;status, sizeof(buffer), buffer, (blob-&gt;getSegment(&amp;status, sizeof(buffer), buffer,
&amp;actualLength))</I></FONT></P> &amp;actualLength))</I></FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>{</I></FONT></P> <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>{</I></FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>case <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>case
IStatus::RESULT_OK:</I></FONT></P> IStatus::RESULT_OK:</I></FONT></P>
<P STYLE="margin-bottom: 0in"> <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>userFunctionAcceptingBlobData(buffer,
<FONT SIZE=4><I>userFunctionAcceptingBlobData(buffer, actualLength, actualLength, true);</I></FONT></P>
true);</I></FONT></P> <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>continue;</I></FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>continue;</I></FONT></P> <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>case
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>case
IStatus::RESULT_SEGMENT:</I></FONT></P> IStatus::RESULT_SEGMENT:</I></FONT></P>
<P STYLE="margin-bottom: 0in"> <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>userFunctionAcceptingBlobData(buffer,
<FONT SIZE=4><I>userFunctionAcceptingBlobData(buffer, actualLength, actualLength, false);</I></FONT></P>
false);</I></FONT></P> <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>continue;</I></FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>continue;</I></FONT></P> <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>default:</I></FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>default:</I></FONT></P> <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>break;</I></FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>break;</I></FONT></P> <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>}</I></FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>}</I></FONT></P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>}</I></FONT></P> <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>}</I></FONT></P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>Last parameter in <P STYLE="margin-bottom: 0in"><FONT SIZE=4>Last parameter in
userFunctionAcceptingBlobData() is a flag that end of segment is userFunctionAcceptingBlobData() is a flag that end of segment is
@ -751,23 +748,25 @@ completed in FB3, we expect to have something more interesting in
next version. The minimum existing support is as follows: <A HREF="#Attachment">IAttachment</A> next version. The minimum existing support is as follows: <A HREF="#Attachment">IAttachment</A>
contains call queEvents() which performs almost same functions as contains call queEvents() which performs almost same functions as
isc_que_events() call. Instead the pair of parameters isc_que_events() call. Instead the pair of parameters
<I>FPTR_EVENT_CALLBACK ast</I> and <I>void* arg</I>, required to </FONT><FONT SIZE=4><I>FPTR_EVENT_CALLBACK ast</I></FONT><FONT SIZE=4>
invoke user code when event happens in firebird engine, callback and </FONT><FONT SIZE=4><I>void* arg</I></FONT><FONT SIZE=4>,
interface IEventCallback is used. This is traditional approach which required to invoke user code when event happens in firebird engine,
helps to avoid non-safe casts from void* in user function. Another callback interface IEventCallback is used. This is traditional
important difference is that instead event identifier (a kind of approach which helps to avoid non-safe casts from void* in user
handler) this function returns reference counted interface <A HREF="#Events">IEvents</A> function. Another important difference is that instead event
having method cancel() used when waiting for event should be stopped. identifier (a kind of handler) this function returns reference
Unlike identifier which is automatically destroyed when event arrives counted interface <A HREF="#Events">IEvents</A> having method
cancel() used when waiting for event should be stopped. Unlike
identifier which is automatically destroyed when event arrives
interface can not be automatically destroyed in case when event interface can not be automatically destroyed in case when event
is received right before canceling interface call to cancel() would is received right before canceling interface call to cancel() would
cause segfault when interface is already destroyed. Therefore cause segfault when interface is already destroyed. Therefore
interface <A HREF="#Events">IEvents</A> must be explicitly released interface <A HREF="#Events">IEvents</A> must be explicitly released
after receiving an event. This may be done for example right before after receiving an event. This may be done for example right before
queuing for an event next time:</FONT></P> queuing for an event next time:</FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>events-&gt;release();</I></FONT></P> <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>events-&gt;release();</I></FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>events = NULL;</I></FONT></P> <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>events = NULL;</I></FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>events = <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>events =
attachment-&gt;queEvents(&amp;status, this, eveLen, eveBuffer);</I></FONT></P> attachment-&gt;queEvents(&amp;status, this, eveLen, eveBuffer);</I></FONT></P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>Setting interface pointer <P STYLE="margin-bottom: 0in"><FONT SIZE=4>Setting interface pointer
to NULL is useful in case of exception during queEvents. In other to NULL is useful in case of exception during queEvents. In other
@ -780,7 +779,7 @@ use for additional details our sample 08.events.cpp. </FONT>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>To begin to use services <P STYLE="margin-bottom: 0in"><FONT SIZE=4>To begin to use services
one should first of all connect to service manager. This is done one should first of all connect to service manager. This is done
using attachServiceManager() method of <A HREF="#Provider">IProvider</A>. using attachServiceManager() method of <A HREF="#Provider">IProvider</A>.
This method returns <A HREF="#Service">IService</A> interface which This method returns <A HREF="#Service">IService</A> interface which
is used later to talk to service. To prepare SPB to attach to service is used later to talk to service. To prepare SPB to attach to service
manager one can use IXpbBuilder:</FONT></P> manager one can use IXpbBuilder:</FONT></P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>IXpbBuilder* spb1 = <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>IXpbBuilder* spb1 =
@ -830,7 +829,7 @@ spb2-&gt;getBufferLength(&amp;status), spb2-&gt;getBuffer(&amp;status));</FONT><
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>Many started services <P STYLE="margin-bottom: 0in"><FONT SIZE=4>Many started services
(including mentioned here gstat) return text information during (including mentioned here gstat) return text information during
execution. To display it one should query started service anout that execution. To display it one should query started service anout that
information line by line. This is done by calling query() method of information line by line. This is done by calling query() method of
<A HREF="#Service">IService</A> interface with appropriate send and <A HREF="#Service">IService</A> interface with appropriate send and
receive blocks of parameters. Send block may contain various helper receive blocks of parameters. Send block may contain various helper
information (like timeout when querying service) or information to be information (like timeout when querying service) or information to be
@ -848,7 +847,7 @@ steps we are ready to query service in a loop (each line returned in
a single call to query()):</FONT></P> a single call to query()):</FONT></P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>do</I></FONT></P> <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>do</I></FONT></P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>{</I></FONT></P> <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>{</I></FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>svc-&gt;query(&amp;status, <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>svc-&gt;query(&amp;status,
0, NULL, sizeof(receiveItems1), receiveItems1, sizeof(results), 0, NULL, sizeof(receiveItems1), receiveItems1, sizeof(results),
results);</I></FONT></P> results);</I></FONT></P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>} while <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>} while
@ -890,13 +889,13 @@ services tasks do not forget to close an interface:</FONT></P>
<FONT FACE="Albany, sans-serif"><FONT SIZE=5>Writing plugins.</FONT></FONT></P> <FONT FACE="Albany, sans-serif"><FONT SIZE=5>Writing plugins.</FONT></FONT></P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>To write a plugin means to <P STYLE="margin-bottom: 0in"><FONT SIZE=4>To write a plugin means to
implement some interfaces and place your implementation into dynamic implement some interfaces and place your implementation into dynamic
library (.dll in windows or .so in linux) later referenced as <I>plugin library (.dll in windows or .so in linux) later referenced as </FONT><FONT SIZE=4><I>plugin
module</I> or just <I>module</I>. In most cases single plugin is module</I></FONT><FONT SIZE=4> or just </FONT><FONT SIZE=4><I>module</I></FONT><FONT SIZE=4>.
place in dynamic library but in common case. One of that interfaces In most cases single plugin is place in dynamic library but in common
<A HREF="#PluginModule">IPluginModule</A> is module-wide (as more case. One of that interfaces <A HREF="#PluginModule">IPluginModule</A>
or less clear from it's name), others are per plugin. Also each is module-wide (as more or less clear from it's name), others are
plugin module should contain special exported entrypoint per plugin. Also each plugin module should contain special exported
firebird_plugin() which name is defined in include file entrypoint firebird_plugin() which name is defined in include file
firebird/Interfaces.h as FB_PLUGIN_ENTRY_POINT.</FONT></P> firebird/Interfaces.h as FB_PLUGIN_ENTRY_POINT.</FONT></P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>In previous part of this <P STYLE="margin-bottom: 0in"><FONT SIZE=4>In previous part of this
text we were mostly describing how to use existing interfaces, here text we were mostly describing how to use existing interfaces, here
@ -915,12 +914,13 @@ sample yourself and learn it when reading later.</FONT></P>
</P> </P>
<H1><FONT SIZE=4>Implementation of plugin module.</FONT></H1> <H1><FONT SIZE=4>Implementation of plugin module.</FONT></H1>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>Plugins actively interact <P STYLE="margin-bottom: 0in"><FONT SIZE=4>Plugins actively interact
with special firebird component called <I>plugin manager</I>. In with special firebird component called </FONT><FONT SIZE=4><I>plugin
particular plugin manager should be aware what plugin modules were manager</I></FONT><FONT SIZE=4>. In particular plugin manager should
loaded and must be notified if operating system tries to unload one be aware what plugin modules were loaded and must be notified if
of that modules without explicit plugin manager command (this may operating system tries to unload one of that modules without explicit
happen first of all when using embedded access when exit() is plugin manager command (this may happen first of all when using
called in a program or main firebird library <I><SPAN STYLE="font-weight: normal">fbclient</SPAN></I> embedded access when exit() is called in a program or main
firebird library </FONT><FONT SIZE=4><I><SPAN STYLE="font-weight: normal">fbclient</SPAN></I></FONT><FONT SIZE=4>
is unloaded). Primary task of IPluginModule interface is that is unloaded). Primary task of IPluginModule interface is that
notification. First of all one must decide - how to detect that notification. First of all one must decide - how to detect that
module is going to be unloaded? When dynamic library is unloaded for module is going to be unloaded? When dynamic library is unloaded for
@ -943,44 +943,38 @@ looks as follows:</FONT></P>
public IPluginModuleImpl&lt;PluginModule, CheckStatusWrapper&gt;</I></FONT></P> public IPluginModuleImpl&lt;PluginModule, CheckStatusWrapper&gt;</I></FONT></P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>{</I></FONT></P> <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>{</I></FONT></P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>private:</I></FONT></P> <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>private:</I></FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>IPluginManager* <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>IPluginManager*
pluginManager;</I></FONT></P> pluginManager;</I></FONT></P>
<P STYLE="margin-bottom: 0in"><BR> <P STYLE="margin-bottom: 0in"><BR>
</P> </P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>public:</I></FONT></P> <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>public:</I></FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>PluginModule()</I></FONT></P> <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>PluginModule()</I></FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>: <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>: pluginManager(NULL)</I></FONT></P>
pluginManager(NULL)</I></FONT></P> <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>{ }</I></FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>{ }</I></FONT></P>
<P STYLE="margin-bottom: 0in"><BR> <P STYLE="margin-bottom: 0in"><BR>
</P> </P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>~PluginModule()</I></FONT></P> <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>~PluginModule()</I></FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>{</I></FONT></P> <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>{</I></FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>if <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>if (pluginManager)</I></FONT></P>
(pluginManager)</I></FONT></P> <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>{</I></FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>{</I></FONT></P> <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>pluginManager-&gt;unregisterModule(this);</I></FONT></P>
<P STYLE="margin-bottom: 0in"> <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>doClean();</I></FONT></P>
<FONT SIZE=4><I>pluginManager-&gt;unregisterModule(this);</I></FONT></P> <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>}</I></FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>doClean();</I></FONT></P> <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>}</I></FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>}</I></FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>}</I></FONT></P>
<P STYLE="margin-bottom: 0in"><BR> <P STYLE="margin-bottom: 0in"><BR>
</P> </P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>void <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>void
registerMe(IPluginManager* m)</I></FONT></P> registerMe(IPluginManager* m)</I></FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>{</I></FONT></P> <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>{</I></FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>pluginManager = <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>pluginManager = m;</I></FONT></P>
m;</I></FONT></P> <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>pluginManager-&gt;registerModule(this);</I></FONT></P>
<P STYLE="margin-bottom: 0in"> <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>}</I></FONT></P>
<FONT SIZE=4><I>pluginManager-&gt;registerModule(this);</I></FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>}</I></FONT></P>
<P STYLE="margin-bottom: 0in"><BR> <P STYLE="margin-bottom: 0in"><BR>
</P> </P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>void doClean()</I></FONT></P> <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>void doClean()</I></FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>{</I></FONT></P> <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>{</I></FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>pluginManager <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>pluginManager = NULL;</I></FONT></P>
= NULL;</I></FONT></P> <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>}</I></FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>}</I></FONT></P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>};</I></FONT></P> <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>};</I></FONT></P>
<P STYLE="margin-bottom: 0in"><BR> <P STYLE="margin-bottom: 0in"><BR>
</P> </P>
@ -989,15 +983,15 @@ plugin manager interface <A HREF="#PluginManager">IPluginManager</A>.
It's passed to registerModule() function and saved in private It's passed to registerModule() function and saved in private
variable, at the same time module is registered in plugin manager by variable, at the same time module is registered in plugin manager by
the call to registerModule() method with own address as a single the call to registerModule() method with own address as a single
parameter. Variable <I>pluginManager </I>not only stores pointer to parameter. Variable </FONT><FONT SIZE=4><I>pluginManager </I></FONT><FONT SIZE=4>not
interface, at the same time it serves as a flag that module is only stores pointer to interface, at the same time it serves as a
registered. When destructor of registered module is invoked it flag that module is registered. When destructor of registered module
notifies plugin manager (yes, this is what for this class exists!) is invoked it notifies plugin manager (yes, this is what for this
about unexpected unload by the call to unregisterModule() passing class exists!) about unexpected unload by the call to
pointer to itself. When plugin manager is going to unload module in unregisterModule() passing pointer to itself. When plugin manager is
regular way in first of all calls doClean() method changing module going to unload module in regular way in first of all calls doClean()
state to unregistered and this avoiding call to unregisterModule() method changing module state to unregistered and this avoiding call
when OS performs actual unload.</FONT></P> to unregisterModule() when OS performs actual unload.</FONT></P>
<P STYLE="margin-bottom: 0in"><BR> <P STYLE="margin-bottom: 0in"><BR>
</P> </P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>Implementing plugin's <P STYLE="margin-bottom: 0in"><FONT SIZE=4>Implementing plugin's
@ -1031,13 +1025,13 @@ non-existent type SomePlugin):</FONT></P>
ISomePluginImpl&lt;MyPlugin, CheckStatusWrapper&gt;</I></FONT></P> ISomePluginImpl&lt;MyPlugin, CheckStatusWrapper&gt;</I></FONT></P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>{</I></FONT></P> <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>{</I></FONT></P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>public:</I></FONT></P> <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>public:</I></FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>explicit <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>explicit
MyPlugin(<A HREF="#PluginConfig">IPluginConfig</A>* cnf) throw()</I></FONT></P> MyPlugin(<A HREF="#PluginConfig">IPluginConfig</A>* cnf) throw()</I></FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>: <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>: config(cnf),
config(cnf), refCounter(0), owner(NULL)</I></FONT></P> refCounter(0), owner(NULL)</I></FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>{</I></FONT></P> <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>{</I></FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>config-&gt;addRef();</I></FONT></P> <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>config-&gt;addRef();</I></FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>}</I></FONT></P> <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>}</I></FONT></P>
<P STYLE="margin-bottom: 0in; font-style: normal"><FONT SIZE=4>Constructor <P STYLE="margin-bottom: 0in; font-style: normal"><FONT SIZE=4>Constructor
gets as parameter plugin configuration interface. If you are going to gets as parameter plugin configuration interface. If you are going to
have you plugin configured in some way it's good idea to save this have you plugin configured in some way it's good idea to save this
@ -1047,74 +1041,67 @@ familiar configuration and minimize code written. Certainly when
saving any reference counted interface it's better not forget to add saving any reference counted interface it's better not forget to add
reference to it. Also set reference counter to 0 and plugin owner to reference to it. Also set reference counter to 0 and plugin owner to
NULL.</FONT></P> NULL.</FONT></P>
<P STYLE="margin-bottom: 0in; font-style: normal"><BR> <P STYLE="margin-bottom: 0in"><BR>
</P> </P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>~MyPlugin()</I></FONT></P> <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>~MyPlugin()</I></FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>{</I></FONT></P> <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>{</I></FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>config-&gt;release();</I></FONT></P> <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>config-&gt;release();</I></FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>}</I></FONT></P> <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>}</I></FONT></P>
<P STYLE="margin-bottom: 0in; font-style: normal"><FONT SIZE=4>Destructor <P STYLE="margin-bottom: 0in; font-style: normal"><FONT SIZE=4>Destructor
releases config interface. Pay attention we do not change releases config interface. Pay attention we do not change
reference counter of our owner cause it owns us, not we own it.</FONT></P> reference counter of our owner cause it owns us, not we own it.</FONT></P>
<P STYLE="margin-bottom: 0in; font-style: normal"><BR>
</P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>// IRefCounted
implementation</I></FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>int release()</I></FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>{</I></FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>if
(--refCounter == 0)</I></FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>{</I></FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>delete
this;</I></FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>return
0;</I></FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>}</I></FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>return
1;</I></FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>}</I></FONT></P>
<P STYLE="margin-bottom: 0in"><BR> <P STYLE="margin-bottom: 0in"><BR>
</P> </P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>void addRef()</I></FONT></P> <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>// IRefCounted
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>{</I></FONT></P> implementation</I></FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>++refCounter;</I></FONT></P> <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>int release()</I></FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>}</I></FONT></P> <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>{</I></FONT></P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>if (--refCounter == 0)</I></FONT></P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>{</I></FONT></P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>delete this;</I></FONT></P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>return 0;</I></FONT></P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>}</I></FONT></P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>return 1;</I></FONT></P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>}</I></FONT></P>
<P STYLE="margin-bottom: 0in"><BR>
</P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>void addRef()</I></FONT></P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>{</I></FONT></P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>++refCounter;</I></FONT></P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>}</I></FONT></P>
<P STYLE="margin-bottom: 0in; font-style: normal"><FONT SIZE=4>Absolutely <P STYLE="margin-bottom: 0in; font-style: normal"><FONT SIZE=4>Absolutely
typical implementation of reference counted object.</FONT></P> typical implementation of reference counted object.</FONT></P>
<P STYLE="margin-bottom: 0in; font-style: normal"><BR>
</P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>// IPluginBase
implementation</I></FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>void
setOwner(IReferenceCounted* o)</I></FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>{</I></FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>owner =
o;</I></FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>}</I></FONT></P>
<P STYLE="margin-bottom: 0in"><BR> <P STYLE="margin-bottom: 0in"><BR>
</P> </P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>IReferenceCounted* <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>// IPluginBase
implementation</I></FONT></P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>void
setOwner(IReferenceCounted* o)</I></FONT></P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>{</I></FONT></P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>owner = o;</I></FONT></P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>}</I></FONT></P>
<P STYLE="margin-bottom: 0in"><BR>
</P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>IReferenceCounted*
getOwner()</I></FONT></P> getOwner()</I></FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>{</I></FONT></P> <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>{</I></FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>return <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>return owner;</I></FONT></P>
owner;</I></FONT></P> <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>}</I></FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>}</I></FONT></P>
<P STYLE="margin-bottom: 0in; font-style: normal"><FONT SIZE=4>As it <P STYLE="margin-bottom: 0in; font-style: normal"><FONT SIZE=4>As it
was promised implementation of IPluginBase is trivial.</FONT></P> was promised implementation of IPluginBase is trivial.</FONT></P>
<P STYLE="margin-bottom: 0in; font-style: normal"><BR> <P STYLE="margin-bottom: 0in"><BR>
</P> </P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>// ISomePlugin <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>// ISomePlugin
implementation</I></FONT></P> implementation</I></FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>// … here go <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>// … here go various
various methods required for particular plugin type</I></FONT></P> methods required for particular plugin type</I></FONT></P>
<P STYLE="margin-bottom: 0in"><BR> <P STYLE="margin-bottom: 0in"><BR>
</P> </P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>private:</I></FONT></P> <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>private:</I></FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>IPluginConfig* <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>IPluginConfig* config;</I></FONT></P>
config;</I></FONT></P> <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>FbSampleAtomic
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>FbSampleAtomic
refCounter;</I></FONT></P> refCounter;</I></FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>IReferenceCounted* <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>IReferenceCounted*
owner;</I></FONT></P> owner;</I></FONT></P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>};</I></FONT></P> <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>};</I></FONT></P>
<P STYLE="margin-bottom: 0in"><BR> <P STYLE="margin-bottom: 0in"><BR>
@ -1134,17 +1121,17 @@ manager. Factory typically looks this way:</FONT></P>
IPluginFactoryImpl&lt;Factory, CheckStatusWrapper&gt;</I></FONT></P> IPluginFactoryImpl&lt;Factory, CheckStatusWrapper&gt;</I></FONT></P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>{</I></FONT></P> <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>{</I></FONT></P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>public:</I></FONT></P> <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>public:</I></FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>IPluginBase* <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>IPluginBase*
createPlugin(CheckStatusWrapper* status, IPluginConfig* createPlugin(CheckStatusWrapper* status, IPluginConfig*
factoryParameter)</I></FONT></P> factoryParameter)</I></FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>{</I></FONT></P> <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>{</I></FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>MyPlugin* p = <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>MyPlugin* p = new
new MyPlugin(factoryParameter);</I></FONT></P> MyPlugin(factoryParameter);</I></FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>p-&gt;addRef();</I></FONT></P> <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>p-&gt;addRef();</I></FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>return p;</I></FONT></P> <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>return p;</I></FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4><I>}</I></FONT></P> <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>}</I></FONT></P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>};</I></FONT></P> <P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>};</I></FONT></P>
<P STYLE="margin-bottom: 0in; font-style: normal"><BR> <P STYLE="margin-bottom: 0in"><BR>
</P> </P>
<P STYLE="margin-bottom: 0in; font-style: normal"><FONT SIZE=4>Here <P STYLE="margin-bottom: 0in; font-style: normal"><FONT SIZE=4>Here
attention should be payed to the fact that even in a case when code attention should be payed to the fact that even in a case when code
@ -1182,13 +1169,12 @@ plugin manager:</FONT></P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>extern &quot;C&quot; void <P STYLE="margin-bottom: 0in"><FONT SIZE=4>extern &quot;C&quot; void
FB_DLL_EXPORT FB_PLUGIN_ENTRY_POINT(IMaster* master)</FONT></P> FB_DLL_EXPORT FB_PLUGIN_ENTRY_POINT(IMaster* master)</FONT></P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>{</FONT></P> <P STYLE="margin-bottom: 0in"><FONT SIZE=4>{</FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4>IPluginManager* <P STYLE="margin-bottom: 0in"><FONT SIZE=4>IPluginManager*
pluginManager = master-&gt;getPluginManager();</FONT></P> pluginManager = master-&gt;getPluginManager();</FONT></P>
<P STYLE="margin-bottom: 0in"><BR> <P STYLE="margin-bottom: 0in"><BR>
</P> </P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4>module.registerMe(pluginManager);</FONT></P> <P STYLE="margin-bottom: 0in"><FONT SIZE=4>module.registerMe(pluginManager);</FONT></P>
<P STYLE="margin-bottom: 0in"> <P STYLE="margin-bottom: 0in"><FONT SIZE=4>pluginManager-&gt;registerPluginFactory(IPluginManager::TYPE_DB_CRYPT,
<FONT SIZE=4>pluginManager-&gt;registerPluginFactory(IPluginManager::TYPE_DB_CRYPT,
&quot;DbCrypt_example&quot;, &amp;factory);</FONT></P> &quot;DbCrypt_example&quot;, &amp;factory);</FONT></P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>}</FONT></P> <P STYLE="margin-bottom: 0in"><FONT SIZE=4>}</FONT></P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>First of all we call <P STYLE="margin-bottom: 0in"><FONT SIZE=4>First of all we call
@ -1396,39 +1382,38 @@ objects:</FONT></P>
</OL> </OL>
<P STYLE="margin-bottom: 0in"><A NAME="Directory codes"></A><FONT SIZE=4>Directory <P STYLE="margin-bottom: 0in"><A NAME="Directory codes"></A><FONT SIZE=4>Directory
codes:</FONT></P> codes:</FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4>DIR_BIN bin <P STYLE="margin-bottom: 0in"><FONT SIZE=4>DIR_BIN bin (utilities
(utilities like isql, gbak, gstat)</FONT></P> like isql, gbak, gstat)</FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4>DIR_SBIN sbin <P STYLE="margin-bottom: 0in"><FONT SIZE=4>DIR_SBIN sbin (fbguard
(fbguard and firebird server)</FONT></P> and firebird server)</FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4>DIR_CONF <P STYLE="margin-bottom: 0in"><FONT SIZE=4>DIR_CONF configuration
configuration files (firebird.conf, databases.conf, plugins.conf)</FONT></P> files (firebird.conf, databases.conf, plugins.conf)</FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4>DIR_LIB lib <P STYLE="margin-bottom: 0in"><FONT SIZE=4>DIR_LIB lib (fbclient,
(fbclient, ib_util)</FONT></P> ib_util)</FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4>DIR_INC include <P STYLE="margin-bottom: 0in"><FONT SIZE=4>DIR_INC include
(ibase.h, firebird/Interfaces.h)</FONT></P> (ibase.h, firebird/Interfaces.h)</FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4>DIR_DOC - <P STYLE="margin-bottom: 0in"><FONT SIZE=4>DIR_DOC - documentation</FONT></P>
documentation</FONT></P> <P STYLE="margin-bottom: 0in"><FONT SIZE=4>DIR_UDF UDF (ib_udf,
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4>DIR_UDF UDF fbudf)</FONT></P>
(ib_udf, fbudf)</FONT></P> <P STYLE="margin-bottom: 0in"><FONT SIZE=4>DIR_SAMPLE - samples</FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4>DIR_SAMPLE - samples</FONT></P> <P STYLE="margin-bottom: 0in"><FONT SIZE=4>DIR_SAMPLEDB samples
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4>DIR_SAMPLEDB database (employee.fdb)</FONT></P>
samples database (employee.fdb)</FONT></P> <P STYLE="margin-bottom: 0in"><FONT SIZE=4>DIR_HELP qli help
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4>DIR_HELP qli help
(help.fdb)</FONT></P> (help.fdb)</FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4>DIR_INTL <P STYLE="margin-bottom: 0in"><FONT SIZE=4>DIR_INTL international
international libraries (fbintl)</FONT></P> libraries (fbintl)</FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4>DIR_MISC <P STYLE="margin-bottom: 0in"><FONT SIZE=4>DIR_MISC miscellaneous
miscellaneous files (like uninstall manifest and something else)</FONT></P> files (like uninstall manifest and something else)</FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4>DIR_SECDB where <P STYLE="margin-bottom: 0in"><FONT SIZE=4>DIR_SECDB where
security database is stored (securityN.fdb)</FONT></P> security database is stored (securityN.fdb)</FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4>DIR_MSG where <P STYLE="margin-bottom: 0in"><FONT SIZE=4>DIR_MSG where messages
messages file is stored (firebird.msg)</FONT></P> file is stored (firebird.msg)</FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4>DIR_LOG where log <P STYLE="margin-bottom: 0in"><FONT SIZE=4>DIR_LOG where log file
file is stored (firebird.log)</FONT></P> is stored (firebird.log)</FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4>DIR_GUARD where <P STYLE="margin-bottom: 0in"><FONT SIZE=4>DIR_GUARD where
guardian lock is stored (fb_guard)</FONT></P> guardian lock is stored (fb_guard)</FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4>DIR_PLUGINS <P STYLE="margin-bottom: 0in"><FONT SIZE=4>DIR_PLUGINS plugins
plugins directory ([lib]Engine13.{dll|so})</FONT></P> directory ([lib]Engine13.{dll|so})</FONT></P>
<P STYLE="margin-bottom: 0in"><BR> <P STYLE="margin-bottom: 0in"><BR>
</P> </P>
<P STYLE="margin-bottom: 0in"><BR> <P STYLE="margin-bottom: 0in"><BR>
@ -1757,15 +1742,15 @@ interface API of plugin manager.</FONT></P>
</P> </P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>Constants defined by <P STYLE="margin-bottom: 0in"><FONT SIZE=4>Constants defined by
PluginManager interface (plugin types):</FONT></P> PluginManager interface (plugin types):</FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4>TYPE_PROVIDER</FONT></P> <P STYLE="margin-bottom: 0in"><FONT SIZE=4>TYPE_PROVIDER</FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4>TYPE_AUTH_SERVER</FONT></P> <P STYLE="margin-bottom: 0in"><FONT SIZE=4>TYPE_AUTH_SERVER</FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4>TYPE_AUTH_CLIENT</FONT></P> <P STYLE="margin-bottom: 0in"><FONT SIZE=4>TYPE_AUTH_CLIENT</FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4>TYPE_AUTH_USER_MANAGEMENT</FONT></P> <P STYLE="margin-bottom: 0in"><FONT SIZE=4>TYPE_AUTH_USER_MANAGEMENT</FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4>TYPE_EXTERNAL_ENGINE</FONT></P> <P STYLE="margin-bottom: 0in"><FONT SIZE=4>TYPE_EXTERNAL_ENGINE</FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4>TYPE_TRACE</FONT></P> <P STYLE="margin-bottom: 0in"><FONT SIZE=4>TYPE_TRACE</FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4>TYPE_WIRE_CRYPT</FONT></P> <P STYLE="margin-bottom: 0in"><FONT SIZE=4>TYPE_WIRE_CRYPT</FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4>TYPE_DB_CRYPT</FONT></P> <P STYLE="margin-bottom: 0in"><FONT SIZE=4>TYPE_DB_CRYPT</FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4>TYPE_KEY_HOLDER</FONT></P> <P STYLE="margin-bottom: 0in"><FONT SIZE=4>TYPE_KEY_HOLDER</FONT></P>
<P STYLE="margin-bottom: 0in"><BR> <P STYLE="margin-bottom: 0in"><BR>
</P> </P>
<P STYLE="margin-bottom: 0in"><BR> <P STYLE="margin-bottom: 0in"><BR>
@ -1966,7 +1951,7 @@ Statement interface:</FONT></P>
</P> </P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>IAttachment::prepare() <P STYLE="margin-bottom: 0in"><FONT SIZE=4>IAttachment::prepare()
flags:</FONT></P> flags:</FONT></P>
<P STYLE="margin-left: 0.38in; text-indent: -0.01in; margin-bottom: 0in; page-break-before: auto"> <P STYLE="margin-left: 0.38in; text-indent: -0.01in; margin-bottom: 0in; page-break-before: auto; page-break-after: auto">
<FONT SIZE=4>PREPARE_PREFETCH_NONE constant to pass no flags, 0 <FONT SIZE=4>PREPARE_PREFETCH_NONE constant to pass no flags, 0
value.</FONT></P> value.</FONT></P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>The following flags may be <P STYLE="margin-bottom: 0in"><FONT SIZE=4>The following flags may be
@ -2088,8 +2073,8 @@ moment when given timer should alarm.</FONT></P>
<LI><P STYLE="margin-bottom: 0in"><FONT SIZE=4>void <LI><P STYLE="margin-bottom: 0in"><FONT SIZE=4>void
start(StatusType* status, ITimer* timer, ISC_UINT64 microSeconds) start(StatusType* status, ITimer* timer, ISC_UINT64 microSeconds)
start <A HREF="#Timer">ITimer</A> to alarm after given delay (in start <A HREF="#Timer">ITimer</A> to alarm after given delay (in
microseconds, 10<SUP>-6</SUP> seconds). Timer will be waked up only microseconds, 10</FONT><SUP><FONT SIZE=4>-6</FONT></SUP><FONT SIZE=4>
once after this call.</FONT></P> seconds). Timer will be waked up only once after this call.</FONT></P>
<LI><P STYLE="margin-bottom: 0in"><FONT SIZE=4>void stop(StatusType* <LI><P STYLE="margin-bottom: 0in"><FONT SIZE=4>void stop(StatusType*
status, ITimer* timer) stop <A HREF="#Timer">ITimer</A>. It's status, ITimer* timer) stop <A HREF="#Timer">ITimer</A>. It's
not an error to stop not started timer thus avoiding problems with not an error to stop not started timer thus avoiding problems with
@ -2190,7 +2175,8 @@ interface various helper methods required here or there.</FONT></P>
unsigned fractions) replaces isc_encode_sql_time().</FONT></P> unsigned fractions) replaces isc_encode_sql_time().</FONT></P>
<LI><P STYLE="margin-bottom: 0in"><FONT SIZE=4>unsigned <LI><P STYLE="margin-bottom: 0in"><FONT SIZE=4>unsigned
formatStatus(char* buffer, unsigned bufferSize, IStatus* status) formatStatus(char* buffer, unsigned bufferSize, IStatus* status)
replaces fb_interpret().</FONT></P> replaces fb_interpret(). Size of buffer, passed into this method,
should not be less than 50 bytes.</FONT></P>
<LI><P STYLE="margin-bottom: 0in"><FONT SIZE=4>unsigned <LI><P STYLE="margin-bottom: 0in"><FONT SIZE=4>unsigned
getClientVersion() returns integer, containing major version in getClientVersion() returns integer, containing major version in
byte 0 and minor version in byte 1.</FONT></P> byte 0 and minor version in byte 1.</FONT></P>
@ -2311,13 +2297,13 @@ be selected by firebird and passed to that interface.</FONT></P>
<OL> <OL>
<LI><P STYLE="margin-bottom: 0in"><FONT SIZE=4>void <LI><P STYLE="margin-bottom: 0in"><FONT SIZE=4>void
setSymmetric(StatusType* status, const char* type, unsigned setSymmetric(StatusType* status, const char* type, unsigned
keyLength, const void* key) make it store symmetric key of keyLength, const void* key) make it store symmetric key of given
given type.</FONT></P> type.</FONT></P>
<LI><P STYLE="margin-bottom: 0in"><FONT SIZE=4>void <LI><P STYLE="margin-bottom: 0in"><FONT SIZE=4>void
setAsymmetric(StatusType* status, const char* type, unsigned setAsymmetric(StatusType* status, const char* type, unsigned
encryptKeyLength, const void* encryptKey, unsigned decryptKeyLength, encryptKeyLength, const void* encryptKey, unsigned decryptKeyLength,
const void* decryptKey) make it store pair of asymmetric keys of const void* decryptKey) make it store pair of asymmetric keys of
given type.</FONT></P> given type.</FONT></P>
<LI><P STYLE="margin-bottom: 0in"><FONT SIZE=4>const void* <LI><P STYLE="margin-bottom: 0in"><FONT SIZE=4>const void*
getEncryptKey(unsigned* length) get a key for encryption.</FONT></P> getEncryptKey(unsigned* length) get a key for encryption.</FONT></P>
<LI><P STYLE="margin-bottom: 0in"><FONT SIZE=4>const void* <LI><P STYLE="margin-bottom: 0in"><FONT SIZE=4>const void*
@ -2502,7 +2488,7 @@ interface:</FONT></P>
<P STYLE="margin-bottom: 0in"><A NAME="IntUserField"></A><FONT SIZE=4>IntUserField <P STYLE="margin-bottom: 0in"><A NAME="IntUserField"></A><FONT SIZE=4>IntUserField
interface:</FONT></P> interface:</FONT></P>
<OL> <OL>
<LI><P STYLE="margin-bottom: 0in"><FONT SIZE=4>int get() - get <LI><P STYLE="margin-bottom: 0in"><FONT SIZE=4>int get() - get
field's value.</FONT></P> field's value.</FONT></P>
<LI><P STYLE="margin-bottom: 0in"><FONT SIZE=4>void set(StatusType* <LI><P STYLE="margin-bottom: 0in"><FONT SIZE=4>void set(StatusType*
status, int newValue) assigns value to the field. Sets entered status, int newValue) assigns value to the field. Sets entered
@ -2663,7 +2649,7 @@ plugin or key holder plugin.</FONT></P>
bufferLength, void* buffer) when performing callback information bufferLength, void* buffer) when performing callback information
is passed in both directions. The source of a key receives is passed in both directions. The source of a key receives
dataLength bytes of data and may send up to bufferLength bytes into dataLength bytes of data and may send up to bufferLength bytes into
buffer returning actual number of bytes placed into buffer.</FONT></P> buffer returning actual number of bytes placed into buffer.</FONT></P>
</OL> </OL>
<P STYLE="margin-bottom: 0in"><BR> <P STYLE="margin-bottom: 0in"><BR>
</P> </P>
@ -2737,40 +2723,40 @@ static messages.</FONT></P>
</P> </P>
<P STYLE="margin-bottom: 0in"><A NAME="FbDate"></A><FONT SIZE=4>class <P STYLE="margin-bottom: 0in"><A NAME="FbDate"></A><FONT SIZE=4>class
FbDate methods:</FONT></P> FbDate methods:</FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4>void decode(IUtil* <P STYLE="margin-bottom: 0in"><FONT SIZE=4>void decode(IUtil* util,
util, unsigned* year, unsigned* month, unsigned* day)</FONT></P> unsigned* year, unsigned* month, unsigned* day)</FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4>unsigned <P STYLE="margin-bottom: 0in"><FONT SIZE=4>unsigned getYear(IUtil*
getYear(IUtil* util) </FONT> util) </FONT>
</P> </P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4>unsigned <P STYLE="margin-bottom: 0in"><FONT SIZE=4>unsigned getMonth(IUtil*
getMonth(IUtil* util)</FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4>unsigned getDay(IUtil*
util)</FONT></P> util)</FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4>void encode(IUtil* <P STYLE="margin-bottom: 0in"><FONT SIZE=4>unsigned getDay(IUtil*
util, unsigned year, unsigned month, unsigned day)</FONT></P> util)</FONT></P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>void encode(IUtil* util,
unsigned year, unsigned month, unsigned day)</FONT></P>
<P STYLE="margin-bottom: 0in"><BR> <P STYLE="margin-bottom: 0in"><BR>
</P> </P>
<P STYLE="margin-bottom: 0in"><A NAME="FbTime"></A><FONT SIZE=4>class <P STYLE="margin-bottom: 0in"><A NAME="FbTime"></A><FONT SIZE=4>class
FbTime methods:</FONT></P> FbTime methods:</FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4>void decode(IUtil* <P STYLE="margin-bottom: 0in"><FONT SIZE=4>void decode(IUtil* util,
util, unsigned* hours, unsigned* minutes, unsigned* seconds, unsigned* hours, unsigned* minutes, unsigned* seconds, unsigned*
unsigned* fractions)</FONT></P> fractions)</FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4>unsigned <P STYLE="margin-bottom: 0in"><FONT SIZE=4>unsigned getHours(IUtil*
getHours(IUtil* util)</FONT></P> util)</FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4>unsigned <P STYLE="margin-bottom: 0in"><FONT SIZE=4>unsigned getMinutes(IUtil*
getMinutes(IUtil* util)</FONT></P> util)</FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4>unsigned <P STYLE="margin-bottom: 0in"><FONT SIZE=4>unsigned getSeconds(IUtil*
getSeconds(IUtil* util)</FONT></P> util)</FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4>unsigned <P STYLE="margin-bottom: 0in"><FONT SIZE=4>unsigned
getFractions(IUtil* util)</FONT></P> getFractions(IUtil* util)</FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4>void encode(IUtil* <P STYLE="margin-bottom: 0in"><FONT SIZE=4>void encode(IUtil* util,
util, unsigned hours, unsigned minutes, unsigned seconds, unsigned unsigned hours, unsigned minutes, unsigned seconds, unsigned
fractions)</FONT></P> fractions)</FONT></P>
<P STYLE="margin-bottom: 0in"><BR> <P STYLE="margin-bottom: 0in"><BR>
</P> </P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>class FbTimestamp members:</FONT></P> <P STYLE="margin-bottom: 0in"><FONT SIZE=4>class FbTimestamp members:</FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4>FbDate date;</FONT></P> <P STYLE="margin-bottom: 0in"><FONT SIZE=4>FbDate date;</FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4>FbTime time;</FONT></P> <P STYLE="margin-bottom: 0in"><FONT SIZE=4>FbTime time;</FONT></P>
<P STYLE="margin-bottom: 0in"><BR> <P STYLE="margin-bottom: 0in"><BR>
</P> </P>
<P STYLE="margin-bottom: 0in"><BR> <P STYLE="margin-bottom: 0in"><BR>
@ -2785,7 +2771,7 @@ fields. </FONT>
<P STYLE="margin-bottom: 0in"><A NAME="FbChar"></A><FONT SIZE=4>struct <P STYLE="margin-bottom: 0in"><A NAME="FbChar"></A><FONT SIZE=4>struct
FbChar</FONT></P> FbChar</FONT></P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>{</FONT></P> <P STYLE="margin-bottom: 0in"><FONT SIZE=4>{</FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4>char str[N];</FONT></P> <P STYLE="margin-bottom: 0in"><FONT SIZE=4>char str[N];</FONT></P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>};</FONT></P> <P STYLE="margin-bottom: 0in"><FONT SIZE=4>};</FONT></P>
<P STYLE="margin-bottom: 0in"><BR> <P STYLE="margin-bottom: 0in"><BR>
</P> </P>
@ -2793,10 +2779,9 @@ FbChar</FONT></P>
<P STYLE="margin-bottom: 0in"><A NAME="FbVarChar"></A><FONT SIZE=4>struct <P STYLE="margin-bottom: 0in"><A NAME="FbVarChar"></A><FONT SIZE=4>struct
FbVarChar</FONT></P> FbVarChar</FONT></P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>{</FONT></P> <P STYLE="margin-bottom: 0in"><FONT SIZE=4>{</FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4>ISC_USHORT length;</FONT></P> <P STYLE="margin-bottom: 0in"><FONT SIZE=4>ISC_USHORT length;</FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4>char str[N];</FONT></P> <P STYLE="margin-bottom: 0in"><FONT SIZE=4>char str[N];</FONT></P>
<P STYLE="margin-bottom: 0in"> <FONT SIZE=4>void set(const char* <P STYLE="margin-bottom: 0in"><FONT SIZE=4>void set(const char* s);</FONT></P>
s);</FONT></P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>};</FONT></P> <P STYLE="margin-bottom: 0in"><FONT SIZE=4>};</FONT></P>
<P STYLE="margin-bottom: 0in"><BR> <P STYLE="margin-bottom: 0in"><BR>
</P> </P>