|
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 } |