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