diff -r aa99f2208aad -r b8d18c84f71c localisation/apparchitecture/apgrfx/apgrecog.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/localisation/apparchitecture/apgrfx/apgrecog.cpp Tue Aug 03 10:20:34 2010 +0100 @@ -0,0 +1,689 @@ +// Copyright (c) 1997-2010 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// apgrecog.cpp +// + + +#include "../apserv/APSCLSV.H" +#include "APGCLI.H" +#include "APGPRIV.H" + +class CAsyncFileRecognition; + +_LIT8(KAllDataTypes,"*"); + + +/** +This class is an extension class for RApaLsSession. It was added to reduce the need +of BC breaks in later releases. +@internalComponent +*/ +NONSHARABLE_CLASS(CApaLsSessionExtension) : public CBase + { +public: + CApaLsSessionExtension(RApaLsSession& aSession); + ~CApaLsSessionExtension(); + + void SendReceive(TInt aFunction,const TIpcArgs& aArgs,TRequestStatus& aStatus) const; + TInt SendReceive(TInt aFunction,const TIpcArgs& aArgs) const; + + // file recognition functions + void RecognizeFilesL(const TDesC& aPath, const TDesC8& aDataType, CDataRecognitionResultArray& aResult, TRequestStatus& aStatus); + void CancelRecognizeFiles(); + void FilesRecognized(const TDesC& aPath, TInt aRequiredBufferSize, CDataRecognitionResultArray& aResult, TRequestStatus& aUsersRequestStatus, const TRequestStatus& aErrorCode); + TBool RecognitionActive() const; +private: + RApaLsSession& iSession; // we are a friend of this class! + CAsyncFileRecognition* iAsyncFileRecognition; + }; + +/** +This class is used to simplify the usage of the asynchronous RApaLsSession::RecognizeFilesL() function. +@internalComponent +*/ +NONSHARABLE_CLASS(CAsyncFileRecognition) : public CActive + { +public: + CAsyncFileRecognition(CDataRecognitionResultArray& aResult, TRequestStatus& aUsersRequestStatus, CApaLsSessionExtension& aSession); + ~CAsyncFileRecognition(); + void Start(const TDesC& aPath, const TDesC8& aDataType); +private: + void RunL(); + void DoCancel(); +private: // data + TPckgBuf iRequiredBufferSizePckg; + CDataRecognitionResultArray& iResult; + TRequestStatus& iUsersRequestStatus; + CApaLsSessionExtension& iSession; + const TDesC* iPath; + const TDesC8* iDataType; + }; + +/** +An entry of a CDataRecognitionResultArray object. Stores TDataRecognitionResult and the file name +in a compact format. +@internalComponent +*/ +NONSHARABLE_CLASS(CDataRecognitionResultArray::CItem) : public CBase + { +public: + CItem(HBufC* aFileName, HBufC8* aDataType, TUid aUid, TInt aConfidence); + ~CItem(); + void GetDataRecognitionResult(TDataRecognitionResult& aResult) const; + const TDesC& FileName() const; +private: + HBufC* iFileName; + HBufC8* iDataType; + TUid iUid; + TInt iConfidence; + }; + + +// +// CApaLsSessionExtension +// + +CApaLsSessionExtension::CApaLsSessionExtension(RApaLsSession& aSession) + : iSession(aSession), + iAsyncFileRecognition(NULL) + { + } + +CApaLsSessionExtension::~CApaLsSessionExtension() + { + delete iAsyncFileRecognition; + } + +void CApaLsSessionExtension::SendReceive(TInt aFunction,const TIpcArgs& aArgs,TRequestStatus& aStatus) const + { + iSession.SendReceive(aFunction,aArgs,aStatus); //lint !e1060 Suppress protected member is not accessible to non-member non-friend + } + +TInt CApaLsSessionExtension::SendReceive(TInt aFunction,const TIpcArgs& aArgs) const + { + return iSession.SendReceive(aFunction,aArgs); //lint !e1060 Suppress protected member is not accessible to non-member non-friend + } + + + +// +// CAsyncFileRecognition +// + +CAsyncFileRecognition::CAsyncFileRecognition(CDataRecognitionResultArray& aResult, TRequestStatus& aUsersRequestStatus, CApaLsSessionExtension& aSession) + : CActive(EPriorityStandard), + iResult(aResult), + iUsersRequestStatus(aUsersRequestStatus), + iSession(aSession) + { + CActiveScheduler::Add(this); + } + +void CAsyncFileRecognition::Start(const TDesC& aPath, const TDesC8& aDataType) + { + iPath = &aPath; + iDataType = &aDataType; + iStatus = KRequestPending; + iSession.SendReceive(EAppListServRecognizeFilesAsync,TIpcArgs(&aPath,&iRequiredBufferSizePckg,&aDataType),iStatus); + SetActive(); + } + +CAsyncFileRecognition::~CAsyncFileRecognition() + { + Cancel(); + iPath = NULL; + iDataType = NULL; + } + +void CAsyncFileRecognition::RunL() + { + iSession.FilesRecognized(*iPath, iRequiredBufferSizePckg(), iResult, iUsersRequestStatus, iStatus); + } + +void CAsyncFileRecognition::DoCancel() + { + iSession.SendReceive(ECancelRecognizeFiles,TIpcArgs(TIpcArgs::ENothing)); + TRequestStatus* status = &iUsersRequestStatus; + User::RequestComplete( status, KErrCancel ); + } + + +/** +Asynchronous recognition of a directory. +Function uses an internal CAsyncFileRecognition object to hide the +second server message (transferring the data to the client) from the user. +When the path is not correct or the server is already busy with another +recognition request, the function completes the request with an error. +@internalComponent +*/ +void CApaLsSessionExtension::RecognizeFilesL(const TDesC& aPath, const TDesC8& aDataType, CDataRecognitionResultArray& aResult, TRequestStatus& aStatus) + { + _LIT(KBackslash,"\\"); + + if(aPath.Right(1) != KBackslash) + { + TRequestStatus* status = &aStatus; + User::RequestComplete(status,KErrPathNotFound); + } + + aResult.SetPath(aPath); + aStatus = KRequestPending; + + if(!iAsyncFileRecognition) + { + iAsyncFileRecognition = new (ELeave) CAsyncFileRecognition(aResult, aStatus, *this); + iAsyncFileRecognition->Start(aPath, aDataType); + } + else + { + TRequestStatus* status = &aStatus; + User::RequestComplete(status,KErrInUse); + } + } + +TBool CApaLsSessionExtension::RecognitionActive() const + { + return iAsyncFileRecognition ? ETrue : EFalse; + } + +void CApaLsSessionExtension::CancelRecognizeFiles() + { + if(iAsyncFileRecognition) + { + iAsyncFileRecognition->Cancel(); + delete iAsyncFileRecognition; + iAsyncFileRecognition = NULL; + } + } + +/** +Callback function called by an CAsyncFileRecognition object, when an asynchronous +recognition has finished. If the recognition was successful, the data is transferred +to the client-side. +@internalComponent +*/ +void CApaLsSessionExtension::FilesRecognized(const TDesC& aPath, TInt aRequiredBufferSize, CDataRecognitionResultArray& aResult, TRequestStatus& aUsersRequestStatus, const TRequestStatus& aErrorCode) + { + TRequestStatus* status = &aUsersRequestStatus; + if(aErrorCode == KErrNone) + { + // transfer the result + TRAPD(error,iSession.TransferAndInternalizeDataL(aPath, aRequiredBufferSize, aResult)); + User::RequestComplete(status, error); + } + else + User::RequestComplete(status, aErrorCode.Int()); + + delete iAsyncFileRecognition; + iAsyncFileRecognition = 0; + } + + +// +// CItem +// + +CDataRecognitionResultArray::CItem::CItem(HBufC* aFileName, HBufC8* aDataType, TUid aUid, TInt aConfidence) + : iFileName(aFileName), + iDataType(aDataType), + iUid(aUid), + iConfidence(aConfidence) + { + } + +CDataRecognitionResultArray::CItem::~CItem() + { + delete iFileName; + delete iDataType; + } + +void CDataRecognitionResultArray::CItem::GetDataRecognitionResult(TDataRecognitionResult& aResult) const + { + TDataRecognitionResult result; + if(iDataType->Length() != 0) + { + TDataType dataType(*iDataType); + result.iDataType = dataType; + } + else + { + TDataType dataType(iUid); + result.iDataType = dataType; + } + + result.iConfidence = iConfidence; + aResult = result; + } + +const TDesC& CDataRecognitionResultArray::CItem::FileName() const + { + if (iFileName == NULL) + return KNullDesC; + else + return *iFileName; + } + + +// +// CDataRecognitionResultArray +// + +/** +Constructor +@publishedAll +@released +*/ +EXPORT_C CDataRecognitionResultArray::CDataRecognitionResultArray() + { + } + +/** +Destructor +@publishedAll +@released +*/ +EXPORT_C CDataRecognitionResultArray::~CDataRecognitionResultArray() + { + iItems.ResetAndDestroy(); + } + +/** +Returns the path of the recognition results. +@publishedAll +@released +@return The path of the recognition results +*/ +EXPORT_C const TFileName& CDataRecognitionResultArray::Path() const + { + return iPath; + } + +/** +Returns the number of entries in the CDataRecognitionResultArray. +@publishedAll +@released +@return The number of entries in the CDataRecognitionResultArray. +*/ +EXPORT_C TUint CDataRecognitionResultArray::Count() const + { + return iItems.Count(); + } + +/** +Returns the recognition result of the given index. +@publishedAll +@released +@param aResult On successful completion, this parameter contains the recognition result at the given index. +@param aIndex The index of the recognition result to be returned. An invalid index causes +the function to leave with KErrNotFound. +@return The requested TDataRecognitionResult object +@leave KErrNotFound An invalid index is passed +*/ +EXPORT_C void CDataRecognitionResultArray::GetDataRecognitionResultL(TDataRecognitionResult& aResult, const TUint aIndex) const + { + if( aIndex >= iItems.Count() ) + User::Leave(KErrNotFound); + + iItems[aIndex]->GetDataRecognitionResult(aResult); + } + +/** +Returns the file name of the object at the given index. +@publishedAll +@released +@param aFileName On successful completion, this parameter contains the file name of the object at the given index. +@param aIndex Specifies which file name to be returned. An invalid index causes +the function to leave with KErrNotFound. +@return The requested file name +@leave KErrNotFound An invalid index is passed +*/ +EXPORT_C void CDataRecognitionResultArray::GetFileNameL(TFileName& aFileName, const TUint aIndex) const + { + if( aIndex >= iItems.Count() ) + User::Leave(KErrNotFound); + + aFileName.Zero(); + aFileName.Copy( (iItems[aIndex]->FileName()) ); + } + +TUint CDataRecognitionResultArray::InternalizeL(const CBufFlat& aBuffer) + { + RBufReadStream readStream; + + readStream.Open(aBuffer); + const TInt count=readStream.ReadUint32L(); + for (TInt i=0; iDes(); + readStream.ReadL(fileNamePtr,fileNameLength); + + const TInt dataTypeLength = readStream.ReadUint8L(); + HBufC8* const dataType = HBufC8::NewLC(dataTypeLength); + TPtr8 dataTypePtr = dataType->Des(); + readStream.ReadL(dataTypePtr,dataTypeLength); + + TUid uid; + uid.iUid = readStream.ReadInt32L(); + + TInt const confidence = readStream.ReadInt32L(); + + CItem* entry = new (ELeave) CItem(fileName,dataType,uid,confidence); + iItems.Append(entry); + + CleanupStack::Pop(dataType); // ownership was transferred to "entry" + CleanupStack::Pop(fileName); // ownership was transferred to "entry" + } + + readStream.Close(); + + return KErrNone; + } + +void CDataRecognitionResultArray::SetPath(const TFileName& aPath) + { + iPath.Copy(aPath); + } + +// +//RApaLsSession +// + +/** Gets the data (MIME) type of data passed by buffer. + +@param aBuffer A buffer containing data; Provide preferred size of buffer. +If MIME type could not be recognized using this buffer, provide a buffer of +larger size. +@param aDataType On return, contains the result of the attempt to recognize +data. +@return KErrNone, if successful; otherwise one of the other system-wide error +codes. + +@see RApaLsSession::GetPreferredBufSize() +*/ +EXPORT_C TInt RApaLsSession::RecognizeData(const TDesC8& aBuffer, TDataRecognitionResult& aDataType) const + { + return RecognizeData(KNullDesC,aBuffer,aDataType); + } + +/** Gets the data (MIME) type for data taken from a file with a specified name. + +@param aName The full filename, including drive and path, of the file containing the data. +@param aBuffer A buffer containing data taken from the specified file; Provide preferred size of buffer +from beginning of the file. If MIME type could not be recognized using this buffer, provide a buffer of +larger size. +@param aDataType On return, contains the result of the attempt to recognize +data. +@return KErrNone, if successful; otherwise one of the other system-wide error +codes. + +@see RApaLsSession::GetPreferredBufSize() +*/ +EXPORT_C TInt RApaLsSession::RecognizeData(const TDesC& aName, const TDesC8& aBuffer, TDataRecognitionResult& aDataType) const + { + TPckg result(aDataType); + return SendReceiveWithReconnect(EAppListServRecognizeData,TIpcArgs(&result, &aName, &aBuffer)); + } //lint !e1764: Suppress reference parameter could be declared const ref + +/** Gets the data (MIME) type for data in a file passed by handle. + +@param aFile The file containing the data. Before this function can be called, +the file server session which owns this file handle must first be marked as shareable by +calling RFs::ShareProtected(). +@param aDataType On return, contains the result of the attempt to recognize +data. +@return KErrNone, if successful; otherwise one of the other system-wide error +codes. */ +EXPORT_C TInt RApaLsSession::RecognizeData(const RFile& aFile, TDataRecognitionResult& aDataType) const + { + TPckg result(aDataType); + TIpcArgs ipcArgs(&result); + const TInt error = aFile.TransferToServer(ipcArgs, 1, 2); + if (error) + return error; + + return SendReceiveWithReconnect(EAppListServRecognizeDataPassedByFileHandle,ipcArgs); + } //lint !e1764 Suppress reference parameter 'aDataType' could be declared const ref + + + +/** Tests whether data taken from a named file has the specified + * data (MIME) type. + +@param aName The name of the file containing the data. +@param aBuffer A buffer containing data taken from the specified file; Provide preferred size of buffer +from beginning of the file. If MIME type could not be recognized using this buffer, provide a buffer of +larger size. +@param aDataType The data (MIME) type. +@param aResult On return, contains the result of the test. +@return KErrNone, if successful; otherwise one of the other system-wide error +codes. + +@see RApaLsSession::GetPreferredBufSize() +*/ +EXPORT_C TInt RApaLsSession::RecognizeSpecificData(const TDesC& aName, const TDesC8& aBuffer, const TDataType& aDataType, TBool& aResult) const + { + const TPckgC dataType(aDataType); + const TInt returnValue=SendReceiveWithReconnect(EAppListServRecognizeSpecificData,TIpcArgs(&dataType, &aName, &aBuffer)); + if (returnValue<0) + return returnValue; + + aResult = returnValue; + return KErrNone; + } + +/** +Gets the data (MIME) type for files in a specified directory. Because this call may take a long +time to complete, the asynchronous version is strongly recommended. Furthermore, it is not possible +to use this synchronous function while an asynchronous request is still active. +@publishedAll +@released +@param aPath A valid path. Note that the path must end with a backslash. +@param aResult If the call was successful, this parameter contains the recognition result. +@return KErrNone, if successful; otherwise one of the other system-wide error codes. +*/ +EXPORT_C TInt RApaLsSession::RecognizeFilesL(const TDesC& aPath, CDataRecognitionResultArray& aResult) const + { + return RecognizeFilesL(aPath, KAllDataTypes, aResult); + } + +/** +Gets the data (MIME) type for files in a specified directory. Because this call may take a long +time to complete, the asynchronous version is strongly recommended. Furthermore, it is not possible +to use this synchronous function while an asynchronous request is still active. +@publishedAll +@released +@param aPath A valid path. Note that the path must end with a backslash. +@param aDataType A data type filter. Wildcards are allowed. For example, "text*" would also +add "text/plain" data types to the result. +@param aResult If the call was successful, this parameter contains the recognition result. +@return KErrNone, if successful; otherwise one of the other system-wide error codes. +*/ +EXPORT_C TInt RApaLsSession::RecognizeFilesL(const TDesC& aPath, const TDesC8& aDataType, CDataRecognitionResultArray& aResult) const + { + if(iExtension && iExtension->RecognitionActive()) + return KErrInUse; + + _LIT(KBackslash,"\\"); + if(aPath.Right(1) != KBackslash) + return KErrPathNotFound; + + TPckgBuf requiredBufferSizePckg; + aResult.SetPath(aPath); + TInt error = SendReceiveWithReconnect(EAppListServRecognizeFiles,TIpcArgs(&aPath,&requiredBufferSizePckg,&aDataType)); + if(!error) + error=TransferAndInternalizeDataL(aPath, requiredBufferSizePckg(), aResult); + + return error; + + } + +/** +Gets the data (MIME) type for files in a specified directory. +@publishedAll +@released +@param aPath A valid path. Note that the path must end with a backslash. +@param aResult If the call was successful, this parameter contains the recognition result. +@param aStatus A request status object. +*/ +EXPORT_C void RApaLsSession::RecognizeFilesL(const TDesC& aPath, CDataRecognitionResultArray& aResult, TRequestStatus& aStatus) + { + RecognizeFilesL(aPath,KAllDataTypes,aResult,aStatus); + } + +/** +Gets the data (MIME) type for files in a specified directory. +@publishedAll +@released +@param aPath A valid path. Note that the path must end with a backslash. +@param aDataType A data type filter. Wildcards are allowed. For example, "text*" would also +add "text/plain" data types to the result. +@param aResult If the call was successful, this parameter contains the recognition result. +@param aStatus A request status object +*/ +EXPORT_C void RApaLsSession::RecognizeFilesL(const TDesC& aPath, const TDesC8& aDataType, CDataRecognitionResultArray& aResult, TRequestStatus& aStatus) + { + if(!iExtension) + iExtension = new (ELeave) CApaLsSessionExtension(*this); + + iExtension->RecognizeFilesL(aPath, aDataType, aResult, aStatus); + } + +/** +This function transfers the data to the client-side and "fills" the CDataRecognitionResultArray object. +@internalComponent +*/ +TInt RApaLsSession::TransferAndInternalizeDataL(const TDesC& aPath, const TInt aRequiredBufferSize, CDataRecognitionResultArray& aResult) const + { + CBufFlat* const buffer = CBufFlat::NewL(aRequiredBufferSize); + CleanupStack::PushL(buffer); + buffer->ExpandL(0,aRequiredBufferSize); + TPtr8 bufPtr=buffer->Ptr(0); + + // transfer recognition buffer + TInt error = SendReceiveWithReconnect(EAppListServTransferRecognitionResult,TIpcArgs(&aPath,&bufPtr,aRequiredBufferSize)); + if(!error) + error = aResult.InternalizeL(*buffer); + + CleanupStack::PopAndDestroy(buffer); + return error; + } + +/** +Cancels any outstanding asynchronous recognition requests. +@publishedAll +@released +*/ +EXPORT_C void RApaLsSession::CancelRecognizeFiles() + { + if(iExtension) + iExtension->CancelRecognizeFiles(); + + delete iExtension; + iExtension = NULL; + } + +/** Tests whether data taken from a file passed by handle has the specified +data (MIME) type. + +@param aFile The file containing the data. Before this function can be called, +the file server session which owns this file handle must first be marked as shareable by +calling RFs::ShareProtected(). +@param aDataType The data (MIME) type. +@param aResult On return, contains the result of the test. +@return KErrNone, if successful; otherwise one of the other system-wide error +codes. */ +EXPORT_C TInt RApaLsSession::RecognizeSpecificData(const RFile& aFile, const TDataType& aDataType, TBool& aResult) const + { + const TPckgC dataType(aDataType); + TIpcArgs ipcArgs(&dataType); + TInt returnValue = aFile.TransferToServer(ipcArgs, 1, 2); + if (returnValue == KErrNone) + returnValue = SendReceiveWithReconnect(EAppListServRecognizeSpecificDataPassedByFileHandle,ipcArgs); + + if (returnValue < KErrNone) + return returnValue; + + aResult = returnValue; + return KErrNone; + } + + + +/** Gets the confidence threshold for successful data recognition. + +This is the minimum acceptable confidence level that must be reported by a +data recognizer for data to be accepted as of a given type. + +@param aConfidence On return, the confidence threshold. +@return KErrNone, if successful; otherwise one of the other system-wide error +codes. +*/ +EXPORT_C TInt RApaLsSession::GetAcceptedConfidence(TInt& aConfidence) const + { + TPckg confidence(aConfidence); + return SendReceiveWithReconnect(EAppListServGetConfidence,TIpcArgs(&confidence)); + } //lint !e1764 Suppress reference parameter could be declared const ref + + + +/** Sets the confidence threshold for successful data recognition. + +This is the minimum acceptable confidence level that must be reported by a +data recognizer for data to be accepted as of a given type. + +@param aConfidence The confidence threshold. Although this is an integer value, +data recognizers use the discrete values defined by the CApaDataRecognizerType::TRecognitionConfidence +enumeration. +@return KErrNone, if successful; otherwise one of the other system-wide error +codes. +@capability WriteDeviceData +*/ +EXPORT_C TInt RApaLsSession::SetAcceptedConfidence(TInt aConfidence) + { + return SendReceiveWithReconnect(EAppListServSetConfidence,TIpcArgs(aConfidence)); + } //lint !e1762 Suppress member function could be made const + + +/** Gets a list of recognized data(MIME) types by all recognizers. + +@param aDataTypes The array of data (MIME) types. +@return KErrNone, if successful; otherwise one of the other system-wide error +codes. +*/ +EXPORT_C TInt RApaLsSession::GetSupportedDataTypesL(CDataTypeArray& aDataTypes) const + { + // gets the datatype count in terms of buffer length; negative value means one of the system-wide error + TInt ret = SendReceiveWithReconnect(EAppListServGetDataTypesPhase1,TIpcArgs()); + if (ret>0) + { + CBufFlat* const buf=CBufFlat::NewL(ret); + CleanupStack::PushL(buf); + buf->ExpandL(0,ret); + TPtr8 ptr=buf->Ptr(0); + ret=SendReceiveWithReconnect(EAppListServGetDataTypesPhase2,TIpcArgs(&ptr)); + if (ret==KErrNone) + { + RBufReadStream readStream(*buf); + readStream >> aDataTypes; + } + + CleanupStack::PopAndDestroy(buf); + } + + return ret; + } + +