diff -r 000000000000 -r f979ecb2b13e pimappservices/calendar/shared/src/agmattachment.cpp --- /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 + +// AttachmentFactory // + +/** Create a new attachment from a stream. +*/ +EXPORT_C CAgnAttachment* AttachmentFactory::NewAttachmentL(RReadStream& aStream) + { + CCalAttachment::TType type = static_cast(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(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(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(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; + }