os/security/contentmgmt/contentaccessfwfordrm/source/reccaf/CafApaRecognizer.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
     1 /*
     2 * Copyright (c) 2003-2010 Nokia Corporation and/or its subsidiary(-ies).
     3 * All rights reserved.
     4 * This component and the accompanying materials are made available
     5 * under the terms of the License "Eclipse Public License v1.0"
     6 * which accompanies this distribution, and is available
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
     8 *
     9 * Initial Contributors:
    10 * Nokia Corporation - initial contribution.
    11 *
    12 * Contributors:
    13 *
    14 * Description: 
    15 *
    16 */
    17 
    18 
    19 #include <s32file.h>
    20 #include <ecom/ecom.h>
    21 #include <ecom/implementationproxy.h>
    22 
    23 #include "resolver.h"
    24 #include "mimetypemapping.h"
    25 #include "CafApaRecognizer.h"
    26 
    27 using namespace ContentAccess;
    28 
    29 
    30 CApaCafRecognizer* CApaCafRecognizer::NewL()
    31 	{
    32 	CApaCafRecognizer* self;
    33 	self = new (ELeave) CApaCafRecognizer();
    34 	CleanupStack::PushL(self);
    35 	self->ConstructL();
    36 	CleanupStack::Pop(self);
    37 	return self;
    38 	}
    39 
    40 void CApaCafRecognizer::ConstructL()
    41 	{
    42 	iResolver = CAgentResolver::NewL(ETrue);
    43 	SetupContentTypesL();
    44 	}
    45 
    46 CApaCafRecognizer::CApaCafRecognizer() : 
    47 	CApaDataRecognizerType(KUidCafApaRecognizer, CApaDataRecognizerType::ELow)
    48 	{
    49 	// Assume initially we don't recognize any data types (ie. no agents)
    50 	iCountDataTypes = 0;
    51 	}
    52 
    53 CApaCafRecognizer::~CApaCafRecognizer()
    54 	{
    55 	iContentTypes.ResetAndDestroy();
    56 	delete iResolver;
    57 	}
    58 
    59 void CApaCafRecognizer::SetupContentTypesL()
    60 	{
    61 	// Construct the array used to map content types to our drm mime types
    62 	CMimeTypeMapping* mimeType; 
    63 
    64 	// The RecCaf configuration file is just a list of content mime types
    65 	// CApaCafRecognizer expects each mime type to be on a separate line
    66 	// The configuration file is stored in the Apparc server's private directory.
    67 	// This should be ok since the recognizer is run in the apparc servers process
    68 	
    69 	// ROM file
    70 	_LIT(KRomConfigurationFile, "Z:\\private\\10003A3F\\RecCaf\\RecCafMimeTypes.txt");
    71 
    72 	// System drive file	
    73 	_LIT(KConfigurationFile, "_:\\private\\10003A3F\\RecCaf\\RecCafMimeTypes.txt");
    74 	TBuf<47> sysDriveConfigFile(KConfigurationFile);
    75 	sysDriveConfigFile[0] = 'A' + static_cast<TInt>(RFs::GetSystemDrive());
    76 
    77 	RFs fs;
    78 	User::LeaveIfError(fs.Connect());
    79 	CleanupClosePushL(fs);
    80 
    81 	RFile file;
    82 	TInt result = file.Open(fs, sysDriveConfigFile, EFileRead | EFileStream | EFileShareAny);
    83 	if (result != KErrNone)
    84 		{
    85 		result = file.Open(fs, KRomConfigurationFile(), EFileRead | EFileStream | EFileShareAny);
    86 		}
    87 
    88 	if (result == KErrNone)
    89 		{
    90 		CleanupClosePushL(file);
    91 		
    92 		// create file stream
    93 		RFileReadStream inputFileStream(file);
    94 	    CleanupClosePushL(inputFileStream);
    95 
    96 		TBuf8 <KMaxDataTypeLength> buf;
    97 
    98 		do
    99 			{
   100 			// Read a content mime type from the file
   101 			result = ReadLine(inputFileStream, buf);
   102 
   103 			if (result == KErrNone || result == KErrEof)
   104 				{
   105 				// Add a new entry into the array of mime types
   106 				if (buf.Length())
   107 					{
   108 					// force to lower case to ensure that chosen lower case scheme for mime
   109 					// types is maintained
   110 					buf.LowerCase();
   111 					mimeType = CMimeTypeMapping::NewL(buf);
   112 					CleanupStack::PushL(mimeType);
   113 					User::LeaveIfError(iContentTypes.Append(mimeType));
   114 					CleanupStack::Pop(mimeType); 
   115 					}
   116 				}
   117 			else
   118 				{
   119 				// Encountered an error reading the file
   120 				// don't know how to recover so leave
   121 				iContentTypes.ResetAndDestroy();
   122 				User::Leave(result);
   123 				}
   124 			} while (result != KErrEof);
   125 
   126 		CleanupStack::PopAndDestroy(2, &file); // inputFileStream, file
   127 		}
   128 
   129 	CleanupStack::PopAndDestroy(&fs);
   130 
   131 	// Add multiple content object file mime type
   132 	_LIT8(KApplicationXCafStr, "application/x-caf");
   133 	mimeType = CMimeTypeMapping::NewL(KApplicationXCafStr());
   134 	CleanupStack::PushL(mimeType);
   135 	User::LeaveIfError(iContentTypes.Append(mimeType));
   136 	CleanupStack::Pop(mimeType); 
   137 
   138 
   139 	// Add supplier Mime types 
   140 	// otherwise nobody will recognize unprocessed files 
   141 	// that could be churned through the CAF Supplier API
   142 	// The resolver ensures that its supplier mime types are lower case
   143 	for(TInt index = 0; index < iResolver->SupplierMimeTypes().Count(); index++)
   144 		{
   145 		mimeType = CMimeTypeMapping::NewL(iResolver->SupplierMimeTypes()[index],
   146 										  iResolver->SupplierMimeTypes()[index]);
   147 		CleanupStack::PushL(mimeType);
   148 		User::LeaveIfError(iContentTypes.Append(mimeType));
   149 		CleanupStack::Pop(mimeType); 
   150 		}
   151 	
   152 	iCountDataTypes = iContentTypes.Count();
   153 	}
   154 
   155 TInt CApaCafRecognizer::ReadLine(RFileReadStream& aInStream, TDes8& aBuffer)
   156 	{
   157 	const TChar KCarriageReturn = '\r';
   158 	const TChar KLineFeed = '\n';
   159 
   160 	// Clear the buffer
   161 	aBuffer.SetLength(0);
   162 	
   163 	// Read line upto linefeed delimiter
   164 	TRAPD(err, aInStream.ReadL(aBuffer, KLineFeed));
   165 	TInt length = aBuffer.Length();
   166 	
   167 	// assume all lines must end in CRLF and do not 
   168 	// allow blank lines. So length must be at least 2 for
   169 	// the CRLF characters
   170 	if(length < 3)
   171 		{
   172 		err = KErrEof;
   173 		}
   174 	if (err == KErrNone)
   175 		{
   176 		// remove line feed and any carriage return 
   177 		if (aBuffer[length - 1] == KLineFeed)
   178 			{
   179 			--length;
   180 			}
   181 		if (aBuffer[length - 1] == KCarriageReturn)
   182 			{
   183 			--length;
   184 			}
   185 		aBuffer.SetLength(length);
   186 		}
   187 	return err;
   188 	}
   189 
   190 
   191 TUint CApaCafRecognizer::PreferredBufSize()
   192 	{
   193 	// Ask all of the agents if they have a preferred buffer size for calls to DoRecognizeL()
   194 	return iResolver->PreferredBufferSize();
   195 	}
   196 
   197 TDataType CApaCafRecognizer::SupportedDataTypeL(TInt aIndex) const
   198 	{
   199 	// leave if an out of range aIndex is supplied
   200 	if (aIndex < 0 || aIndex >= iContentTypes.Count())
   201 		{
   202 		User::Leave(KErrArgument);
   203 		}
   204 
   205 	return TDataType(iContentTypes[aIndex]->CafMimeType());
   206 	}
   207 	
   208 void CApaCafRecognizer::DoRecognizeL(const TDesC& aName, const TDesC8& aBuffer)
   209 	{
   210 	TBuf8 <KMaxDataTypeLength> FileMimeType;
   211 	TBuf8 <KMaxDataTypeLength> ContentMimeType;
   212 	
   213 	// Need to start by assuming we don't recognize the file
   214 	iConfidence = ENotRecognized;
   215 	
   216 	TBool isRecognized = EFalse;
   217 	
   218 	// If aName is prepended with 2 colons (::), then it is not valid, and we need to
   219 	// derive it from the file handle. Otherwise, we assume that aName is valid
   220 	if (aName.Match(_L("::*")) == KErrNotFound)
   221 		{
   222 		isRecognized = iResolver->DoRecognizeL(aName, aBuffer, FileMimeType, ContentMimeType);
   223 		}
   224 	// aName is not a valid URI/filename and a file handle must be used. This is marked
   225 	// by two colons at the start of aName.
   226 	// We need to get the actual file name from the file handle.
   227 	else 
   228 		{
   229 		RFile* fileHandle = CApaCafRecognizer::FilePassedByHandleL();
   230 		
   231 		if( fileHandle == NULL )
   232 		{
   233 			return;
   234 		}
   235 
   236 		TBuf<KMaxDataTypeLength> fileName;
   237 		User::LeaveIfError(fileHandle->Name(fileName));
   238 		isRecognized = iResolver->DoRecognizeL(fileName, aBuffer, FileMimeType, ContentMimeType);
   239 		}
   240 	
   241 	if (isRecognized == EFalse)
   242 	{
   243 		return;
   244 	}
   245 
   246 
   247 	// If there is no content type but the file is recognized it is assumed
   248 	// to be a file that can be processed through the supplier interface
   249 		
   250 	// dummy object for comparison in match function
   251 	CMimeTypeMapping* mimeTypeMapping = (ContentMimeType.Length() == 0) ?  
   252 										 CMimeTypeMapping::NewL(FileMimeType) :
   253 										 CMimeTypeMapping::NewL(ContentMimeType);
   254 
   255 
   256 	// check that the content mime type is one of the ones we
   257 	// told Apparc we can recognize in the beginning
   258 	// The mime type should always be found as the file has been recognised.
   259 	// If not it is because an agent, when recognising the file, has set a mime type not in its supplier list.
   260 	// Mime types are always forced to lower case therefore this match can be case sensitive.
   261 	TInt index = iContentTypes.Find(mimeTypeMapping, CMimeTypeMapping::ContentMimeTypeMatch);
   262 	if (index != KErrNotFound)
   263 	{
   264 	    iDataType = TDataType(iContentTypes[index]->CafMimeType());
   265 		iConfidence=ECertain;
   266 	}
   267 
   268 	delete mimeTypeMapping;
   269 	}
   270 
   271 const TImplementationProxy ImplementationTable[] = 
   272 	{
   273 	IMPLEMENTATION_PROXY_ENTRY(0x102031E9, CApaCafRecognizer::NewL)
   274 	};
   275 
   276 EXPORT_C const TImplementationProxy* ImplementationGroupProxy(TInt& aTableCount)
   277 	{
   278 	aTableCount = sizeof(ImplementationTable) / sizeof(TImplementationProxy);
   279 	return ImplementationTable;
   280 	}	
   281 
   282