|
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 <versit.h> |
|
17 #include <vprop.h> |
|
18 #include <vutil.h> |
|
19 #include <s32mem.h> |
|
20 #include <concnf.h> |
|
21 #include <confndr.h> |
|
22 #include <conlist.h> |
|
23 #include <charconv.h> |
|
24 #include <utf.h> |
|
25 |
|
26 #include <vcal.h> |
|
27 #include <vcard.h> |
|
28 |
|
29 #ifdef SYMBIAN_ENABLE_SPLIT_HEADERS |
|
30 #include <vpropbinaryfile.h> |
|
31 #include "versit_internal.h" |
|
32 #endif |
|
33 |
|
34 // User includes |
|
35 #include <vstaticutils.h> |
|
36 #include <vobserv.h> |
|
37 #include "vpbapplugin.h" |
|
38 |
|
39 |
|
40 // Constants |
|
41 #ifdef SYMBIAN_ENABLE_SPLIT_HEADERS |
|
42 const TInt KRandomnumberlen = 5; |
|
43 const TInt KMaxGeneratedfilenamelen =16; |
|
44 #endif |
|
45 const TInt KBase64MaxLineLength = 64; // chars |
|
46 const TInt KFileProtocolStringLength = 7; //file:// |
|
47 const TInt KMinFileNameLen = 4; // eg: c:\<1 digit number> , assuming that the property name was zero len. |
|
48 // But always the property name will be at least 1 // char in length . |
|
49 // This constant used in LoadBinaryValuesFromFilesL() to check whether the URI is fine |
|
50 |
|
51 |
|
52 _LIT8(KValue,"VALUE"); |
|
53 _LIT8(KUri,"URI"); |
|
54 _LIT(KFileProtocol,"file://"); |
|
55 |
|
56 #define UNUSED_VAR(a) a = a |
|
57 |
|
58 // |
|
59 // CParserParam |
|
60 // |
|
61 |
|
62 |
|
63 EXPORT_C CParserParam* CParserParam::NewL(const TDesC8& aName,const TDesC8& aValue) |
|
64 /** Allocates and constructs a new property parameter with the name and value specified. |
|
65 |
|
66 This object does does not take ownership of aName or aValue. |
|
67 |
|
68 @param aName The parameter name. |
|
69 @param aValue The parameter value. Use KNullDesC8 if not applicable. |
|
70 @return Pointer to the newly created property parameter. */ |
|
71 { |
|
72 HBufC8* paramName=aName.AllocLC(); |
|
73 HBufC8* value=NULL; |
|
74 if (aValue.Length()>0) |
|
75 value=aValue.AllocLC(); |
|
76 CParserParam* param=new(ELeave) CParserParam(paramName,value); |
|
77 if (value) |
|
78 CleanupStack::Pop(value); |
|
79 CleanupStack::Pop(paramName); |
|
80 return param; |
|
81 } |
|
82 |
|
83 EXPORT_C CParserParam* CParserParam::NewL(const TDesC8& aName,const TDesC& aValue) |
|
84 /** Allocates and constructs a new property parameter with the name and value specified. |
|
85 |
|
86 This object does does not take ownership of aName or aValue. |
|
87 |
|
88 A Unicode value string is converted to a narrow string for storage. |
|
89 |
|
90 @param aName The parameter name. |
|
91 @param aValue The parameter value. (Use KNullDesC if applicable). |
|
92 @return Pointer to the newly created property parameter. */ |
|
93 { |
|
94 HBufC8* paramName=aName.AllocLC(); |
|
95 HBufC8* value=NULL; |
|
96 TInt len=aValue.Length(); |
|
97 if (len>0) |
|
98 { |
|
99 value=HBufC8::NewLC(len); |
|
100 value->Des().Copy(aValue); |
|
101 } |
|
102 CParserParam* param=new(ELeave) CParserParam(paramName,value); |
|
103 if (value) |
|
104 CleanupStack::Pop(value); |
|
105 CleanupStack::Pop(paramName); |
|
106 return param; |
|
107 } |
|
108 |
|
109 |
|
110 EXPORT_C CParserParam::~CParserParam() |
|
111 /** Frees all resources owned by the property parameter, prior to its destruction. */ |
|
112 { |
|
113 delete iParamName; |
|
114 delete iValue; |
|
115 } |
|
116 |
|
117 EXPORT_C void CParserParam::SetValueL(const TDesC8& aValue) |
|
118 /** Sets the property parameter value. |
|
119 |
|
120 @param aValue The new property parameter value. */ |
|
121 { |
|
122 delete iValue; |
|
123 iValue=0; |
|
124 iValue=aValue.AllocL(); |
|
125 } |
|
126 |
|
127 EXPORT_C void CParserParam::SetValueL(HBufC8* aValue) |
|
128 /** Sets the property parameter value. |
|
129 |
|
130 The property parameter takes ownership of aValue. |
|
131 |
|
132 @param aValue The new property parameter value. */ |
|
133 { |
|
134 delete iValue; |
|
135 iValue=aValue; |
|
136 } |
|
137 |
|
138 EXPORT_C TInt CParserParam::ExternalizeL(RWriteStream& aStream) const |
|
139 /** Externalises a property parameter to the stream, in the form NAME=VALUE (or just |
|
140 NAME, depending on whether there is a value). |
|
141 |
|
142 This function performs the esacaping of characters. |
|
143 |
|
144 @param aStream Stream to which the property parameter is to be externalised. |
|
145 @return The length of data written to the stream. */ |
|
146 { |
|
147 // |
|
148 // Write a property parameter in the format of |
|
149 // NAME=VALUE |
|
150 // |
|
151 aStream.WriteL(*iParamName); |
|
152 TInt outputLen=iParamName->Length(); |
|
153 |
|
154 // If there isn't a VALUE part for this property parameter then just return here... |
|
155 if (!iValue) |
|
156 return outputLen; |
|
157 |
|
158 // Write the equals... |
|
159 aStream.WriteL(KVersitTokenEquals); |
|
160 |
|
161 // Escape semi-colon characters |
|
162 TInt length = iValue->Length(); |
|
163 TInt ii; |
|
164 TUint8 ch; |
|
165 outputLen+=length+1; //1 for the "=" |
|
166 for (ii=0;ii<length;++ii) |
|
167 { |
|
168 ch=(*iValue)[ii]; |
|
169 if (ch==KVersitTokenSemiColonVal || ch==KVersitTokenBackslashVal) |
|
170 { |
|
171 aStream.WriteUint8L(KVersitTokenBackslashVal); |
|
172 ++outputLen; |
|
173 } |
|
174 aStream.WriteUint8L(ch); |
|
175 } |
|
176 return outputLen; |
|
177 } |
|
178 |
|
179 |
|
180 EXPORT_C TInt CParserParam::ExternalizeL(RWriteStream& aStream, TInt& aLengthOutput, CVersitParser* aVersitParser) const |
|
181 /** Externalises vCard3.0 property parameter to the stream, in the form NAME=VALUE or just |
|
182 VALUE, if it is a nameless parameter. |
|
183 |
|
184 This function performs the esacaping of characters. */ |
|
185 { |
|
186 TBool namelessParam = EFalse; |
|
187 |
|
188 /** Property parameter contains value only -> TEL;Home:984536577 in which case iParamName |
|
189 contains the parameter value. */ |
|
190 HBufC8* buf = NULL; |
|
191 TInt nameLen = 0; |
|
192 if(iValue == NULL) |
|
193 { |
|
194 buf = iParamName; |
|
195 namelessParam = ETrue; |
|
196 } |
|
197 else |
|
198 { |
|
199 buf = iValue; |
|
200 nameLen = iParamName->Length()+1; //1 for the "=" |
|
201 } |
|
202 |
|
203 //allocate a buffer large enough to cope with all characters in the string being |
|
204 //escaped. If this allocation fails no escaping is attempted which will result in |
|
205 //the creation of an invalid vCard |
|
206 HBufC8* valueBuf = HBufC8::NewLC(2*buf->Length()); |
|
207 TPtr8 valuePtr(valueBuf->Des()); |
|
208 |
|
209 /** Escape semi-colon,backslash,comma characters in parameter value. */ |
|
210 const TUint8* pSource = buf->Ptr(); |
|
211 TInt length = buf->Length(); |
|
212 for(TInt i = 0; i<length; i++, pSource++) |
|
213 { |
|
214 switch (*pSource) |
|
215 { |
|
216 case KVersitTokenCommaVal: |
|
217 { |
|
218 //replace "," with "\," |
|
219 valuePtr.Append(KVersitTokenBackslashVal); |
|
220 valuePtr.Append(*pSource); |
|
221 } |
|
222 break; |
|
223 case KVersitTokenSemiColonVal: |
|
224 { |
|
225 //replace ";" with "\;" |
|
226 valuePtr.Append(KVersitTokenBackslashVal); |
|
227 valuePtr.Append(*pSource); |
|
228 } |
|
229 break; |
|
230 case KVersitTokenBackslashVal: |
|
231 { |
|
232 //replace "\" with "\\" |
|
233 valuePtr.Append(KVersitTokenBackslashVal); |
|
234 valuePtr.Append(*pSource); |
|
235 } |
|
236 break; |
|
237 default: |
|
238 valuePtr.Append(*pSource); |
|
239 break; |
|
240 } |
|
241 } |
|
242 |
|
243 TInt nameValueLen = nameLen + valueBuf->Length(); |
|
244 HBufC8* nameValue = HBufC8::NewLC(nameValueLen); |
|
245 TPtr8 pText(nameValue->Des()); |
|
246 |
|
247 if(!namelessParam) |
|
248 { |
|
249 //create text in the form NAME=VALUE. |
|
250 pText.Append(*iParamName); |
|
251 pText.Append(KVersitTokenEqualsVal); |
|
252 pText.Append(*valueBuf); |
|
253 } |
|
254 else |
|
255 { |
|
256 //nameless parameter. |
|
257 pText.Append(*valueBuf); |
|
258 } |
|
259 |
|
260 //fold property parameter. |
|
261 if(aVersitParser->PlugIn()) |
|
262 { |
|
263 aVersitParser->PlugIn()->WrapLine(aStream, aLengthOutput, pText); |
|
264 } |
|
265 |
|
266 CleanupStack::PopAndDestroy(nameValue); |
|
267 CleanupStack::PopAndDestroy(valueBuf); |
|
268 |
|
269 return aLengthOutput; |
|
270 } |
|
271 |
|
272 |
|
273 EXPORT_C TPtrC8 CParserParam::Name() const |
|
274 /** Gets the property parameter name. |
|
275 |
|
276 If no name has been set, the function returns an empty string. |
|
277 |
|
278 @return The property parameter name. */ |
|
279 { |
|
280 if (iParamName) |
|
281 return iParamName->Des(); |
|
282 return KVersitTokenEmptyNarrow(); |
|
283 } |
|
284 |
|
285 EXPORT_C TPtrC8 CParserParam::Value() const |
|
286 /** Gets the property parameter value. |
|
287 |
|
288 If no value has been set, the function returns an empty descriptor. |
|
289 |
|
290 @return The property parameter value. */ |
|
291 { |
|
292 if (iValue) |
|
293 return iValue->Des(); |
|
294 return KVersitTokenEmptyNarrow(); |
|
295 } |
|
296 |
|
297 EXPORT_C HBufC* CParserParam::ValueL() const |
|
298 /** Gets the property parameter value as a Unicode heap descriptor. |
|
299 |
|
300 If no value has been set, the function returns an empty descriptor. |
|
301 |
|
302 @return A Unicode version of the property parameter value. */ |
|
303 { |
|
304 TInt len=0; |
|
305 if (iValue) |
|
306 len=iValue->Length(); |
|
307 HBufC* value=HBufC::NewL(len); |
|
308 if (iValue) |
|
309 value->Des().Copy(*iValue); |
|
310 return value; |
|
311 } |
|
312 |
|
313 CParserParam::CParserParam(HBufC8* aName,HBufC8* aValue) |
|
314 : iParamName(aName) |
|
315 , iValue(aValue) |
|
316 {} |
|
317 |
|
318 // |
|
319 // TVersitDateTime |
|
320 // |
|
321 |
|
322 EXPORT_C TVersitDateTime::TVersitDateTime(const TDateTime& aDateTime,TRelativeTime aRelativeTime) |
|
323 : iDateTime(aDateTime) |
|
324 ,iRelativeTime(aRelativeTime) |
|
325 /** Constructs the Versit date/time object with a date/time value and a specification |
|
326 of whether this value is local to the machine which originated the vCard, local |
|
327 to the machine on which the code is running, or universal time. |
|
328 |
|
329 @param aDateTime The date/time value. |
|
330 @param aRelativeTime The time the date/time value represents. */ |
|
331 { |
|
332 iFlags = EExportNullFlag; |
|
333 } |
|
334 // |
|
335 // CParserPropertyValue |
|
336 // |
|
337 EXPORT_C TBool CParserPropertyValue::SupportsInterface(const TUid& /*aInterfaceUid*/) const |
|
338 /** Tests whether the property value supports the specified interface. |
|
339 |
|
340 This implementation returns EFalse. |
|
341 |
|
342 It is implemented by the derived class CParserTimePropertyValue to return ETrue if |
|
343 aInterfaceUid is KVersitTimePropertyUid. |
|
344 |
|
345 @param aInterfaceUid Not used. |
|
346 @return EFalse. */ |
|
347 { |
|
348 return EFalse; |
|
349 } |
|
350 |
|
351 GLDEF_C void DestroyHBufC(TAny* aHBufC) |
|
352 { |
|
353 delete *STATIC_CAST(HBufC**, aHBufC); |
|
354 } |
|
355 |
|
356 EXPORT_C void CParserPropertyValue::FoldEncodeAndWriteValueToStreamL(RWriteStream& aStream, const CDesCArray* aValueArray |
|
357 ,const Versit::TEncodingAndCharset& aEncodingCharset,TInt& aLengthOutput) const |
|
358 { |
|
359 if (!aValueArray) |
|
360 return; |
|
361 TInt count=aValueArray->Count(); |
|
362 if (count==0) |
|
363 return; |
|
364 |
|
365 TInt bufferLen=64; |
|
366 HBufC* unicodeValue = HBufC::NewL(bufferLen); |
|
367 TPtr pUnicode(unicodeValue->Des()); |
|
368 CleanupStack::PushL(TCleanupItem(DestroyHBufC, &unicodeValue));//unicodeValue's address |
|
369 TPtrC pValue; |
|
370 TInt extraLengthNeeded; |
|
371 TInt ii=0; |
|
372 FOREVER |
|
373 { |
|
374 pValue.Set(aValueArray->MdcaPoint(ii)); |
|
375 extraLengthNeeded=2*pValue.Length()+1+pUnicode.Length()-bufferLen; |
|
376 if (extraLengthNeeded>0) |
|
377 { |
|
378 bufferLen+=32*(1+extraLengthNeeded/32); |
|
379 unicodeValue=unicodeValue->ReAllocL(bufferLen); |
|
380 pUnicode.Set(unicodeValue->Des()); |
|
381 } |
|
382 VersitUtils::AddEscapedString(pUnicode,pValue,aEncodingCharset.iCharSetId); |
|
383 if (++ii==count) |
|
384 break; |
|
385 pUnicode.Append(KVersitTokenSemiColonUnicode); |
|
386 } |
|
387 if (iPlugIn) |
|
388 iPlugIn->AddEscaping(unicodeValue); |
|
389 FoldAndWriteValueToStreamL(aStream,*unicodeValue,aEncodingCharset,aLengthOutput); |
|
390 CleanupStack::PopAndDestroy(&unicodeValue); |
|
391 } |
|
392 |
|
393 EXPORT_C void CParserPropertyValue::FoldEncodeAndWriteValueToStreamL(RWriteStream& aStream, const TDesC& aValue |
|
394 ,const Versit::TEncodingAndCharset& aEncodingCharset,TInt& aLengthOutput) const |
|
395 { |
|
396 TInt length = aValue.Length(); |
|
397 if (!length) |
|
398 return; |
|
399 |
|
400 HBufC* unicodeValue = HBufC::NewL(2*length); |
|
401 TPtr pUnicode(unicodeValue->Des()); |
|
402 CleanupStack::PushL(TCleanupItem(DestroyHBufC, &unicodeValue)); |
|
403 VersitUtils::AddEscapedString(pUnicode,aValue,aEncodingCharset.iCharSetId); |
|
404 if (iPlugIn) |
|
405 iPlugIn->AddEscaping(unicodeValue); |
|
406 FoldAndWriteValueToStreamL(aStream,*unicodeValue,aEncodingCharset,aLengthOutput); |
|
407 CleanupStack::PopAndDestroy(&unicodeValue); |
|
408 } |
|
409 |
|
410 EXPORT_C void CParserPropertyValue::FoldAndWriteValueToStreamL(RWriteStream& aStream, const TDesC& aValue |
|
411 ,const Versit::TEncodingAndCharset& aEncodingCharset,TInt& aLengthOutput) const |
|
412 { |
|
413 __ASSERT_DEBUG(aEncodingCharset.iEncoding!=Versit::EEightBitEncoding, Panic(EVersitPanicUnexpectedEightBitEncoding)); |
|
414 HBufC8* narrowBuffer = HBufC8::NewLC(3*aValue.Length()); |
|
415 TPtr8 pText(narrowBuffer->Des()); |
|
416 VersitUtils::UncodeToNarrowL(aValue,pText,aEncodingCharset); |
|
417 CBufFlat* buffer=NULL; |
|
418 if (aEncodingCharset.iEncoding!=Versit::ENoEncoding) |
|
419 { |
|
420 buffer=CBufFlat::NewL(3*pText.Length()/2); |
|
421 CleanupStack::PushL(buffer); |
|
422 TUid encodingUid = VersitUtils::ConArcEncodingUid(aEncodingCharset.iEncoding); |
|
423 EncodeL(buffer,*narrowBuffer,encodingUid); |
|
424 pText.Set(buffer->Ptr(0)); |
|
425 if (aEncodingCharset.iEncoding==Versit::EBase64Encoding) |
|
426 { |
|
427 if (pText.Length()+aLengthOutput>KMaxExternalizedTokenLength) |
|
428 VersitUtils::WrapLinesL(*buffer, KBase64MaxLineLength); |
|
429 buffer->InsertL(buffer->Size(), KVersitTokenCRLF); |
|
430 pText.Set(buffer->Ptr(0)); |
|
431 } |
|
432 else |
|
433 { |
|
434 TInt firstLineLine=pText.Find(KVersitTokenCRLF); |
|
435 if (firstLineLine+aLengthOutput>KMaxExternalizedTokenLength) |
|
436 { |
|
437 aStream.WriteL(KVersitTokenEquals); |
|
438 aStream.WriteL(KVersitTokenCRLF); |
|
439 } |
|
440 } |
|
441 aStream.WriteL(pText); |
|
442 aLengthOutput=0; //aLengthOutput should not be used again when encoding is Quoted-Printable |
|
443 CleanupStack::PopAndDestroy(buffer); |
|
444 } |
|
445 else if (!iPlugIn || !iPlugIn->WrapLine(aStream,aLengthOutput,pText)) |
|
446 { |
|
447 TPtr8 searchString(NULL,0,0); |
|
448 TInt lineLength=Max(KMaxExternalizedTokenLength-aLengthOutput,0); |
|
449 TInt lengthLeft=pText.Length(); |
|
450 TInt searchPos; |
|
451 while (lengthLeft>lineLength) |
|
452 { |
|
453 searchPos=lineLength; |
|
454 while (searchPos>=0 && pText[searchPos]==CVersitParser::ESpace) //Search for last non-space before wrapping length |
|
455 --searchPos; |
|
456 if (searchPos>0) |
|
457 { |
|
458 searchString.Set(&pText[0],searchPos,searchPos); |
|
459 searchPos=searchString.LocateReverse(CVersitParser::ESpace); //If there is one search for a space before that |
|
460 } |
|
461 else |
|
462 searchPos=KErrNotFound; |
|
463 if (searchPos==KErrNotFound) //If can't break before wrapping length find first suitable place after it |
|
464 { |
|
465 searchPos=lengthLeft-lineLength; |
|
466 searchString.Set(&pText[lineLength],searchPos,searchPos); |
|
467 searchPos=lineLength+searchString.Locate(CVersitParser::ESpace); |
|
468 if (searchPos<lineLength) |
|
469 break; //No more spaces |
|
470 while (searchPos<lengthLeft && pText[searchPos]==CVersitParser::ESpace) |
|
471 ++searchPos; |
|
472 --searchPos; |
|
473 } |
|
474 searchString.Set(&pText[0],searchPos,searchPos); |
|
475 aStream.WriteL(searchString); |
|
476 aStream.WriteL(KVersitLineBreak); |
|
477 aLengthOutput=2; |
|
478 lengthLeft-=++searchPos; |
|
479 if (lengthLeft==0) |
|
480 { |
|
481 pText.Set(NULL,0,0); |
|
482 break; |
|
483 } |
|
484 pText.Set(&pText[searchPos],lengthLeft,lengthLeft); |
|
485 lineLength=KMaxExternalizedTokenLength; |
|
486 } |
|
487 aLengthOutput+=pText.Length(); |
|
488 aStream.WriteL(pText); |
|
489 } |
|
490 CleanupStack::PopAndDestroy(narrowBuffer); |
|
491 } |
|
492 |
|
493 EXPORT_C CParserPropertyValue::CParserPropertyValue(const TUid& aPropertyValueUid) |
|
494 : iPropertyValueTypeUid(aPropertyValueUid) |
|
495 {} |
|
496 |
|
497 EXPORT_C TBool CParserPropertyValue::IsAsciiCharacterSetSufficient() |
|
498 /** Tests whether the Ascii character set is sufficient to represent a property |
|
499 value. |
|
500 |
|
501 This implementation returns ETrue. |
|
502 |
|
503 It is overridden by classes CParserPropertyValueAlarm, CParserPropertyValueHBufC |
|
504 and CParserPropertyValueCDesCArray. |
|
505 |
|
506 This function is called by CParserProperty::ExternalizeL(). |
|
507 |
|
508 @return ETrue. */ |
|
509 { |
|
510 return ETrue; |
|
511 } |
|
512 |
|
513 EXPORT_C void CParserPropertyValue::EncodeL(CBufBase* aTarget,const TDesC8& aSource,const TUid& aEncoding) const |
|
514 /** Encodes the text property value referred to in aSource, if encoding is required. |
|
515 |
|
516 Uses the encoding format identified by aEncoding. This is only used for |
|
517 text property values (e.g. HBufC or DesCArray property types). |
|
518 |
|
519 Invoked by implementations of ExternalizeL(). |
|
520 |
|
521 @param aTarget A pointer to the buffer which will have the converted text |
|
522 written into it. |
|
523 @param aSource The source text. |
|
524 @param aEncoding An encoding UID. The possible encoding formats are defined |
|
525 in vuid.h. Specify NULL UID if no encoding is required. */ |
|
526 { |
|
527 __ASSERT_DEBUG(aTarget, User::Invariant()); |
|
528 RDesReadStream readStream(aSource); |
|
529 CleanupClosePushL(readStream); |
|
530 VersitUtils::ConArcEncodeL(readStream, *aTarget, aEncoding); |
|
531 CleanupStack::PopAndDestroy(); |
|
532 } |
|
533 |
|
534 EXPORT_C void CParserPropertyValue::Append(TDes16& aTarget,TDesC8& aSource) |
|
535 { |
|
536 TInt lenT=aTarget.Length(); |
|
537 TInt lenS=aSource.Length(); |
|
538 aTarget.SetLength(lenT+lenS); |
|
539 TPtr16 target(&aTarget[lenT],lenS,lenS); |
|
540 target.Copy(aSource); |
|
541 } |
|
542 |
|
543 |
|
544 // |
|
545 // CParserTimeProperty |
|
546 // |
|
547 |
|
548 EXPORT_C CParserTimePropertyValue::CParserTimePropertyValue(const TUid& aPropertyValueUid) |
|
549 : CParserPropertyValue(aPropertyValueUid) |
|
550 {} |
|
551 |
|
552 EXPORT_C TBool CParserTimePropertyValue::SupportsInterface(const TUid& aInterfaceUid) const |
|
553 /** Tests whether the property value supports the specified interface. |
|
554 |
|
555 It overrides the base class function, which always returns EFalse. |
|
556 |
|
557 This function is used to test whether or not a property value is |
|
558 time-related (i.e. derived from CParserTimePropertyValue). It returns |
|
559 ETrue if aInterfaceUid is KVersitTimePropertyUid. |
|
560 |
|
561 @param aInterfaceUid An interface UID. |
|
562 @return ETrue if KVersitTimePropertyUid is specified as the interface UID, |
|
563 otherwise EFalse. */ |
|
564 { |
|
565 if (aInterfaceUid==TUid::Uid(KVersitTimePropertyUid)) |
|
566 return ETrue; |
|
567 return CParserPropertyValue::SupportsInterface(aInterfaceUid); |
|
568 } |
|
569 |
|
570 EXPORT_C void CParserTimePropertyValue::ConvertDateTime(TDateTime* aDateTime,const TTimeIntervalSeconds& aIncrement,const CVersitDaylight* aDaylight) |
|
571 { |
|
572 ConvertDateTime(*aDateTime,aIncrement,aDaylight,ETrue); |
|
573 } |
|
574 |
|
575 void CParserTimePropertyValue::ConvertDateTime(TDateTime& aDateTime,const TTimeIntervalSeconds& aIncrement,const CVersitDaylight* aDaylight,TBool aToUTC) |
|
576 { |
|
577 TTime runTime(aDateTime); |
|
578 TBool summerTime=EFalse; |
|
579 if ((aDaylight)&&(aDaylight->iSavings)&&(aDaylight->iStartTime)&&(aDaylight->iEndTime)) |
|
580 { |
|
581 TTime savingsStart(aDaylight->iStartTime->iDateTime); |
|
582 TTime savingsEnd(aDaylight->iEndTime->iDateTime); |
|
583 if ((runTime>savingsStart)&&(runTime<savingsEnd)) |
|
584 { |
|
585 if (aToUTC) |
|
586 runTime-=aDaylight->iOffset; |
|
587 else |
|
588 runTime+=aDaylight->iOffset; |
|
589 summerTime=ETrue; |
|
590 } |
|
591 } |
|
592 if (!summerTime) |
|
593 runTime+=aIncrement; |
|
594 aDateTime=runTime.DateTime(); |
|
595 } |
|
596 |
|
597 EXPORT_C void CParserTimePropertyValue::EncodeVersitDateTimeL(TDes8& aBuf,const TVersitDateTime& aDateTime,TBool aEncodeTime) const |
|
598 // Convert aDateTime to descriptor format |
|
599 { |
|
600 _LIT8(formatString1, "%04d%02d%02d"); |
|
601 aBuf.Format(formatString1, aDateTime.iDateTime.Year(), aDateTime.iDateTime.Month() + 1, aDateTime.iDateTime.Day() + 1); |
|
602 if (aEncodeTime) |
|
603 { |
|
604 _LIT8(formatString2, "%S%02d%02d%02d"); |
|
605 aBuf.AppendFormat(formatString2, &KVersitTimePeriodTime, aDateTime.iDateTime.Hour(), aDateTime.iDateTime.Minute(), aDateTime.iDateTime.Second()); |
|
606 |
|
607 if (aDateTime.iRelativeTime == TVersitDateTime::EIsUTC) |
|
608 { |
|
609 aBuf.Append(KVersitTokenUniversalTime); |
|
610 } |
|
611 } |
|
612 } |
|
613 |
|
614 EXPORT_C void CParserTimePropertyValue::EncodeTimePeriodL(TDes8& aBuf,const TTime& aTimePeriod) const |
|
615 { |
|
616 _LIT8(formatString, "%d%S"); |
|
617 TDateTime dateTime = aTimePeriod.DateTime(); |
|
618 |
|
619 aBuf=KVersitTimePeriodBegin; |
|
620 TInt time = dateTime.Year(); |
|
621 if (time) |
|
622 aBuf.AppendFormat(formatString, time, &KVersitTimePeriodYear); |
|
623 time = dateTime.Month(); |
|
624 if (time) |
|
625 aBuf.AppendFormat(formatString, time, &KVersitTimePeriodMonth); |
|
626 time = dateTime.Day(); |
|
627 if (time) |
|
628 aBuf.AppendFormat(formatString, time, &KVersitTimePeriodDay); |
|
629 aBuf.Append(KVersitTimePeriodTime); |
|
630 time = dateTime.Hour(); |
|
631 if (time) |
|
632 aBuf.AppendFormat(formatString, time, &KVersitTimePeriodHour); |
|
633 time = dateTime.Minute(); |
|
634 if (time) |
|
635 aBuf.AppendFormat(formatString, time, &KVersitTimePeriodMinute); |
|
636 time = dateTime.Second(); |
|
637 if (time) |
|
638 aBuf.AppendFormat(formatString, time, &KVersitTimePeriodSecond); |
|
639 } |
|
640 |
|
641 // |
|
642 // CParserPropertyValueHBufC |
|
643 // |
|
644 |
|
645 EXPORT_C CParserPropertyValueHBufC::CParserPropertyValueHBufC(HBufC16* aValue) |
|
646 :CParserPropertyValue(TUid::Uid(KVersitPropertyHBufCUid)),iValue(aValue) |
|
647 {} |
|
648 |
|
649 CParserPropertyValueHBufC::CParserPropertyValueHBufC() |
|
650 : CParserPropertyValue(TUid::Uid(KVersitPropertyHBufCUid)) |
|
651 { |
|
652 } |
|
653 |
|
654 void CParserPropertyValueHBufC::ConstructL(const TDesC& aValue) |
|
655 { |
|
656 iValue = aValue.AllocL(); |
|
657 } |
|
658 |
|
659 EXPORT_C CParserPropertyValueHBufC* CParserPropertyValueHBufC::NewL(const TDesC& aValue) |
|
660 /** Allocates and constructs a new heap descriptor property value with a descriptor. |
|
661 |
|
662 Sets the property value's UID to KVersitPropertyHBufCUid. |
|
663 |
|
664 @param aValue The property value. |
|
665 @return Pointer to the newly created heap descriptor property value. */ |
|
666 { |
|
667 CParserPropertyValueHBufC* self = new(ELeave) CParserPropertyValueHBufC(); |
|
668 CleanupStack::PushL(self); |
|
669 self->ConstructL(aValue); |
|
670 CleanupStack::Pop(self); |
|
671 return self; |
|
672 } |
|
673 |
|
674 EXPORT_C CParserPropertyValueHBufC::~CParserPropertyValueHBufC() |
|
675 /** Frees all resources owned by the property value, prior to its destruction. */ |
|
676 { |
|
677 delete iValue; |
|
678 } |
|
679 |
|
680 EXPORT_C TBool CParserPropertyValueHBufC::IsAsciiCharacterSetSufficient() |
|
681 // From CParserPropertyValue |
|
682 /** Tests whether the property value can be represented using the ASCII character |
|
683 set. |
|
684 |
|
685 @return ETrue if the property value can be represented using the ASCII character |
|
686 set. If not, EFalse. */ |
|
687 { |
|
688 return VersitUtils::DescriptorContainsOnlySevenBitCharacters(*iValue); |
|
689 } |
|
690 |
|
691 EXPORT_C void CParserPropertyValueHBufC::ExternalizeL(RWriteStream& aStream,const Versit::TEncodingAndCharset& aEncodingCharset,TInt aLengthOutput) |
|
692 /** Externalizes the descriptor property value into aStream. |
|
693 |
|
694 This function is invoked by the parser's ExternalizeL() function. |
|
695 |
|
696 @param aStream Stream into which the value is to be externalised. |
|
697 @param aEncodingCharset Specifies the character set and encoding information. |
|
698 @param aLengthOutput The amount of text that has been output so far on the |
|
699 line, which needs to be taken into account when calculating if and where any |
|
700 line break should occur. */ |
|
701 { |
|
702 FoldEncodeAndWriteValueToStreamL(aStream,Value(),aEncodingCharset,aLengthOutput); |
|
703 } |
|
704 |
|
705 EXPORT_C TPtrC CParserPropertyValueHBufC::Value() const |
|
706 /** Retrieves the property value. |
|
707 |
|
708 @return Pointer descriptor representing the property value. */ |
|
709 { |
|
710 if (iValue) |
|
711 return iValue->Des(); |
|
712 return KVersitTokenEmpty(); |
|
713 } |
|
714 |
|
715 EXPORT_C HBufC* CParserPropertyValueHBufC::TakeValueOwnership() |
|
716 /** Take ownership of the heap descriptor property value. |
|
717 |
|
718 The property value previously owned by the object is deleted. |
|
719 |
|
720 @return A pointer to the property value. */ |
|
721 { |
|
722 HBufC* value=iValue; |
|
723 iValue=NULL; |
|
724 return value; |
|
725 } |
|
726 |
|
727 EXPORT_C CParserPropertyValueCDesCArray* CParserPropertyValueHBufC::TreatAsArrayPropertyLC(const CParserProperty& aOwningProperty) const |
|
728 /** Treats this HBufC-based property value as a possible array-based property. |
|
729 |
|
730 This function was added for compatibility reasons to support array-based SOUND |
|
731 property values. This does not alter the representation of this parser property |
|
732 value. |
|
733 |
|
734 If the underlying HBufC value cannot be parsed into any array elements, then this method |
|
735 returns an array containing only a single item. Otherwise, the HBufC is split into its |
|
736 constituent elements and returned as an array. |
|
737 |
|
738 @param aOwningProperty The property that contains this property value. |
|
739 @return An array-based representation of this object. */ |
|
740 { |
|
741 CDesCArray* arrayOfValues = NULL; |
|
742 const CParserPropertyValue* valueFromStorage = VersitUtils::AdditionalPropertyValueFromStorageL(aOwningProperty); |
|
743 // |
|
744 if (valueFromStorage && valueFromStorage->Uid().iUid == KVersitPropertyCDesCArrayUid) |
|
745 { |
|
746 const CParserPropertyValueCDesCArray* valueAsArrayProperty = static_cast<const CParserPropertyValueCDesCArray*>(valueFromStorage); |
|
747 CDesCArray* array = valueAsArrayProperty->Value(); |
|
748 // |
|
749 if (array && array->Count()) |
|
750 { |
|
751 // Create a new array... |
|
752 const TInt count = array->Count(); |
|
753 arrayOfValues = new(ELeave) CDesCArrayFlat(count); |
|
754 CleanupStack::PushL(arrayOfValues); |
|
755 |
|
756 // ... and copy the elements |
|
757 for(TInt i=0; i<count; i++) |
|
758 { |
|
759 arrayOfValues->AppendL(array->MdcaPoint(i)); |
|
760 } |
|
761 } |
|
762 } |
|
763 |
|
764 if (!arrayOfValues) |
|
765 { |
|
766 // Just copy the single element in the HBufC structure to the |
|
767 // first element of an array-based structure. |
|
768 arrayOfValues = new(ELeave) CDesCArrayFlat(1); |
|
769 CleanupStack::PushL(arrayOfValues); |
|
770 arrayOfValues->AppendL(Value()); |
|
771 } |
|
772 |
|
773 // Create array-property storage type... |
|
774 CParserPropertyValueCDesCArray* value = new(ELeave) CParserPropertyValueCDesCArray(arrayOfValues); |
|
775 CleanupStack::Pop(arrayOfValues); |
|
776 CleanupStack::PushL(value); |
|
777 // |
|
778 return value; |
|
779 } |
|
780 |
|
781 // |
|
782 // CParserPropertyValueBinary |
|
783 // |
|
784 |
|
785 void CParserPropertyValueBinary::ConstructL(const TDesC8& aValue) |
|
786 { |
|
787 iValue=CBufSeg::NewL(128); |
|
788 iValue->InsertL(0,aValue); |
|
789 } |
|
790 |
|
791 EXPORT_C CParserPropertyValueBinary* CParserPropertyValueBinary::NewL(const TDesC8& aValue) |
|
792 /** Allocates and constructs a new binary property value with the value specified. |
|
793 |
|
794 Sets the property value's UID to KVersitPropertyBinaryUid. |
|
795 |
|
796 @param aValue The property value. |
|
797 @return Pointer to the newly created binary property value. */ |
|
798 { |
|
799 CParserPropertyValueBinary* self = CParserPropertyValueBinary::NewLC(aValue); |
|
800 CleanupStack::Pop(self); |
|
801 return self; |
|
802 } |
|
803 |
|
804 EXPORT_C CParserPropertyValueBinary* CParserPropertyValueBinary::NewLC(const TDesC8& aValue) |
|
805 /** Allocates and constructs a new binary property value with the value specified. |
|
806 |
|
807 Leaves the object on the cleanup stack. |
|
808 |
|
809 Sets the property value's UID to KVersitPropertyBinaryUid. |
|
810 |
|
811 @param aValue The property value. |
|
812 @return Pointer to the newly created binary property value. */ |
|
813 { |
|
814 CParserPropertyValueBinary* self = new(ELeave) CParserPropertyValueBinary(); |
|
815 CleanupStack::PushL(self); |
|
816 self->ConstructL(aValue); |
|
817 return self; |
|
818 } |
|
819 |
|
820 EXPORT_C CParserPropertyValueBinary::~CParserPropertyValueBinary() |
|
821 /** Frees all resources owned by the property value, prior to its destruction. */ |
|
822 { |
|
823 delete iValue; |
|
824 } |
|
825 |
|
826 EXPORT_C void CParserPropertyValueBinary::ExternalizeL(RWriteStream& aStream, const Versit::TEncodingAndCharset& aEncodingCharset, TInt aLengthOutput) |
|
827 /** Externalises the binary property value into aStream. |
|
828 |
|
829 Uses the encoding format specified in aEncodingCharset. (Any character set |
|
830 specified in aEncodingCharset is not used). |
|
831 |
|
832 @param aStream Stream into which the value is to be externalised. |
|
833 @param aEncodingCharset Specifies the character set and encoding information. |
|
834 The encoding selected for a binary property value is Versit::EBase64Encoding. |
|
835 @param aLengthOutput The amount of text that has been output so far on the |
|
836 line (for the property name). */ |
|
837 { |
|
838 RBufReadStream readStream; |
|
839 readStream.Open(*iValue); |
|
840 CleanupClosePushL(readStream); |
|
841 ExternalizeL(aStream, aEncodingCharset, aLengthOutput, readStream); |
|
842 CleanupStack::PopAndDestroy(&readStream); |
|
843 } |
|
844 |
|
845 void CParserPropertyValueBinary::ExternalizeL(RWriteStream& aStream, const Versit::TEncodingAndCharset& aEncodingCharset, TInt aLengthOutput, RReadStream& aReadStream) |
|
846 /** Externalises the binary property value into aStream. |
|
847 |
|
848 Uses the encoding format specified in aEncodingCharset. (Any character set |
|
849 specified in aEncodingCharset is not used). |
|
850 |
|
851 @param aStream Stream into which the value is to be externalised. |
|
852 @param aEncodingCharset Specifies the character set and encoding information. |
|
853 The encoding selected for a binary property value is Versit::EBase64Encoding. |
|
854 @param aLengthOutput The amount of text that has been output so far on the |
|
855 line (for the property name). */ |
|
856 { |
|
857 TAny* extPlugIn = NULL; |
|
858 |
|
859 if (PlugIn()) |
|
860 { |
|
861 PlugIn()->GetInterface(KUidVersitPlugInExtension, extPlugIn); |
|
862 } |
|
863 TInt dataLength = 0; |
|
864 MStreamBuf * streamBuf = aReadStream.Source(); |
|
865 if(streamBuf) |
|
866 { |
|
867 dataLength = streamBuf->SizeL(); |
|
868 } |
|
869 |
|
870 if (dataLength > 0) |
|
871 { |
|
872 //Make sure read from the beginning |
|
873 TStreamPos posStart(0); |
|
874 streamBuf->SeekL(MStreamBuf::ERead, posStart); |
|
875 /* |
|
876 1). Create a segmented buffer with optimum granularity, this will have the converted data. |
|
877 2). Read chunk of data from aReadStream and store it in temporary segmented buffer for processing. |
|
878 3). Pass the buffer for line wrapping and write it to the output stream. |
|
879 4). Repeat the steps in the loop until data in iValue is exhausted. |
|
880 */ |
|
881 //Number of segments to process. |
|
882 TInt splitSize = 30720; //optimum size of buffer which CONARC |
|
883 CBufSeg* target = CBufSeg::NewL(splitSize); |
|
884 CleanupStack::PushL(target); |
|
885 CBufSeg* tempSeg = CBufSeg::NewL(splitSize); |
|
886 CleanupStack::PushL(tempSeg); |
|
887 HBufC8* readdata = HBufC8::NewLC(splitSize); |
|
888 RBufReadStream readStream; |
|
889 |
|
890 TPtr8 ptr = readdata->Des(); |
|
891 TInt numOfSplits = dataLength / splitSize; |
|
892 for(TInt loop = 0;loop <= numOfSplits; ++loop) |
|
893 { |
|
894 if(loop == numOfSplits) |
|
895 {//The length of data to read at the last loop |
|
896 splitSize = dataLength%splitSize; |
|
897 if(splitSize == 0) |
|
898 { |
|
899 break; |
|
900 } |
|
901 } |
|
902 |
|
903 ptr.Zero(); |
|
904 aReadStream.ReadL(ptr, splitSize); |
|
905 |
|
906 tempSeg->InsertL(0, ptr); |
|
907 readStream.Open(*tempSeg); |
|
908 CleanupClosePushL(readStream); |
|
909 // Do the BASE64 encoding |
|
910 VersitUtils::ConArcEncodeL(readStream, *target, VersitUtils::ConArcEncodingUid(aEncodingCharset.iEncoding)); |
|
911 CleanupStack::PopAndDestroy(&readStream); |
|
912 |
|
913 if (!extPlugIn || !static_cast<MVersitPlugInExtension*>(extPlugIn)->WrapBinaryLinesL(*target, aLengthOutput)) |
|
914 { |
|
915 VersitUtils::WrapLinesL(*target, KBase64MaxLineLength); |
|
916 } |
|
917 |
|
918 // Write the buffer to the output stream |
|
919 TInt bufPos = 0; |
|
920 TInt len = target->Size(); |
|
921 |
|
922 while (bufPos < len) |
|
923 { |
|
924 TPtr8 ptr = target->Ptr(bufPos); |
|
925 aStream.WriteL(ptr); |
|
926 bufPos += ptr.Length(); |
|
927 } |
|
928 |
|
929 tempSeg->Reset(); |
|
930 ptr.Zero(); |
|
931 target->Reset(); |
|
932 } |
|
933 |
|
934 CleanupStack::PopAndDestroy(3, target);//readdata tempSeg target |
|
935 } |
|
936 |
|
937 // vCard specification says that end of the text is marked with two CRLF sequences (2nd one added latter) |
|
938 if (!extPlugIn || !static_cast<MVersitPlugInExtension*>(extPlugIn)->DisableBlankLineAfterBinaryValue()) |
|
939 { |
|
940 aStream.WriteL(KVersitTokenCRLF); |
|
941 } |
|
942 } |
|
943 |
|
944 EXPORT_C const CBufSeg* CParserPropertyValueBinary::Value() const |
|
945 /** Returns the binary property value. |
|
946 |
|
947 @return Pointer to the property value. */ |
|
948 { |
|
949 return iValue; |
|
950 } |
|
951 // |
|
952 // CParserPropertyValueBinaryFile |
|
953 // |
|
954 void CParserPropertyValueBinaryFile::ConstructL(const RFile& aFileHandle) |
|
955 { |
|
956 RFile dupHandle; |
|
957 User::LeaveIfError(dupHandle.Duplicate(aFileHandle)); |
|
958 iFileStream.Attach(dupHandle); |
|
959 } |
|
960 |
|
961 |
|
962 EXPORT_C CParserPropertyValueBinaryFile* CParserPropertyValueBinaryFile::NewL(const RFile& aFileHandle) |
|
963 /** Allocates and constructs a new file property value with the file handle to the data. |
|
964 |
|
965 The property value's UID will be set to KVersitPropertyBinaryUid. |
|
966 |
|
967 @param aFileHandle The file handle to the binary data. |
|
968 @return Pointer to the newly created file property value. */ |
|
969 { |
|
970 CParserPropertyValueBinaryFile* self = new(ELeave) CParserPropertyValueBinaryFile(); |
|
971 CleanupStack::PushL(self); |
|
972 self->ConstructL(aFileHandle); |
|
973 CleanupStack::Pop(self); |
|
974 return self; |
|
975 } |
|
976 |
|
977 EXPORT_C CParserPropertyValueBinaryFile::~CParserPropertyValueBinaryFile() |
|
978 /** Frees all resources owned by the property value, prior to its destruction. */ |
|
979 { |
|
980 iFileStream.Close(); |
|
981 } |
|
982 |
|
983 void CParserPropertyValueBinaryFile::ExternalizeL(RWriteStream& aStream, const Versit::TEncodingAndCharset& aEncodingCharset, TInt aLengthOutput) |
|
984 /** Externalises the binary data through the file handle into aStream. |
|
985 |
|
986 Uses the encoding format specified in aEncodingCharset. (Any character set |
|
987 specified in aEncodingCharset is not used). |
|
988 |
|
989 @param aStream Stream into which the value is to be externalized. |
|
990 @param aEncodingCharset Specifies the character set and encoding information. |
|
991 The encoding selected for a binary property value is Versit::EBase64Encoding. |
|
992 @param aLengthOutput The amount of text that has been output so far on the |
|
993 line (for the property name). */ |
|
994 { |
|
995 CParserPropertyValueBinary::ExternalizeL(aStream, aEncodingCharset, aLengthOutput, iFileStream); |
|
996 } |
|
997 |
|
998 // |
|
999 // CParserPropertyValueCDesCArray |
|
1000 // |
|
1001 |
|
1002 EXPORT_C CParserPropertyValueCDesCArray::CParserPropertyValueCDesCArray(CDesCArray* aValue) |
|
1003 : CParserPropertyValue(TUid::Uid(KVersitPropertyCDesCArrayUid)) |
|
1004 ,iValue(aValue) |
|
1005 /** Constructs a new descriptor array property value with the array pointed to |
|
1006 by aValue. |
|
1007 |
|
1008 Sets the property value's UID to KVersitPropertyCDesCArrayUid. |
|
1009 |
|
1010 The property value takes ownership of aValue. |
|
1011 |
|
1012 Called by CVersitParser::MakePropertyValueL() when internalising from a |
|
1013 stream. |
|
1014 |
|
1015 @param aValue Pointer to the descriptor array. */ |
|
1016 {} |
|
1017 |
|
1018 EXPORT_C CParserPropertyValueCDesCArray::~CParserPropertyValueCDesCArray() |
|
1019 /** Frees all resources owned by the property value array, prior to its destruction. */ |
|
1020 { |
|
1021 delete iValue; |
|
1022 } |
|
1023 |
|
1024 EXPORT_C TBool CParserPropertyValueCDesCArray::IsAsciiCharacterSetSufficient() |
|
1025 // From CParserPropertyValue |
|
1026 /** Tests whether the property value can be represented using the ASCII character |
|
1027 set. |
|
1028 |
|
1029 Tests every item in the array and returns ETrue only if all items contain only |
|
1030 7-bit characters. |
|
1031 |
|
1032 @return ETrue if the property value can be represented using the ASCII character |
|
1033 set. If not, EFalse. |
|
1034 @see VersitUtils::DescriptorContainsOnlySevenBitCharacters() */ |
|
1035 { |
|
1036 if (!iValue) |
|
1037 return ETrue; |
|
1038 TInt count = iValue->Count(); |
|
1039 if (!count) |
|
1040 return ETrue; |
|
1041 |
|
1042 for(TInt i=0; i<count; i++) |
|
1043 { |
|
1044 const TDesC& item = (*iValue)[i]; |
|
1045 if (!VersitUtils::DescriptorContainsOnlySevenBitCharacters(item)) |
|
1046 return EFalse; |
|
1047 } |
|
1048 |
|
1049 return ETrue; |
|
1050 } |
|
1051 |
|
1052 EXPORT_C void CParserPropertyValueCDesCArray::ExternalizeL(RWriteStream& aStream,const Versit::TEncodingAndCharset& aEncodingCharset,TInt aLengthOutput) |
|
1053 // From CParserPropertyValue |
|
1054 /** Externalizes the descriptor array property value into aStream. |
|
1055 |
|
1056 Uses the character set and encoding format specified in aEncodingCharset. |
|
1057 |
|
1058 Called by CParserProperty::ExternalizeL(). |
|
1059 |
|
1060 @param aStream Stream into which the value is to be externalised. |
|
1061 @param aEncodingCharset Specifies the character set and encoding information. |
|
1062 @param aLengthOutput The amount of text that has been output so far on the |
|
1063 line (for the property name), which needs to be taken into account when calculating |
|
1064 if and where any line break should occur. */ |
|
1065 { |
|
1066 FoldEncodeAndWriteValueToStreamL(aStream, iValue, aEncodingCharset, aLengthOutput); |
|
1067 } |
|
1068 |
|
1069 EXPORT_C TBool CParserPropertyValueCDesCArray::IsPresent(const TDesC& aValue) const |
|
1070 /** Tests whether a specified value is present in the array of descriptors owned |
|
1071 by the property value object. |
|
1072 |
|
1073 Not used internally. |
|
1074 |
|
1075 @param aValue The value of interest. |
|
1076 @return ETrue if the value specified is present in the descriptor array. EFalse |
|
1077 if not. */ |
|
1078 { |
|
1079 if (iValue) |
|
1080 { |
|
1081 TInt count=iValue->Count(); |
|
1082 for (TInt ii=0; ii<count; ii++) |
|
1083 { |
|
1084 if ((*iValue)[ii]==aValue) |
|
1085 { |
|
1086 return ETrue; |
|
1087 } |
|
1088 } |
|
1089 } |
|
1090 return EFalse; |
|
1091 } |
|
1092 |
|
1093 // |
|
1094 // CParserPropertyValueTimeZone |
|
1095 // |
|
1096 |
|
1097 EXPORT_C CParserPropertyValueTimeZone::CParserPropertyValueTimeZone(TTimeIntervalSeconds aValue) |
|
1098 : CParserPropertyValue(TUid::Uid(KVersitPropertyTimeZoneUid)) |
|
1099 , iValue(aValue) |
|
1100 /** Constructs a new time zone property value parser with a time interval in seconds, |
|
1101 which represents the universal time offset of the time zone. |
|
1102 |
|
1103 Sets the property value's UID to KVersitPropertyTimeZoneUid. |
|
1104 |
|
1105 @param aValue A time interval (in seconds) which represents the offset of |
|
1106 the time zone from universal time. The property value takes ownership of the |
|
1107 pointer. */ |
|
1108 {} |
|
1109 |
|
1110 void CParserPropertyValueTimeZone::EncodeTimeZone(TDes8& aBuf,TTimeIntervalSeconds aValue) |
|
1111 { |
|
1112 TInt hours=aValue.Int()/3600; |
|
1113 TInt sign=1; |
|
1114 _LIT8(KTwoDigits,"%02d"); |
|
1115 if (hours<0) //This code could be simplified if & when the E32 bug is fixed. |
|
1116 { |
|
1117 _LIT8(KMinus,"-"); |
|
1118 aBuf=KMinus; |
|
1119 sign=-1; |
|
1120 } |
|
1121 else |
|
1122 { |
|
1123 _LIT8(KPlus,"+"); |
|
1124 aBuf=KPlus; |
|
1125 } |
|
1126 aBuf.AppendFormat(KTwoDigits,sign*hours); |
|
1127 TInt minutes=sign*(aValue.Int()/60-60*hours); |
|
1128 if (minutes>0) |
|
1129 aBuf.AppendFormat(KTwoDigits,minutes); |
|
1130 } |
|
1131 |
|
1132 EXPORT_C void CParserPropertyValueTimeZone::ExternalizeL(RWriteStream& aStream,const Versit::TEncodingAndCharset& /*aEncodingCharset*/ |
|
1133 ,TInt /*aLengthOutput*/) |
|
1134 /** Externalises the time zone property value into aStream. |
|
1135 |
|
1136 @param aStream Stream into which the value is to be externalised. |
|
1137 @param aEncodingCharset Specifies the character set and encoding information. |
|
1138 (Not used by this function). |
|
1139 @param aLengthOutput The amount of text that has been output so far |
|
1140 on the line. (Not used by this function). */ |
|
1141 { |
|
1142 TBuf8<KVersitDefaultBufferSize> buf; |
|
1143 EncodeTimeZone(buf,iValue.Int()); |
|
1144 aStream.WriteL(buf); |
|
1145 } |
|
1146 |
|
1147 // |
|
1148 // CVersitDaylight |
|
1149 // |
|
1150 |
|
1151 CVersitDaylight::CVersitDaylight(TBool aSavings, TTimeIntervalSeconds aOffset, TVersitDateTime* aStartTime, TVersitDateTime* aEndTime) |
|
1152 : iSavings(aSavings), |
|
1153 iOffset(aOffset), |
|
1154 iStartTime(aStartTime), |
|
1155 iEndTime(aEndTime) |
|
1156 { |
|
1157 if (aSavings) |
|
1158 { |
|
1159 iStartTimeSortKey = TTime(iStartTime->iDateTime).Int64(); |
|
1160 } |
|
1161 else |
|
1162 { |
|
1163 iStartTimeSortKey = TTime(Time::MinTTime()).Int64(); |
|
1164 } |
|
1165 } |
|
1166 |
|
1167 void CVersitDaylight::ConstructL(const TDesC& aStandardDesignation, const TDesC& aDaylightDesignation) |
|
1168 { |
|
1169 iStandardDesignation = aStandardDesignation.AllocL(); |
|
1170 CleanupStack::PushL(iStandardDesignation); |
|
1171 iDaylightDesignation = aDaylightDesignation.AllocL(); |
|
1172 CleanupStack::Pop(iStandardDesignation); |
|
1173 } |
|
1174 |
|
1175 EXPORT_C CVersitDaylight* CVersitDaylight::NewL(TBool aSavings, TTimeIntervalSeconds aOffset, TVersitDateTime* aStartTime, TVersitDateTime* aEndTime, const TDesC& aStandardDesignation, const TDesC& aDaylightDesignation) |
|
1176 /** Allocates and constructs a new universal time offset object. |
|
1177 |
|
1178 Ownership of aStartTime and aEndTime is taken at end of this function. |
|
1179 |
|
1180 @param aSavings The daylight savings flag, i.e. ETrue if daylight saving is |
|
1181 currently observed in the locale; EFalse if not. |
|
1182 @param aOffset The universal time offset (in seconds). |
|
1183 @param aStartTime The date/time at which the period for daylight saving begins. |
|
1184 |
|
1185 @param aEndTime The date/time at which the period for daylight saving ends. |
|
1186 @param aStandardDesignation The standard time designation, e.g. GMT, EST. |
|
1187 @param aDaylightDesignation The daylight saving time designation, e.g. BST, |
|
1188 EDT. |
|
1189 @return The new universal time offset object. */ |
|
1190 { |
|
1191 CVersitDaylight* self = new(ELeave) CVersitDaylight(aSavings, aOffset, aStartTime, aEndTime); |
|
1192 CleanupStack::PushL(STATIC_CAST(TAny*,self)); |
|
1193 self->ConstructL(aStandardDesignation, aDaylightDesignation); |
|
1194 CleanupStack::Pop(self); |
|
1195 return self; |
|
1196 } |
|
1197 |
|
1198 EXPORT_C CVersitDaylight::~CVersitDaylight() |
|
1199 /** The destructor frees all resources owned by the object, prior to its destruction. */ |
|
1200 { |
|
1201 delete iStartTime; |
|
1202 delete iEndTime; |
|
1203 delete iStandardDesignation; |
|
1204 delete iDaylightDesignation; |
|
1205 } |
|
1206 |
|
1207 // |
|
1208 // CParserPropertyValueDaylight |
|
1209 // |
|
1210 |
|
1211 EXPORT_C CParserPropertyValueDaylight::CParserPropertyValueDaylight(CVersitDaylight* aValue) |
|
1212 : CParserTimePropertyValue(TUid::Uid(KVersitPropertyDaylightUid)), iValue(aValue) |
|
1213 /** Constructs a new CParserPropertyValueDaylight. |
|
1214 |
|
1215 Sets the property value's UID to KVersitPropertyDaylightUid. |
|
1216 |
|
1217 @param aValue Pointer to the daylight saving specification. The property value |
|
1218 takes ownership of the pointer. */ |
|
1219 {} |
|
1220 |
|
1221 EXPORT_C CParserPropertyValueDaylight::~CParserPropertyValueDaylight() |
|
1222 /** Frees all resources owned by the property value, prior to its destruction. */ |
|
1223 { |
|
1224 delete iValue; |
|
1225 } |
|
1226 |
|
1227 EXPORT_C void CParserPropertyValueDaylight::ConvertAllDateTimesToUTCL(const TTimeIntervalSeconds& /*aIncrement*/,const CVersitDaylight* /*aDaylight*/) |
|
1228 /** This function does nothing, as daylight saving times should always be specified |
|
1229 as local times. |
|
1230 |
|
1231 @param aIncrement Not used. |
|
1232 @param aDaylight Not used. |
|
1233 @deprecated since 9.1 |
|
1234 */ |
|
1235 {} |
|
1236 |
|
1237 EXPORT_C void CParserPropertyValueDaylight::ConvertAllUTCDateTimesToMachineLocalL(const TTimeIntervalSeconds& /*aIncrement*/) |
|
1238 /** Converts the start and end times for the daylight saving period to machine-local. |
|
1239 |
|
1240 This process involves adjusting the date/time values by the offset in aIncrement. |
|
1241 |
|
1242 It has no effect if daylight savings is not in effect or on values |
|
1243 already stored in machine-local time. |
|
1244 |
|
1245 This function is deprecated. |
|
1246 |
|
1247 @param aIncrement A time interval in seconds to add to the start and end date/times |
|
1248 for daylight saving. This should normally be the universal time offset for |
|
1249 the machine's locale. |
|
1250 @deprecated since 9.1 |
|
1251 */ |
|
1252 { |
|
1253 } |
|
1254 |
|
1255 EXPORT_C void CParserPropertyValueDaylight::ExternalizeL(RWriteStream& aStream,const Versit::TEncodingAndCharset& aEncodingCharset,TInt aLengthOutput) |
|
1256 // From CParserProperty |
|
1257 /** Externalizes the daylight saving property value into aStream. |
|
1258 |
|
1259 This is invoked by the parser's ExternalizeL() function. |
|
1260 |
|
1261 @param aStream Stream to which the value is to be externalised. |
|
1262 @param aEncodingCharset Specifies the character set and encoding information. |
|
1263 @param aLengthOutput The amount of text that has been output so far on the |
|
1264 line, which needs to be taken into account when calculating if and where any |
|
1265 line break should occur. */ |
|
1266 { |
|
1267 if (!iValue) |
|
1268 return; |
|
1269 TBuf<64> buf; |
|
1270 if (!iValue->iSavings) |
|
1271 buf.Append(KVersitVarTokenFALSE); |
|
1272 else |
|
1273 { |
|
1274 buf.Append(KVersitVarTokenTRUE); |
|
1275 buf.Append(KVersitTokenSemiColonUnicode); |
|
1276 TBuf8<KVersitDefaultBufferSize> timeBuf; |
|
1277 CParserPropertyValueTimeZone::EncodeTimeZone(timeBuf,iValue->iOffset); |
|
1278 Append(buf,timeBuf); |
|
1279 buf.Append(KVersitTokenSemiColonUnicode); |
|
1280 if (iValue->iStartTime) |
|
1281 { |
|
1282 EncodeVersitDateTimeL(timeBuf,*iValue->iStartTime); |
|
1283 Append(buf,timeBuf); |
|
1284 } |
|
1285 buf.Append(KVersitTokenSemiColonUnicode); |
|
1286 if (iValue->iEndTime) |
|
1287 { |
|
1288 EncodeVersitDateTimeL(timeBuf,*iValue->iEndTime); |
|
1289 Append(buf,timeBuf); |
|
1290 } |
|
1291 buf.Append(KVersitTokenSemiColonUnicode); |
|
1292 if (iValue->iStandardDesignation) |
|
1293 { |
|
1294 buf.Append(*(iValue->iStandardDesignation)); |
|
1295 } |
|
1296 buf.Append(KVersitTokenSemiColonUnicode); |
|
1297 if (iValue->iDaylightDesignation) |
|
1298 { |
|
1299 buf.Append(*(iValue->iDaylightDesignation)); |
|
1300 } |
|
1301 } |
|
1302 FoldAndWriteValueToStreamL(aStream,buf,aEncodingCharset,aLengthOutput); |
|
1303 } |
|
1304 |
|
1305 // |
|
1306 // CParserPropertyValueDateTimeL |
|
1307 // |
|
1308 EXPORT_C CParserPropertyValueDateTime::CParserPropertyValueDateTime(TVersitDateTime* aValue) |
|
1309 : CParserTimePropertyValue(TUid::Uid(KVersitPropertyDateTimeUid)) |
|
1310 , iValue(aValue) |
|
1311 /** Constructs a CParserPropertyValueDateTime with a TVersitDateTime value. |
|
1312 |
|
1313 Sets the property value's UID to KVersitPropertyDateTimeUid. |
|
1314 |
|
1315 @param aValue Pointer to the date/time specification, which includes information |
|
1316 about the date/time. The property value takes ownership of the pointer. */ |
|
1317 {} |
|
1318 |
|
1319 EXPORT_C CParserPropertyValueDateTime::~CParserPropertyValueDateTime() |
|
1320 /** Frees all resources owned by the property value, prior to its destruction. */ |
|
1321 { |
|
1322 delete iValue; |
|
1323 } |
|
1324 |
|
1325 EXPORT_C void CParserPropertyValueDateTime::ConvertAllDateTimesToUTCL(const TTimeIntervalSeconds& aIncrement,const CVersitDaylight* aDaylight) |
|
1326 /** Converts the object's date/time value into universal time. |
|
1327 |
|
1328 The date/time is checked against the daylight saving information provided |
|
1329 in aDaylight. If it falls inside the daylight saving period then the daylight |
|
1330 saving offset is subtracted from the time to convert it to universal time. |
|
1331 Otherwise aIncrement is added to the date/time to convert it to universal |
|
1332 time. |
|
1333 |
|
1334 Note that the daylight savings offset will adjust the time both for the daylight |
|
1335 saving and for the time zone. |
|
1336 |
|
1337 The function has no effect if the value is already stored as universal time. |
|
1338 |
|
1339 If aDaylight is a NULL pointer then aIncrement is used. |
|
1340 |
|
1341 @param aIncrement A time interval in seconds which represents the negative |
|
1342 of the time zone of the originating machine.For instance, if the time zone |
|
1343 is +04:30 (that is 4hr 30mins ahead of UTC), aIncrement should be set to minus |
|
1344 the number of seconds in 4hr 30mins. |
|
1345 @param aDaylight Pointer to the specification for daylight saving. If the date/time |
|
1346 value is within the period for daylight saving, the value is modified by the |
|
1347 daylight saving offset (which accounts for both the time zone and daylight |
|
1348 saving rule). |
|
1349 @deprecated since 9.1 |
|
1350 */ |
|
1351 { |
|
1352 if ((iValue) && (iValue->iRelativeTime!=TVersitDateTime::EIsUTC) && !iValue->IsFlagSet(TVersitDateTime::EExportLeaveAsLocalTime)) |
|
1353 { |
|
1354 ConvertDateTime(&iValue->iDateTime,aIncrement,aDaylight); |
|
1355 iValue->iRelativeTime=TVersitDateTime::EIsUTC; |
|
1356 } |
|
1357 } |
|
1358 |
|
1359 EXPORT_C void CParserPropertyValueDateTime::ConvertAllUTCDateTimesToMachineLocalL(const TTimeIntervalSeconds& aIncrement) |
|
1360 /** Converts the date/time property value into machine-local time. |
|
1361 |
|
1362 This process involves adjusting the date/time value by the offset in aIncrement. |
|
1363 |
|
1364 The function has no effect if the value is already stored as machine-local |
|
1365 time. |
|
1366 |
|
1367 @param aIncrement A time interval which represents the number of seconds which |
|
1368 is to be added to the date/time value. This should normally be the universal |
|
1369 time offset for the machine's locale. |
|
1370 @deprecated since 9.1 |
|
1371 */ |
|
1372 { |
|
1373 if ((iValue)&&(iValue->iRelativeTime==TVersitDateTime::EIsUTC)) |
|
1374 { |
|
1375 ConvertDateTime(&iValue->iDateTime,aIncrement,NULL); |
|
1376 iValue->iRelativeTime=TVersitDateTime::EIsMachineLocal; |
|
1377 } |
|
1378 } |
|
1379 |
|
1380 EXPORT_C void CParserPropertyValueDateTime::ExternalizeL(RWriteStream& aStream,const Versit::TEncodingAndCharset& /*aEncodingCharset*/ |
|
1381 ,TInt /*aLengthOutput*/) |
|
1382 // From CParserPropertyValue |
|
1383 /** Externalises the date/time property value to aStream. |
|
1384 |
|
1385 @param aStream Stream to which the value should be externalised |
|
1386 @param aEncodingCharset Specifies the character set and encoding information. This |
|
1387 is not used by this function. |
|
1388 @param aLengthOutput The amount of text that has been output so far on the line (for the |
|
1389 property name). This is not used by this function. */ |
|
1390 { |
|
1391 if (iValue) |
|
1392 { |
|
1393 TBuf8<KVersitMaxDateTimeLength> buf; |
|
1394 EncodeVersitDateTimeL(buf,*iValue); |
|
1395 aStream.WriteL(buf); |
|
1396 } |
|
1397 } |
|
1398 |
|
1399 |
|
1400 // |
|
1401 // CParserPropertyValueDate |
|
1402 // |
|
1403 EXPORT_C CParserPropertyValueDate::CParserPropertyValueDate(TVersitDateTime* aValue) |
|
1404 :CParserTimePropertyValue(TUid::Uid(KVersitPropertyDateUid)) |
|
1405 ,iValue(aValue) |
|
1406 /** Constructs a date property value parser with a TVersitDateTime value. |
|
1407 |
|
1408 Sets the property value's UID to KVersitPropertyDateUid. |
|
1409 |
|
1410 @param aValue Specifies the date and information about the date. The object |
|
1411 takes ownership of the pointer. */ |
|
1412 {} |
|
1413 |
|
1414 EXPORT_C CParserPropertyValueDate::~CParserPropertyValueDate() |
|
1415 /** Frees all resources owned by the object, prior to its destruction. */ |
|
1416 { |
|
1417 delete iValue; |
|
1418 } |
|
1419 |
|
1420 EXPORT_C void CParserPropertyValueDate::ConvertAllDateTimesToUTCL(const TTimeIntervalSeconds& /*aIncrement*/,const CVersitDaylight* /*aDaylight*/) |
|
1421 /** This function is inherited from the base class CParserTimePropertyValue. |
|
1422 |
|
1423 It has an empty implementation because this class represents a date not a time value. |
|
1424 |
|
1425 @param aIncrement Not used. |
|
1426 @param aDaylight Not used. |
|
1427 @deprecated since 9.1 |
|
1428 */ |
|
1429 {} |
|
1430 |
|
1431 EXPORT_C void CParserPropertyValueDate::ConvertAllUTCDateTimesToMachineLocalL(const TTimeIntervalSeconds& /*aIncrement*/) |
|
1432 /** This function is inherited from the base class CParserTimePropertyValue. |
|
1433 |
|
1434 It has an empty implementation because this class represents a date not a time value. |
|
1435 |
|
1436 @param aIncrement Not used. |
|
1437 @deprecated since 9.1 |
|
1438 */ |
|
1439 {} |
|
1440 |
|
1441 EXPORT_C void CParserPropertyValueDate::ExternalizeL(RWriteStream& aStream,const Versit::TEncodingAndCharset& /*aEncodingCharset*/,TInt /*aLengthOutput*/) |
|
1442 // From CParserProperty |
|
1443 /** Externalises the property value into aStream. |
|
1444 |
|
1445 @param aStream Stream to which the value should be externalised. |
|
1446 @param aEncodingCharset Specifies the character set and encoding information. This |
|
1447 information is not used by this function |
|
1448 @param aLengthOutput The amount of text that has been output so far on the line |
|
1449 (for the property name). This value is not used by this function. */ |
|
1450 { |
|
1451 if (iValue) |
|
1452 { |
|
1453 TBuf8<KVersitMaxDateTimeLength> buf; |
|
1454 EncodeVersitDateTimeL(buf,*iValue,EFalse); |
|
1455 aStream.WriteL(buf); |
|
1456 } |
|
1457 } |
|
1458 |
|
1459 // |
|
1460 // CParserPropertyValueMultiDateTimeL |
|
1461 // |
|
1462 EXPORT_C CParserPropertyValueMultiDateTime::CParserPropertyValueMultiDateTime(CArrayPtr<TVersitDateTime>* aValue) |
|
1463 : CParserTimePropertyValue(TUid::Uid(KVersitPropertyMultiDateTimeUid)) |
|
1464 ,iValue(aValue) |
|
1465 /** Constructs a multi-date/time property value parser with an array of TVersitDateTimes. |
|
1466 |
|
1467 Sets the property value's UID to KVersitPropertyMultiDateTimeUid. |
|
1468 |
|
1469 @param aValue Pointer to an array of TVersitDateTime objects, each of which |
|
1470 specifies a date/time value, and information about the value. The property |
|
1471 value takes ownership of the array. */ |
|
1472 {} |
|
1473 |
|
1474 EXPORT_C CParserPropertyValueMultiDateTime::~CParserPropertyValueMultiDateTime() |
|
1475 /** Frees all resources owned by the property value, prior to its destruction. */ |
|
1476 { |
|
1477 if (iValue) |
|
1478 { |
|
1479 iValue->ResetAndDestroy(); |
|
1480 delete iValue; |
|
1481 } |
|
1482 } |
|
1483 |
|
1484 EXPORT_C void CParserPropertyValueMultiDateTime::ConvertAllDateTimesToUTCL(const TTimeIntervalSeconds& aIncrement,const CVersitDaylight* aDaylight) |
|
1485 /** Converts each of the date/time values owned by the object into universal time. |
|
1486 |
|
1487 Each date/time is checked against the daylight saving information provided |
|
1488 in aDaylight. If it falls inside the daylight saving period then the daylight |
|
1489 saving offset is subtracted from the time to convert it to universal time. |
|
1490 Otherwise aIncrement is added to the date/time of the alarm to convert it |
|
1491 to universal time. |
|
1492 |
|
1493 Note that the daylight savings offset will adjust the time both for the daylight |
|
1494 saving and for the time zone. |
|
1495 |
|
1496 The function does not effect any date/time value already stored in universal |
|
1497 time. |
|
1498 |
|
1499 If aDaylight is a NULL pointer then aIncrement is used. |
|
1500 |
|
1501 @param aIncrement A time interval in seconds which represents the negative |
|
1502 of the time zone of the originating machine. For instance, if the time zone |
|
1503 is +04:30 (that is 4hr 30mins ahead of UTC), aIncrement should be set to minus |
|
1504 the number of seconds in 4hr 30mins. |
|
1505 @param aDaylight Pointer to the specification for daylight saving. If the time |
|
1506 value is within the period for daylight saving, the value is modified by the |
|
1507 daylight saving offset (which accounts for both the time zone and daylight |
|
1508 saving rule). |
|
1509 @deprecated since 9.1 |
|
1510 */ |
|
1511 { |
|
1512 if (iValue) |
|
1513 { |
|
1514 TInt count=iValue->Count(); |
|
1515 for (TInt ii=0;ii<count; ii++) |
|
1516 { |
|
1517 TVersitDateTime& time=*(*iValue)[ii]; |
|
1518 if (!(time.iRelativeTime==TVersitDateTime::EIsUTC) && !time.IsFlagSet(TVersitDateTime::EExportLeaveAsLocalTime)) |
|
1519 { |
|
1520 ConvertDateTime(&time.iDateTime,aIncrement,aDaylight); |
|
1521 time.iRelativeTime=TVersitDateTime::EIsUTC; |
|
1522 } |
|
1523 } |
|
1524 } |
|
1525 } |
|
1526 |
|
1527 EXPORT_C void CParserPropertyValueMultiDateTime::ConvertAllUTCDateTimesToMachineLocalL(const TTimeIntervalSeconds& aIncrement) |
|
1528 /** Converts the date/time property values into machine-local time. |
|
1529 |
|
1530 This process involves adjusting the date/time values by the offset in aIncrement. |
|
1531 |
|
1532 The function has no effect on any values already stored in machine-local time. |
|
1533 |
|
1534 @param aIncrement A time interval which represents the number of seconds which |
|
1535 is to be added to the date/time values. This should normally be the universal |
|
1536 time offset for the machine's locale. |
|
1537 @deprecated since 9.1 |
|
1538 */ |
|
1539 { |
|
1540 if (iValue) |
|
1541 { |
|
1542 TInt count=iValue->Count(); |
|
1543 for (TInt ii=0;ii<count; ii++) |
|
1544 { |
|
1545 if ((*iValue)[ii]->iRelativeTime==TVersitDateTime::EIsUTC) |
|
1546 { |
|
1547 ConvertDateTime(&(*iValue)[ii]->iDateTime,aIncrement,NULL); |
|
1548 (*iValue)[ii]->iRelativeTime=TVersitDateTime::EIsMachineLocal; |
|
1549 } |
|
1550 } |
|
1551 } |
|
1552 } |
|
1553 |
|
1554 EXPORT_C void CParserPropertyValueMultiDateTime::ExternalizeL(RWriteStream& aStream,const Versit::TEncodingAndCharset& /*aEncodingCharset*/ |
|
1555 ,TInt aLengthOutput) |
|
1556 // From CParserPropertyValue |
|
1557 /** Externalises the array of date/time property values into aStream. |
|
1558 |
|
1559 @param Stream to which the value should be externalised. |
|
1560 @param Specifies the character set and encoding information. This information |
|
1561 is not used by this function. |
|
1562 @param The amount of text that has been output on the line so far, which |
|
1563 needs to be taken into account when calculating if and where any line break |
|
1564 should occur. */ |
|
1565 { |
|
1566 const TInt maxCharsTimeOutput=KVersitMaxDateTimeLength+1; |
|
1567 if (iValue) |
|
1568 { |
|
1569 TBuf8<KVersitMaxDateTimeLength> buf; |
|
1570 TInt count = iValue->Count(); |
|
1571 TInt ii=0; |
|
1572 FOREVER |
|
1573 { |
|
1574 if (aLengthOutput+maxCharsTimeOutput>KMaxExternalizedTokenLength) |
|
1575 { |
|
1576 aStream.WriteL(KVersitLineBreak); |
|
1577 aLengthOutput=2; |
|
1578 } |
|
1579 EncodeVersitDateTimeL(buf,*(*iValue)[ii]); |
|
1580 aStream.WriteL(buf); |
|
1581 if (++ii==count) |
|
1582 break; |
|
1583 aStream.WriteL(KVersitTokenSemiColon); |
|
1584 aLengthOutput+=buf.Length()+1; |
|
1585 } |
|
1586 } |
|
1587 } |
|
1588 |
|
1589 // |
|
1590 // CParserPropertyValueInt |
|
1591 // |
|
1592 EXPORT_C CParserPropertyValueInt::CParserPropertyValueInt(TInt aValue) |
|
1593 : CParserPropertyValue(TUid::Uid(KVersitPropertyIntUid)), iValue(aValue) |
|
1594 /** Constructs the property value with a signed integer. |
|
1595 |
|
1596 Sets the property value's UID to KVersitPropertyIntUid. |
|
1597 |
|
1598 @param aValue A signed integer value. */ |
|
1599 {} |
|
1600 |
|
1601 EXPORT_C void CParserPropertyValueInt::ExternalizeL(RWriteStream& aStream,const Versit::TEncodingAndCharset& /*aEncodingCharset*/,TInt /*aLengthOutput*/) |
|
1602 // From CParserPropertyValue |
|
1603 /** Externalizes the integer property value to aStream. |
|
1604 |
|
1605 @param aStream Stream to which the value is to be externalised |
|
1606 @param aEncodingCharset Specifies the character set and encoding information. |
|
1607 Not used by this function. |
|
1608 @param aLengthOutput The amount of text that has been output so far on the line. |
|
1609 Not used by this function.*/ |
|
1610 { |
|
1611 TBuf8<KVersitDefaultBufferSize> buf; |
|
1612 buf.Num(iValue); |
|
1613 aStream.WriteL(buf); |
|
1614 } |
|
1615 |
|
1616 // |
|
1617 // CParserProperty |
|
1618 // |
|
1619 |
|
1620 EXPORT_C CParserProperty::CParserProperty(CParserPropertyValue& aPropertyValue,CArrayPtr<CParserParam>* aArrayOfParams) |
|
1621 : iPropertyValue(&aPropertyValue), iArrayOfParams(aArrayOfParams) |
|
1622 // Constructor takes ownership of aArrayOfParams, but not aName |
|
1623 {} |
|
1624 |
|
1625 EXPORT_C CParserProperty::CParserProperty(CArrayPtr<CParserParam>* aArrayOfParams) |
|
1626 : iArrayOfParams(aArrayOfParams) |
|
1627 /** C++ constructor which sets the array of property parameters only. |
|
1628 |
|
1629 The property takes ownership of the array of parameters. |
|
1630 |
|
1631 @param aArrayOfParams Pointer to the property parameters. */ |
|
1632 {} |
|
1633 |
|
1634 EXPORT_C void CParserProperty::ConstructSelfL(CParserProperty& aSelf,const TDesC8& aName) |
|
1635 { |
|
1636 if (aName.Length()>0) |
|
1637 { |
|
1638 CleanupStack::PushL(STATIC_CAST(TAny*,&aSelf)); |
|
1639 aSelf.SetNameL(aName); |
|
1640 CleanupStack::Pop(&aSelf); |
|
1641 } |
|
1642 } |
|
1643 |
|
1644 EXPORT_C CParserProperty* CParserProperty::NewL(CParserPropertyValue& aPropertyValue, const TDesC8& aName, CArrayPtr<CParserParam>* aArrayOfParams) |
|
1645 /** Allocates and constructs a new vCalendar or vCard property with the property |
|
1646 value, property name and array of property parameters specified. |
|
1647 |
|
1648 Takes ownership of aPropertyValue and aArrayOfParams. |
|
1649 |
|
1650 @param aPropertyValue The property value. |
|
1651 @param aName The property name. |
|
1652 @param aArrayOfParams Pointer to the property parameters. |
|
1653 @return Pointer to the newly created property. */ |
|
1654 { |
|
1655 // coverity [alloc_fn] |
|
1656 CParserProperty* self = new(ELeave) CParserProperty(aPropertyValue,aArrayOfParams); |
|
1657 ConstructSelfL(*self,aName); |
|
1658 return self; |
|
1659 } |
|
1660 |
|
1661 EXPORT_C CParserProperty::~CParserProperty() |
|
1662 /** Frees all resources owned by the property, prior to its destruction. */ |
|
1663 { |
|
1664 TRAPD(errIgnored, VersitUtils::FreeAdditionalPropertyStorageL(*this)); |
|
1665 UNUSED_VAR(errIgnored); // used to suppress build warnings |
|
1666 // |
|
1667 delete iPropertyValue; |
|
1668 delete iPropertyName; |
|
1669 if (iArrayOfParams) |
|
1670 { |
|
1671 iArrayOfParams->ResetAndDestroy(); |
|
1672 delete iArrayOfParams; |
|
1673 } |
|
1674 } |
|
1675 |
|
1676 EXPORT_C void CParserProperty::ExternalizeL(RWriteStream& aStream, CVersitParser* aVersitParser) |
|
1677 /** Externalises a property. |
|
1678 |
|
1679 The property has the general format: |
|
1680 |
|
1681 \<NAME\>;\<PARAMNAME=PARAMVALUE\>:\<VALUE\> |
|
1682 |
|
1683 Checks the property value, and Versit's default encoding and character |
|
1684 set, to decide what encoding, if any, and character set should be applied |
|
1685 to the property value. |
|
1686 |
|
1687 If the encoding is not the default, (no encoding), then a parameter (with |
|
1688 the name KVersitTokenENCODING) is added to the property to specify the encoding |
|
1689 used. Similarly, if the character set used is not the default, (Ascii), |
|
1690 then a parameter (with the name KVersitTokenCHARSET) is added |
|
1691 to the property to specify the character set used. |
|
1692 |
|
1693 A parser parameter needs to be supplied when calling this function: if NULL |
|
1694 is passed then a panic is raised. |
|
1695 |
|
1696 The name is externalised by this function directly. The parameters (if there |
|
1697 are any) are externalised using CParserParam::ExternalizeL(). The value (if |
|
1698 there is one) is externalised using the ExternalizeL() function of the appropriate |
|
1699 property value class. |
|
1700 |
|
1701 Using the encoding format and character set selected for the property value, |
|
1702 the function forms a Versit specific UID (Versit::TEncodingAndCharset). When |
|
1703 the property value is externalised, this UID is passed to the property value |
|
1704 class' ExternalizeL() function, so that it knows which character set and encoding |
|
1705 format to use. |
|
1706 |
|
1707 Also passed to the ExternalizeL() function of the property value class are |
|
1708 the output stream and the 'output length'. The output stream is the same as |
|
1709 is passed to this function. The 'output length' refers to the amount of data |
|
1710 that has been output to the current line in the stream. This is kept track |
|
1711 of while the property name and parameters are externalised, and then passed |
|
1712 to the ExternalizeL() function of the property value class to make sure the |
|
1713 line length does not exceed the maximum length allowed. |
|
1714 |
|
1715 As well as inserting the semi-colon and colon between the name and parameter(s) |
|
1716 and parameter(s) and value, a CRLF is written at the end. |
|
1717 |
|
1718 @param aStream Stream to which the value is to be externalised. |
|
1719 @param aVersitParser The Versit parser whose ExternalizeL() function calls |
|
1720 this function, and in whose array of properties this instance of CParserProperty |
|
1721 is held. */ |
|
1722 { |
|
1723 if (!iPropertyValue) |
|
1724 return; |
|
1725 __ASSERT_DEBUG(aVersitParser,Panic(EVersitPanicNeedToSpecifyParser)); |
|
1726 |
|
1727 // Updated in this method |
|
1728 const TUid propertyValueUid(iPropertyValue->Uid()); |
|
1729 TBool requiresEncoding = EFalse; |
|
1730 TUint propCharsetId=KCharacterSetIdentifierAscii; |
|
1731 |
|
1732 TAny* extPlugIn=NULL; |
|
1733 |
|
1734 // Why Daylight? |
|
1735 if (propertyValueUid == TUid::Uid(KVersitPropertyHBufCUid) || |
|
1736 propertyValueUid == TUid::Uid(KVersitPropertyCDesCArrayUid) || |
|
1737 propertyValueUid == TUid::Uid(KVCalPropertyAlarmUid) || |
|
1738 propertyValueUid == TUid::Uid(KVersitPropertyDaylightUid) || |
|
1739 propertyValueUid == TUid::Uid(KVersitPropertyBinaryUid) || |
|
1740 propertyValueUid == TUid::Uid(KVCalPropertyExtendedAlarmUid) |
|
1741 ) |
|
1742 { |
|
1743 TBool sevenBitsAreSufficient = ETrue; |
|
1744 |
|
1745 // This next section checks to see if the buffer passed to CheckEncodings requires a ENCODING=SOMETHING |
|
1746 // line as a property parameter for this item. If it does, then encode is set to ETrue (in most instances... |
|
1747 // Alarms, and Daylight's override any ETrue value to EFalse. Buffers that require this property parameter |
|
1748 // usually contain carriage returns, linefeeds or contain characters that fall outside the 0-127 range |
|
1749 switch(propertyValueUid.iUid) |
|
1750 { |
|
1751 case KVersitPropertyHBufCUid: |
|
1752 { |
|
1753 CParserPropertyValueHBufC* bufValue = STATIC_CAST(CParserPropertyValueHBufC*, iPropertyValue); |
|
1754 // |
|
1755 sevenBitsAreSufficient = VersitUtils::DescriptorContainsOnlySevenBitCharacters(bufValue->Value()); |
|
1756 requiresEncoding = VersitUtils::RequiresEncoding(bufValue->Value()); |
|
1757 break; |
|
1758 } |
|
1759 case KVersitPropertyCDesCArrayUid: |
|
1760 { |
|
1761 CParserPropertyValueCDesCArray* arrayValue = STATIC_CAST(CParserPropertyValueCDesCArray*, iPropertyValue); |
|
1762 const CDesCArray* value = arrayValue->Value(); |
|
1763 if (value) |
|
1764 { |
|
1765 TInt noOfProperties = value->Count(); |
|
1766 for (TInt jj = 0; jj < noOfProperties; jj++) |
|
1767 { |
|
1768 TPtrC pValue(value->MdcaPoint(jj)); |
|
1769 |
|
1770 // Keep local flags |
|
1771 TBool sevenBitsAreSufficientInternal = VersitUtils::DescriptorContainsOnlySevenBitCharacters(pValue); |
|
1772 TBool requiresEncodingInternal = VersitUtils::RequiresEncoding(pValue); |
|
1773 |
|
1774 // Now check combined with global flags & update as appropriate |
|
1775 if (!sevenBitsAreSufficientInternal && sevenBitsAreSufficient) |
|
1776 sevenBitsAreSufficient = sevenBitsAreSufficientInternal; |
|
1777 if (requiresEncodingInternal && !requiresEncoding) |
|
1778 requiresEncoding = requiresEncodingInternal; |
|
1779 |
|
1780 // Optimisation |
|
1781 if (!sevenBitsAreSufficient && requiresEncoding) |
|
1782 break; // Need both of these, no point checking anymore |
|
1783 } |
|
1784 } |
|
1785 break; |
|
1786 } |
|
1787 case KVCalPropertyAlarmUid: |
|
1788 { |
|
1789 CParserPropertyValueAlarm* bufValue = STATIC_CAST(CParserPropertyValueAlarm*, iPropertyValue); |
|
1790 CVersitAlarm* alarm = bufValue->Value(); |
|
1791 if (alarm) |
|
1792 { |
|
1793 if (alarm->iAudioContent) |
|
1794 { |
|
1795 sevenBitsAreSufficient = bufValue->IsAsciiCharacterSetSufficient(); |
|
1796 requiresEncoding = VersitUtils::RequiresEncoding(*alarm->iAudioContent); |
|
1797 } |
|
1798 // Only do this check if the audio content can still fit in 7 bits otherwise |
|
1799 // we will need to encode both anyway... |
|
1800 if (alarm->iNote && sevenBitsAreSufficient) |
|
1801 sevenBitsAreSufficient = VersitUtils::DescriptorContainsOnlySevenBitCharacters(*alarm->iNote); |
|
1802 } |
|
1803 break; |
|
1804 } |
|
1805 case KVCalPropertyExtendedAlarmUid: |
|
1806 { |
|
1807 CParserPropertyValueExtendedAlarm* bufValue = STATIC_CAST(CParserPropertyValueExtendedAlarm*, iPropertyValue); |
|
1808 CVersitExtendedAlarm* extendedAlarm = bufValue->Value(); |
|
1809 if (extendedAlarm) |
|
1810 { |
|
1811 if (extendedAlarm->iContent) |
|
1812 { |
|
1813 if (extendedAlarm->iDisposition == CVersitExtendedAlarm::EDispositionUrl) |
|
1814 { |
|
1815 sevenBitsAreSufficient = bufValue->IsAsciiCharacterSetSufficient(); |
|
1816 } |
|
1817 else |
|
1818 { |
|
1819 sevenBitsAreSufficient = EFalse; |
|
1820 requiresEncoding = ETrue; |
|
1821 } |
|
1822 } |
|
1823 } |
|
1824 break; |
|
1825 } |
|
1826 case KVersitPropertyDaylightUid: |
|
1827 { |
|
1828 // AW: requiresEncoding not used - I'm not sure why |
|
1829 CParserPropertyValueDaylight* bufValue = STATIC_CAST(CParserPropertyValueDaylight*, iPropertyValue); |
|
1830 CVersitDaylight* daylight = bufValue->Value(); |
|
1831 if (daylight) |
|
1832 { |
|
1833 if (daylight->iStandardDesignation) |
|
1834 sevenBitsAreSufficient = VersitUtils::DescriptorContainsOnlySevenBitCharacters(*daylight->iStandardDesignation); |
|
1835 |
|
1836 // Only do this check if 7 bits was suffient for the standard designation |
|
1837 if (daylight->iDaylightDesignation && sevenBitsAreSufficient) |
|
1838 sevenBitsAreSufficient = VersitUtils::DescriptorContainsOnlySevenBitCharacters(*daylight->iDaylightDesignation); |
|
1839 } |
|
1840 break; |
|
1841 } |
|
1842 case KVersitPropertyBinaryUid: |
|
1843 { |
|
1844 // Not handled here, see further down in the encodings "special case" section |
|
1845 break; |
|
1846 } |
|
1847 default: |
|
1848 __ASSERT_DEBUG(EFalse, User::Invariant()); |
|
1849 break; |
|
1850 } // switch |
|
1851 |
|
1852 /* |
|
1853 * Work out what character set we need to use for this property. |
|
1854 * |
|
1855 * Always try and use 7 bit ASCII because this is assumed as the default |
|
1856 * and therefore requires no CHARSET parameter. |
|
1857 * |
|
1858 * If ASCII isn't sufficient (see 'sevenBitsAreSufficient'), because there |
|
1859 * are character that can't be represented in ASCII then use the default |
|
1860 * charset instead. However, in the instance where ASCII is also the |
|
1861 * default, then use UTF-8. |
|
1862 * |
|
1863 * UTF-7 overrides all charsets and if specified as the default it should always be |
|
1864 * used in preference to ASCII or any other CHARSET |
|
1865 */ |
|
1866 if (!sevenBitsAreSufficient) |
|
1867 { |
|
1868 propCharsetId = aVersitParser->DefaultCharSetId(); |
|
1869 if (propCharsetId == KCharacterSetIdentifierAscii && !iPropertyValue->IsAsciiCharacterSetSufficient()) |
|
1870 propCharsetId = KCharacterSetIdentifierUtf8; |
|
1871 } |
|
1872 |
|
1873 /* |
|
1874 * If a default encoding has been specified then always use that, regardless of |
|
1875 * whether its required or not. |
|
1876 */ |
|
1877 if (!requiresEncoding && aVersitParser->DefaultEncoding() != Versit::ENoEncoding) |
|
1878 requiresEncoding = ETrue; |
|
1879 } // if |
|
1880 |
|
1881 /* |
|
1882 * If the property value is 8 bit (because of the required character set) or the value |
|
1883 * cannot be represented as is (e.g. it might contain CR or LF inside the value) then |
|
1884 * the value must be encoded. |
|
1885 * |
|
1886 * If it's just the charset that's 8bit, then we only need write ENCODING=8-BIT, but |
|
1887 * if it's more complicated because of the property value, then we must use a suitable |
|
1888 * encoding method. |
|
1889 */ |
|
1890 Versit::TVersitEncoding encoding = Versit::ENoEncoding; |
|
1891 if (!aVersitParser->PlugIn() || !aVersitParser->PlugIn()->EncodingType(encoding,requiresEncoding,aVersitParser->DefaultEncoding() |
|
1892 ,propertyValueUid,propCharsetId)) |
|
1893 { |
|
1894 if (propertyValueUid == TUid::Uid(KVersitPropertyBinaryUid)) |
|
1895 { |
|
1896 // A special case - this is encoded using BASE64 *always* |
|
1897 encoding = Versit::EBase64Encoding; |
|
1898 } |
|
1899 else if ((propertyValueUid == TUid::Uid(KVCalPropertyExtendedAlarmUid) && requiresEncoding)) |
|
1900 { |
|
1901 encoding = Versit::EBase64Encoding; |
|
1902 } |
|
1903 else if (requiresEncoding) |
|
1904 { |
|
1905 // This is superceeds an 8-bit charset - We will use the default, or |
|
1906 // if none is specified then we'll go with QP. |
|
1907 encoding = aVersitParser->DefaultEncoding(); |
|
1908 if (encoding == Versit::ENoEncoding || (propertyValueUid==TUid::Uid(KVCalPropertyAlarmUid) && encoding==Versit::EBase64Encoding)) |
|
1909 encoding = Versit::EQuotedPrintableEncoding; |
|
1910 } |
|
1911 else if (VersitUtils::EightBitEncoding(propCharsetId)) |
|
1912 { |
|
1913 // It's just an 8 bit charset, no QP or B64 required - Do nothing |
|
1914 encoding = Versit::EEightBitEncoding; |
|
1915 } |
|
1916 else |
|
1917 { |
|
1918 // Don't need any ENCODING=<something> tag - Do nothing |
|
1919 } |
|
1920 /* |
|
1921 * Some properties can't output Base64 data |
|
1922 * this is now corrected so the encoded is specified correctly |
|
1923 */ |
|
1924 if (encoding==Versit::EBase64Encoding) |
|
1925 { |
|
1926 if (propertyValueUid == TUid::Uid(KVersitPropertyTimeZoneUid) || |
|
1927 propertyValueUid == TUid::Uid(KVersitPropertyDateTimeUid) || |
|
1928 propertyValueUid == TUid::Uid(KVersitPropertyDateUid) || |
|
1929 propertyValueUid == TUid::Uid(KVersitPropertyMultiDateTimeUid) || |
|
1930 propertyValueUid == TUid::Uid(KVersitPropertyIntUid) || |
|
1931 propertyValueUid == TUid::Uid(KVCalPropertyRecurrenceUid)) |
|
1932 { |
|
1933 encoding=Versit::ENoEncoding; |
|
1934 } |
|
1935 } |
|
1936 } |
|
1937 |
|
1938 /* |
|
1939 * If we have to add an encoding line parameter, then we do that here. If the encoding |
|
1940 * is BASE64 or QP, then we always write the encoding tag. |
|
1941 * |
|
1942 * In addition, if we're using an 8 bit character set, E.g. ISO-8859-1, then we should |
|
1943 * also add the 8-bit encoding |
|
1944 */ |
|
1945 if (encoding != Versit::ENoEncoding) |
|
1946 { |
|
1947 CParserParam* param = CParserParam::NewL(KVersitTokenENCODING,KNullDesC8); |
|
1948 CleanupStack::PushL(param); |
|
1949 TBool pramAdded=EFalse; |
|
1950 if (aVersitParser->PlugIn()) |
|
1951 { |
|
1952 const TDesC8& des=aVersitParser->PlugIn()->EncodingName(encoding); |
|
1953 if (des.Length()>0) |
|
1954 { |
|
1955 param->SetValueL(des); |
|
1956 pramAdded=ETrue; |
|
1957 } |
|
1958 } |
|
1959 if (!pramAdded) |
|
1960 param->SetValueL(VersitUtils::IANAEncodingName(encoding)); |
|
1961 AddParamL(param); // takes ownership |
|
1962 CleanupStack::Pop(param); |
|
1963 if (encoding==Versit::EEightBitEncoding) |
|
1964 encoding=Versit::ENoEncoding; |
|
1965 } |
|
1966 else |
|
1967 {// delete the ENCODING parameter if it was there |
|
1968 TPtrC8 bufEncoding(KVersitTokenENCODING); |
|
1969 DeleteParam(bufEncoding); |
|
1970 } |
|
1971 |
|
1972 /* |
|
1973 * We now combine the encoding (if any) with the character set to form |
|
1974 * a versit specific uid which represents both of these things in one |
|
1975 * value. |
|
1976 * |
|
1977 * This uid is passed to the property value when it's externalized, and |
|
1978 * used to ensure that any text is written in the correct character set |
|
1979 * and with the correct encoding. |
|
1980 * |
|
1981 */ |
|
1982 Versit::TEncodingAndCharset encodingAndCharset(encoding,propCharsetId); |
|
1983 aVersitParser->SetCharacterConverter(encodingAndCharset); |
|
1984 |
|
1985 /* |
|
1986 * In the instance where ASCII representation is not sufficient, it is necessary to create |
|
1987 * an extra property parameter which indicates the CHARSET that was used during the |
|
1988 * export process. |
|
1989 */ |
|
1990 |
|
1991 /* |
|
1992 * vCard 3.0 format allows automatic CHARSET parameter export to be disabled. |
|
1993 * And to generate a content line in the format <NAME>;<PARAMNAME=PARAMVALUE>:<VALUE> , |
|
1994 * lines longer than 75 characters SHOULD be folded as defined by RFC2425 and RFC2426. |
|
1995 */ |
|
1996 TBool disableCharset=EFalse; |
|
1997 if (aVersitParser->PlugIn()) |
|
1998 { |
|
1999 aVersitParser->PlugIn()->GetInterface(KUidVersitPlugInExtension, extPlugIn); |
|
2000 if (extPlugIn) |
|
2001 { |
|
2002 disableCharset = static_cast<MVersitPlugInExtension*>(extPlugIn)->DisableCharsetParam(); |
|
2003 } |
|
2004 } |
|
2005 |
|
2006 if (propCharsetId != KCharacterSetIdentifierAscii && !disableCharset) |
|
2007 { |
|
2008 CParserParam* param = CParserParam::NewL(KVersitTokenCHARSET,KNullDesC8); |
|
2009 CleanupStack::PushL(param); |
|
2010 HBufC8* standardName = aVersitParser->UnicodeUtils().StandardNameL(propCharsetId); |
|
2011 if (standardName->CompareF(KVersitTokenUTF8()) == 0) |
|
2012 { |
|
2013 standardName->Des().Fold(); |
|
2014 } |
|
2015 param->SetValueL(standardName); |
|
2016 AddParamL(param); |
|
2017 CleanupStack::Pop(param); |
|
2018 } |
|
2019 else |
|
2020 {// delete the CHARSET parameter if it was there |
|
2021 TPtrC8 bufCharset(KVersitTokenCHARSET); |
|
2022 DeleteParam(bufCharset); |
|
2023 } |
|
2024 |
|
2025 /* |
|
2026 * General format is: |
|
2027 * |
|
2028 * <NAME>;<PARAMNAME=PARAMVALUE>:<VALUE> |
|
2029 * |
|
2030 */ |
|
2031 |
|
2032 TBool foldParam=EFalse; |
|
2033 if (extPlugIn) |
|
2034 { |
|
2035 foldParam = static_cast<MVersitPlugInExtension*>(extPlugIn)->FoldParam(); |
|
2036 } |
|
2037 |
|
2038 // Write out NAME part |
|
2039 TInt outputLen = 0; |
|
2040 if(foldParam) |
|
2041 { |
|
2042 HBufC8* name = Name().AllocLC(); |
|
2043 TPtr8 text(name->Des()); |
|
2044 aVersitParser->PlugIn()->WrapLine(aStream, outputLen, text); |
|
2045 CleanupStack::PopAndDestroy(name); |
|
2046 } |
|
2047 else |
|
2048 { |
|
2049 aStream.WriteL(Name()); |
|
2050 outputLen = Name().Length(); |
|
2051 } |
|
2052 |
|
2053 // Write out PARAMNAME=PARAMVALUE part |
|
2054 if (iArrayOfParams) |
|
2055 { |
|
2056 TInt noOfParams = iArrayOfParams->Count(); |
|
2057 for (TInt ii = 0; ii < noOfParams; ii++) |
|
2058 { |
|
2059 aStream.WriteL(KVersitTokenSemiColon); |
|
2060 |
|
2061 if(foldParam) |
|
2062 { |
|
2063 outputLen++; //1 for the ";" |
|
2064 iArrayOfParams->At(ii)->ExternalizeL(aStream, outputLen, aVersitParser); |
|
2065 } |
|
2066 else |
|
2067 { |
|
2068 outputLen += iArrayOfParams->At(ii)->ExternalizeL(aStream)+1; |
|
2069 } |
|
2070 } |
|
2071 } |
|
2072 |
|
2073 // Write out VALUE part |
|
2074 aStream.WriteL(KVersitTokenColon); |
|
2075 outputLen++; //1 for the ":" |
|
2076 |
|
2077 iPropertyValue->ExternalizeL(aStream, encodingAndCharset, outputLen); |
|
2078 aStream.WriteL(KVersitTokenCRLF); |
|
2079 } |
|
2080 |
|
2081 EXPORT_C CParserParam* CParserProperty::Param(const TDesC8& aParamName) const |
|
2082 // return first parameter found with specified name |
|
2083 /** Gets a pointer to the property parameter with the specified name. |
|
2084 |
|
2085 If the property has more than one parameter with the same name, the function |
|
2086 returns the one nearest the start of the array, but there should never be |
|
2087 more than one of each possible parameter. |
|
2088 |
|
2089 @param aParamName The name of the parameter to search for. |
|
2090 @return Pointer to a property parameter. NULL if the parameter name specified |
|
2091 is not found in the array. */ |
|
2092 { |
|
2093 if (iArrayOfParams) |
|
2094 { |
|
2095 TInt count = iArrayOfParams->Count(); |
|
2096 for (TInt ii = 0; ii < count; ii++) |
|
2097 { |
|
2098 if ((*iArrayOfParams)[ii]->Name().CompareF(aParamName) == 0) |
|
2099 return ((*iArrayOfParams)[ii]); |
|
2100 } |
|
2101 } |
|
2102 return NULL; |
|
2103 } |
|
2104 |
|
2105 EXPORT_C CArrayPtr<CParserParam>* CParserProperty::ParamArray()const |
|
2106 /** Returns a pointer to the array of property parameters. |
|
2107 |
|
2108 @return Pointer to array of property parameters. NULL if the property is not having any parameters.*/ |
|
2109 { |
|
2110 //if the array doesn't exist, return NULL. |
|
2111 if(!iArrayOfParams) |
|
2112 { |
|
2113 return NULL; |
|
2114 } |
|
2115 return iArrayOfParams; |
|
2116 } |
|
2117 |
|
2118 EXPORT_C void CParserProperty::AddParamL(CParserParam* aParam) |
|
2119 /** Adds a property parameter to the property. |
|
2120 |
|
2121 Any existing parameter with the same name is replaced. The parameter is appended |
|
2122 to the property's parameter array. If no property parameter array has been |
|
2123 allocated, the function will first allocate one. |
|
2124 |
|
2125 @param aParam Pointer to a generic property parameter, consisting of a name |
|
2126 and optionally a value, both specified as descriptors. The property takes |
|
2127 ownership of the new parameter. */ |
|
2128 { |
|
2129 TPtrC8 name=aParam->Name(); |
|
2130 DeleteParam(name); |
|
2131 |
|
2132 // if the array doesn't exist, create one here |
|
2133 if (!iArrayOfParams) |
|
2134 iArrayOfParams = new(ELeave)CArrayPtrFlat<CParserParam>(4); |
|
2135 iArrayOfParams->AppendL(aParam); |
|
2136 } |
|
2137 |
|
2138 EXPORT_C void CParserProperty::DeleteParam(TDesC8& aParamName) |
|
2139 /** Deletes the specified property parameter from the property's array of parameters, |
|
2140 if it exists in the array. |
|
2141 |
|
2142 If the property has more than one parameter with the same name, the function |
|
2143 deletes the one nearest the start of the array, but there should never be |
|
2144 more than one of each possible parameter. |
|
2145 |
|
2146 @param aParamName The name of the parameter to delete. */ |
|
2147 { |
|
2148 if (iArrayOfParams) |
|
2149 { |
|
2150 const TInt count = iArrayOfParams->Count(); |
|
2151 for (TInt ii = 0; ii < count; ii++) |
|
2152 { |
|
2153 if ((*iArrayOfParams)[ii]->Name() == aParamName) |
|
2154 { |
|
2155 delete (*iArrayOfParams)[ii]; |
|
2156 iArrayOfParams->Delete(ii); |
|
2157 break; |
|
2158 } |
|
2159 } |
|
2160 } |
|
2161 } |
|
2162 |
|
2163 EXPORT_C void CParserProperty::SetNameL(const TDesC8& aName) |
|
2164 /** Sets the property name. |
|
2165 |
|
2166 If a name has already been set, this function will replace it. |
|
2167 |
|
2168 This function allocates and constructs a new heap descriptor |
|
2169 and initialises it using the content of aName, so can leave if insufficient |
|
2170 memory is available. |
|
2171 |
|
2172 @param aName The new property name. Property names are defined in vtoken.h. */ |
|
2173 { |
|
2174 delete iPropertyName; |
|
2175 iPropertyName = NULL; |
|
2176 iPropertyName = aName.AllocL(); |
|
2177 } |
|
2178 |
|
2179 EXPORT_C TBool CParserProperty::SupportsInterface(const TUid& /*aInterfaceUid*/) const |
|
2180 /** Tests whether the property value supports the specified interface. |
|
2181 |
|
2182 This implementation returns EFalse. |
|
2183 |
|
2184 @param aInterfaceUid Not used. |
|
2185 @return EFalse. */ |
|
2186 { |
|
2187 return EFalse; |
|
2188 } |
|
2189 |
|
2190 EXPORT_C TPtrC8 CParserProperty::Name() const |
|
2191 /** Gets the property name. |
|
2192 |
|
2193 If no name has been set, the function returns an empty descriptor. |
|
2194 |
|
2195 @return The property name. */ |
|
2196 { |
|
2197 if (iPropertyName) |
|
2198 return iPropertyName->Des(); |
|
2199 return KVersitTokenEmptyNarrow(); |
|
2200 } |
|
2201 |
|
2202 |
|
2203 EXPORT_C TBool CParserProperty::SaveBinaryValuesToFilesL(TInt aSizeThreshold,const TDesC& aPath,RFs& aFileSession) |
|
2204 /** If the property value is binary and is larger than the specified threshold, |
|
2205 this function saves the binary data to a file and sets the property value |
|
2206 to be a URI representing the file rather than the binary data iself. |
|
2207 |
|
2208 If the property value is not binary, or if it is binary, but is smaller than |
|
2209 the threshold, the function just returns EFalse. |
|
2210 |
|
2211 The file is created in the folder identified by aPath, and is assigned a unique |
|
2212 filename that consists of the property name and some random numbers. |
|
2213 |
|
2214 The new URI property value is prefixed with file:// and contains the path |
|
2215 and filename of the file created. |
|
2216 |
|
2217 The function uses the file server session supplied, which is needed to create |
|
2218 the files. It leaves if there is a problem creating any of the files. |
|
2219 |
|
2220 This function is used by CVersitParser::SaveBinaryValuesToFilesL(). |
|
2221 |
|
2222 @param aSizeThreshold The threshold number of bytes for the binary data, above |
|
2223 which a file is created and the binary data is stored in it. |
|
2224 @param aPath The path identifying the location in which the file is created. |
|
2225 Must not be greater than 240 characters long or the function leaves with KErrArgument. |
|
2226 If it doesn't end in a slash, then one is appended. |
|
2227 @param aFileSession The file server session used to create the files. |
|
2228 @return ETrue if the property value is binary and its size is greater than |
|
2229 the threshold. EFalse if not. */ |
|
2230 { |
|
2231 |
|
2232 // The length of the path can be maximum 240 characters. |
|
2233 __ASSERT_ALWAYS((aPath.Length() <= (KMaxFileName - KMaxGeneratedfilenamelen)),User::Leave(KErrArgument)); |
|
2234 |
|
2235 if (iPropertyValue->Uid().iUid==KVCardPropertyAgentUid) |
|
2236 { |
|
2237 return ((static_cast<CParserPropertyValueAgent*>(iPropertyValue)->Value())->SaveBinaryValuesToFilesL(aSizeThreshold,aPath,aFileSession)); |
|
2238 } |
|
2239 else if (iPropertyValue->Uid().iUid!=KVersitPropertyBinaryUid) |
|
2240 { |
|
2241 return EFalse; |
|
2242 } |
|
2243 |
|
2244 const CBufSeg* bufseg_ptr = static_cast<CParserPropertyValueBinary*>(iPropertyValue)->Value(); |
|
2245 if (!bufseg_ptr || bufseg_ptr->Size() <= aSizeThreshold) |
|
2246 { |
|
2247 return EFalse; |
|
2248 } |
|
2249 |
|
2250 // read the binary data into a buffer so as to create and write to a file later on |
|
2251 HBufC8* buffer = HBufC8::NewL(0); |
|
2252 CleanupStack::PushL(TCleanupItem(DestroyHBufC, &buffer)); |
|
2253 ReadBinaryDataL(bufseg_ptr, &buffer); |
|
2254 |
|
2255 // create a file . The file name is generated with the function call and then the file is created |
|
2256 TBuf<KMaxFileName + KFileProtocolStringLength> filename(aPath); |
|
2257 RFile file; |
|
2258 GenerateNameAndCreateFileL(aFileSession, iPropertyName->Des(), file, filename); |
|
2259 |
|
2260 // Write the binary value to the file. |
|
2261 CleanupClosePushL(file); |
|
2262 User::LeaveIfError(file.Write(*buffer)); |
|
2263 // pop and destroy the file and the buffer objects |
|
2264 CleanupStack::PopAndDestroy(2); |
|
2265 |
|
2266 // Convert the filename to a URI in accordance with RFC 1738: prefix "file://" and change all \s to /s. |
|
2267 filename.Insert(0,KFileProtocol); |
|
2268 const TInt fileNameLength = filename.Length(); |
|
2269 for (TInt i = KFileProtocolStringLength; i < fileNameLength; i++) |
|
2270 { |
|
2271 if (filename[i] == '\\') |
|
2272 { |
|
2273 filename[i] = '/'; |
|
2274 } |
|
2275 } |
|
2276 |
|
2277 CDesCArrayFlat* desarray = new(ELeave) CDesCArrayFlat(filename.Length()); |
|
2278 CleanupStack::PushL(desarray); |
|
2279 TPtrC ptrc(filename); |
|
2280 desarray->InsertL(0,ptrc); |
|
2281 CParserPropertyValueCDesCArray* value = new(ELeave) CParserPropertyValueCDesCArray(desarray); |
|
2282 CleanupStack::Pop(desarray); |
|
2283 CleanupStack::PushL(value); |
|
2284 |
|
2285 // Add a parameter identifying the property value as a URI. |
|
2286 CParserParam* uripropertyparam = CParserParam::NewL(KValue,KUri); |
|
2287 CleanupStack::PushL(uripropertyparam); |
|
2288 AddParamL(uripropertyparam); |
|
2289 CleanupStack::Pop(uripropertyparam); |
|
2290 |
|
2291 // Remove any other value parameters. The new parameter is the last one. |
|
2292 const TInt count = iArrayOfParams->Count(); |
|
2293 for (TInt ii = 0; ii < count; ii++) |
|
2294 { |
|
2295 if ((*iArrayOfParams)[ii]->Name() == KValue) |
|
2296 { |
|
2297 if (ii == (count-1)) |
|
2298 { |
|
2299 break; |
|
2300 } |
|
2301 else |
|
2302 { |
|
2303 delete (*iArrayOfParams)[ii]; |
|
2304 iArrayOfParams->Delete(ii); |
|
2305 } |
|
2306 } |
|
2307 } |
|
2308 delete iPropertyValue; |
|
2309 iPropertyValue = value; |
|
2310 CleanupStack::Pop(value); |
|
2311 return ETrue; |
|
2312 } |
|
2313 |
|
2314 EXPORT_C TBool CParserProperty::LoadBinaryValuesFromFilesL(RFs& aFileSession) |
|
2315 /** If the property value is a URI, this function loads the file represented by |
|
2316 the URI and sets the binary data it contains to be the property value, instead |
|
2317 of the URI. |
|
2318 |
|
2319 If the property value is not a URI, the function just returns EFalse. |
|
2320 |
|
2321 The function also operates on any agents in a vCard that contain URI property |
|
2322 values. |
|
2323 |
|
2324 The function uses the file server session supplied, which is needed to open |
|
2325 the files. It leaves if there is a problem opening any of the files. |
|
2326 |
|
2327 This function is used by CVersitParser::LoadBinaryValuesFromFilesL(). |
|
2328 |
|
2329 @param aFileSession The file server session used to open the files. |
|
2330 @return ETrue if the property value is a URI, EFalse if not. */ |
|
2331 { |
|
2332 |
|
2333 if (iPropertyValue->Uid().iUid==KVCardPropertyAgentUid) |
|
2334 { |
|
2335 return ((static_cast<CParserPropertyValueAgent*>(iPropertyValue)->Value())->LoadBinaryValuesFromFilesL(aFileSession)); |
|
2336 } |
|
2337 // Do nothing if the value is not a text value . |
|
2338 else if (iPropertyValue->Uid().iUid!=KVersitPropertyCDesCArrayUid) |
|
2339 { |
|
2340 return EFalse; |
|
2341 } |
|
2342 CDesCArray* text_ptr = static_cast<CParserPropertyValueCDesCArray*>(iPropertyValue)->Value(); |
|
2343 if (text_ptr == NULL) |
|
2344 { |
|
2345 return EFalse; |
|
2346 } |
|
2347 const TDesC& text = text_ptr->MdcaPoint(0); |
|
2348 //The URI should contain file:// and some filename with path.. The min file name would be eg. c:\<1digitnumber> |
|
2349 if ((text.Length() < (KFileProtocolStringLength + KMinFileNameLen)) || (text.Left(KFileProtocolStringLength).CompareF(KFileProtocol) != 0)) |
|
2350 { |
|
2351 return EFalse; |
|
2352 } |
|
2353 // Do nothing if this is not a URI value representing a file. |
|
2354 const CParserParam* param = Param(KValue); |
|
2355 if (param == NULL || ( param->Value().CompareF(KUri) != 0)) |
|
2356 { |
|
2357 return EFalse; |
|
2358 } |
|
2359 |
|
2360 // Convert the URI to a filename: remove "file://" and change /s to \s. |
|
2361 TPtrC fptrc = text.Mid(KFileProtocolStringLength); |
|
2362 if (fptrc.Length() > KMaxFileName) |
|
2363 { |
|
2364 fptrc.Set(fptrc.Ptr(),KMaxFileName); |
|
2365 } |
|
2366 TFileName filename(fptrc); |
|
2367 const TInt filenameLength = filename.Length(); |
|
2368 for (TInt i = 0; i < filenameLength; i++) |
|
2369 { |
|
2370 if (filename[i] == '/') |
|
2371 { |
|
2372 filename[i] = '\\'; |
|
2373 } |
|
2374 } |
|
2375 // Load the file and put it into a CVersitBinaryValue. |
|
2376 RFile file; |
|
2377 User::LeaveIfError(file.Open(aFileSession,filename,EFileRead)); |
|
2378 CleanupClosePushL(file); |
|
2379 TInt bytes; |
|
2380 User::LeaveIfError(file.Size(bytes)); |
|
2381 |
|
2382 HBufC8* buffer = HBufC8::NewL(bytes); |
|
2383 CleanupStack::PushL(TCleanupItem(DestroyHBufC, &buffer)); |
|
2384 TPtr8 des(buffer->Des()); |
|
2385 User::LeaveIfError(file.Read(des)); |
|
2386 __ASSERT_ALWAYS((buffer->Length() >= bytes),User::Leave(KErrGeneral)); |
|
2387 CParserPropertyValueBinary* value = CParserPropertyValueBinary::NewL(buffer->Left(buffer->Length())); |
|
2388 // pop and destroy the file and the buffer objects |
|
2389 CleanupStack::PopAndDestroy(2); |
|
2390 |
|
2391 //There should only ever be one VALUE parameter, and, in order have gotten to |
|
2392 // this point in the code, it has to be value=URI |
|
2393 // so we just delete all VALUE parameters (there should only be one, but this handles |
|
2394 // corrupt data better, even though it is a bit slower). |
|
2395 |
|
2396 const TInt count = iArrayOfParams->Count(); |
|
2397 for (TInt ii = 0; ii < count; ii++) |
|
2398 { |
|
2399 if ((*iArrayOfParams)[ii]->Name() == KValue) |
|
2400 { |
|
2401 delete (*iArrayOfParams)[ii]; |
|
2402 iArrayOfParams->Delete(ii); |
|
2403 } |
|
2404 } |
|
2405 |
|
2406 // Replace the existing value with the new binary value. |
|
2407 delete iPropertyValue; |
|
2408 iPropertyValue = value; |
|
2409 |
|
2410 return ETrue; |
|
2411 } |
|
2412 |
|
2413 /* |
|
2414 * Reads the binary data from the segmented buffer onto a heap descriptor |
|
2415 * |
|
2416 * |
|
2417 * @param "const CBufSeg* aBufseg_ptr" ( source ) |
|
2418 * The segemnted buffer that contains the binary data |
|
2419 * @param "HBufC8** aBuffer" ( destination ) |
|
2420 * The pointer to the heap descriptor data location which |
|
2421 * eventually holds the data |
|
2422 * A ptr to ptr is passed since the reloaction is happening inside |
|
2423 */ |
|
2424 void CParserProperty::ReadBinaryDataL(const CBufSeg* aBufseg_ptr,HBufC8** aBuffer) |
|
2425 { |
|
2426 TInt buf_size = aBufseg_ptr->Size(); |
|
2427 TInt pos = 0; |
|
2428 TInt len = 0; |
|
2429 |
|
2430 while ( pos < buf_size) |
|
2431 { |
|
2432 len =const_cast<CBufSeg*>(aBufseg_ptr)->Ptr(pos).Length(); |
|
2433 TUint8* temp = new (ELeave) TUint8 [len]; |
|
2434 CleanupArrayDeletePushL(temp); |
|
2435 aBufseg_ptr->Read(pos,temp,len); |
|
2436 // copy the data to the buffer |
|
2437 *aBuffer = (*aBuffer)->ReAllocL(pos+len); |
|
2438 TPtr8 localptr = (*aBuffer)->Des(); |
|
2439 localptr.Append(const_cast<TUint8*>(temp),len); |
|
2440 //continue the iteration |
|
2441 pos += len; |
|
2442 CleanupStack::PopAndDestroy(temp); |
|
2443 } |
|
2444 return; |
|
2445 } |
|
2446 |
|
2447 /* |
|
2448 * Creates a file. The name of the file is generated using the following parameters |
|
2449 * <propertyname limited in length if required depending on the length of the path> |
|
2450 * <a randomly generated number which is max upto 5 characters in len> |
|
2451 * The path is specified as an input to teh fuction which is used in creating a file. |
|
2452 * |
|
2453 * @param "RFs& aFileSession" |
|
2454 * The file server session to be used |
|
2455 * @param "TPtr8 aPropertyName" |
|
2456 * The property name that holds the binary data |
|
2457 * @param "RFile& aFile" |
|
2458 * The handle to the file created |
|
2459 * @param "TDes& aFileName" |
|
2460 * The name of the file created. Initially this contains the path when it is passed to the function. |
|
2461 * Inside teh function the filename is appended |
|
2462 */ |
|
2463 void CParserProperty::GenerateNameAndCreateFileL(RFs& aFileSession, TPtr8 aPropertyName, RFile& aFile, TDes& aFileName) |
|
2464 { |
|
2465 // the total space available to store the path+ filename = 256 ( KMaxFileName) |
|
2466 // aFileName.Length() gives the length of the path |
|
2467 // hence available length for filename ( propertyname + 5 digit randomnumber ) = 256 - aFileName.Length() |
|
2468 TInt available = (KMaxFileName - aFileName.Length()); |
|
2469 |
|
2470 if (aFileName[aFileName.Length() - 1] != '\\') |
|
2471 { |
|
2472 aFileName.Append('\\'); |
|
2473 available--; |
|
2474 } |
|
2475 // gets the property name into a TPtrC |
|
2476 TInt proplen = aPropertyName.Length(); |
|
2477 HBufC* propertyname = HBufC::NewL(proplen); |
|
2478 CleanupStack::PushL(TCleanupItem(DestroyHBufC, &propertyname)); |
|
2479 TPtr propnameptr = propertyname->Des(); |
|
2480 propnameptr.Copy(aPropertyName); |
|
2481 TPtrC name(propertyname->Left(proplen)); |
|
2482 |
|
2483 // limit the property name so that u limit the path+filename = 256 characters |
|
2484 if (name.Length() > available - KRandomnumberlen) |
|
2485 { |
|
2486 name.Set(name.Ptr(),available - KRandomnumberlen); |
|
2487 } |
|
2488 aFileName.Append(name); |
|
2489 CleanupStack::PopAndDestroy(&propertyname); |
|
2490 // Fill in any missing parts of the filename. |
|
2491 TParse parse; |
|
2492 User::LeaveIfError(aFileSession.Parse(aFileName,parse)); |
|
2493 aFileName = parse.FullName(); |
|
2494 |
|
2495 TTime time; |
|
2496 time.UniversalTime(); |
|
2497 TInt64 seed = time.Int64(); |
|
2498 TInt length = aFileName.Length(); |
|
2499 TInt n; |
|
2500 |
|
2501 FOREVER |
|
2502 { |
|
2503 n = Math::Rand(seed) >> 16; |
|
2504 aFileName.AppendNum(n); |
|
2505 TInt error = aFile.Create(aFileSession,aFileName,EFileWrite); |
|
2506 if(error == KErrNone) |
|
2507 { |
|
2508 break; |
|
2509 } |
|
2510 else |
|
2511 { |
|
2512 __ASSERT_ALWAYS((error == KErrAlreadyExists),User::Leave(error)); |
|
2513 } |
|
2514 |
|
2515 aFileName.SetLength(length); |
|
2516 } |
|
2517 |
|
2518 return; |
|
2519 } |
|
2520 |
|
2521 EXPORT_C void CParserProperty::Reserved() |
|
2522 {} |