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