pimappservices/calendar/shared/src/agmattachment.cpp
changeset 0 f979ecb2b13e
equal deleted inserted replaced
-1:000000000000 0:f979ecb2b13e
       
     1 // Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 #include "agmattachment.h"
       
    17 #include "agmpanic.h"
       
    18 #include "agmcontent.h"
       
    19 #include <s32stor.h>
       
    20 
       
    21 // AttachmentFactory //
       
    22 
       
    23 /** Create a new attachment from a stream.
       
    24 */
       
    25 EXPORT_C CAgnAttachment* AttachmentFactory::NewAttachmentL(RReadStream& aStream)
       
    26 	{
       
    27 	CCalAttachment::TType type = static_cast<CCalAttachment::TType>(aStream.ReadUint8L());
       
    28 	CAgnAttachment* attachment = NULL;
       
    29 	if (type == CCalAttachment::EUri)
       
    30 		{
       
    31 		attachment = new (ELeave) CAgnAttachmentUri();
       
    32 		}
       
    33 	else if (type == CCalAttachment::EFile)
       
    34 		{
       
    35 		attachment = new (ELeave) CAgnAttachmentFile();
       
    36 		}
       
    37 	else
       
    38 		{
       
    39 		User::Leave(KErrCorrupt);
       
    40 		}
       
    41 
       
    42 	CleanupStack::PushL(attachment);
       
    43 	attachment->InternalizeL(aStream);
       
    44 	CleanupStack::Pop(attachment);		
       
    45 	return attachment;
       
    46 	}
       
    47 
       
    48 /** Create a new attachment by copying an existing attachment.
       
    49 */
       
    50 EXPORT_C CAgnAttachment* AttachmentFactory::CloneL(const CAgnAttachment& aOriginal)
       
    51 	{
       
    52 	CCalContent::TDisposition type = aOriginal.Type();
       
    53 	CAgnAttachment* newAttachment = NULL;
       
    54 	if (type == CCalContent::EDispositionUrl)
       
    55 		{
       
    56 		newAttachment = new (ELeave) CAgnAttachmentUri();
       
    57 		}
       
    58 	else if (type == CCalContent::EDispositionInline)
       
    59 		{
       
    60 		newAttachment = new (ELeave) CAgnAttachmentFile();
       
    61 		}
       
    62 	else
       
    63 		{
       
    64 		Panic(EAgmErrBadAttachmentType);
       
    65 		}
       
    66 		
       
    67 	CleanupStack::PushL(newAttachment);
       
    68 	newAttachment->CopyL(aOriginal);
       
    69 	CleanupStack::Pop(newAttachment);
       
    70 	return newAttachment;
       
    71 	}
       
    72 
       
    73 /** Create a new attachment by specifying its type only.
       
    74 */
       
    75 EXPORT_C CAgnAttachment* AttachmentFactory::NewAttachmentL(CCalContent::TDisposition aType)
       
    76 	{
       
    77 	CAgnAttachment* newAttachment = NULL;
       
    78 	if (aType == CCalContent::EDispositionUrl)
       
    79 		{
       
    80 		newAttachment = new (ELeave) CAgnAttachmentUri();
       
    81 		}
       
    82 	else if (aType == CCalContent::EDispositionInline)
       
    83 		{
       
    84 		newAttachment = new (ELeave) CAgnAttachmentFile();
       
    85 		}
       
    86 	else
       
    87 		{
       
    88 		Panic(EAgmErrBadAttachmentType);
       
    89 		}
       
    90 	return newAttachment;
       
    91 	}
       
    92 
       
    93 // CAgnAttachment //
       
    94 
       
    95 //Constructors and Destructors
       
    96 CAgnAttachment::CAgnAttachment(CCalContent::TDisposition aType) :
       
    97 	CAgnContent(aType)
       
    98 	{
       
    99 	}
       
   100 
       
   101 EXPORT_C CAgnAttachment::~CAgnAttachment()
       
   102 	{
       
   103 	delete iLabel;
       
   104 	}
       
   105 
       
   106 /** Set the value of the attachment.
       
   107 For a CCalContent::EDispositionUrl attachment, this is the URI.
       
   108 For a CCalContent::EDispositionInline attachment, this is the binary data.
       
   109 */
       
   110 EXPORT_C void CAgnAttachment::SetValue(TDesC8* aContent)
       
   111 	{
       
   112 	SetContent(aContent);
       
   113 	if (aContent)
       
   114 		{
       
   115 		iSize = aContent->Length();
       
   116 		}
       
   117 	else
       
   118 		{
       
   119 		iSize = 0;	
       
   120 		}
       
   121 	}
       
   122 
       
   123 EXPORT_C void CAgnAttachment::SetMimeTypeL(const TDesC8& aMimeType)
       
   124 	{
       
   125 	SetMimeType(aMimeType.AllocL());
       
   126 	}
       
   127 	
       
   128 /** Attributes are defined by CCalAttachment::TAttributes
       
   129 */
       
   130 EXPORT_C void CAgnAttachment::SetAttribute(TUint16 aAttribute)
       
   131 	{
       
   132 	iAttributes |= aAttribute;
       
   133 	}
       
   134 
       
   135 EXPORT_C void CAgnAttachment::ClearAttribute(TUint16 aAttribute)
       
   136 	{
       
   137 	iAttributes &= ~aAttribute;
       
   138 	}
       
   139 
       
   140 EXPORT_C TBool CAgnAttachment::IsAttributeSet(TUint16 aAttribute) const
       
   141 	{
       
   142 	return (iAttributes & aAttribute);
       
   143 	}
       
   144 
       
   145 /** Set / get the attachment label.
       
   146 */
       
   147 EXPORT_C void CAgnAttachment::SetLabelL(const TDesC& aLabel)
       
   148 	{
       
   149 	__ASSERT_ALWAYS(aLabel.Length() <= KCalAttachmentMaxLabelLength, User::Leave(KErrArgument));
       
   150 	delete iLabel;
       
   151 	iLabel = NULL;
       
   152 	iLabel = aLabel.AllocL();
       
   153 	}
       
   154  
       
   155 EXPORT_C const TDesC& CAgnAttachment::Label() const
       
   156 	{
       
   157 	if (iLabel)
       
   158 		{
       
   159 		return *iLabel;
       
   160 		}
       
   161 	return KNullDesC();
       
   162 	}
       
   163 
       
   164 /** Set / get the attachment UID. This UID is internal and used to uniquely identify an attachment in a file (using the attachment index).
       
   165 */
       
   166 EXPORT_C TCalAttachmentUid CAgnAttachment::Uid() const
       
   167 	{
       
   168 	return iUid;
       
   169 	}
       
   170 
       
   171 EXPORT_C void CAgnAttachment::SetUid(TCalAttachmentUid aUid)
       
   172 	{
       
   173 	iUid = aUid;
       
   174 	}
       
   175 	
       
   176 void CAgnAttachment::InternalizeL(RReadStream& aStream)
       
   177 	{
       
   178 	// don't read in type as assume already read
       
   179 	HBufC8* mimeType = HBufC8::NewL(aStream, KCalAttachmentMaxMimeTypeLength);
       
   180 	SetMimeType(mimeType);
       
   181 	iUid = aStream.ReadUint32L();
       
   182 	iAttributes = static_cast<CCalAttachment::TAttributes>(aStream.ReadUint16L());
       
   183 	iFlags = aStream.ReadUint16L();
       
   184 	iSize = aStream.ReadInt32L();
       
   185 	delete iLabel;
       
   186 	iLabel = NULL;
       
   187 	iLabel = HBufC::NewL(aStream, KCalAttachmentMaxLabelLength);
       
   188 	}
       
   189 
       
   190 void CAgnAttachment::ExternalizeL(RWriteStream& aStream) const
       
   191 	{
       
   192 	aStream.WriteUint8L(Type());
       
   193 	
       
   194 	aStream << MimeType();
       
   195 	aStream.WriteUint32L(iUid);
       
   196 	aStream.WriteUint16L(iAttributes);
       
   197 	aStream.WriteUint16L(iFlags);
       
   198 	aStream.WriteInt32L(iSize);
       
   199 	aStream << Label();
       
   200 	}
       
   201 
       
   202 // Used when an entry is copied
       
   203 void CAgnAttachment::CopyL(const CAgnAttachment& aSource)
       
   204 	{
       
   205 	__ASSERT_ALWAYS(Type() == aSource.Type(), Panic(EAgmErrBadAttachmentType));
       
   206 	
       
   207 	HBufC8* content = NULL;
       
   208 	if (aSource.Content().Length())
       
   209 		{
       
   210 		content = aSource.Content().AllocL();
       
   211 		}
       
   212 	SetContent(content);
       
   213 
       
   214 	HBufC8* mimeType = NULL;
       
   215 	if (aSource.MimeType().Length())
       
   216 		{
       
   217 		mimeType = aSource.MimeType().AllocL();
       
   218 		}
       
   219 	SetMimeType(mimeType);
       
   220 
       
   221 	SetUid(aSource.Uid());
       
   222 	iAttributes = aSource.iAttributes;
       
   223 	iFlags = aSource.iFlags;
       
   224 	SetSize(aSource.Size());
       
   225 	SetLabelL(aSource.Label());
       
   226 	}
       
   227 
       
   228 // return ETrue if the attachment passed in is the same
       
   229 TBool CAgnAttachment::CompareL(const CAgnAttachment& aSource) const
       
   230 	{
       
   231 	if (Type() != aSource.Type())
       
   232 		{
       
   233 		return EFalse;
       
   234 		}
       
   235 	
       
   236 	if (MimeType() != aSource.MimeType())
       
   237 		{
       
   238 		return EFalse;
       
   239 		}
       
   240 	
       
   241 	if (Content() != aSource.Content())
       
   242 		{
       
   243 		return EFalse;
       
   244 		}
       
   245 	
       
   246 	if (iAttributes != aSource.iAttributes)
       
   247 		{
       
   248 		return EFalse;
       
   249 		}
       
   250 	
       
   251 	if (Label() != aSource.Label())
       
   252 		{
       
   253 		return EFalse;
       
   254 		}
       
   255 		
       
   256 	if (Size() != aSource.Size())
       
   257 		{
       
   258 		return EFalse;
       
   259 		}
       
   260 	// Only properties exposed to clients are compared, i.e. not UIDs.
       
   261 	
       
   262 	return ETrue;
       
   263 	}
       
   264 
       
   265 /** Set / get the attachment flags. Unlike the attributes, these flags are internal and not exposed to the client.
       
   266 */
       
   267 EXPORT_C void CAgnAttachment::SetFlag(TUint16 aFlag)
       
   268 	{
       
   269 	iFlags |= aFlag;
       
   270 	}
       
   271 
       
   272 EXPORT_C void CAgnAttachment::ClearFlag(TUint16 aFlag)
       
   273 	{
       
   274 	iFlags &= ~aFlag;
       
   275 	}
       
   276 
       
   277 EXPORT_C TBool CAgnAttachment::FlagsSet(TUint16 aFlag) const
       
   278 	{
       
   279 	return (iFlags & aFlag);
       
   280 	}
       
   281 
       
   282 /** Set / get the attachment size. 
       
   283 For file attachments, this effectively caches it for the client.
       
   284 */
       
   285 EXPORT_C TInt CAgnAttachment::Size() const
       
   286 	{
       
   287 	return iSize;
       
   288 	}
       
   289 
       
   290 EXPORT_C void CAgnAttachment::SetSize(TInt aSize)
       
   291 	{
       
   292 	iSize = aSize;
       
   293 	}
       
   294 
       
   295 // CAgnAttachmentUri //
       
   296 	
       
   297 CAgnAttachmentUri::CAgnAttachmentUri() : 
       
   298 	CAgnAttachment(CCalContent::EDispositionUrl)
       
   299 	{
       
   300 	}
       
   301 
       
   302 void CAgnAttachmentUri::ExternalizeL(RWriteStream& aStream) const
       
   303 	{
       
   304 	CAgnAttachment::ExternalizeL(aStream);
       
   305 	aStream << Content();
       
   306 	}
       
   307 
       
   308 void CAgnAttachmentUri::InternalizeL(RReadStream& aStream)
       
   309 	{
       
   310 	CAgnAttachment::InternalizeL(aStream);
       
   311 	HBufC8* content = HBufC8::NewL(aStream, KMaxTInt);
       
   312 	SetContent(content);
       
   313 	}
       
   314 
       
   315 // CAgnAttachmentFile //
       
   316 
       
   317 //Constructors and Destructors 
       
   318 CAgnAttachmentFile::CAgnAttachmentFile() : 
       
   319 	CAgnAttachment(CCalContent::EDispositionInline),
       
   320 	iLastModifiedTimeUtc(Time::NullTTime())
       
   321 	{
       
   322 	}
       
   323 
       
   324 EXPORT_C CAgnAttachmentFile::~CAgnAttachmentFile()
       
   325 	{
       
   326 	delete iContentId;
       
   327 	delete iFileName;
       
   328 	
       
   329 	iFileHandle.Close();
       
   330 	}
       
   331 	
       
   332 EXPORT_C TBool CAgnAttachmentFile::IsFileHandleSet() const
       
   333 	{
       
   334 	return iIsFileHandleSet;	
       
   335 	}
       
   336 	
       
   337 /** Set the file handle (should be called on client side only).
       
   338 */
       
   339 EXPORT_C void CAgnAttachmentFile::CopyFileHandle(const RFile& aFile)
       
   340 	{
       
   341 	iFileHandle.Close();
       
   342 	User::LeaveIfError(iFileHandle.Duplicate(aFile));
       
   343 	iIsFileHandleSet = ETrue;
       
   344 	// any attachment with a file handle will not be exported inline by default
       
   345 	ClearAttribute(CCalAttachment::EExportInline);
       
   346 	SetFlag(EDataHasBeenSet);
       
   347 	TInt size;
       
   348 	aFile.Size(size);
       
   349 	SetSize(size);
       
   350 	}
       
   351 /** Get the file handle (should be called on client side only).
       
   352 */
       
   353 EXPORT_C  const RFile& CAgnAttachmentFile::FileHandle() const 
       
   354 	{
       
   355 	return iFileHandle;
       
   356 	}
       
   357 
       
   358 /** Set the drive on which to store the attachment
       
   359 */
       
   360 EXPORT_C void CAgnAttachmentFile::SetDriveL(const TDesC& aDrive)
       
   361 	{
       
   362 	if ( ! iFileName || iFileName->Length() <= KMaxDriveName)
       
   363 		{
       
   364 		SetFileNameL(aDrive.Left(KMaxDriveName));
       
   365 		}
       
   366 	else
       
   367 		{
       
   368 		if (iFileName->Left(1) != aDrive.Left(1))
       
   369 			{
       
   370 			TPtr ptr(iFileName->Des());
       
   371 			ptr.Replace(0, aDrive.Length(), aDrive);
       
   372 			}
       
   373 		}
       
   374 	}
       
   375 
       
   376 /** Set the name of the file where the attachment is stored internally. 
       
   377 This is not exposed to clients.
       
   378 */
       
   379 EXPORT_C void CAgnAttachmentFile::SetFileNameL(const TDesC& aFileName)
       
   380 	{
       
   381 	delete iFileName;
       
   382 	iFileName = NULL;
       
   383 	iFileName = aFileName.AllocL();
       
   384 	}
       
   385 
       
   386 /** returns the attachment's file name 
       
   387   */
       
   388 EXPORT_C const TDesC& CAgnAttachmentFile::FileName() const
       
   389 	{
       
   390 	if (iFileName)
       
   391 		{
       
   392 		return *iFileName;
       
   393 		}
       
   394 	return KNullDesC();
       
   395 	}
       
   396 
       
   397 EXPORT_C TDriveName CAgnAttachmentFile::Drive() const
       
   398 	{
       
   399 	if (iFileName && iFileName->Length() >= KMaxDriveName)
       
   400 		{
       
   401 		return iFileName->Left(KMaxDriveName);
       
   402 		}
       
   403 	return KDefaultAttachmentDrive();
       
   404 	}
       
   405 
       
   406 /** Last modified date of an attachment is separate data from the entry's last modified time.
       
   407 It is set by the client and may not match the actual file attachment's modified time.
       
   408 */
       
   409 EXPORT_C const TTime& CAgnAttachmentFile::LastModifiedTimeUtc() const
       
   410 	{
       
   411 	return iLastModifiedTimeUtc;
       
   412 	}
       
   413 
       
   414 EXPORT_C void CAgnAttachmentFile::SetLastModifiedTimeUtc(const TTime& aTime)
       
   415 	{
       
   416 	iLastModifiedTimeUtc = aTime;
       
   417 	}
       
   418 
       
   419 /** The content ID should only be set by a client on import or export.
       
   420 */
       
   421 EXPORT_C void CAgnAttachmentFile::SetContentIdL(const TDesC8& aContentId)
       
   422 	{
       
   423 	delete iContentId;
       
   424 	iContentId = NULL;
       
   425 	iContentId = aContentId.AllocL();
       
   426 	}
       
   427 
       
   428 EXPORT_C const TDesC8& CAgnAttachmentFile::ContentId() const
       
   429 	{
       
   430 	if (iContentId)
       
   431 		{
       
   432 		return *iContentId;
       
   433 		}
       
   434 	return KNullDesC8();
       
   435 	}
       
   436 
       
   437 /** Used when store\restore the object to\from the file
       
   438 */
       
   439 EXPORT_C void CAgnAttachmentFile::InternalizeL(RReadStream& aStream)
       
   440 	{
       
   441 	CAgnAttachment::InternalizeL(aStream);
       
   442 	TInt64 lastModifiedUtc;
       
   443 	aStream >> lastModifiedUtc;
       
   444 	iLastModifiedTimeUtc = lastModifiedUtc;
       
   445 	iFileName = HBufC::NewL(aStream, KMaxFileName);
       
   446 	}
       
   447 
       
   448 EXPORT_C void CAgnAttachmentFile::ExternalizeL(RWriteStream& aStream) const
       
   449 	{
       
   450 	CAgnAttachment::ExternalizeL(aStream);
       
   451 	aStream << iLastModifiedTimeUtc.Int64();
       
   452 	aStream << FileName();
       
   453 	}
       
   454 	
       
   455 EXPORT_C void CAgnAttachmentFile::SetHasFileHandle(TBool aHasFileHandel)
       
   456 	{
       
   457 	iIsFileHandleSet = aHasFileHandel;
       
   458 	}
       
   459 	
       
   460 //Used when an entry is copied
       
   461 void CAgnAttachmentFile::CopyL(const CAgnAttachment& aSource)
       
   462 	{
       
   463 	CAgnAttachment::CopyL(aSource);
       
   464 
       
   465 	const CAgnAttachmentFile& KFileSource = static_cast<const CAgnAttachmentFile&>(aSource);
       
   466 		
       
   467 	delete iContentId;
       
   468 	iContentId = NULL;
       
   469 	if (KFileSource.ContentId().Length())
       
   470 		{
       
   471 		iContentId = KFileSource.ContentId().AllocL();
       
   472 		}
       
   473 	SetLastModifiedTimeUtc(KFileSource.LastModifiedTimeUtc());
       
   474 	SetFileNameL(KFileSource.FileName());
       
   475 	
       
   476 	if (KFileSource.IsFileHandleSet())
       
   477 		{
       
   478 		CopyFileHandle(KFileSource.FileHandle());	
       
   479 		}
       
   480 	}
       
   481 
       
   482 TBool CAgnAttachmentFile::CompareL(const CAgnAttachment& aSource) const
       
   483 	{
       
   484 	if (!CAgnAttachment::CompareL(aSource))
       
   485 		{
       
   486 		return EFalse;
       
   487 		}
       
   488 	
       
   489 	// CAgnAttachment::CompareL already compared disposition, so both are file attachments
       
   490 	const CAgnAttachmentFile& KFileSource = static_cast<const CAgnAttachmentFile&>(aSource);
       
   491 	
       
   492 	if (ContentId() != KFileSource.ContentId())
       
   493 		{
       
   494 		return EFalse;
       
   495 		}
       
   496 
       
   497 	if (LastModifiedTimeUtc() != KFileSource.LastModifiedTimeUtc())
       
   498 		{
       
   499 		return EFalse;
       
   500 		}
       
   501 	
       
   502 	TDriveName drv1 = Drive();
       
   503 	TDriveName drv2 = KFileSource.Drive();
       
   504 	drv1.UpperCase();
       
   505 	drv2.UpperCase();
       
   506 	if (drv1 != drv2)
       
   507 		{
       
   508 		return EFalse;
       
   509 		}
       
   510 
       
   511 	return ETrue;
       
   512 	}