|
1 /* |
|
2 * Copyright (c) 2002-2004 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: Implements the definition of CICalProperty. |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 |
|
20 // Class include. |
|
21 #include "ICalProperty.h" // CICalProperty |
|
22 |
|
23 //debug |
|
24 #include "calendarengines_debug.h" |
|
25 |
|
26 // User includes. |
|
27 #include "ICalContentLineWriter.h" // CICalContentLineWriter |
|
28 #include "ICalErrors.h" // Error values |
|
29 #include "ICalKeyWords.h" // Literals |
|
30 #include "ICalPropertyParam.h" // CICalPropertyParam |
|
31 #include "ICalUtil.h" // NICalUtil |
|
32 #include "ICalValue.h" // CICalValue |
|
33 |
|
34 /** |
|
35 Constructs a new CICalProperty with given type and value and returns it. |
|
36 Note that other values may be added later. |
|
37 @param aType The type of the property. |
|
38 @param aValue The value of the property. |
|
39 @return a pointer to a new CICalProperty |
|
40 @publishedPartner |
|
41 */ |
|
42 EXPORT_C CICalProperty* CICalProperty::NewL(const TDesC& aType, const TDesC& aValue) |
|
43 { |
|
44 TRACE_ENTRY_POINT; |
|
45 |
|
46 CICalProperty* self = CICalProperty::NewLC(aType, aValue); |
|
47 CleanupStack::Pop(self); |
|
48 |
|
49 TRACE_EXIT_POINT; |
|
50 return self; |
|
51 } |
|
52 |
|
53 /** |
|
54 Constructs a new CICalProperty with given type and value, pushes it onto the |
|
55 Cleanup Stack, and returns it. Note that other values may be added later. |
|
56 @param aType The type of the property. |
|
57 @param aValue The value of the property. |
|
58 @return a pointer to a new CICalProperty |
|
59 @publishedPartner |
|
60 */ |
|
61 EXPORT_C CICalProperty* CICalProperty::NewLC(const TDesC& aType, const TDesC& aValue) |
|
62 { |
|
63 TRACE_ENTRY_POINT; |
|
64 |
|
65 CICalProperty* self = new (ELeave) CICalProperty; |
|
66 CleanupStack::PushL(self); |
|
67 self->ConstructL(aType, aValue); |
|
68 |
|
69 TRACE_EXIT_POINT; |
|
70 return self; |
|
71 } |
|
72 |
|
73 /** |
|
74 Constructs a new CICalProperty with given type and value and returns it. Takes |
|
75 ownership of the passed value pointer and deletes it if this function leaves. |
|
76 Note that other values may be added later. |
|
77 @param aType The type of the property. |
|
78 @param aValue The value of the property. |
|
79 @return a pointer to a new CICalProperty |
|
80 @leave Leaves with KErrPropertyHasNoValue if aValue is NULL. |
|
81 @publishedPartner |
|
82 */ |
|
83 EXPORT_C CICalProperty* CICalProperty::NewL(const TDesC& aType, CICalValue* aValue) |
|
84 { |
|
85 TRACE_ENTRY_POINT; |
|
86 |
|
87 CICalProperty* self = CICalProperty::NewLC(aType, aValue); |
|
88 CleanupStack::Pop(self); |
|
89 |
|
90 TRACE_EXIT_POINT; |
|
91 return self; |
|
92 } |
|
93 |
|
94 /** |
|
95 Constructs a new CICalProperty with given type and value, pushes it onto the |
|
96 Cleanup Stack, and returns it. Takes ownership of the passed value pointer and |
|
97 deletes it if this function leaves. Note that other values may be added later. |
|
98 @param aType The type of the property. |
|
99 @param aValue The value of the property. |
|
100 @return a pointer to a new CICalProperty |
|
101 @leave Leaves with KErrPropertyHasNoValue if aValue is NULL. |
|
102 @publishedPartner |
|
103 */ |
|
104 EXPORT_C CICalProperty* CICalProperty::NewLC(const TDesC& aType, CICalValue* aValue) |
|
105 { |
|
106 TRACE_ENTRY_POINT; |
|
107 |
|
108 // Test that the value is valid before construction. |
|
109 if (!aValue) |
|
110 { |
|
111 User::Leave(KErrPropertyHasNoValue); |
|
112 } |
|
113 |
|
114 // Push the passed value onto the Cleanup Stack. |
|
115 CleanupStack::PushL(aValue); |
|
116 |
|
117 // Create a new property. |
|
118 CICalProperty* self = new (ELeave) CICalProperty(aValue); |
|
119 |
|
120 // Pop the passed value from the Cleanup Stack as it is temporarily owned by self. |
|
121 CleanupStack::Pop(aValue); |
|
122 |
|
123 // Construct the property. |
|
124 CleanupStack::PushL(self); |
|
125 self->ConstructL(aType, aValue); |
|
126 |
|
127 TRACE_EXIT_POINT; |
|
128 return self; |
|
129 } |
|
130 |
|
131 /** |
|
132 Destructor. |
|
133 @internalTechnology |
|
134 */ |
|
135 CICalProperty::~CICalProperty() |
|
136 { |
|
137 TRACE_ENTRY_POINT; |
|
138 |
|
139 delete iValue; |
|
140 delete iType; |
|
141 iParams.ResetAndDestroy(); |
|
142 iValues.ResetAndDestroy(); |
|
143 |
|
144 TRACE_EXIT_POINT; |
|
145 } |
|
146 |
|
147 /** |
|
148 Constructs a new CICalProperty with given type and returns it |
|
149 @param aType The type of the property. |
|
150 @return a pointer to a new CICalProperty |
|
151 @internalTechnology |
|
152 */ |
|
153 CICalProperty* CICalProperty::NewL(const TDesC& aType) |
|
154 { |
|
155 TRACE_ENTRY_POINT; |
|
156 |
|
157 CICalProperty* self = CICalProperty::NewLC(aType); |
|
158 CleanupStack::Pop(self); |
|
159 |
|
160 TRACE_EXIT_POINT; |
|
161 return self; |
|
162 } |
|
163 |
|
164 /** |
|
165 Constructs a new CICalProperty with given type, pushes it onto the Cleanup |
|
166 Stack, and returns it. |
|
167 @param aType The type of the property. |
|
168 @return a pointer to a new CICalProperty. |
|
169 @internalTechnology |
|
170 */ |
|
171 CICalProperty* CICalProperty::NewLC(const TDesC& aType) |
|
172 { |
|
173 TRACE_ENTRY_POINT; |
|
174 |
|
175 CICalProperty* self = new (ELeave) CICalProperty; |
|
176 CleanupStack::PushL(self); |
|
177 self->ConstructL(aType); |
|
178 |
|
179 TRACE_EXIT_POINT; |
|
180 return self; |
|
181 } |
|
182 |
|
183 /** |
|
184 Gets the type of the property. |
|
185 @return The type of the property as a string. |
|
186 @publishedPartner |
|
187 */ |
|
188 EXPORT_C const TDesC& CICalProperty::Type() const |
|
189 { |
|
190 TRACE_ENTRY_POINT; |
|
191 TRACE_EXIT_POINT; |
|
192 return *iType; |
|
193 } |
|
194 |
|
195 /** |
|
196 Adds a parameter with given type and value to the property, taking ownership of |
|
197 the value. Note that further values may be added later. |
|
198 @param aType The type of property parameter. |
|
199 @param aValue A value of the property parameter - this will be deleted if this function leaves. |
|
200 @return A new property parameter. |
|
201 @leave Leaves with KErrParameterHasNoValue if aValue is NULL. |
|
202 @publishedPartner |
|
203 */ |
|
204 EXPORT_C CICalPropertyParam& CICalProperty::AddPropertyParamL(const TDesC& aType, CICalValue* aValue) |
|
205 { |
|
206 TRACE_ENTRY_POINT; |
|
207 |
|
208 if (!aValue) |
|
209 { |
|
210 User::Leave(KErrParameterHasNoValue); |
|
211 } |
|
212 |
|
213 CICalPropertyParam* param = CICalPropertyParam::NewLC(aType, aValue); |
|
214 User::LeaveIfError(iParams.Append(param)); |
|
215 CleanupStack::Pop(param); |
|
216 |
|
217 TRACE_EXIT_POINT; |
|
218 return *param; |
|
219 } |
|
220 |
|
221 /** |
|
222 Adds a parameter with given type and value to the property. |
|
223 Note that further values may be added later. |
|
224 @param aType The type of property parameter. |
|
225 @param aValue A value of the property parameter. |
|
226 @return A new property parameter. |
|
227 @leave Leaves with if there is an error adding a parameter. |
|
228 @publishedPartner |
|
229 */ |
|
230 EXPORT_C CICalPropertyParam& CICalProperty::AddPropertyParamL(const TDesC& aType, const TDesC& aValue) |
|
231 { |
|
232 TRACE_ENTRY_POINT; |
|
233 |
|
234 CICalPropertyParam* param = CICalPropertyParam::NewLC(aType, aValue); |
|
235 User::LeaveIfError(iParams.Append(param)); |
|
236 CleanupStack::Pop(param); |
|
237 |
|
238 TRACE_EXIT_POINT; |
|
239 return *param; |
|
240 } |
|
241 |
|
242 /** |
|
243 Adds a value to the property. Any escaped characters in the value string are |
|
244 translated to the actual characters. |
|
245 @param aValue The text string of the value, as would be entered into an |
|
246 iCalendar file. |
|
247 @leave Leaves if there is an error adding a value. |
|
248 @publishedPartner |
|
249 */ |
|
250 EXPORT_C void CICalProperty::AddValueL(const TDesC& aValue) |
|
251 { |
|
252 TRACE_ENTRY_POINT; |
|
253 |
|
254 HBufC* parameterValue = NULL; |
|
255 |
|
256 // Create a new value. |
|
257 CICalValue* value = CICalValue::NewLC(); |
|
258 |
|
259 // If the property has a text value then find any escaped characters and convert |
|
260 // them. Property values use backslash to escape the following characters: |
|
261 // commas, semi-colons, newlines (using \n or \N) and backslash itself. |
|
262 |
|
263 if (NICalUtil::PropertyHasTextValueL(*this)) |
|
264 { |
|
265 parameterValue = aValue.AllocLC(); |
|
266 TInt length(parameterValue->Length()); |
|
267 TBool escaped(EFalse); |
|
268 |
|
269 for (TInt location = 0; location < length; location++) |
|
270 { |
|
271 if (escaped) |
|
272 { |
|
273 if (((*parameterValue)[location] == KICalUpperCaseNChar) || |
|
274 ((*parameterValue)[location] == KICalLowerCaseNChar)) |
|
275 { |
|
276 // Found an escaped newline - replace with a single linefeed character. |
|
277 (parameterValue->Des()).operator[](location) = KICalNewlineChar; |
|
278 } |
|
279 |
|
280 // Else found an escaped backslash, semi-colon or comma, or |
|
281 // a single backslash (which is not valid). |
|
282 |
|
283 // In all cases remove the previous backslash character. |
|
284 // This assumes that (location - 1) >= 0, since escaped == ETrue |
|
285 // (The previous character was a backslash, so there *is* a previous character.) |
|
286 parameterValue->Des().Delete(location - 1, 1); |
|
287 length--; // The length of the descriptor has shrunk by one. |
|
288 location--; // The current character has slipped back a place. |
|
289 escaped = EFalse; |
|
290 } |
|
291 else |
|
292 { |
|
293 if ((*parameterValue)[location] == KICalBackslashChar) |
|
294 { |
|
295 escaped = ETrue; |
|
296 |
|
297 if (location == (length - 1)) |
|
298 { |
|
299 // Found a single backslash at the end - this is not valid, so remove it. |
|
300 parameterValue->Des().Delete(location, 1); |
|
301 break; |
|
302 } |
|
303 } |
|
304 } |
|
305 } |
|
306 } |
|
307 |
|
308 // Set the value. |
|
309 if (parameterValue) |
|
310 { |
|
311 value->SetTextL(*parameterValue); |
|
312 CleanupStack::PopAndDestroy(parameterValue); |
|
313 } |
|
314 else |
|
315 { |
|
316 // If the property does not have a text type then just use the given string as is... |
|
317 value->SetTextL(aValue); |
|
318 } |
|
319 |
|
320 // Append the new value to the list of values. |
|
321 User::LeaveIfError(iValues.Append(value)); |
|
322 CleanupStack::Pop(value); |
|
323 TRACE_EXIT_POINT; |
|
324 } |
|
325 |
|
326 /** |
|
327 Adds value to this property, taking ownership of the passed value pointer and |
|
328 deleting it if this function leaves. |
|
329 @param aValue The value to add - this must not be NULL. |
|
330 @leave Leaves with KErrPropertyHasNoValue if aValue is NULL. |
|
331 @publishedPartner |
|
332 */ |
|
333 EXPORT_C void CICalProperty::AddValueL(CICalValue* aValue) |
|
334 { |
|
335 TRACE_ENTRY_POINT; |
|
336 |
|
337 if (!aValue) |
|
338 { |
|
339 User::Leave(KErrPropertyHasNoValue); |
|
340 } |
|
341 |
|
342 // Append the value to the list of values. |
|
343 TInt err(iValues.Append(aValue)); |
|
344 |
|
345 if (err) |
|
346 { |
|
347 delete aValue; |
|
348 User::Leave(err); |
|
349 } |
|
350 TRACE_EXIT_POINT; |
|
351 } |
|
352 |
|
353 /** |
|
354 Access method for the array of parameters. |
|
355 @return The array of parameters. |
|
356 @publishedPartner |
|
357 */ |
|
358 EXPORT_C const RPointerArray<CICalPropertyParam>& CICalProperty::Parameters() const |
|
359 { |
|
360 TRACE_ENTRY_POINT; |
|
361 TRACE_EXIT_POINT; |
|
362 return iParams; |
|
363 } |
|
364 |
|
365 /** |
|
366 Access method for the array of properties. |
|
367 @return The array of properties. |
|
368 @publishedPartner |
|
369 */ |
|
370 EXPORT_C const RPointerArray<CICalValue>& CICalProperty::Values() const |
|
371 { |
|
372 TRACE_ENTRY_POINT; |
|
373 TRACE_EXIT_POINT; |
|
374 return iValues; |
|
375 } |
|
376 |
|
377 /** |
|
378 Find a parameter with the given name. Ownership is not passed out. |
|
379 @param aType The type of the parameter to search for |
|
380 @return A pointer to the parameter, or NULL if it is not found. |
|
381 @publishedPartner |
|
382 */ |
|
383 EXPORT_C const CICalPropertyParam* CICalProperty::FindParam(const TDesC& aType) const |
|
384 { |
|
385 TRACE_ENTRY_POINT; |
|
386 |
|
387 const TInt count = iParams.Count(); |
|
388 |
|
389 for (TInt p = 0; p < count; ++p) |
|
390 { |
|
391 if (iParams[p]->Type().CompareF(aType) == 0) |
|
392 { |
|
393 return iParams[p]; |
|
394 } |
|
395 } |
|
396 |
|
397 TRACE_EXIT_POINT; |
|
398 return NULL; |
|
399 } |
|
400 |
|
401 /** |
|
402 Adds an empty parameter to the property. |
|
403 @return A new, empty parameter. |
|
404 @leave Leaves if there is an error adding a parameter. |
|
405 @internalTechnology |
|
406 */ |
|
407 CICalPropertyParam& CICalProperty::AddPropertyParamL() |
|
408 { |
|
409 TRACE_ENTRY_POINT; |
|
410 |
|
411 CICalPropertyParam* param = CICalPropertyParam::NewLC(); |
|
412 User::LeaveIfError(iParams.Append(param)); |
|
413 CleanupStack::Pop(param); |
|
414 |
|
415 TRACE_EXIT_POINT; |
|
416 return *param; |
|
417 } |
|
418 |
|
419 /** |
|
420 Removes the given parameter from the property. |
|
421 @param aParam The parameter to remove. |
|
422 @leave Leaves in debug mode if the parameter is not found (release mode ignores |
|
423 this). |
|
424 @internalTechnology |
|
425 */ |
|
426 void CICalProperty::RemovePropertyParamL(const CICalPropertyParam& aParam) |
|
427 { |
|
428 TRACE_ENTRY_POINT; |
|
429 |
|
430 // Find the parameter to remove. |
|
431 TInt index = iParams.Find(&aParam, CICalPropertyParam::EqualsL); |
|
432 |
|
433 #ifdef _DEBUG |
|
434 User::LeaveIfError(index); // Not expecting this. |
|
435 #else // _DEBUG |
|
436 if (index < 0) |
|
437 { |
|
438 return; // Return quietly in release builds |
|
439 } |
|
440 #endif // _DEBUG |
|
441 |
|
442 // Destroy the parameter and remove it. |
|
443 delete iParams[index]; |
|
444 iParams.Remove(index); |
|
445 |
|
446 TRACE_EXIT_POINT; |
|
447 } |
|
448 |
|
449 /** |
|
450 Export this property using the given line writer, escaping any necessary |
|
451 characters. Assumes it contains at least one value from the check in |
|
452 CICalBase::ExternalizeL(). |
|
453 @param aWriter The content line writer to export to. |
|
454 @internalTechnology |
|
455 */ |
|
456 void CICalProperty::ExternalizeL(CICalContentLineWriter& aWriter) |
|
457 { |
|
458 TRACE_ENTRY_POINT; |
|
459 |
|
460 // Export property name. |
|
461 aWriter.AppendL(*iType); |
|
462 |
|
463 // Export parameters. |
|
464 const TInt paramCount = iParams.Count(); |
|
465 |
|
466 for (TInt x = 0; x < paramCount; ++x) |
|
467 { |
|
468 if (iParams[x]->Values().Count() > 0) |
|
469 { |
|
470 aWriter.AppendL(KICalSemiColon()); |
|
471 iParams[x]->ExternalizeL(aWriter); |
|
472 } |
|
473 } |
|
474 |
|
475 // Export values. |
|
476 aWriter.AppendL(KICalColon()); |
|
477 |
|
478 const TInt valCount = iValues.Count(); |
|
479 |
|
480 for (TInt x = 0; x < valCount; ++x) |
|
481 { |
|
482 const TDesC& value = iValues[x]->TextL(); |
|
483 |
|
484 // If the property has a text value then escape any necessary characters. |
|
485 if (NICalUtil::PropertyHasTextValueL(*this)) |
|
486 { |
|
487 const TInt valueLength = value.Length(); |
|
488 |
|
489 // Export each value a character at a time, translating any characters that need escaping. |
|
490 for (TInt character = 0; character < valueLength; character++) |
|
491 { |
|
492 // Property values use backslash to escape the following characters: |
|
493 // commas, semi-colons, newlines (using \n or \N) and backslash itself. |
|
494 if ((value[character] == KICalBackslashChar) || |
|
495 (value[character] == KICalSemiColonChar) || |
|
496 (value[character] == KICalCommaChar)) |
|
497 { |
|
498 aWriter.AppendL(KICalBackslash()); |
|
499 aWriter.AppendL(value[character]); |
|
500 } |
|
501 else if (value[character] == KICalNewlineChar) |
|
502 { |
|
503 aWriter.AppendL(KICalBackslashN()); |
|
504 } |
|
505 else |
|
506 { |
|
507 aWriter.AppendL(value[character]); |
|
508 } |
|
509 } |
|
510 } |
|
511 else // No escaping needed. |
|
512 { |
|
513 aWriter.AppendL(value); |
|
514 } |
|
515 |
|
516 if (x < valCount -1) |
|
517 { |
|
518 aWriter.AppendL(KICalComma()); |
|
519 } |
|
520 } |
|
521 |
|
522 aWriter.WriteContentLineL(); |
|
523 |
|
524 TRACE_EXIT_POINT; |
|
525 } |
|
526 |
|
527 /** |
|
528 Constructor |
|
529 @internalTechnology |
|
530 */ |
|
531 CICalProperty::CICalProperty() |
|
532 { |
|
533 TRACE_ENTRY_POINT; |
|
534 TRACE_EXIT_POINT; |
|
535 } |
|
536 |
|
537 /** |
|
538 Constructor |
|
539 @param aValue The initial value. |
|
540 @internalTechnology |
|
541 */ |
|
542 CICalProperty::CICalProperty(CICalValue* aValue) |
|
543 : iValue(aValue) |
|
544 { |
|
545 TRACE_ENTRY_POINT; |
|
546 TRACE_EXIT_POINT; |
|
547 } |
|
548 |
|
549 /** |
|
550 Internal construction |
|
551 @param aType The type of property. |
|
552 @internalTechnology |
|
553 */ |
|
554 void CICalProperty::ConstructL(const TDesC& aType) |
|
555 { |
|
556 TRACE_ENTRY_POINT; |
|
557 |
|
558 iType = aType.AllocL(); |
|
559 |
|
560 TRACE_EXIT_POINT; |
|
561 } |
|
562 |
|
563 /** |
|
564 Internal construction. |
|
565 @param aType The type of property. |
|
566 @param aValue A value of the property. |
|
567 @internalTechnology |
|
568 */ |
|
569 void CICalProperty::ConstructL(const TDesC& aType, const TDesC& aValue) |
|
570 { |
|
571 TRACE_ENTRY_POINT; |
|
572 |
|
573 ConstructL(aType); |
|
574 |
|
575 // Add the value. |
|
576 AddValueL(aValue); |
|
577 |
|
578 TRACE_EXIT_POINT; |
|
579 } |
|
580 |
|
581 /** |
|
582 Internal construction. Takes ownership of the passed value pointer and |
|
583 deletes it if this function leaves. |
|
584 @param aType The type of property. |
|
585 @param aValue A value of the property - this class takes ownership. |
|
586 @internalTechnology |
|
587 */ |
|
588 void CICalProperty::ConstructL(const TDesC& aType, CICalValue* aValue) |
|
589 { |
|
590 TRACE_ENTRY_POINT; |
|
591 |
|
592 ConstructL(aType); |
|
593 |
|
594 // Add the value. |
|
595 iValue = NULL; // If we got this far then we can release direct ownership of the value. |
|
596 AddValueL(aValue); // Value is deleted if this leaves. |
|
597 |
|
598 TRACE_EXIT_POINT; |
|
599 } |
|
600 |
|
601 // End of File |