messagingfw/wappushfw/ROAPTContentHandler/src/ROCHCAFInterface.cpp
changeset 0 8e480a14352b
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/messagingfw/wappushfw/ROAPTContentHandler/src/ROCHCAFInterface.cpp	Mon Jan 18 20:36:02 2010 +0200
@@ -0,0 +1,265 @@
+// Copyright (c) 2006-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:
+// Implementation of the CROCHCAFInterface class.
+// 
+//
+
+
+#include "ROCHCAFInterface.h"
+
+_LIT8(KXHyphen,"X-");
+_LIT8(KContentHyphen,"Content-");
+const TUint8 KImcvColon	= ':';
+
+#if  _DEBUG
+_LIT(KErrInvalidCafState,	"Invalid CAF State");
+#endif
+
+/**
+Construct with callers file session handle.
+c'tor
+*/
+EXPORT_C CROCHCAFInterface::CROCHCAFInterface(RFs& aFs) : iFsSession(aFs)
+	{}
+
+/**
+d'tor
+*/
+EXPORT_C  CROCHCAFInterface::~CROCHCAFInterface()
+	{
+	delete iSupplier;
+	delete iContentType;
+	delete iMetaData;
+	delete iImportFile;
+	iAttachmentFile.Close();
+	}
+	
+
+/**
+Prior to StartProcessing() the CAF agent could provide an initial filename for the CAF session.
+@param aAttachmentFileName Descriptor for writing CAF agent suggested filename.
+@return KErrNone success or system error code.
+@pre PrepareProcessingL() must be called prior to this call.
+@panic imut 36
+*/
+EXPORT_C TInt CROCHCAFInterface::GetSuggestedAttachmentFileName(TDes& aAttachmentFileName) const
+	{
+	__ASSERT_DEBUG(iImportFile != NULL, User::Panic(KErrInvalidCafState, EPanicInvalidCafState));
+	return iImportFile->GetSuggestedOutputFileName(aAttachmentFileName);
+	}
+
+
+/**
+Write a buffer of data to the CAF Agent.
+@param aData Data to write to the CAF agent.
+@return KErrNone success or system error code.
+@pre StartProcessingL() must be called prior to this call
+@post Generates 0-N receipt files under the current message attachment entry.
+@panic imut 36
+*/
+EXPORT_C void CROCHCAFInterface::WriteDataL(const TDesC8& aData)
+	{
+	__ASSERT_DEBUG(iImportFile != NULL, User::Panic(KErrInvalidCafState, EPanicInvalidCafState));
+	User::LeaveIfError(iImportFile->WriteData(aData));
+	}
+
+/**
+Add Mime header metadata to CAF class in preparation for PrepareProcessingL()
+Metadata comprises a field and data pair. For example:
+aField - "X-Oma-Drm-Separate-Delivery" aData - "12"
+If field does not contain "X-" or "Content-" then the method returns without
+adding them to the class.
+@param aField - Mime header field
+@param aData - Mime field's corresponding data
+@panic imut 36
+*/
+EXPORT_C void CROCHCAFInterface::AddToMetaDataL(const TDesC8& aField, const TDesC8& aData)
+	{
+	if(aField.FindF(KContentHyphen) == KErrNone && aField.FindF(KXHyphen) == KErrNone)
+		{		
+		return;
+		}
+	if(!iMetaData)
+		{		
+		iMetaData = CMetaDataArray::NewL();
+		}
+	// Check we're not overwriting an existing one. Could show up a logic error.
+	#if (defined _DEBUG)
+	TPtrC8 des(iMetaData->SearchL(aField));
+	__ASSERT_DEBUG(des.Length() == 0, User::Panic(KErrInvalidCafState, EPanicInvalidCafState));	
+	#endif
+	iMetaData->AddL(aField,aData);
+	}
+
+/**
+Add Mime header metadata to CAF class in preparation for PrepareProcessingL()
+Parses a complete unfolded mime header line to extract fields and values
+Format expected:
+Fieldxxx: Valuexxx;ParamField=ParamValue
+If line does not contain "X-" or "Content-" then the method returns without
+adding data to the class.
+@param aMimeLine - Mime header data line minus CRLF
+@panic imut 36
+*/
+EXPORT_C void CROCHCAFInterface::AddToMetaDataL(const TDesC8& aMimeLine)
+	{
+	// Don't bother adding if it's neither of these
+	// This means we won't add envelope stuff
+	if(aMimeLine.FindF(KContentHyphen) == KErrNone && aMimeLine.FindF(KXHyphen) == KErrNone)
+		{
+		return;
+		}
+	if(!iMetaData)
+		{		
+		iMetaData = CMetaDataArray::NewL();
+		}
+	TInt offset;
+	TPtrC8 field;
+	TPtrC8 data;
+	// Isolate the field and data pair separated by ':'	
+	if((offset = aMimeLine.Locate(KImcvColon)) != KErrNotFound)
+		{
+		field.Set(aMimeLine.Left(++offset));
+		// Remove leading whitespace
+		while(aMimeLine[offset] == ' ')
+			{
+			offset++;
+			}
+		data.Set(aMimeLine.Mid(offset));
+		}
+	else
+		{
+		// No colon should never happen if mail is not corrupt
+		__ASSERT_DEBUG(offset != KErrNotFound, User::Panic(KErrInvalidCafState, EPanicInvalidCafState));
+		return;
+		}
+	// Check we're not overwriting an existing one. Could show up a logic error.
+	#if (defined _DEBUG)
+	TPtrC8 des(iMetaData->SearchL(field));
+	__ASSERT_DEBUG(des.Length() == 0, User::Panic(KErrInvalidCafState, EPanicInvalidCafState));				
+	#endif
+	iMetaData->AddL(field,data);
+	}
+
+/**
+Prepare the CROCHCAFInterface class for a CAF session.
+@pre RegisterL() must be called prior to this call and success checked with a Registered() call.
+@panic imut 36
+*/
+EXPORT_C void CROCHCAFInterface::PrepareProcessingL()
+	{
+	__ASSERT_DEBUG(iSupplier != NULL && iContentType != NULL && iMetaData != NULL && iImportFile == NULL, User::Panic(KErrInvalidCafState, EPanicInvalidCafState));
+	iImportFile = iSupplier->ImportFileL(iContentType->Des(),*iMetaData);// Prepare agent for writing data.
+	Deregister();
+	}
+	
+/**
+Set the CAF class variables required to Start the CAF write session.
+@param aDefaultAttachmentFileName Localised default attachment name.
+@param aAttachmentFilePath If CAF agent requires extra files, this is the folder/attachment entry path.
+@param aStartFile An open File handle for attachment write. Caller can close following this call.
+@pre PrepareProcessingL() must be called prior to this call
+@panic imut 36
+*/
+EXPORT_C void CROCHCAFInterface::StartProcessing(const TDesC& aDefaultAttachmentFileName,const TDesC& aAttachmentFilePath,RFile& aStartFile)
+	{
+	__ASSERT_DEBUG(iSupplier != NULL && iImportFile != NULL && iContentType == NULL && iMetaData == NULL && aStartFile.SubSessionHandle() != 0, User::Panic(KErrInvalidCafState, EPanicInvalidCafState));
+	iDefaultAttachmentFileName.Set(aDefaultAttachmentFileName);
+	iAttachmentFilePath = aAttachmentFilePath;
+	iAttachmentFile.Duplicate(aStartFile); // Caller can close their copy
+	}
+	
+/**
+Terminate CAF session.
+Set the mime type to a unique CAF one if there are.
+@panic imut 36
+*/
+EXPORT_C void CROCHCAFInterface::EndProcessingL()
+	{
+	__ASSERT_DEBUG(iImportFile != NULL, User::Panic(KErrInvalidCafState, EPanicInvalidCafState));
+	WriteDataCompleteL();
+
+	delete iImportFile;
+	iImportFile = NULL;
+	}
+
+/**
+Attempt to register a mime content-type with a CAF agent.
+Success can be checked by a subsequent call to Registered().
+@param aMimeLine MIME Content-Type for possible interest by a CAF agent. For example - application/vnd.oma.drm.rights+xml
+@panic imut 36
+*/
+EXPORT_C void CROCHCAFInterface::RegisterL(const TDesC8& aMimeLine)
+	{
+	__ASSERT_DEBUG(iContentType == NULL, User::Panic(KErrInvalidCafState, EPanicInvalidCafState));
+	if(!iSupplier)
+		{		
+		iSupplier = CSupplier::NewL();
+		}
+	if(iSupplier->IsImportSupported(aMimeLine))
+		{
+		// CAF agent interested in the content-type
+		// Use this buffer for storing the content-type.
+		// We could extract it from the caf metadata later but this will be quicker
+		iContentType = aMimeLine.AllocL();
+		// REMOVE when CAF fixed
+		iContentType->Des().LowerCase();
+		// Construct the metadata array here but add to it later
+		// Could contain stuff like "X-Oma-Drm-Separate-Delivery: 12"
+		if(!iMetaData)
+			{		
+			iMetaData = CMetaDataArray::NewL();
+			}
+		}
+	}
+
+/**
+Free resources allocated during CAF session
+@pre RegisterL() must be called prior to this call.
+@panic imut 36
+*/
+EXPORT_C void CROCHCAFInterface::Deregister()
+	{
+	__ASSERT_DEBUG(Registered(), User::Panic(KErrInvalidCafState, EPanicInvalidCafState));
+	// Don't delete iSupplier. This is kept open to prevent reloading of DLLs
+	delete iContentType;
+	iContentType = NULL;
+	delete iMetaData;
+	iMetaData = NULL;
+	}
+		
+/**
+Check whether RegisterL() succeeded.
+@return Registered status of the CAF instance.
+*/
+EXPORT_C TBool CROCHCAFInterface::Registered() const
+	{
+	return iContentType != NULL;
+	}
+	
+/**
+Retrieve processing status for the CAF session.
+@return Processing status of the CAF instance
+*/
+EXPORT_C TBool CROCHCAFInterface::Processing() const
+	{
+	return iImportFile != NULL;
+	}
+
+//Tell the CAF agent this that the last data for the CAF session has been written.
+void CROCHCAFInterface::WriteDataCompleteL()
+	{
+	User::LeaveIfError(iImportFile->WriteDataComplete());
+	}
+