Symbian
Symbian Developer Library

SYMBIAN OS V9.4

Feedback

[Index] [Previous] [Next]


How to write a data recognizer

[Top]


Introduction

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\.

[Top]


ECOM framework code

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.

[Top]


The project file

The mmp file used to build the data recognizer should use the following settings:

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

[Top]


The recognizer interface (CApaDataRecognizerType)

All data recognizers must implement the polymorphic interface defined by CApaDataRecognizerType. This section describes the most important functions in the interface.


The constructor

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).