imagingandcamerafws/imagingfws/ImageDisplay/src/ImageDisplayRecognizer.cpp
changeset 0 40261b775718
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/imagingandcamerafws/imagingfws/ImageDisplay/src/ImageDisplayRecognizer.cpp	Tue Feb 02 01:56:55 2010 +0200
@@ -0,0 +1,312 @@
+// Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "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:
+//
+
+/**    @file
+   @internalComponent */
+#include "ImageDisplayFramework.h"
+
+#include "ImageDisplay.hrh"
+#include "../../src/ImageUtils.h"
+#include "ImageDisplayResolvrUtils.h"
+
+#include "ImageDisplayRecognizer.h"
+
+NONSHARABLE_CLASS( CImgDisplayMimeTypeRecognizer::CBody) : public CActive
+   	{
+public:
+   	static CBody* NewL();
+   	~CBody();
+   	TBool GetTypeByFileDataL(const TDesC8& aImageData, TDes8& aMimeType);
+   	TBool GetTypeByFileNameL(const TDesC& aFileName, TDes8& aMimeType);
+   	void GetFileTypesL(RFileExtensionMIMETypeArray& aExtArray);
+
+protected:
+
+	//from CActive
+	virtual void DoCancel();
+	virtual void RunL();
+private:
+	CBody();
+	void ConstructL();
+	void StartNotification();
+	void BuildPluginListL();
+
+private:
+   	/** an array of pointers to CImplementationInformation objects */
+   	RImplInfoPtrArray iPluginArray;
+   	/** for opening a session to the ECom server */
+   	REComSession iEcomSession;
+    /** used when creating decoders */
+    RFs iFs;
+	};
+
+/**
+ 	object factory function
+ 	@return class instance pointer
+*/
+EXPORT_C CImgDisplayMimeTypeRecognizer* CImgDisplayMimeTypeRecognizer::NewL()
+	{
+	CImgDisplayMimeTypeRecognizer* self=new (ELeave) CImgDisplayMimeTypeRecognizer();
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop(self);
+	return self;
+	}
+	
+CImgDisplayMimeTypeRecognizer::CImgDisplayMimeTypeRecognizer()
+	{
+	}
+	
+/**
+	destructor
+*/
+CImgDisplayMimeTypeRecognizer::~CImgDisplayMimeTypeRecognizer()
+	{
+	delete iBody;
+	}
+	
+void CImgDisplayMimeTypeRecognizer::ConstructL()
+	{
+	iBody = CBody::NewL();
+	}
+	
+/**
+	@param aExtArray array that will be filled with supported file extension information. Information is appended to existing array.
+*/
+EXPORT_C void CImgDisplayMimeTypeRecognizer::GetFileTypesL(RFileExtensionMIMETypeArray& aExtArray)
+	{
+	iBody->GetFileTypesL(aExtArray);
+	}
+	
+/**
+	determines Mime type by using filename and its content
+	@param aImageData file data
+	@param aFileName  file name
+	@param aMimeType reference to a buffer that would be given mime type value upon successfull recognition
+	@return ETrue if Mime type has been recognized
+*/
+EXPORT_C TBool CImgDisplayMimeTypeRecognizer::GetMimeTypeL(const TDesC8& aImageData, const TDesC& aFileName, TDes8& aMimeType)
+	{
+	TBool gotType=EFalse;
+	aMimeType.SetLength(0);
+	if (aImageData.Length()!=0)
+		{
+		gotType=iBody->GetTypeByFileDataL(aImageData, aMimeType);
+		}
+	if (!gotType && aFileName.Length()!=0)
+		{
+		gotType=iBody->GetTypeByFileNameL(aFileName, aMimeType);
+		}
+	return gotType;
+	}
+	
+CImgDisplayMimeTypeRecognizer::CBody* CImgDisplayMimeTypeRecognizer::CBody::NewL()
+	{
+	CImgDisplayMimeTypeRecognizer::CBody* self=new (ELeave) CImgDisplayMimeTypeRecognizer::CBody();
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+CImgDisplayMimeTypeRecognizer::CBody::CBody():
+	CActive(CActive::EPriorityStandard)
+	{
+	}
+
+CImgDisplayMimeTypeRecognizer::CBody::~CBody()
+	{
+	Cancel();
+	iEcomSession.Close();
+	iFs.Close();
+	iPluginArray.ResetAndDestroy();
+	}
+
+// Request ECom to be notified when interface implementation registration 
+// data changes so that we can refresh the list of interface implementations.
+void CImgDisplayMimeTypeRecognizer::CBody::StartNotification()
+	{
+	iEcomSession.NotifyOnChange(iStatus);
+	SetActive();
+	}
+
+// build a list of interface implementation objects
+void CImgDisplayMimeTypeRecognizer::CBody::BuildPluginListL()
+	{
+	iPluginArray.ResetAndDestroy();
+	REComSession::ListImplementationsL(
+		TUid::Uid(KUidDisplayInterface), 
+		iPluginArray);
+	}
+
+inline
+TBool IsExtAlreadyAdded(const RFileExtensionMIMETypeArray& aExtArray, const TDesC8& aExt)
+	{
+	TFileName extU;
+	extU.Copy(aExt);
+	for (TInt i=aExtArray.Count(); i--;)
+		{
+		const TDesC& ext=(*aExtArray[i]).FileExtension();
+		if (ext.Length()==extU.Length() && extU.CompareF(ext)==0)
+			{
+			return ETrue;
+			}
+		}
+	return EFalse;
+	}
+	
+inline
+TBool IsMimeAlreadyAdded(const RFileExtensionMIMETypeArray& aExtArray, const TDesC8& aMime)
+	{
+	for (TInt i=aExtArray.Count(); i--;)
+		{
+		const TDesC8& mime=(*aExtArray[i]).MIMEType();
+		if (mime.Length()==aMime.Length() &&  aMime.CompareF(mime)==0)
+			{
+			return ETrue;
+			}
+		}
+	return EFalse;
+	}
+
+void CImgDisplayMimeTypeRecognizer::CBody::GetFileTypesL(RFileExtensionMIMETypeArray& aExtArray)
+	{
+	for (TInt i=iPluginArray.Count(); i--;)
+		{
+		const CImplementationInformation& impData = *(iPluginArray[i]);
+		COpaqueDataParse* parse = COpaqueDataParse::NewLC(impData.OpaqueData());
+
+		parse->EnsureMIMETypesReadL();
+		
+		if (parse->MIMEType(0).Length() && !IsMimeAlreadyAdded(aExtArray, parse->MIMEType(0)))
+			{
+			parse->EnsureExtnsReadL();
+			for (TInt extN=parse->ExtnsCount(); extN--;)
+				{
+				if (parse->Extn(extN).Length()==0 || IsExtAlreadyAdded(aExtArray, parse->Extn(extN)))
+					{
+					continue;
+					}
+				CFileExtensionMIMEType* ext=CFileExtensionMIMEType::NewLC(
+												parse->Extn(extN),
+												parse->MIMEType(0), // we always use the FIRST MIME type
+												impData.DisplayName(),
+												parse->ImageTypeUid(),
+												parse->ImageSubTypeUid(),
+												impData.ImplementationUid()
+											);
+				User::LeaveIfError( aExtArray.Append(ext) );
+				CleanupStack::Pop(ext);
+				}
+			}
+		CleanupStack::PopAndDestroy(parse);
+		}
+	}
+
+void CImgDisplayMimeTypeRecognizer::CBody::ConstructL()
+	{
+	BuildPluginListL();
+	CActiveScheduler::Add(this);
+	User::LeaveIfError(iFs.Connect());
+    iEcomSession = REComSession::OpenL();
+	// request notification from ECOM of any file system changes
+	StartNotification();
+	}
+
+void CImgDisplayMimeTypeRecognizer::CBody::RunL()
+	{
+	BuildPluginListL();
+	StartNotification();
+	}
+
+void CImgDisplayMimeTypeRecognizer::CBody::DoCancel()
+	{
+	if (iStatus == KRequestPending)
+		{
+		iEcomSession.CancelNotifyOnChange(iStatus);
+		}
+	}
+
+TBool CImgDisplayMimeTypeRecognizer::CBody::GetTypeByFileNameL(
+	const TDesC& aFileName,
+	TDes8& aMimeType)
+	{
+	aMimeType.SetLength(0);
+	TParse fileName;
+	fileName.Set(aFileName,NULL,NULL);
+
+	//No file extension
+	if (!fileName.ExtPresent())	
+		{
+		return EFalse;
+		}
+	const TPtrC suffix(fileName.Ext());
+		
+	for (TInt i=iPluginArray.Count(); i--;)
+		{
+		const CImplementationInformation& impData = *(iPluginArray[i]);
+		COpaqueDataParse* parse = COpaqueDataParse::NewLC(impData.OpaqueData());
+		parse->EnsureExtnsReadL();
+		TFileName ext;
+		TBool match=EFalse;
+		for (TInt extN=0; !match && extN<parse->ExtnsCount(); ++extN)
+			{
+			ext.Copy(parse->Extn(extN));
+			match=(ext.Length()==suffix.Length() && ext.CompareF(suffix)==0);
+			}
+		if (match)
+			{			
+			parse->EnsureMIMETypesReadL();
+			aMimeType.Copy(parse->MIMEType(0)); // we always use the FIRST MIME type
+			}
+		CleanupStack::PopAndDestroy(parse);
+		if (match)
+			{
+			return ETrue;
+			}
+		}
+	return EFalse;
+	}
+
+TBool CImgDisplayMimeTypeRecognizer::CBody::GetTypeByFileDataL(const TDesC8& aImageData, TDes8& aMimeType)
+	{
+	aMimeType.SetLength(0);
+	for (TInt i=iPluginArray.Count(); i--;)
+		{
+		const CImplementationInformation& impData = *(iPluginArray[i]);
+		TInt bytesMatched=0;
+		TBool match=CImageDisplayResolverUtils::Match(aImageData, impData.DataType(), bytesMatched);
+		if (match && bytesMatched==impData.DataType().Length())
+			{
+			COpaqueDataParse* parse = COpaqueDataParse::NewLC(impData.OpaqueData());
+			parse->EnsureMIMETypesReadL();
+			aMimeType.Copy(parse->MIMEType(0)); // we always use the FIRST MIME type
+			CleanupStack::PopAndDestroy(parse);
+			if (aMimeType.Length()==0)
+				{
+				// we've got plug-in with empty MIME type i.e. generic one, so
+				// it doesn't have MIME type and can't be used to recognize data
+				continue;
+				}
+			return ETrue;
+			}
+		}
+	return EFalse;
+	}
+
+
+
+
+