|
1 // Copyright (c) 1997-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 <vcard.h> |
|
17 |
|
18 #include <s32mem.h> |
|
19 |
|
20 #include <vutil.h> |
|
21 #include <vstaticutils.h> |
|
22 #include "verror.h" |
|
23 #include <vobserv.h> |
|
24 #include "vpbapplugin.h" |
|
25 #ifdef SYMBIAN_ENABLE_SPLIT_HEADERS |
|
26 #include "vcard3.h" |
|
27 #endif |
|
28 |
|
29 _LIT(KVersitTokenVCard3VersionNo, "3.0"); |
|
30 |
|
31 |
|
32 |
|
33 _LIT8(KVCard3LineBreakAndWSP, "\r\n "); |
|
34 _LIT8(KVCard3TokenB, "b"); |
|
35 |
|
36 const TUint KTokenNewLineVal = 'n'; |
|
37 const TUint KTokenCarriageReturnVal = '\r'; |
|
38 const TUint KTokenLineFeedVal = '\n'; |
|
39 |
|
40 const TInt KMaxVCard3LineLength = 75; //line length recommended in RFC2426 |
|
41 |
|
42 // |
|
43 // CParserVCard |
|
44 // |
|
45 EXPORT_C CParserVCard* CParserVCard::NewL() |
|
46 /** Allocates and constructs a vCard parser. |
|
47 |
|
48 @return A pointer to the newly constructed vCard parser. */ |
|
49 { |
|
50 CParserVCard* self=new(ELeave) CParserVCard(); |
|
51 CleanupStack::PushL(self); |
|
52 self->ConstructL(); |
|
53 CleanupStack::Pop(self); |
|
54 return self; |
|
55 } |
|
56 |
|
57 CParserVCard* CParserVCard::NewL(TBool aParsingAgent) |
|
58 /* Allocates and constructs a vCard parser. |
|
59 This is used internally to limit the number of recursive AGENT vcards that |
|
60 may be found within an AGENT property */ |
|
61 { |
|
62 CParserVCard* self=new(ELeave) CParserVCard(aParsingAgent); |
|
63 CleanupStack::PushL(self); |
|
64 self->ConstructL(); |
|
65 CleanupStack::Pop(self); |
|
66 return self; |
|
67 } |
|
68 |
|
69 CParserVCard::CParserVCard() |
|
70 : CVersitParser(ESupportsVersion), iParsingAgent(EFalse) |
|
71 { |
|
72 iDefaultVersion = KVersitTokenVCardVersionNo; |
|
73 } |
|
74 |
|
75 CParserVCard::CParserVCard(TBool aParsingAgent) |
|
76 : CVersitParser(ESupportsVersion), iParsingAgent(aParsingAgent) |
|
77 { |
|
78 iDefaultVersion = KVersitTokenVCardVersionNo; |
|
79 } |
|
80 |
|
81 EXPORT_C CArrayPtr<CParserProperty>* CParserVCard::GroupOfPropertiesL(const TDesC8& aGroupName) const |
|
82 /** Gets an array of all properties in the named property group from the vCard entity. |
|
83 |
|
84 A property group is a collection of related properties, identified by a group name. |
|
85 |
|
86 Ownership of the properties is not transferred. |
|
87 |
|
88 @param aGroupName The name of the property group of interest. |
|
89 @return An array of all properties in the specified group. NULL if the named property |
|
90 group was not found. */ |
|
91 { |
|
92 if (!iArrayOfProperties) |
|
93 return NULL; |
|
94 |
|
95 TInt properties=iArrayOfProperties->Count(); |
|
96 CArrayPtr<CParserProperty>* arrayOfGroupedProperties=new(ELeave) CArrayPtrFlat<CParserProperty>(5); |
|
97 CleanupStack::PushL(arrayOfGroupedProperties); |
|
98 TUid uid; |
|
99 CParserGroupedProperty* groupedProperty; |
|
100 for (TInt ii=0; ii<properties; ii++) |
|
101 { |
|
102 uid.iUid=KVersitGroupedPropertyUid; |
|
103 if ((*iArrayOfProperties)[ii]->SupportsInterface(uid)) |
|
104 { |
|
105 groupedProperty=STATIC_CAST(CParserGroupedProperty*,(*iArrayOfProperties)[ii]); |
|
106 if(groupedProperty->Group(aGroupName)) |
|
107 arrayOfGroupedProperties->AppendL((*iArrayOfProperties)[ii]); |
|
108 } |
|
109 } |
|
110 CleanupStack::Pop(arrayOfGroupedProperties); |
|
111 if (arrayOfGroupedProperties->Count()) |
|
112 return arrayOfGroupedProperties; |
|
113 delete arrayOfGroupedProperties; |
|
114 return NULL; |
|
115 } |
|
116 |
|
117 EXPORT_C void CParserVCard::InternalizeL(RReadStream& aStream) |
|
118 /** Internalises a vCard entity from a read stream. |
|
119 |
|
120 The presence of this function means that the standard templated operator>>() |
|
121 (defined in s32strm.h) is available to internalise objects of this class. |
|
122 |
|
123 @param aStream Stream from which the vCard entity should be internalised. |
|
124 @see CVersitParser::InternalizeL() */ |
|
125 { |
|
126 // Generic Internalize that loads properties\values with no extra processing |
|
127 CVersitParser::InternalizeL(aStream); |
|
128 } |
|
129 |
|
130 EXPORT_C void CParserVCard::ConvertDateTimesToMachineLocalAndDeleteTZL() |
|
131 /** Converts all date/time property values contained in the vCard entity into machine |
|
132 local values (including all date/time values contained in agent properties). |
|
133 |
|
134 This conversion is needed because of differences in universal and local times |
|
135 due to time zones. |
|
136 |
|
137 Finds the necessary increment to compensate for the time zone, using the value |
|
138 given by the first time zone property (named KVersitTokenTZ) in the array |
|
139 of properties. This increment is passed as a parameter to ConvertAllPropertyDateTimesToMachineLocalL(). |
|
140 The CVersitDaylight* parameter passed to ConvertAllPropertyDateTimesToMachineLocalL() |
|
141 is NULL, so no compensation can be made by this function for any daylight |
|
142 saving (seasonal time shift). |
|
143 @deprecated since 9.1 |
|
144 */ |
|
145 { |
|
146 CArrayPtr<CParserProperty>* arrayOfTimeZones = PropertyL(KVersitTokenTZ, TUid::Uid(KVersitPropertyTimeZoneUid),ETrue); |
|
147 if (!arrayOfTimeZones) |
|
148 { |
|
149 if (iFlags&EImportSyncML) |
|
150 AdjustAllPropertyDateTimesToMachineLocalL(); |
|
151 return; |
|
152 } |
|
153 |
|
154 CleanupStack::PushL(TCleanupItem(ResetAndDestroyArrayOfProperties, arrayOfTimeZones)); |
|
155 CParserPropertyValueTimeZone* timeZone = STATIC_CAST(CParserPropertyValueTimeZone*, (*arrayOfTimeZones)[0]->Value()); |
|
156 TTimeIntervalSeconds increment = timeZone->Value().Int(); |
|
157 ConvertAllPropertyDateTimesToMachineLocalL(increment,NULL); |
|
158 CleanupStack::PopAndDestroy(arrayOfTimeZones); |
|
159 } |
|
160 |
|
161 EXPORT_C void CParserVCard::ExternalizeL(RWriteStream& aStream) |
|
162 /** Externalises a vCard entity (and all sub-entities) to a write stream. |
|
163 |
|
164 Sets the entity name to KVersitVarTokenVCARD if it hasn't already been set. |
|
165 |
|
166 Adds a version property to the start of the current entity's array of properties |
|
167 if the entity supports this. (If there isn't an array of properties then one |
|
168 is made). |
|
169 |
|
170 The presence of this function means that the standard templated operator<<() |
|
171 (defined in s32strm.h) is available to externalise objects of this class. |
|
172 |
|
173 @param aStream Stream to which the vCard entity should be externalised. |
|
174 @see CVersitParser::ExternalizeL() */ |
|
175 { |
|
176 if (!iEntityName) |
|
177 SetEntityNameL(KVersitVarTokenVCARD); |
|
178 CVersitParser::ExternalizeL(aStream); |
|
179 } |
|
180 |
|
181 EXPORT_C void CParserVCard::ConvertAllPropertyDateTimesToMachineLocalL(const TTimeIntervalSeconds& aIncrement,const CVersitDaylight* aDaylight) |
|
182 /** Converts all date/time property values contained in the vCard entity into machine |
|
183 local values (including all date/time values contained in agent properties). |
|
184 |
|
185 This conversion is needed because of differences in universal and local times |
|
186 due to time zones and daylight savings (seasonal time shifts). |
|
187 |
|
188 If there is a daylight savings rule associated with the date/time (held in |
|
189 the aDaylight parameter) then this will be used to compensate for differences |
|
190 between universal and local times due to both time zones and the daylight |
|
191 savings rule. Otherwise, the aIncrement parameter is used to compensate for |
|
192 any difference due to time zones alone. |
|
193 |
|
194 @param aIncrement A time interval in seconds which represents the negative |
|
195 of the time zone of the originating machine. For instance, if the time zone |
|
196 is +04:30, aIncrement should be set to -04:30. |
|
197 @param aDaylight Pointer to the specification for daylight saving. If the date/time |
|
198 value is within the period for daylight saving, the value is modified by the |
|
199 daylight saving offset (which accounts for both the time zone and daylight |
|
200 saving rule). |
|
201 @deprecated since 9.1 |
|
202 */ |
|
203 { |
|
204 CVersitParser::ConvertAllPropertyDateTimesToMachineLocalL(aIncrement,aDaylight); |
|
205 CArrayPtr<CParserProperty>* properties = PropertyL(KVersitTokenAGENT, TUid::Uid(KVCardPropertyAgentUid), EFalse); |
|
206 if (!properties) |
|
207 return; |
|
208 CleanupStack::PushL(properties); |
|
209 TInt count = properties->Count(); |
|
210 CParserPropertyValueAgent* agent; |
|
211 for (TInt ii = 0; ii < count; ii++) |
|
212 { |
|
213 agent = STATIC_CAST(CParserPropertyValueAgent*, (*properties)[ii]->Value()); |
|
214 if (agent && agent->Value()) |
|
215 agent->Value()->ConvertAllPropertyDateTimesToMachineLocalL(aIncrement, aDaylight); |
|
216 } |
|
217 CleanupStack::PopAndDestroy(properties); |
|
218 } |
|
219 |
|
220 EXPORT_C CParserPropertyValue* CParserVCard::MakePropertyValueAgentL(TPtr16 aValue) |
|
221 { |
|
222 if(!iParsingAgent) |
|
223 { |
|
224 HBufC* entityName = NULL; |
|
225 TInt start=aValue.Find(KVersitVarTokenBEGIN); |
|
226 if (start>KErrNotFound) |
|
227 { //BEGIN is on the same line as AGENT |
|
228 start+=KVersitVarTokenBEGIN.iTypeLength; |
|
229 TInt length=aValue.Length()-start; |
|
230 aValue.Set(&aValue[start],length,length); |
|
231 start=aValue.Find(KVersitTokenColonUnicode); |
|
232 if (start==KErrNotFound) |
|
233 User::Leave(KErrNotFound); |
|
234 start+=KVersitTokenColonUnicode.iTypeLength; |
|
235 length=aValue.Length()-start; |
|
236 if (length==0) |
|
237 User::Leave(KErrNotFound); |
|
238 aValue.Set(&aValue[start],length,length); |
|
239 VersitUtils::StripWhiteSpace(aValue); |
|
240 entityName=aValue.AllocLC(); |
|
241 } |
|
242 else |
|
243 { |
|
244 TBool moreCharsOnLine = VersitUtils::IsNoneWhiteSpaceWideChar(aValue); |
|
245 if( EFalse == moreCharsOnLine ) |
|
246 { // ... rest of line is empty, so BEGIN is on a following line |
|
247 CParserProperty* agentProperty=iCurrentProperty; |
|
248 iCurrentProperty=NULL; |
|
249 CleanupStack::PushL(agentProperty); |
|
250 ParsePropertyL(); |
|
251 if (iCurrentProperty->NameUid().iUid!=KVersitTokenBeginUid) |
|
252 User::Leave(KVersitErrNestedVcardExpected); |
|
253 entityName=STATIC_CAST(CParserPropertyValueHBufC*,iCurrentProperty->Value())->TakeValueOwnership(); |
|
254 delete iCurrentProperty; |
|
255 CleanupStack::Pop(agentProperty); |
|
256 iCurrentProperty=agentProperty; |
|
257 CleanupStack::PushL(entityName); |
|
258 } |
|
259 else |
|
260 { // ... rest of line contains non-standard data, ignore it. |
|
261 User::Leave(KVersitErrNestedVcardExpected); |
|
262 } |
|
263 } |
|
264 |
|
265 // create a parser setting iAgentParsing member variable to true |
|
266 CParserVCard* parser=CParserVCard::NewL(ETrue); |
|
267 CleanupStack::PushL(parser); |
|
268 if (iObserver) |
|
269 { |
|
270 iObserver->NewParser(parser); |
|
271 } |
|
272 |
|
273 parser->SetAutoDetect(iFlags&EUseAutoDetection,iAutoDetectCharSets); |
|
274 |
|
275 parser->CVersitParser::InternalizeL(entityName, iLineReader); |
|
276 CleanupStack::Pop(2, entityName); |
|
277 CleanupStack::PushL(parser); |
|
278 |
|
279 CParserPropertyValue* propertyValue=new(ELeave)CParserPropertyValueAgent(parser); |
|
280 CleanupStack::Pop(parser); |
|
281 return propertyValue; |
|
282 } |
|
283 |
|
284 // we leave if iParsingAgent is ETrue because we do not support nested agent properties |
|
285 delete iCurrentProperty; |
|
286 iCurrentProperty=NULL; |
|
287 User::Leave(KErrNotSupported); |
|
288 return NULL; // satisfy compiler |
|
289 } |
|
290 |
|
291 |
|
292 |
|
293 EXPORT_C CDesC8Array* CParserVCard::GetGroupNamesL(TPtr8& aGroupsAndName) |
|
294 { |
|
295 CDesC8Array* arrayOfGroups=NULL; |
|
296 TInt periodPos; |
|
297 TInt len; |
|
298 FOREVER |
|
299 { |
|
300 periodPos=aGroupsAndName.Find(KVersitTokenPeriod); |
|
301 if (periodPos==KErrNotFound) |
|
302 break; |
|
303 if (!arrayOfGroups) |
|
304 { |
|
305 arrayOfGroups=new(ELeave) CDesC8ArrayFlat(5); |
|
306 CleanupStack::PushL(arrayOfGroups); |
|
307 } |
|
308 arrayOfGroups->AppendL(TPtrC8(&aGroupsAndName[0],periodPos)); |
|
309 len=aGroupsAndName.Length()-(++periodPos); |
|
310 |
|
311 // INC113960:vCard crash when parsing random data |
|
312 //data cause crash:"ariat@etsi.fr=0D=0ATel.:" |
|
313 //In the case there is no data after the KVersitTokenPeriod, don't set aGroupsAndName. |
|
314 if (len ==0) |
|
315 { |
|
316 break; |
|
317 } |
|
318 |
|
319 aGroupsAndName.Set(&aGroupsAndName[periodPos],len,len); |
|
320 } |
|
321 if (arrayOfGroups) |
|
322 CleanupStack::Pop(arrayOfGroups); |
|
323 return arrayOfGroups; |
|
324 } |
|
325 |
|
326 EXPORT_C void CParserVCard::ParsePropertyL() |
|
327 { |
|
328 TInt valueStart; |
|
329 TInt lenNameGroup; |
|
330 CArrayPtr<CParserParam>* arrayOfParams=ReadLineAndDecodeParamsLC(valueStart,lenNameGroup); |
|
331 TPtr8 propName(&BufPtr()[0],lenNameGroup,lenNameGroup); |
|
332 CDesC8Array* arrayOfGroups=GetGroupNamesL(propName); |
|
333 if (arrayOfGroups) |
|
334 CleanupStack::PushL(arrayOfGroups); |
|
335 iCurrentProperty=new(ELeave) CParserGroupedProperty(arrayOfGroups,arrayOfParams); |
|
336 if (arrayOfGroups) |
|
337 CleanupStack::Pop(arrayOfGroups); |
|
338 CleanupStack::Pop(arrayOfParams); |
|
339 // Change according to defect DEF022049. If a vCard property does not have a name, |
|
340 // it should not create a property for this field. |
|
341 if (propName.Length()>0) |
|
342 { |
|
343 MakePropertyL(propName,valueStart); |
|
344 } |
|
345 else |
|
346 { |
|
347 User::Leave(KVersitErrNoPropertyName); |
|
348 } |
|
349 } |
|
350 |
|
351 EXPORT_C CParserPropertyValue* CParserVCard::MakePropertyValueL(const TUid& aPropertyUid, HBufC16*& aValue) |
|
352 /** Creates a property value, by parsing the specified descriptor. |
|
353 |
|
354 This function overrides CVersitParser::MakePropertyValueL() to ensure that agent and |
|
355 sound properties are correctly recognised and constructed. |
|
356 |
|
357 Note that aValue may be set to NULL on return from this method. |
|
358 |
|
359 @param aPropertyUid The UID type associated with the raw property string. |
|
360 @param aValue The raw property value descriptor. The function removes anything that |
|
361 is not part of the property. |
|
362 @return A property value. */ |
|
363 { |
|
364 if(!aValue && (aPropertyUid.iUid != KVersitPropertyBinaryUid || !iLargeDataBuf)) |
|
365 { |
|
366 return NULL; |
|
367 } |
|
368 |
|
369 switch (aPropertyUid.iUid) |
|
370 { |
|
371 case KVCardPropertyAgentUid: |
|
372 { |
|
373 return MakePropertyValueAgentL(aValue->Des()); |
|
374 } |
|
375 case KVCardPropertySoundUid: |
|
376 { |
|
377 return MakePropertyValueSoundL(aValue); |
|
378 } |
|
379 default: |
|
380 { |
|
381 return CVersitParser::MakePropertyValueL(aPropertyUid,aValue); |
|
382 } |
|
383 }; |
|
384 } |
|
385 |
|
386 EXPORT_C CParserPropertyValue* CParserVCard::MakePropertyValueSoundL(HBufC16*& aValue) |
|
387 /** Creates a property value object from a SOUND property value. |
|
388 |
|
389 SOUND property values can either contain a single string (using HBufC storage) |
|
390 or, following the addition of Japanese pronunciation support to Symbian's |
|
391 Versit API, an array (using CDesCArray storage). This method allocates |
|
392 the additional storage needed to support array-based sound properties, when |
|
393 necessary. |
|
394 |
|
395 Note that aValue will be set to NULL on return from this method. |
|
396 |
|
397 @param aValue The raw property value descriptor. |
|
398 @return A constructed sound property value. */ |
|
399 { |
|
400 // Allocate additional storage if necessary |
|
401 if(!aValue) |
|
402 return NULL; |
|
403 |
|
404 HBufC16 *buf = HBufC16::NewLC(aValue->Length()); |
|
405 *buf = *aValue;//copy avalue into buf |
|
406 |
|
407 TPtr16 pValue(buf->Des()); |
|
408 //pass copy of avalue into AllocateAdditionalPropertyStorageL so that RemoveEscapeChars isnt applied twice to the string |
|
409 VersitUtils::AllocateAdditionalPropertyStorageL(*iStaticUtils, *iCurrentProperty, pValue, LineCharSetId()); |
|
410 |
|
411 // Now we remove any escaping |
|
412 VersitUtils::RemoveEscapeChars(*aValue, LineCharSetId()); |
|
413 |
|
414 CleanupStack::PopAndDestroy( buf ); |
|
415 |
|
416 // ... and create a property value |
|
417 CParserPropertyValueHBufC* returnedValue = new(ELeave) CParserPropertyValueHBufC(aValue); |
|
418 aValue = NULL; |
|
419 return returnedValue; |
|
420 } |
|
421 |
|
422 EXPORT_C TUid CParserVCard::RecognizeToken(const TDesC8& aToken) const |
|
423 // From CVersitParser - extra recognition capablities are added by overriding this |
|
424 // virtual function. These properties are specific to vCards |
|
425 /** Returns a UID that identifies a specified token's type. |
|
426 |
|
427 For example, if aToken contains the property name BDAY, the function returns |
|
428 KVersitPropertyDateUid. If the token is not recognized as vCard-specific, the |
|
429 function calls CVersitParser::RecognizeToken(), which recognizes generic Versit |
|
430 tokens. |
|
431 |
|
432 @param aToken The token to be recognized. |
|
433 @return A defined UID value if the token is recognized and KVersitTokenUnknownUid |
|
434 if not. */ |
|
435 { |
|
436 TUid uid = KNullUid; |
|
437 TChar firstChar(aToken.Ptr()[0]); |
|
438 firstChar=firstChar.GetUpperCase(); |
|
439 switch (firstChar) |
|
440 { |
|
441 case 'A': |
|
442 if (!aToken.CompareF(KVersitTokenADR)) |
|
443 uid.iUid=KVersitPropertyCDesCArrayUid; |
|
444 else if (!aToken.CompareF(KVersitTokenAGENT)) |
|
445 uid.iUid=KVCardPropertyAgentUid; |
|
446 break; |
|
447 case 'B': |
|
448 if (!aToken.CompareF(KVersitTokenBDAY)) |
|
449 uid.iUid=KVersitPropertyDateUid; |
|
450 break; |
|
451 case 'E': |
|
452 if (!aToken.CompareF(KVersitTokenEMAIL)) |
|
453 uid.iUid=KVersitPropertyHBufCUid; |
|
454 break; |
|
455 case 'F': |
|
456 if (!aToken.CompareF(KVersitTokenFN)) |
|
457 uid.iUid=KVersitPropertyHBufCUid; |
|
458 break; |
|
459 case 'G': |
|
460 if (!aToken.CompareF(KVersitTokenGEO)) |
|
461 uid.iUid=KVersitPropertyHBufCUid; |
|
462 break; |
|
463 case 'K': |
|
464 if (!aToken.CompareF(KVersitTokenKEY)) |
|
465 { |
|
466 Versit::TVersitEncoding encodingValue = LineEncoding(); |
|
467 if(encodingValue == Versit::EBase64Encoding) |
|
468 { |
|
469 uid.iUid = KVersitPropertyBinaryUid; |
|
470 } |
|
471 else |
|
472 { |
|
473 uid.iUid=KVersitPropertyHBufCUid; |
|
474 } |
|
475 } |
|
476 break; |
|
477 case 'L': |
|
478 if (!aToken.CompareF(KVersitTokenLABEL)) |
|
479 uid.iUid=KVersitPropertyHBufCUid; |
|
480 else if (!aToken.CompareF(KVersitTokenLOGO)) |
|
481 uid.iUid=KVersitPropertyBinaryUid; |
|
482 break; |
|
483 case 'M': |
|
484 if (!aToken.CompareF(KVersitTokenMAILER)) |
|
485 uid.iUid=KVersitPropertyHBufCUid; |
|
486 break; |
|
487 case 'N': |
|
488 if (!aToken.CompareF(KVersitTokenN)) |
|
489 uid.iUid=KVersitPropertyCDesCArrayUid; |
|
490 else if (!aToken.CompareF(KVersitTokenNOTE)) |
|
491 uid.iUid=KVersitPropertyHBufCUid; |
|
492 break; |
|
493 case 'O': |
|
494 if (!aToken.CompareF(KVersitTokenORG)) |
|
495 uid.iUid=KVersitPropertyCDesCArrayUid; |
|
496 break; |
|
497 case 'P': |
|
498 if (!aToken.CompareF(KVersitTokenPHOTO)) |
|
499 uid.iUid=KVersitPropertyBinaryUid; |
|
500 break; |
|
501 case 'R': |
|
502 if (!aToken.CompareF(KVersitTokenREV)) |
|
503 uid.iUid=KVersitPropertyDateTimeUid; |
|
504 else if (!aToken.CompareF(KVersitTokenROLE)) |
|
505 uid.iUid=KVersitPropertyHBufCUid; |
|
506 break; |
|
507 case 'S': |
|
508 if (!aToken.CompareF(KVersitTokenSOUND)) |
|
509 uid.iUid=KVCardPropertySoundUid; |
|
510 break; |
|
511 case 'T': |
|
512 if (!aToken.CompareF(KVersitTokenTZ)) |
|
513 uid.iUid=KVersitPropertyTimeZoneUid; |
|
514 else if ((!aToken.CompareF(KVersitTokenTEL)) |
|
515 ||(!aToken.CompareF(KVersitTokenTITLE))) |
|
516 uid.iUid=KVersitPropertyHBufCUid; |
|
517 break; |
|
518 case 'U': |
|
519 if ((!aToken.CompareF(KVersitTokenURL)) |
|
520 ||(!aToken.CompareF(KVersitTokenUID))) |
|
521 uid.iUid=KVersitPropertyHBufCUid; |
|
522 break; |
|
523 case 'V': |
|
524 if (!aToken.CompareF(KVersitTokenVERSION)) |
|
525 uid.iUid=KVersitTokenVersionUid; |
|
526 break; |
|
527 case 'X': |
|
528 if (!aToken.CompareF(KVersitTokenSECONDNAME)) |
|
529 { |
|
530 uid.iUid=KVersitPropertyHBufCUid; |
|
531 } |
|
532 else if (!aToken.CompareF(KVersitTokenAssistant)) |
|
533 { |
|
534 uid.iUid=KVersitPropertyHBufCUid; |
|
535 } |
|
536 else if (!aToken.CompareF(KVersitTokenAssistantTel)) |
|
537 { |
|
538 uid.iUid=KVersitPropertyHBufCUid; |
|
539 } |
|
540 else if (!aToken.CompareF(KVersitTokenAnniversary)) |
|
541 { |
|
542 uid.iUid=KVersitPropertyDateUid; |
|
543 } |
|
544 else if (!aToken.CompareF(KVersitTokenSpouse)) |
|
545 { |
|
546 uid.iUid=KVersitPropertyHBufCUid; |
|
547 } |
|
548 else if (!aToken.CompareF(KVersitTokenChildren)) |
|
549 { |
|
550 uid.iUid=KVersitPropertyCDesCArrayUid; |
|
551 } |
|
552 else if (!aToken.CompareF(KVersitTokenClass)) |
|
553 { |
|
554 uid.iUid=KVersitPropertyHBufCUid; |
|
555 } |
|
556 break; |
|
557 default: |
|
558 break; |
|
559 } |
|
560 if (uid == KNullUid) // If a vCard specific property was not recognised then get the base class to see if it recognises the token. |
|
561 return CVersitParser::RecognizeToken(aToken); |
|
562 return uid; |
|
563 } |
|
564 |
|
565 EXPORT_C void CParserVCard::Reserved1() |
|
566 {} |
|
567 |
|
568 EXPORT_C void CParserVCard::Reserved2() |
|
569 {} |
|
570 |
|
571 // |
|
572 // CParserVCard3 |
|
573 // |
|
574 EXPORT_C CParserVCard3* CParserVCard3::NewL() |
|
575 /** Allocates and constructs a vCard 3.0 parser. |
|
576 |
|
577 @return A pointer to the newly constructed vCard parser. */ |
|
578 { |
|
579 CParserVCard3* self = new(ELeave) CParserVCard3(); |
|
580 CleanupStack::PushL(self); |
|
581 self->ConstructL(); |
|
582 CleanupStack::Pop(self); |
|
583 return self; |
|
584 } |
|
585 |
|
586 void CParserVCard3::ConstructL() |
|
587 /** Second phase constructor.*/ |
|
588 { |
|
589 CVersitParser::ConstructL(); |
|
590 CreateParserPlugInL(); |
|
591 } |
|
592 |
|
593 CParserVCard3::~CParserVCard3() |
|
594 /** Frees all resources owned by the vCard parser, prior to its destruction. */ |
|
595 { |
|
596 delete iPlugInImpl; |
|
597 } |
|
598 |
|
599 CParserVCard3::CParserVCard3() |
|
600 { |
|
601 iDefaultVersion = KVersitTokenVCard3VersionNo; |
|
602 } |
|
603 |
|
604 void CParserVCard3::CreateParserPlugInL() |
|
605 /** Create Versit plugin to enable vCard 3.0 format export as defined |
|
606 by RFC2425 and RFC2426 */ |
|
607 { |
|
608 iPlugInImpl = new(ELeave) CVCard3ParserPlugIn; |
|
609 SetPlugIn(iPlugInImpl); |
|
610 } |
|
611 |
|
612 EXPORT_C void CParserVCard3::InternalizeL(RReadStream& /*aStream*/) |
|
613 /** Internalises a vCard 3.0 entity from a read stream. |
|
614 Always leaves with KErrNotSupported because this class should only |
|
615 be used for vCard 3.0 export |
|
616 |
|
617 @param aStream Stream from which the vCard entity should be internalised. |
|
618 */ |
|
619 { |
|
620 User::Leave(KErrNotSupported); |
|
621 } |
|
622 |
|
623 |
|
624 // |
|
625 // CVCard3ParserPlugIn |
|
626 // |
|
627 TBool CVCard3ParserPlugIn::AddSpace() |
|
628 { |
|
629 return EFalse; |
|
630 } |
|
631 |
|
632 TBool CVCard3ParserPlugIn::DeleteAllSpaces() |
|
633 { |
|
634 return EFalse; |
|
635 } |
|
636 |
|
637 TBool CVCard3ParserPlugIn::NeedsBlankLine() |
|
638 { |
|
639 return EFalse; |
|
640 } |
|
641 |
|
642 void CVCard3ParserPlugIn::RemoveEscaping(TPtr16& /*aText*/) |
|
643 { |
|
644 //import not supported so do nothing |
|
645 } |
|
646 |
|
647 void CVCard3ParserPlugIn::AddEscaping(HBufC16*& aText) |
|
648 /** Plugin provides escaping of comma characters and also replacement of CRLF |
|
649 sequence with '\n' in property values. */ |
|
650 { |
|
651 HBufC16* targetText = NULL; |
|
652 //allocate a buffer large enough to cope with all characters in the string being |
|
653 //escaped. If this allocation fails no escaping is attempted which will result in |
|
654 //the creation of an invalid vCard |
|
655 TRAPD(error, targetText = HBufC16::NewL(2*aText->Length())); |
|
656 if (error || !targetText) |
|
657 { |
|
658 return; |
|
659 } |
|
660 |
|
661 //escape comma characters and replace CRLF with '\n' |
|
662 TPtr targetPtr(targetText->Des()); |
|
663 const TUint16* pSource = aText->Ptr(); |
|
664 TInt length = aText->Length(); |
|
665 for(TInt i = 0; i<length; i++, pSource++) |
|
666 { |
|
667 switch (*pSource) |
|
668 { |
|
669 case KVersitTokenCommaVal: |
|
670 { |
|
671 //replace "," with "\," |
|
672 targetPtr.Append(KVersitTokenBackslashVal); |
|
673 targetPtr.Append(*pSource); |
|
674 } |
|
675 break; |
|
676 case KTokenCarriageReturnVal: |
|
677 { |
|
678 //CR is skipped and the next LF is replaced with '\n' |
|
679 break; |
|
680 } |
|
681 case KTokenLineFeedVal: |
|
682 { |
|
683 //replace CRLF with "\n" |
|
684 targetPtr.Append(KVersitTokenBackslashVal); |
|
685 targetPtr.Append(KTokenNewLineVal); |
|
686 } |
|
687 break; |
|
688 default: |
|
689 targetPtr.Append(*pSource); |
|
690 break; |
|
691 } |
|
692 } |
|
693 delete aText; |
|
694 aText = targetText; |
|
695 } |
|
696 |
|
697 |
|
698 TBool CVCard3ParserPlugIn::WrapLine(RWriteStream& aStream, TInt& aCurrentLineLength, const TPtr8& aText) |
|
699 /** Plugin provides line folding as defined by RFC2425 and RFC2426*/ |
|
700 { |
|
701 //this is a non-leaving function so all writes to the stream (which can leave) |
|
702 //must be called in a TRAP. Any leaving errors are ignored because there is no |
|
703 //way to report them to the client. This may result in a partial property value |
|
704 //being written to the stream |
|
705 TRAP_IGNORE(DoWrapLineL(aStream, aCurrentLineLength, aText)); |
|
706 return ETrue; |
|
707 } |
|
708 |
|
709 void CVCard3ParserPlugIn::DoWrapLineL(RWriteStream& aStream, TInt& aCurrentLineLength, const TPtr8& aText) |
|
710 { |
|
711 TPtr8 text(aText); |
|
712 TPtr8 line(NULL,0,0); |
|
713 TInt lineLength = Max(KMaxVCard3LineLength-aCurrentLineLength, 0); |
|
714 TInt remaining = text.Length(); |
|
715 |
|
716 while (remaining > lineLength) |
|
717 { |
|
718 line.Set(&text[0], lineLength, lineLength); |
|
719 aStream.WriteL(line); |
|
720 aStream.WriteL(KVCard3LineBreakAndWSP); |
|
721 aCurrentLineLength = 1; |
|
722 remaining -= lineLength; |
|
723 text.Set(&text[lineLength], remaining, remaining); |
|
724 lineLength = KMaxVCard3LineLength-1; |
|
725 } |
|
726 aCurrentLineLength += text.Length(); |
|
727 aStream.WriteL(text); |
|
728 } |
|
729 |
|
730 TBool CVCard3ParserPlugIn::EncodingType(Versit::TVersitEncoding& aEncoding, |
|
731 TBool /*aRequiresEncoding*/, |
|
732 Versit::TVersitEncoding /*aDefaultEncoding*/, |
|
733 TUid aPropertyUid, TUint /*aPropertyCharsetId*/) |
|
734 { |
|
735 //quoted-printable encoding is performed by the transport wrapper so all |
|
736 //non binary property values can be set to have no encoding here |
|
737 aEncoding = Versit::ENoEncoding; |
|
738 |
|
739 if (aPropertyUid == TUid::Uid(KVersitPropertyBinaryUid)) |
|
740 { |
|
741 //inline binary property values are always encoded to base64 |
|
742 aEncoding = Versit::EBase64Encoding; |
|
743 } |
|
744 return ETrue; |
|
745 } |
|
746 |
|
747 const TDesC8& CVCard3ParserPlugIn::EncodingName(Versit::TVersitEncoding aEncoding) |
|
748 { |
|
749 if (aEncoding == Versit::EBase64Encoding) |
|
750 { |
|
751 //base64 encoding parameter value changed from "BASE64" to "B" |
|
752 return KVCard3TokenB; |
|
753 } |
|
754 return VersitUtils::IANAEncodingName(aEncoding); |
|
755 } |
|
756 |
|
757 void CVCard3ParserPlugIn::GetInterface(TUid aInterfaceUid, TAny*& aInterface) |
|
758 /** Returns interface extension. */ |
|
759 { |
|
760 if (aInterfaceUid == KUidVersitPlugInExtension) |
|
761 { |
|
762 aInterface = static_cast<MVersitPlugInExtension*>(this); |
|
763 } |
|
764 } |
|
765 |
|
766 TBool CVCard3ParserPlugIn::DisableCharsetParam() |
|
767 { |
|
768 return ETrue; |
|
769 } |
|
770 |
|
771 TBool CVCard3ParserPlugIn::DisableBlankLineAfterBinaryValue() |
|
772 { |
|
773 return ETrue; |
|
774 } |
|
775 |
|
776 TBool CVCard3ParserPlugIn::WrapBinaryLinesL(CBufBase& aBuffer, TInt& aCurrentLineLength) |
|
777 /** Plugin provides line folding as defined by RFC2425 and RFC2426*/ |
|
778 { |
|
779 TInt lineLength = Max(KMaxVCard3LineLength-aCurrentLineLength, 0); |
|
780 TInt remaining = aBuffer.Size(); |
|
781 TInt pos = 0; |
|
782 while (remaining>lineLength) |
|
783 { |
|
784 pos += lineLength; |
|
785 aBuffer.InsertL(pos, KVCard3LineBreakAndWSP); |
|
786 pos += KVCard3LineBreakAndWSP().Length(); |
|
787 remaining -= lineLength; |
|
788 lineLength = KMaxVCard3LineLength-1; |
|
789 aCurrentLineLength = 1; |
|
790 } |
|
791 aCurrentLineLength += remaining; |
|
792 return ETrue; |
|
793 } |
|
794 |
|
795 TBool CVCard3ParserPlugIn::FoldParam() |
|
796 { |
|
797 return ETrue; |
|
798 } |
|
799 |
|
800 |
|
801 // |
|
802 // CParserGroupedProperty |
|
803 // |
|
804 |
|
805 CParserGroupedProperty::CParserGroupedProperty(CParserPropertyValue& aPropertyValue,CDesC8Array* aArrayOfGroups,CArrayPtr<CParserParam>* aArrayOfParams) |
|
806 : CParserProperty(aPropertyValue, aArrayOfParams), iArrayOfGroups(aArrayOfGroups) |
|
807 {} |
|
808 |
|
809 EXPORT_C CParserGroupedProperty::CParserGroupedProperty(CDesC8Array* aArrayOfGroups, CArrayPtr<CParserParam>* aArrayOfParams) |
|
810 : CParserProperty(aArrayOfParams), iArrayOfGroups(aArrayOfGroups) |
|
811 /** Allocates and partially constructs a new grouped property using the array of |
|
812 grouped property names and array of property parameters specified. |
|
813 |
|
814 @param aArrayOfGroups Pointer to an array of descriptors. Each one specifies |
|
815 a group name. The grouped property takes ownership of this array. |
|
816 (May be NULL). |
|
817 @param aArrayOfParams The property parameters. The grouped property |
|
818 takes ownership of this array. (May be NULL). */ |
|
819 {} |
|
820 |
|
821 EXPORT_C CParserGroupedProperty* CParserGroupedProperty::NewL(CParserPropertyValue& aPropertyValue, const TDesC8& aName, CDesC8Array* aArrayOfGroups, CArrayPtr<CParserParam>* aArrayOfParams) |
|
822 /** Allocates and constructs a new grouped property from the value, name, property |
|
823 parameters and groups specified. |
|
824 |
|
825 Note: the property value, name and array of property parameters are generic |
|
826 to all properties. The array of grouped property names is specific to the CParserGroupedProperty |
|
827 class. |
|
828 |
|
829 @param aPropertyValue The property value. The grouped property takes |
|
830 ownership of this. |
|
831 @param aName The property name. The grouped property takes ownership |
|
832 of this. |
|
833 @param aArrayOfGroups Pointer to an array of descriptors. Each one specifies |
|
834 a group name. The grouped property takes ownership of this array. (May be NULL). |
|
835 @param aArrayOfParams The property parameters. The grouped property |
|
836 takes ownership of this array. (May be NULL). |
|
837 @return Pointer to the newly created grouped property. */ |
|
838 { |
|
839 // coverity [alloc_fn] |
|
840 CParserGroupedProperty* self = new(ELeave) CParserGroupedProperty(aPropertyValue,aArrayOfGroups,aArrayOfParams); |
|
841 ConstructSelfL(*self,aName); |
|
842 return self; |
|
843 } |
|
844 |
|
845 EXPORT_C CParserGroupedProperty::~CParserGroupedProperty() |
|
846 /** Frees all resources owned by the property, prior to its destruction. */ |
|
847 { |
|
848 delete iArrayOfGroups; |
|
849 } |
|
850 |
|
851 EXPORT_C TBool CParserGroupedProperty::Group(const TDesC8& aGroup) const |
|
852 /** Tests whether the property is a member of the specified property group. |
|
853 |
|
854 @param aGroup The name of the property group. |
|
855 @return ETrue if the property is a member of the specified property group. |
|
856 EFalse if not. */ |
|
857 { |
|
858 if (iArrayOfGroups) |
|
859 { |
|
860 TInt notUsed; |
|
861 if (iArrayOfGroups->Find(aGroup,notUsed)==0) |
|
862 return ETrue; |
|
863 } |
|
864 return EFalse; |
|
865 } |
|
866 |
|
867 EXPORT_C TBool CParserGroupedProperty::SupportsInterface(const TUid& aInterfaceUid) const |
|
868 /** Tests whether the property supports the given interface. |
|
869 |
|
870 Returns true if the given interface UID is KVersitGroupedPropertyUid. |
|
871 |
|
872 @param aInterfaceUid An interface UID. |
|
873 @return ETrue if aInterfaceUid is KVersitGroupedPropertyUid, and EFalse if not. */ |
|
874 { |
|
875 if (aInterfaceUid==TUid::Uid(KVersitGroupedPropertyUid)) |
|
876 return ETrue; |
|
877 return CParserProperty::SupportsInterface(aInterfaceUid); |
|
878 } |
|
879 |
|
880 EXPORT_C void CParserGroupedProperty::ExternalizeL(RWriteStream& aStream, CVersitParser* aVersitParser) |
|
881 /** Externalises the property into aStream. |
|
882 |
|
883 Externalises the list of groups to which the property belongs, if there are |
|
884 any, then calls CParserProperty::ExternalizeL() to write the rest of the property |
|
885 data to the stream. |
|
886 |
|
887 @param aStream Stream to which the value should be externalised. |
|
888 @param aVersitParser Versit parser which contains the objects to be externalised. |
|
889 This must not be NULL or a panic occurs. */ |
|
890 { |
|
891 if (iArrayOfGroups) |
|
892 { |
|
893 TInt count=iArrayOfGroups->Count(); |
|
894 for (TInt ii = 0; ii < count; ii++) |
|
895 { |
|
896 #if defined _UNICODE |
|
897 for(TInt i = 0; i < (*iArrayOfGroups)[ii].Length(); i++) |
|
898 aStream.WriteUint8L((*iArrayOfGroups)[ii][i]); |
|
899 #else |
|
900 aStream.WriteL((*iArrayOfGroups)[ii]); |
|
901 #endif |
|
902 aStream.WriteL(KVersitTokenPeriod); |
|
903 } |
|
904 } |
|
905 CParserProperty::ExternalizeL(aStream, aVersitParser); |
|
906 } |
|
907 |
|
908 EXPORT_C void CParserGroupedProperty::Reserved() |
|
909 {} |
|
910 |
|
911 // |
|
912 // CParserPropertyValueAgent |
|
913 // |
|
914 |
|
915 EXPORT_C CParserPropertyValueAgent::CParserPropertyValueAgent(CParserVCard* aValue) |
|
916 : CParserPropertyValue(TUid::Uid(KVCardPropertyAgentUid)) |
|
917 , iValue(aValue) |
|
918 /** Constructs an agent property value, using a pointer to an agent. |
|
919 |
|
920 Sets the property value UID to KVCardPropertyAgentUid. |
|
921 |
|
922 @param aValue A pointer to the agent object to assign to the property value. |
|
923 The property value takes ownership of the pointer. */ |
|
924 {} |
|
925 |
|
926 EXPORT_C CParserPropertyValueAgent::~CParserPropertyValueAgent() |
|
927 /** Frees all resources owned by the property value, prior to its destruction. */ |
|
928 { |
|
929 delete iValue; |
|
930 } |
|
931 |
|
932 EXPORT_C void CParserPropertyValueAgent::ExternalizeL(RWriteStream& aStream,const Versit::TEncodingAndCharset& /*aEncodingCharset*/,TInt /*aLengthOutput*/) |
|
933 /** Externalises the agent property value to aStream. |
|
934 |
|
935 @param aStream Stream to which the value should be externalised. |
|
936 @param aEncodingCharset Contains character set and encoding information. Not used as it is not |
|
937 relevant to this function. |
|
938 @param aLengthOutput The line wrapping offset. Not used as it is not relevant to this function. */ |
|
939 { |
|
940 if (!iValue) |
|
941 return; |
|
942 aStream.WriteL(KVersitTokenCRLF); |
|
943 iValue->ExternalizeL(aStream); |
|
944 } |
|
945 |