First public contribution.
2 * Copyright (c) 2003-2010 Nokia Corporation and/or its subsidiary(-ies).
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".
9 * Initial Contributors:
10 * Nokia Corporation - initial contribution.
20 #include <ecom/ecom.h>
21 #include <ecom/implementationproxy.h>
24 #include "mimetypemapping.h"
25 #include "CafApaRecognizer.h"
27 using namespace ContentAccess;
30 CApaCafRecognizer* CApaCafRecognizer::NewL()
32 CApaCafRecognizer* self;
33 self = new (ELeave) CApaCafRecognizer();
34 CleanupStack::PushL(self);
36 CleanupStack::Pop(self);
40 void CApaCafRecognizer::ConstructL()
42 iResolver = CAgentResolver::NewL(ETrue);
46 CApaCafRecognizer::CApaCafRecognizer() :
47 CApaDataRecognizerType(KUidCafApaRecognizer, CApaDataRecognizerType::ELow)
49 // Assume initially we don't recognize any data types (ie. no agents)
53 CApaCafRecognizer::~CApaCafRecognizer()
55 iContentTypes.ResetAndDestroy();
59 void CApaCafRecognizer::SetupContentTypesL()
61 // Construct the array used to map content types to our drm mime types
62 CMimeTypeMapping* mimeType;
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
70 _LIT(KRomConfigurationFile, "Z:\\private\\10003A3F\\RecCaf\\RecCafMimeTypes.txt");
73 _LIT(KConfigurationFile, "_:\\private\\10003A3F\\RecCaf\\RecCafMimeTypes.txt");
74 TBuf<47> sysDriveConfigFile(KConfigurationFile);
75 sysDriveConfigFile[0] = 'A' + static_cast<TInt>(RFs::GetSystemDrive());
78 User::LeaveIfError(fs.Connect());
79 CleanupClosePushL(fs);
82 TInt result = file.Open(fs, sysDriveConfigFile, EFileRead | EFileStream | EFileShareAny);
83 if (result != KErrNone)
85 result = file.Open(fs, KRomConfigurationFile(), EFileRead | EFileStream | EFileShareAny);
88 if (result == KErrNone)
90 CleanupClosePushL(file);
93 RFileReadStream inputFileStream(file);
94 CleanupClosePushL(inputFileStream);
96 TBuf8 <KMaxDataTypeLength> buf;
100 // Read a content mime type from the file
101 result = ReadLine(inputFileStream, buf);
103 if (result == KErrNone || result == KErrEof)
105 // Add a new entry into the array of mime types
108 // force to lower case to ensure that chosen lower case scheme for mime
109 // types is maintained
111 mimeType = CMimeTypeMapping::NewL(buf);
112 CleanupStack::PushL(mimeType);
113 User::LeaveIfError(iContentTypes.Append(mimeType));
114 CleanupStack::Pop(mimeType);
119 // Encountered an error reading the file
120 // don't know how to recover so leave
121 iContentTypes.ResetAndDestroy();
124 } while (result != KErrEof);
126 CleanupStack::PopAndDestroy(2, &file); // inputFileStream, file
129 CleanupStack::PopAndDestroy(&fs);
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);
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++)
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);
152 iCountDataTypes = iContentTypes.Count();
155 TInt CApaCafRecognizer::ReadLine(RFileReadStream& aInStream, TDes8& aBuffer)
157 const TChar KCarriageReturn = '\r';
158 const TChar KLineFeed = '\n';
161 aBuffer.SetLength(0);
163 // Read line upto linefeed delimiter
164 TRAPD(err, aInStream.ReadL(aBuffer, KLineFeed));
165 TInt length = aBuffer.Length();
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
176 // remove line feed and any carriage return
177 if (aBuffer[length - 1] == KLineFeed)
181 if (aBuffer[length - 1] == KCarriageReturn)
185 aBuffer.SetLength(length);
191 TUint CApaCafRecognizer::PreferredBufSize()
193 // Ask all of the agents if they have a preferred buffer size for calls to DoRecognizeL()
194 return iResolver->PreferredBufferSize();
197 TDataType CApaCafRecognizer::SupportedDataTypeL(TInt aIndex) const
199 // leave if an out of range aIndex is supplied
200 if (aIndex < 0 || aIndex >= iContentTypes.Count())
202 User::Leave(KErrArgument);
205 return TDataType(iContentTypes[aIndex]->CafMimeType());
208 void CApaCafRecognizer::DoRecognizeL(const TDesC& aName, const TDesC8& aBuffer)
210 TBuf8 <KMaxDataTypeLength> FileMimeType;
211 TBuf8 <KMaxDataTypeLength> ContentMimeType;
213 // Need to start by assuming we don't recognize the file
214 iConfidence = ENotRecognized;
216 TBool isRecognized = EFalse;
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)
222 isRecognized = iResolver->DoRecognizeL(aName, aBuffer, FileMimeType, ContentMimeType);
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.
229 RFile* fileHandle = CApaCafRecognizer::FilePassedByHandleL();
231 if( fileHandle == NULL )
236 TBuf<KMaxDataTypeLength> fileName;
237 User::LeaveIfError(fileHandle->Name(fileName));
238 isRecognized = iResolver->DoRecognizeL(fileName, aBuffer, FileMimeType, ContentMimeType);
241 if (isRecognized == EFalse)
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
250 // dummy object for comparison in match function
251 CMimeTypeMapping* mimeTypeMapping = (ContentMimeType.Length() == 0) ?
252 CMimeTypeMapping::NewL(FileMimeType) :
253 CMimeTypeMapping::NewL(ContentMimeType);
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)
264 iDataType = TDataType(iContentTypes[index]->CafMimeType());
265 iConfidence=ECertain;
268 delete mimeTypeMapping;
271 const TImplementationProxy ImplementationTable[] =
273 IMPLEMENTATION_PROXY_ENTRY(0x102031E9, CApaCafRecognizer::NewL)
276 EXPORT_C const TImplementationProxy* ImplementationGroupProxy(TInt& aTableCount)
278 aTableCount = sizeof(ImplementationTable) / sizeof(TImplementationProxy);
279 return ImplementationTable;