diff -r 000000000000 -r 2c201484c85f contentmgmt/contentaccessfwfordrm/source/reccaf/CafApaRecognizer.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/contentmgmt/contentaccessfwfordrm/source/reccaf/CafApaRecognizer.cpp Wed Jul 08 11:25:26 2009 +0100 @@ -0,0 +1,271 @@ +/* +* Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* +*/ + + +#include +#include +#include + +#include "resolver.h" +#include "mimetypemapping.h" +#include "CafApaRecognizer.h" + +using namespace ContentAccess; + + +CApaCafRecognizer* CApaCafRecognizer::NewL() + { + CApaCafRecognizer* self; + self = new (ELeave) CApaCafRecognizer(); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + return self; + } + +void CApaCafRecognizer::ConstructL() + { + iResolver = CAgentResolver::NewL(ETrue); + SetupContentTypesL(); + } + +CApaCafRecognizer::CApaCafRecognizer() : + CApaDataRecognizerType(KUidCafApaRecognizer, CApaDataRecognizerType::ELow) + { + // Assume initially we don't recognize any data types (ie. no agents) + iCountDataTypes = 0; + } + +CApaCafRecognizer::~CApaCafRecognizer() + { + iContentTypes.ResetAndDestroy(); + delete iResolver; + } + +void CApaCafRecognizer::SetupContentTypesL() + { + // Construct the array used to map content types to our drm mime types + CMimeTypeMapping* mimeType; + + // The RecCaf configuration file is just a list of content mime types + // CApaCafRecognizer expects each mime type to be on a separate line + // The configuration file is stored in the Apparc server's private directory. + // This should be ok since the recognizer is run in the apparc servers process + + // ROM file + _LIT(KRomConfigurationFile, "Z:\\private\\10003A3F\\RecCaf\\RecCafMimeTypes.txt"); + + // System drive file + _LIT(KConfigurationFile, "_:\\private\\10003A3F\\RecCaf\\RecCafMimeTypes.txt"); + TBuf<47> sysDriveConfigFile(KConfigurationFile); + sysDriveConfigFile[0] = 'A' + static_cast(RFs::GetSystemDrive()); + + RFs fs; + User::LeaveIfError(fs.Connect()); + CleanupClosePushL(fs); + + RFile file; + TInt result = file.Open(fs, sysDriveConfigFile, EFileRead | EFileStream | EFileShareAny); + if (result != KErrNone) + { + result = file.Open(fs, KRomConfigurationFile(), EFileRead | EFileStream | EFileShareAny); + } + + if (result == KErrNone) + { + CleanupClosePushL(file); + + // create file stream + RFileReadStream inputFileStream(file); + CleanupClosePushL(inputFileStream); + + TBuf8 buf; + + do + { + // Read a content mime type from the file + result = ReadLine(inputFileStream, buf); + + if (result == KErrNone || result == KErrEof) + { + // Add a new entry into the array of mime types + if (buf.Length()) + { + // force to lower case to ensure that chosen lower case scheme for mime + // types is maintained + buf.LowerCase(); + mimeType = CMimeTypeMapping::NewL(buf); + CleanupStack::PushL(mimeType); + User::LeaveIfError(iContentTypes.Append(mimeType)); + CleanupStack::Pop(mimeType); + } + } + else + { + // Encountered an error reading the file + // don't know how to recover so leave + iContentTypes.ResetAndDestroy(); + User::Leave(result); + } + } while (result != KErrEof); + + CleanupStack::PopAndDestroy(2, &file); // inputFileStream, file + } + + CleanupStack::PopAndDestroy(&fs); + + // Add multiple content object file mime type + _LIT8(KApplicationXCafStr, "application/x-caf"); + mimeType = CMimeTypeMapping::NewL(KApplicationXCafStr()); + CleanupStack::PushL(mimeType); + User::LeaveIfError(iContentTypes.Append(mimeType)); + CleanupStack::Pop(mimeType); + + + // Add supplier Mime types + // otherwise nobody will recognize unprocessed files + // that could be churned through the CAF Supplier API + // The resolver ensures that its supplier mime types are lower case + for(TInt index = 0; index < iResolver->SupplierMimeTypes().Count(); index++) + { + mimeType = CMimeTypeMapping::NewL(iResolver->SupplierMimeTypes()[index], + iResolver->SupplierMimeTypes()[index]); + CleanupStack::PushL(mimeType); + User::LeaveIfError(iContentTypes.Append(mimeType)); + CleanupStack::Pop(mimeType); + } + + iCountDataTypes = iContentTypes.Count(); + } + +TInt CApaCafRecognizer::ReadLine(RFileReadStream& aInStream, TDes8& aBuffer) + { + const TChar KCarriageReturn = '\r'; + const TChar KLineFeed = '\n'; + + // Clear the buffer + aBuffer.SetLength(0); + + // Read line upto linefeed delimiter + TRAPD(err, aInStream.ReadL(aBuffer, KLineFeed)); + TInt length = aBuffer.Length(); + + // assume all lines must end in CRLF and do not + // allow blank lines. So length must be at least 2 for + // the CRLF characters + if(length < 3) + { + err = KErrEof; + } + if (err == KErrNone) + { + // remove line feed and any carriage return + if (aBuffer[length - 1] == KLineFeed) + { + --length; + } + if (aBuffer[length - 1] == KCarriageReturn) + { + --length; + } + aBuffer.SetLength(length); + } + return err; + } + + +TUint CApaCafRecognizer::PreferredBufSize() + { + // Ask all of the agents if they have a preferred buffer size for calls to DoRecognizeL() + return iResolver->PreferredBufferSize(); + } + +TDataType CApaCafRecognizer::SupportedDataTypeL(TInt aIndex) const + { + // leave if an out of range aIndex is supplied + if (aIndex < 0 || aIndex >= iContentTypes.Count()) + { + User::Leave(KErrArgument); + } + + return TDataType(iContentTypes[aIndex]->CafMimeType()); + } + +void CApaCafRecognizer::DoRecognizeL(const TDesC& aName, const TDesC8& aBuffer) + { + TBuf8 FileMimeType; + TBuf8 ContentMimeType; + + // Need to start by assuming we don't recognize the file + iConfidence = ENotRecognized; + + TBool isRecognized = EFalse; + + // If aName is prepended with 2 colons (::), then it is not valid, and we need to + // derive it from the file handle. Otherwise, we assume that aName is valid + if (aName.Match(_L("::*")) == KErrNotFound) + { + isRecognized = iResolver->DoRecognizeL(aName, aBuffer, FileMimeType, ContentMimeType); + } + // aName is not a valid URI/filename and a file handle must be used. This is marked + // by two colons at the start of aName. + // We need to get the actual file name from the file handle. + else + { + RFile* fileHandle = CApaCafRecognizer::FilePassedByHandleL(); + TBuf fileName; + User::LeaveIfError(fileHandle->Name(fileName)); + isRecognized = iResolver->DoRecognizeL(fileName, aBuffer, FileMimeType, ContentMimeType); + } + + if (isRecognized) + { + // If there is no content type but the file is recognized it is assumed + // to be a file that can be processed through the supplier interface + + // dummy object for comparison in match function + CMimeTypeMapping* mimeTypeMapping = (ContentMimeType.Length() == 0) ? + CMimeTypeMapping::NewL(FileMimeType) : + CMimeTypeMapping::NewL(ContentMimeType); + + + // check that the content mime type is one of the ones we + // told Apparc we can recognize in the beginning + // The mime type should always be found as the file has been recognised. + // If not it is because an agent, when recognising the file, has set a mime type not in its supplier list. + // Mime types are always forced to lower case therefore this match can be case sensitive. + TInt index = iContentTypes.Find(mimeTypeMapping, CMimeTypeMapping::ContentMimeTypeMatch); + if (index != KErrNotFound) + { + iDataType = TDataType(iContentTypes[index]->CafMimeType()); + iConfidence=ECertain; + } + + delete mimeTypeMapping; + } + } + +const TImplementationProxy ImplementationTable[] = + { + IMPLEMENTATION_PROXY_ENTRY(0x102031E9, CApaCafRecognizer::NewL) + }; + +EXPORT_C const TImplementationProxy* ImplementationGroupProxy(TInt& aTableCount) + { + aTableCount = sizeof(ImplementationTable) / sizeof(TImplementationProxy); + return ImplementationTable; + }