--- /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 <s32file.h>
+#include <ecom/ecom.h>
+#include <ecom/implementationproxy.h>
+
+#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<TInt>(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 <KMaxDataTypeLength> 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 <KMaxDataTypeLength> FileMimeType;
+ TBuf8 <KMaxDataTypeLength> 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<KMaxDataTypeLength> 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;
+ }