pimappservices/calendar/shared/src/agmattachment.cpp
changeset 0 f979ecb2b13e
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pimappservices/calendar/shared/src/agmattachment.cpp	Tue Feb 02 10:12:19 2010 +0200
@@ -0,0 +1,512 @@
+// 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:
+//
+
+#include "agmattachment.h"
+#include "agmpanic.h"
+#include "agmcontent.h"
+#include <s32stor.h>
+
+// AttachmentFactory //
+
+/** Create a new attachment from a stream.
+*/
+EXPORT_C CAgnAttachment* AttachmentFactory::NewAttachmentL(RReadStream& aStream)
+	{
+	CCalAttachment::TType type = static_cast<CCalAttachment::TType>(aStream.ReadUint8L());
+	CAgnAttachment* attachment = NULL;
+	if (type == CCalAttachment::EUri)
+		{
+		attachment = new (ELeave) CAgnAttachmentUri();
+		}
+	else if (type == CCalAttachment::EFile)
+		{
+		attachment = new (ELeave) CAgnAttachmentFile();
+		}
+	else
+		{
+		User::Leave(KErrCorrupt);
+		}
+
+	CleanupStack::PushL(attachment);
+	attachment->InternalizeL(aStream);
+	CleanupStack::Pop(attachment);		
+	return attachment;
+	}
+
+/** Create a new attachment by copying an existing attachment.
+*/
+EXPORT_C CAgnAttachment* AttachmentFactory::CloneL(const CAgnAttachment& aOriginal)
+	{
+	CCalContent::TDisposition type = aOriginal.Type();
+	CAgnAttachment* newAttachment = NULL;
+	if (type == CCalContent::EDispositionUrl)
+		{
+		newAttachment = new (ELeave) CAgnAttachmentUri();
+		}
+	else if (type == CCalContent::EDispositionInline)
+		{
+		newAttachment = new (ELeave) CAgnAttachmentFile();
+		}
+	else
+		{
+		Panic(EAgmErrBadAttachmentType);
+		}
+		
+	CleanupStack::PushL(newAttachment);
+	newAttachment->CopyL(aOriginal);
+	CleanupStack::Pop(newAttachment);
+	return newAttachment;
+	}
+
+/** Create a new attachment by specifying its type only.
+*/
+EXPORT_C CAgnAttachment* AttachmentFactory::NewAttachmentL(CCalContent::TDisposition aType)
+	{
+	CAgnAttachment* newAttachment = NULL;
+	if (aType == CCalContent::EDispositionUrl)
+		{
+		newAttachment = new (ELeave) CAgnAttachmentUri();
+		}
+	else if (aType == CCalContent::EDispositionInline)
+		{
+		newAttachment = new (ELeave) CAgnAttachmentFile();
+		}
+	else
+		{
+		Panic(EAgmErrBadAttachmentType);
+		}
+	return newAttachment;
+	}
+
+// CAgnAttachment //
+
+//Constructors and Destructors
+CAgnAttachment::CAgnAttachment(CCalContent::TDisposition aType) :
+	CAgnContent(aType)
+	{
+	}
+
+EXPORT_C CAgnAttachment::~CAgnAttachment()
+	{
+	delete iLabel;
+	}
+
+/** Set the value of the attachment.
+For a CCalContent::EDispositionUrl attachment, this is the URI.
+For a CCalContent::EDispositionInline attachment, this is the binary data.
+*/
+EXPORT_C void CAgnAttachment::SetValue(TDesC8* aContent)
+	{
+	SetContent(aContent);
+	if (aContent)
+		{
+		iSize = aContent->Length();
+		}
+	else
+		{
+		iSize = 0;	
+		}
+	}
+
+EXPORT_C void CAgnAttachment::SetMimeTypeL(const TDesC8& aMimeType)
+	{
+	SetMimeType(aMimeType.AllocL());
+	}
+	
+/** Attributes are defined by CCalAttachment::TAttributes
+*/
+EXPORT_C void CAgnAttachment::SetAttribute(TUint16 aAttribute)
+	{
+	iAttributes |= aAttribute;
+	}
+
+EXPORT_C void CAgnAttachment::ClearAttribute(TUint16 aAttribute)
+	{
+	iAttributes &= ~aAttribute;
+	}
+
+EXPORT_C TBool CAgnAttachment::IsAttributeSet(TUint16 aAttribute) const
+	{
+	return (iAttributes & aAttribute);
+	}
+
+/** Set / get the attachment label.
+*/
+EXPORT_C void CAgnAttachment::SetLabelL(const TDesC& aLabel)
+	{
+	__ASSERT_ALWAYS(aLabel.Length() <= KCalAttachmentMaxLabelLength, User::Leave(KErrArgument));
+	delete iLabel;
+	iLabel = NULL;
+	iLabel = aLabel.AllocL();
+	}
+ 
+EXPORT_C const TDesC& CAgnAttachment::Label() const
+	{
+	if (iLabel)
+		{
+		return *iLabel;
+		}
+	return KNullDesC();
+	}
+
+/** Set / get the attachment UID. This UID is internal and used to uniquely identify an attachment in a file (using the attachment index).
+*/
+EXPORT_C TCalAttachmentUid CAgnAttachment::Uid() const
+	{
+	return iUid;
+	}
+
+EXPORT_C void CAgnAttachment::SetUid(TCalAttachmentUid aUid)
+	{
+	iUid = aUid;
+	}
+	
+void CAgnAttachment::InternalizeL(RReadStream& aStream)
+	{
+	// don't read in type as assume already read
+	HBufC8* mimeType = HBufC8::NewL(aStream, KCalAttachmentMaxMimeTypeLength);
+	SetMimeType(mimeType);
+	iUid = aStream.ReadUint32L();
+	iAttributes = static_cast<CCalAttachment::TAttributes>(aStream.ReadUint16L());
+	iFlags = aStream.ReadUint16L();
+	iSize = aStream.ReadInt32L();
+	delete iLabel;
+	iLabel = NULL;
+	iLabel = HBufC::NewL(aStream, KCalAttachmentMaxLabelLength);
+	}
+
+void CAgnAttachment::ExternalizeL(RWriteStream& aStream) const
+	{
+	aStream.WriteUint8L(Type());
+	
+	aStream << MimeType();
+	aStream.WriteUint32L(iUid);
+	aStream.WriteUint16L(iAttributes);
+	aStream.WriteUint16L(iFlags);
+	aStream.WriteInt32L(iSize);
+	aStream << Label();
+	}
+
+// Used when an entry is copied
+void CAgnAttachment::CopyL(const CAgnAttachment& aSource)
+	{
+	__ASSERT_ALWAYS(Type() == aSource.Type(), Panic(EAgmErrBadAttachmentType));
+	
+	HBufC8* content = NULL;
+	if (aSource.Content().Length())
+		{
+		content = aSource.Content().AllocL();
+		}
+	SetContent(content);
+
+	HBufC8* mimeType = NULL;
+	if (aSource.MimeType().Length())
+		{
+		mimeType = aSource.MimeType().AllocL();
+		}
+	SetMimeType(mimeType);
+
+	SetUid(aSource.Uid());
+	iAttributes = aSource.iAttributes;
+	iFlags = aSource.iFlags;
+	SetSize(aSource.Size());
+	SetLabelL(aSource.Label());
+	}
+
+// return ETrue if the attachment passed in is the same
+TBool CAgnAttachment::CompareL(const CAgnAttachment& aSource) const
+	{
+	if (Type() != aSource.Type())
+		{
+		return EFalse;
+		}
+	
+	if (MimeType() != aSource.MimeType())
+		{
+		return EFalse;
+		}
+	
+	if (Content() != aSource.Content())
+		{
+		return EFalse;
+		}
+	
+	if (iAttributes != aSource.iAttributes)
+		{
+		return EFalse;
+		}
+	
+	if (Label() != aSource.Label())
+		{
+		return EFalse;
+		}
+		
+	if (Size() != aSource.Size())
+		{
+		return EFalse;
+		}
+	// Only properties exposed to clients are compared, i.e. not UIDs.
+	
+	return ETrue;
+	}
+
+/** Set / get the attachment flags. Unlike the attributes, these flags are internal and not exposed to the client.
+*/
+EXPORT_C void CAgnAttachment::SetFlag(TUint16 aFlag)
+	{
+	iFlags |= aFlag;
+	}
+
+EXPORT_C void CAgnAttachment::ClearFlag(TUint16 aFlag)
+	{
+	iFlags &= ~aFlag;
+	}
+
+EXPORT_C TBool CAgnAttachment::FlagsSet(TUint16 aFlag) const
+	{
+	return (iFlags & aFlag);
+	}
+
+/** Set / get the attachment size. 
+For file attachments, this effectively caches it for the client.
+*/
+EXPORT_C TInt CAgnAttachment::Size() const
+	{
+	return iSize;
+	}
+
+EXPORT_C void CAgnAttachment::SetSize(TInt aSize)
+	{
+	iSize = aSize;
+	}
+
+// CAgnAttachmentUri //
+	
+CAgnAttachmentUri::CAgnAttachmentUri() : 
+	CAgnAttachment(CCalContent::EDispositionUrl)
+	{
+	}
+
+void CAgnAttachmentUri::ExternalizeL(RWriteStream& aStream) const
+	{
+	CAgnAttachment::ExternalizeL(aStream);
+	aStream << Content();
+	}
+
+void CAgnAttachmentUri::InternalizeL(RReadStream& aStream)
+	{
+	CAgnAttachment::InternalizeL(aStream);
+	HBufC8* content = HBufC8::NewL(aStream, KMaxTInt);
+	SetContent(content);
+	}
+
+// CAgnAttachmentFile //
+
+//Constructors and Destructors 
+CAgnAttachmentFile::CAgnAttachmentFile() : 
+	CAgnAttachment(CCalContent::EDispositionInline),
+	iLastModifiedTimeUtc(Time::NullTTime())
+	{
+	}
+
+EXPORT_C CAgnAttachmentFile::~CAgnAttachmentFile()
+	{
+	delete iContentId;
+	delete iFileName;
+	
+	iFileHandle.Close();
+	}
+	
+EXPORT_C TBool CAgnAttachmentFile::IsFileHandleSet() const
+	{
+	return iIsFileHandleSet;	
+	}
+	
+/** Set the file handle (should be called on client side only).
+*/
+EXPORT_C void CAgnAttachmentFile::CopyFileHandle(const RFile& aFile)
+	{
+	iFileHandle.Close();
+	User::LeaveIfError(iFileHandle.Duplicate(aFile));
+	iIsFileHandleSet = ETrue;
+	// any attachment with a file handle will not be exported inline by default
+	ClearAttribute(CCalAttachment::EExportInline);
+	SetFlag(EDataHasBeenSet);
+	TInt size;
+	aFile.Size(size);
+	SetSize(size);
+	}
+/** Get the file handle (should be called on client side only).
+*/
+EXPORT_C  const RFile& CAgnAttachmentFile::FileHandle() const 
+	{
+	return iFileHandle;
+	}
+
+/** Set the drive on which to store the attachment
+*/
+EXPORT_C void CAgnAttachmentFile::SetDriveL(const TDesC& aDrive)
+	{
+	if ( ! iFileName || iFileName->Length() <= KMaxDriveName)
+		{
+		SetFileNameL(aDrive.Left(KMaxDriveName));
+		}
+	else
+		{
+		if (iFileName->Left(1) != aDrive.Left(1))
+			{
+			TPtr ptr(iFileName->Des());
+			ptr.Replace(0, aDrive.Length(), aDrive);
+			}
+		}
+	}
+
+/** Set the name of the file where the attachment is stored internally. 
+This is not exposed to clients.
+*/
+EXPORT_C void CAgnAttachmentFile::SetFileNameL(const TDesC& aFileName)
+	{
+	delete iFileName;
+	iFileName = NULL;
+	iFileName = aFileName.AllocL();
+	}
+
+/** returns the attachment's file name 
+  */
+EXPORT_C const TDesC& CAgnAttachmentFile::FileName() const
+	{
+	if (iFileName)
+		{
+		return *iFileName;
+		}
+	return KNullDesC();
+	}
+
+EXPORT_C TDriveName CAgnAttachmentFile::Drive() const
+	{
+	if (iFileName && iFileName->Length() >= KMaxDriveName)
+		{
+		return iFileName->Left(KMaxDriveName);
+		}
+	return KDefaultAttachmentDrive();
+	}
+
+/** Last modified date of an attachment is separate data from the entry's last modified time.
+It is set by the client and may not match the actual file attachment's modified time.
+*/
+EXPORT_C const TTime& CAgnAttachmentFile::LastModifiedTimeUtc() const
+	{
+	return iLastModifiedTimeUtc;
+	}
+
+EXPORT_C void CAgnAttachmentFile::SetLastModifiedTimeUtc(const TTime& aTime)
+	{
+	iLastModifiedTimeUtc = aTime;
+	}
+
+/** The content ID should only be set by a client on import or export.
+*/
+EXPORT_C void CAgnAttachmentFile::SetContentIdL(const TDesC8& aContentId)
+	{
+	delete iContentId;
+	iContentId = NULL;
+	iContentId = aContentId.AllocL();
+	}
+
+EXPORT_C const TDesC8& CAgnAttachmentFile::ContentId() const
+	{
+	if (iContentId)
+		{
+		return *iContentId;
+		}
+	return KNullDesC8();
+	}
+
+/** Used when store\restore the object to\from the file
+*/
+EXPORT_C void CAgnAttachmentFile::InternalizeL(RReadStream& aStream)
+	{
+	CAgnAttachment::InternalizeL(aStream);
+	TInt64 lastModifiedUtc;
+	aStream >> lastModifiedUtc;
+	iLastModifiedTimeUtc = lastModifiedUtc;
+	iFileName = HBufC::NewL(aStream, KMaxFileName);
+	}
+
+EXPORT_C void CAgnAttachmentFile::ExternalizeL(RWriteStream& aStream) const
+	{
+	CAgnAttachment::ExternalizeL(aStream);
+	aStream << iLastModifiedTimeUtc.Int64();
+	aStream << FileName();
+	}
+	
+EXPORT_C void CAgnAttachmentFile::SetHasFileHandle(TBool aHasFileHandel)
+	{
+	iIsFileHandleSet = aHasFileHandel;
+	}
+	
+//Used when an entry is copied
+void CAgnAttachmentFile::CopyL(const CAgnAttachment& aSource)
+	{
+	CAgnAttachment::CopyL(aSource);
+
+	const CAgnAttachmentFile& KFileSource = static_cast<const CAgnAttachmentFile&>(aSource);
+		
+	delete iContentId;
+	iContentId = NULL;
+	if (KFileSource.ContentId().Length())
+		{
+		iContentId = KFileSource.ContentId().AllocL();
+		}
+	SetLastModifiedTimeUtc(KFileSource.LastModifiedTimeUtc());
+	SetFileNameL(KFileSource.FileName());
+	
+	if (KFileSource.IsFileHandleSet())
+		{
+		CopyFileHandle(KFileSource.FileHandle());	
+		}
+	}
+
+TBool CAgnAttachmentFile::CompareL(const CAgnAttachment& aSource) const
+	{
+	if (!CAgnAttachment::CompareL(aSource))
+		{
+		return EFalse;
+		}
+	
+	// CAgnAttachment::CompareL already compared disposition, so both are file attachments
+	const CAgnAttachmentFile& KFileSource = static_cast<const CAgnAttachmentFile&>(aSource);
+	
+	if (ContentId() != KFileSource.ContentId())
+		{
+		return EFalse;
+		}
+
+	if (LastModifiedTimeUtc() != KFileSource.LastModifiedTimeUtc())
+		{
+		return EFalse;
+		}
+	
+	TDriveName drv1 = Drive();
+	TDriveName drv2 = KFileSource.Drive();
+	drv1.UpperCase();
+	drv2.UpperCase();
+	if (drv1 != drv2)
+		{
+		return EFalse;
+		}
+
+	return ETrue;
+	}