contentmgmt/contentaccessfwfordrm/source/reccaf/CafApaRecognizer.cpp
changeset 0 2c201484c85f
child 8 35751d3474b7
equal deleted inserted replaced
-1:000000000000 0:2c201484c85f
       
     1 /*
       
     2 * Copyright (c) 2003-2009 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 		TBuf<KMaxDataTypeLength> fileName;
       
   231 		User::LeaveIfError(fileHandle->Name(fileName));
       
   232 		isRecognized = iResolver->DoRecognizeL(fileName, aBuffer, FileMimeType, ContentMimeType);
       
   233 		}
       
   234 	
       
   235 	if (isRecognized)
       
   236 		{
       
   237 		// If there is no content type but the file is recognized it is assumed
       
   238 		// to be a file that can be processed through the supplier interface
       
   239 		
       
   240 		// dummy object for comparison in match function
       
   241 		CMimeTypeMapping* mimeTypeMapping = (ContentMimeType.Length() == 0) ?  
       
   242 												CMimeTypeMapping::NewL(FileMimeType) :
       
   243 												CMimeTypeMapping::NewL(ContentMimeType);
       
   244 
       
   245 
       
   246 		// check that the content mime type is one of the ones we
       
   247 		// told Apparc we can recognize in the beginning
       
   248 		// The mime type should always be found as the file has been recognised.
       
   249 		// If not it is because an agent, when recognising the file, has set a mime type not in its supplier list.
       
   250 		// Mime types are always forced to lower case therefore this match can be case sensitive.
       
   251 		TInt index = iContentTypes.Find(mimeTypeMapping, CMimeTypeMapping::ContentMimeTypeMatch);
       
   252 		if (index != KErrNotFound)
       
   253 			{
       
   254 			iDataType = TDataType(iContentTypes[index]->CafMimeType());
       
   255 			iConfidence=ECertain;
       
   256 			}
       
   257 
       
   258 		delete mimeTypeMapping;
       
   259 		}
       
   260 	}
       
   261 
       
   262 const TImplementationProxy ImplementationTable[] = 
       
   263 	{
       
   264 	IMPLEMENTATION_PROXY_ENTRY(0x102031E9, CApaCafRecognizer::NewL)
       
   265 	};
       
   266 
       
   267 EXPORT_C const TImplementationProxy* ImplementationGroupProxy(TInt& aTableCount)
       
   268 	{
       
   269 	aTableCount = sizeof(ImplementationTable) / sizeof(TImplementationProxy);
       
   270 	return ImplementationTable;
       
   271 	}