This document explains how to create a data recognizer.
The code fragments in this document are taken from the example data
recognizer located in examples\AppFramework\Recogniser\
.
Recognizers need to provide the standard ECOM factory code to create an instance of the recognizer. For example,
const TInt KImplementationUID = 0x101F7DA1;
CApaDataRecognizerType* CExampleRecognizer::CreateRecognizerL()
{
return new (ELeave) CExampleRecognizer;
}
const TImplementationProxy ImplementationTable[] =
{
IMPLEMENTATION_PROXY_ENTRY(KImplementationUID,CExampleRecognizer::CreateRecognizerL)
};
EXPORT_C const TImplementationProxy* ImplementationGroupProxy(TInt& aTableCount)
{
aTableCount = sizeof(ImplementationTable) / sizeof(TImplementationProxy);
return ImplementationTable;
For an explanation of this code, see How to export the implementation factories.
The mmp file used to build the data recognizer should use the following settings:
TargetType
: this should be plugin
, which
specifies that the project is an ECOM plugin,
Resource
: the project should use a start
resource ... end
block to build the ECOM registration resource file. The
target
keyword should be used to specify that the built resource
file has the same name (without extension) as the DLL. For a description of the
ECOM registration resource file, see How to provide registry information.
UID
: the first UID should be 0x10009D8D
,
which is common to all ECOM plugins. The second one is the DLL UID, and should
match the dll_uid
member (and the filename) of the ECOM
registration resource file.
Capability
: this must be Protserv
in
order for the recognizer to be loadable by the framework.
For example:
target exampleRecognizer.dll
capability Protserv
targettype plugin
uid 0x10009d8d 0x1d1f75ed
vendorid 0x70000001
sourcepath .
source exampleRecognizer.cpp
systeminclude \EPOC32\INCLUDE
systeminclude \EPOC32\INCLUDE\ECOM
library EUSER.LIB APMIME.LIB
start resource 1d1f75ed.rss
target exampleRecognizer.rsc
end
All data recognizers must implement the polymorphic interface defined
by CApaDataRecognizerType
. This section describes the most
important functions in the interface.
In the constructor for the recognizer, a UID and a priority are specified, for instance:
const TUid KExampleUid = {0x1d1f75ed};
const TInt KNumDataTypes = 1;
CExampleRecognizer::CExampleRecognizer() : CApaDataRecognizerType(KExampleUid,CApaDataRecognizerType::EHigh)
{ iCountDataTypes = KNumDataTypes; }
The priority determines the position at which the recognizer is inserted into the recognizer list. The higher the priority, the nearer it will be to the start of the list. If more than one recognizer recognizes some data with the same confidence, the recognizer with the higher priority takes precedence.
The UID is the same value as the recognizer DLL's UID, as specified in the mmp file.
The constructor may be used to set the recognizer’s
iCountDataTypes
member. This value represents the number of data
types that the recognizer supports. It should be set, and should match the
implementation of SupportedDataTypeL()
.
SupportedDataTypeL()
This pure virtual function must be implemented. As the name suggests, it returns the MIME type(s) that the recognizer is capable of recognizing. The function takes an integer index parameter, in case it recognizes more than one.
_LIT8(KExampleTextMimeType, "text/example");
TDataType CExampleRecognizer::SupportedDataTypeL(TInt /*aIndex*/) const
{
return TDataType(KExampleTextMimeType);
}
Each recognizer’s implementation of SupportedDataTypeL()
is called by the recognizer framework after all the recognizers have been
loaded, to build up a list of all the mime/data types recognized in the system.
This list can be accessed using the
RApaLsSession::GetSupportedDataTypesL()
API function.
The mime type (class TDataType
) is a string of
up to 256 characters, and a UID. The UID is not used in data recognition. It is
used by apparc to associate native Symbian OS files with built-in applications.
DoRecognizeL()
All recognizers must implement
CApaDataRecognizerType::DoRecognizeL()
. This is the
function that is called to do the data recognition. It is not pure virtual, but
the implementation in CApaDataRecognizerType
does not do anything
apart from setting CApaDataRecognizerType::iDataType
to a default
value. Implementations should set iDataType
to the MIME type it
considers the data to belong to and iConfidence
to indicate how
confident it is. The decision is based on the two parameters,
aName
and aBuffer
.
The following code recognizes with maximum confidence the word
"example
" contained in files with a .example
extension.
void CExampleRecognizer::DoRecognizeL(const TDesC& aName, const TDesC8& aBuffer)
{
_LIT8(KExampleData, "example");
_LIT(KDotExample, ".Example");
TParse parse;
parse.Set(aName,NULL,NULL);
TPtrC ext=parse.Ext(); // extract the extension from the filename
if (ext.CompareF(KDotExample)==0 && aBuffer.FindF(KExampleData)!=KErrNotFound)
{
iConfidence=ECertain;
iDataType=TDataType(KExampleTextMimeType);
}
}
If DoRecognizeL()
needs more data than is provided in
the buffer, it can access the file by calling
CApaDataRecognizerType::FilePassedByHandleL()
. This
returns a handle to the file to be recognised, but only if the client passed a
file handle (RFile
) to the relevant
RApaLsSession
client API. If FilePassedByHandleL()
returns NULL, DoRecognizeL()
can open the file by calling
RFile::Open()
on aName
, but only if
aName
is a legal filename, rather than something else, such as a
URL.
PreferredBufSize()
This specifies the size in bytes of the buffer passed to
DoRecognizeL()
that the recognizer needs to work with. The default
implementation in CApaDataRecognizerType
returns zero. The actual
buffer size used is the maximum of all recognizers in the list. The preferred
buffer size cannot be greater than the value passed to
RApaLsSession::SetMaxDataBufSize()
(or 256 bytes by
default).