pimappsupport/vcardandvcal/src/VPROP.CPP
changeset 0 f979ecb2b13e
equal deleted inserted replaced
-1:000000000000 0:f979ecb2b13e
       
     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 	{}