pimappsupport/vcardandvcal/src/VERSIT.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 #ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
       
    18 #include <versitlinereaderext.h>
       
    19 #include "versittlscontainer.h"
       
    20 #include "versit_internal.h"
       
    21 #endif
       
    22 
       
    23 // System includes
       
    24 #include <s32file.h>
       
    25 #include <s32mem.h>
       
    26 #include <utf.h>
       
    27 #include <charconv.h>
       
    28 #include <confndr.h>
       
    29 #include <concnf.h>
       
    30 #include <conlist.h>
       
    31 #include <e32base.h>
       
    32 
       
    33 // User includes
       
    34 #include <vutil.h>
       
    35 #include <vstaticutils.h>
       
    36 #include <versittls.h>
       
    37 #include "verror.h"
       
    38 #include <vobserv.h>
       
    39 #include <vcal.h>
       
    40 #include "VersitAdditionalStorage.h"
       
    41 
       
    42 // Constants
       
    43 _LIT8(KReplacementChars, "?");
       
    44 const TInt KVersitDatePropertySymbianConnectMessageMaximumLenght=1;
       
    45 
       
    46 #define UNUSED_VAR(a) a = a
       
    47 
       
    48 //
       
    49 // CLineReader
       
    50 //
       
    51 
       
    52 EXPORT_C CLineReader* CLineReader::NewL(RReadStream& aStream)
       
    53 /** Constructs and returns a CLineReader.
       
    54 
       
    55 @param aStream The stream to read the lines from. */
       
    56 	{
       
    57 	CLineReader* self=new(ELeave) CLineReader(aStream);
       
    58 	CleanupStack::PushL(self);
       
    59 	self->ConstructL();
       
    60 	CleanupStack::Pop(self);
       
    61 	return self;
       
    62 	}
       
    63 
       
    64 EXPORT_C void CLineReader::ConstructL()
       
    65 	{
       
    66 	iSkipWhiteSpaceAtStart=ETrue;
       
    67 	iLineBuf=HBufC8::NewL(EInitialLineSize);
       
    68 	iBufPtr=iLineBuf->Des();
       
    69 #if defined(__VC32__)
       
    70 	iBufPtr.Set(iLineBuf->Des());    // workaround for VC6 bug
       
    71 #endif
       
    72 	iExtension=CLineReaderExtension::NewL();
       
    73 	}
       
    74 
       
    75 EXPORT_C CLineReader::~CLineReader()
       
    76 /** Frees all resources owned by the line reader prior to its destruction. */
       
    77 	{
       
    78 	delete iLineBuf;
       
    79 	
       
    80 	if (iExtension && iReadStream)
       
    81 		{
       
    82 		if (iExtension->iSize - iExtension->iOffset > 0)
       
    83 			{
       
    84 			// there is data in the buffer that has not yet been parsed
       
    85 			// so we must adjust the seek pointer for the input stream to
       
    86 			// point exactly to the end of the data that has been parsed
       
    87 			// so that the rest will be re-read when the file is next accessed.
       
    88 			// The traps are neccesary because a destructor can't leave.
       
    89 			MStreamBuf* source = iReadStream->Source();
       
    90 			if (source != NULL)
       
    91 				{
       
    92 				TStreamPos pos(0);
       
    93 				TRAPD(err, pos = source->TellL(MStreamBuf::ERead));
       
    94 				if (err == KErrNone)
       
    95 					{
       
    96 					pos -= (iExtension->iSize - iExtension->iOffset);
       
    97 					TRAP(err, source->SeekL(MStreamBuf::ERead, pos));
       
    98 					}
       
    99 				}
       
   100 			}
       
   101 		}
       
   102 
       
   103 	delete iExtension;
       
   104 	}
       
   105 	
       
   106 /** Read base64 multiple lines
       
   107 
       
   108 This should be only called when parsing multi-line base64 data, and the interface 
       
   109 MVersitPlugInExtensionBase64Ending::BlankLineAndLeadingSpaceNotRequired returns ETrue 
       
   110 
       
   111 If the character ':' is not contained in the current line,we know it is base64 value.It is therefore appended to
       
   112 iBufPtr. Otherwise we know it is a new property which will be held in CLineReaderExtension::iLineBase64Value 
       
   113 temporarily until the next propery is to be parsed.
       
   114 
       
   115 @param aPosValueStart The position in the iLineBuffer where base64 value starts 
       
   116 */	
       
   117 void CLineReader::ReadBase64ValueL(TInt aPosValueStart)
       
   118 	{
       
   119 	HBufC8* base64Buffer = iExtension->CreateBase64ValueBufferL();//Creat a buffer to hold a
       
   120 	 
       
   121 	iBufPtr.Delete(0, aPosValueStart);//To make sure iBufPtr only contains base64 value	
       
   122 	TInt err = KErrNone;
       
   123 	TInt ret = ELineIsWhiteSpace;
       
   124 	TPtr8 ptr = base64Buffer->Des();
       
   125 	while (ret != ELineHasColon)
       
   126 		{
       
   127 		__ASSERT_DEBUG(ret==ELineHasContent ||ret==ELineIsWhiteSpace||ret==ELineIsCRLFOnly, Panic(ECurrentTokenNotFound));
       
   128 		if (ret == ELineHasContent)
       
   129 			{
       
   130 			iLineBuf = iLineBuf->ReAllocL(iLineBuf->Length() + ptr.Length());
       
   131 			iBufPtr.Set(iLineBuf->Des());	
       
   132 			iBufPtr.Append(ptr);
       
   133 			}
       
   134 		
       
   135 		ptr.SetLength(0);
       
   136 		ret = ReadLineL(base64Buffer, 0, err);
       
   137 		ptr.Set(base64Buffer->Des());
       
   138 		}
       
   139 	}
       
   140 	
       
   141 /** Reads in a line from the stream.
       
   142 
       
   143 The line is stored in a buffer pointed to by iBufPtr. Data from the stream 
       
   144 is appended to the buffer, starting at buffer position aPos, until the next 
       
   145 'CRLF' ("/r/n") is reached. The line feed and carriage return are not added 
       
   146 to the buffer. Using only linefeeds LF(\n) as the line delimiters is also supported.
       
   147 
       
   148 The buffer will be expanded if necessary to fit the line into it. 
       
   149 
       
   150 If the end of stream is reached, aErr will contain KErrEof upon return.
       
   151 
       
   152 It would be normal to set aPos to the start of the buffer unless reading a 
       
   153 multi-line value.
       
   154 
       
   155 @param aPos The position in the buffer pointed to by iBufPtr at which to begin 
       
   156 appending data to the buffer. Allows lines to be appended to the buffer when 
       
   157 reading multi-line values.
       
   158 @param aErr On return, this will be KErrEof if the end of the stream is reached 
       
   159 and KErrNone otherwise.
       
   160 @return ELineHasContent if the line has content; ELineIsWhiteSpace if the line 
       
   161 has only white space before the CRLF; ELineIsCRLFOnly if the line is only 
       
   162 a CRLF. 
       
   163 */
       
   164 EXPORT_C TInt CLineReader::ReadLineL(TInt aPos,TInt& aErr)
       
   165 	{
       
   166 	TInt ret = ELineHasContent;
       
   167 	HBufC8* base64Buffer = iExtension->Base64ValueBuffer();
       
   168 	if(aPos==0 && base64Buffer && base64Buffer->Length()>0)
       
   169 		{//If the base64Buffer is not empty, we know the current line has
       
   170 		// already been read and the data is held in CLineReaderExtension::iLineBase64Value
       
   171 		// for a new property (see ReadBase64ValueL)
       
   172 		if(iBufPtr.MaxLength() < base64Buffer->Length())
       
   173 			{
       
   174 			iLineBuf = iLineBuf->ReAllocL(base64Buffer->Length());
       
   175 			}
       
   176 		
       
   177 		*iLineBuf = *base64Buffer;
       
   178 		iBufPtr.Set(iLineBuf->Des());
       
   179 		iBufPtr.SetLength(base64Buffer->Length());
       
   180 		iExtension->DeleteBase64ValueBuffer();
       
   181 		}
       
   182 	else //Otherwise read the current line
       
   183 		{
       
   184 		ret = ReadLineL(iLineBuf, aPos, aErr);
       
   185 		if(ret == ELineHasColon)
       
   186 			{
       
   187 			ret = ELineHasContent;//For the sake of backwards compatability - ELineHasColon is only used by ReadBase64ValueL. 
       
   188 			}
       
   189 		iBufPtr.Set(iLineBuf->Des());
       
   190 		}
       
   191 		
       
   192 	return ret;
       
   193 	}
       
   194 
       
   195 TInt CLineReader::ReadLineL(HBufC8*& aHBuf, TInt aPos,TInt& aErr)
       
   196 /** Reads in a line from the stream.
       
   197 
       
   198 The line is stored in a buffer pointed to by aHBuf. Data from the stream 
       
   199 is appended to the buffer, starting at buffer position aPos, until the next 
       
   200 'CRLF' ("/r/n") is reached. The line feed and carriage return are not added 
       
   201 to the buffer. Using only linefeeds LF(\n) as the line delimiters is also supported.
       
   202 
       
   203 The buffer will be expanded if necessary to fit the line into it. 
       
   204 
       
   205 If the end of stream is reached, aErr will contain KErrEof upon return.
       
   206 
       
   207 It would be normal to set aPos to the start of the buffer unless reading a 
       
   208 multi-line value.
       
   209 
       
   210 @param aPos The position in the buffer pointed to by aHBuf at which to begin 
       
   211 appending data to the buffer. Allows lines to be appended to the buffer when 
       
   212 reading multi-line values.
       
   213 @param aErr On return, this will be KErrEof if the end of the stream is reached 
       
   214 and KErrNone otherwise.
       
   215 @return 
       
   216 ELineHasContent if the line has content;
       
   217 ELineIsWhiteSpace if the line has only white space before the CRLF;
       
   218 ELineIsCRLFOnly if the line is only a CRLF.
       
   219 EELineHasColon If character ':' contained in the line
       
   220 */
       
   221 	{
       
   222 	TInt crPos=-1;
       
   223 	TUint8 ch=STATIC_CAST(TUint8,iFirstCharNextLine);
       
   224 	TInt whiteSpaceLine=ELineIsCRLFOnly;
       
   225 	TBool truncateLine=ETrue;
       
   226 	TBool skipWhiteSpaceAtStart=iSkipWhiteSpaceAtStart;
       
   227 	TPtr8 ptrHbuf = aHBuf->Des();
       
   228 	ptrHbuf.SetLength(aPos);
       
   229 	if (iFirstCharNextLine>=0)
       
   230 		{
       
   231 		iFirstCharNextLine=-1;
       
   232 		goto CharacterRead;
       
   233 		}
       
   234 	FOREVER
       
   235 		{
       
   236 		ch=ReadChar(aErr);
       
   237 		if (aErr!=KErrEof)
       
   238 			User::LeaveIfError(aErr);
       
   239 		else
       
   240 			{
       
   241 			crPos=aPos-1;
       
   242 			while (crPos>=0 && (ptrHbuf[crPos]==CVersitParser::ELineFeed || ptrHbuf[crPos]==CVersitParser::ECarriageReturn))
       
   243 				{
       
   244 				--crPos;
       
   245 				}
       
   246 			truncateLine=(++crPos<aPos);
       
   247 			break;
       
   248 			}
       
   249 	CharacterRead:
       
   250 		if (ch==CVersitParser::ECarriageReturn)
       
   251 			{
       
   252 			if (crPos<0)
       
   253 				crPos=aPos;
       
   254 			skipWhiteSpaceAtStart=EFalse;
       
   255 			// next character should be a LF...
       
   256 			}
       
   257 		else if (ch==CVersitParser::ELineFeed)
       
   258 			{
       
   259 			if (crPos<0)
       
   260 				{
       
   261 				// LF without CR
       
   262 				crPos=aPos;
       
   263 				skipWhiteSpaceAtStart=EFalse;
       
   264 				}		
       
   265 			break; // The end of a line.
       
   266 			}
       
   267 		else 
       
   268 			{
       
   269 			crPos=-1;
       
   270 			if (whiteSpaceLine == ELineIsWhiteSpace || whiteSpaceLine == ELineIsCRLFOnly )
       
   271 				{
       
   272 				whiteSpaceLine=(VersitUtils::IsWhiteSpace(ch) ? ELineIsWhiteSpace:ELineHasContent);
       
   273 				if (!whiteSpaceLine)
       
   274 					skipWhiteSpaceAtStart=EFalse;
       
   275 				}
       
   276 				
       
   277 			if (ch == CVersitParser::EColon)
       
   278 				{
       
   279 				whiteSpaceLine = ELineHasColon;
       
   280 				}
       
   281 			}
       
   282 		if (skipWhiteSpaceAtStart)
       
   283 			{
       
   284 			if (iPlugIn)
       
   285 				skipWhiteSpaceAtStart=iPlugIn->DeleteAllSpaces();
       
   286 			}
       
   287 		else
       
   288 			{
       
   289 			if (aPos==ptrHbuf.MaxLength())
       
   290 				{
       
   291 				aHBuf=aHBuf->ReAllocL(aPos+EExpandSize);
       
   292 				ptrHbuf.Set(aHBuf->Des());
       
   293 				}
       
   294 
       
   295 			++aPos;
       
   296 			ptrHbuf.Append(ch);
       
   297 			}
       
   298 		}
       
   299 	if (truncateLine)
       
   300 		ptrHbuf.SetLength(crPos);
       
   301 	return whiteSpaceLine;
       
   302 	}
       
   303 
       
   304 EXPORT_C TBool CLineReader::AppendLineIfSpaceNextL()
       
   305 /** Checks the first character of the next line and, if it is a white space, reads 
       
   306 the next line into the buffer (pointed to by iBufPtr).
       
   307 
       
   308 The line is appended to the buffer rather than overwriting data already in 
       
   309 the buffer.
       
   310 
       
   311 A plug-in option can determine that no space is to be written to the buffer 
       
   312 between the lines. By default, a space will be written.
       
   313 
       
   314 Used by the Versit parser while it is reading multi-line property values.
       
   315 
       
   316 @return ETrue if a line was read (because the first character of the next 
       
   317 line is a space); EFalse if a line wasn't read (because the first character 
       
   318 of the next line isn't a space or an error occured). */
       
   319 	{
       
   320 	TInt err=KErrNone;
       
   321 	if (iFirstCharNextLine<0)
       
   322 		iFirstCharNextLine=ReadChar(err);
       
   323 	if (err!=KErrNone || !VersitUtils::IsWhiteSpace(iFirstCharNextLine))
       
   324 		return EFalse;
       
   325 	TInt len;
       
   326 	if (iPlugIn && !iPlugIn->AddSpace())
       
   327 		len=iBufPtr.Length();
       
   328 	else
       
   329 		len=AppendSpaceL();
       
   330 	ReadLineL(len,err);
       
   331 	return ETrue;
       
   332 	}
       
   333 
       
   334 EXPORT_C TBool CLineReader::IsSpaceNextL()
       
   335 /** Checks to see if the first character of the next line is white space.
       
   336 
       
   337 This function should not be called more than once without a line being read 
       
   338 in.
       
   339 
       
   340 Used by the Versit parser while it is reading multi-line property values.
       
   341 
       
   342 @return ETrue if the next line starts with a white space character; EFalse 
       
   343 if it doesn't or an error occurs. */
       
   344 	{
       
   345 	TInt err;
       
   346 	iFirstCharNextLine=ReadChar(err);
       
   347 	return (err==KErrNone && VersitUtils::IsWhiteSpace(iFirstCharNextLine));
       
   348 	}
       
   349 
       
   350 EXPORT_C TInt CLineReader::AppendSpaceL()
       
   351 /** Appends a space to the end of the buffer (pointed to by iBufPtr).
       
   352 
       
   353 The buffer will be expanded if necessary.
       
   354 
       
   355 This is called by AppendLineIfSpaceNextL() to create a space in the buffer 
       
   356 between the lines being read (as long as there is no plug-in option to to 
       
   357 indicate there should be no space).
       
   358 
       
   359 @param The length of the buffer after the space has been added. */
       
   360 	{
       
   361 	TInt len=iBufPtr.Length();
       
   362 	if (len==iBufPtr.MaxLength())
       
   363 		ExpandBufferL(len);
       
   364 	iBufPtr.Append(CVersitParser::ESpace);
       
   365 	return len+1;
       
   366 	}
       
   367 
       
   368 EXPORT_C void CLineReader::ExpandBufferL(TInt aCurrentSize)
       
   369 	{
       
   370 	iLineBuf=iLineBuf->ReAllocL(aCurrentSize+EExpandSize);
       
   371 	iBufPtr.Set(iLineBuf->Des());
       
   372 	}
       
   373 
       
   374 EXPORT_C TUint8 CLineReader::ReadChar(TInt& aErr)
       
   375 	{
       
   376 	// Return the next character from the read buffer. If it is the
       
   377 	// end of the buffer or it is empty then refill the buffer.
       
   378 	aErr = KErrNone;
       
   379 	if (iExtension->iOffset >= iExtension->iSize)
       
   380 		{
       
   381 		iExtension->iOffset = 0;
       
   382 		MStreamBuf* source = iReadStream->Source();
       
   383 		TRAP(aErr, iExtension->iSize = source->ReadL(iExtension->iBuf, 1024));
       
   384 		if (aErr != KErrNone)
       
   385 			{
       
   386 			return 0;
       
   387 			}
       
   388 		if (iExtension->iSize == 0)
       
   389 			{
       
   390 			aErr = KErrEof;
       
   391 			return 0;
       
   392 			}
       
   393 		}
       
   394 	return iExtension->iBuf[iExtension->iOffset++];
       
   395 	}
       
   396 
       
   397 EXPORT_C void CLineReader::Reserved()
       
   398 	{}
       
   399 
       
   400 
       
   401 //
       
   402 // CVersitParser
       
   403 //
       
   404 
       
   405 EXPORT_C CVersitParser::CVersitParser(TUint aFlags) : iFlags(aFlags)
       
   406 /** The first phase constructor for a Versit parser. 
       
   407 
       
   408 Sets the default encoding to Versit::ENoEncoding and the default character 
       
   409 set to Versit::EUSAsciiCharSet.
       
   410 
       
   411 Note: this function is called by the CParserVCal and CParserVCard constructors. It 
       
   412 should only be called directly by a user if creating a new parser
       
   413 
       
   414 @param aFlags The flag to indicate whether this entity needs a version property. 
       
   415 The possible values for this flag are given in the TVersitParserFlags enumeration. 
       
   416 If a version property is needed, one will be created and appended to the 
       
   417 start of the array of properties. */
       
   418 	{
       
   419 	SetDefaultEncoding(Versit::ENoEncoding);
       
   420 	SetDefaultCharSet(Versit::EUSAsciiCharSet);
       
   421 	
       
   422 	RestoreLineCodingDetailsToDefault();
       
   423 	}
       
   424 
       
   425 void CloseTlsData(TAny *aData)
       
   426 	{
       
   427 	CVersitTlsData *data = static_cast<CVersitTlsData *>(aData);
       
   428 	data->CloseVersitTlsData();
       
   429 	}
       
   430 
       
   431 EXPORT_C void CVersitParser::ConstructL()
       
   432 /** The second phase constructor for a Versit parser.
       
   433 
       
   434 Stores a pointer to a CVersitTlsData (thread local storage data class). This 
       
   435 is used to allow an instance of CVersitUnicodeUtils to be shared by all co-existing 
       
   436 parsers, which provides a major performance improvement.
       
   437 
       
   438 Called by the CParserVCal and CParserVCard constructors.
       
   439 
       
   440 Should only be called directly by a user if creating a new parser. */
       
   441 	{
       
   442 	_LIT8(KEscapeCharacter8, "\\");
       
   443 	iStaticUtils=&CVersitTlsData::VersitTlsDataL();
       
   444 	
       
   445 	//query charconv for the plugin dependant shift-jis escape character, 
       
   446 	//store in TLS to be accessed by versit static utils
       
   447 	CCnvCharacterSetConverter::TAvailability avail=UnicodeUtils().SetCurrentCharSetL(KCharacterSetIdentifierShiftJis);
       
   448 	if (avail == CCnvCharacterSetConverter::EAvailable)
       
   449 		{
       
   450 		// Do the conversion
       
   451 		CCnvCharacterSetConverter& converter=UnicodeUtils().CharacterSetConverter();
       
   452 		TInt ignore = 0;
       
   453 		converter.SetReplacementForUnconvertibleUnicodeCharactersL(KReplacementChars);
       
   454 
       
   455 		CVersitTlsData& data = CVersitTlsData::VersitTlsDataL();
       
   456 		CleanupStack::PushL( TCleanupItem( CloseTlsData, &data ) );
       
   457 
       
   458 		CVersitAdditionalStorage& additionalStorage = data.AdditionalStorage();
       
   459 		CBase* storedValue = additionalStorage.FromStorage(KTLSVars);
       
   460 
       
   461 		if( NULL == storedValue )
       
   462 			{
       
   463 			CVersitTLSContainer *tlsContainer = CVersitTLSContainer::NewLC(2);
       
   464 			TPtrC8 ptr8 = KEscapeCharacter8();
       
   465 			TPtr ptr16( tlsContainer->iShiftJisEscape->Des() );
       
   466 			converter.ConvertToUnicode(ptr16, ptr8, ignore);
       
   467 			additionalStorage.AddToStorageL(KTLSVars, tlsContainer);
       
   468 			CleanupStack::Pop( tlsContainer );
       
   469 			}
       
   470 
       
   471 		CleanupStack::PopAndDestroy();//data
       
   472 		}
       
   473 	}
       
   474 
       
   475 EXPORT_C CVersitParser::~CVersitParser()
       
   476 // Note: CVersitParser never owns iReadStream/iWriteStream
       
   477 /** Frees all resources owned by the object, prior to its destruction. */
       
   478 	{
       
   479 	if (iArrayOfEntities)
       
   480 		{
       
   481 		iArrayOfEntities->ResetAndDestroy();
       
   482 		delete iArrayOfEntities;
       
   483 		}
       
   484 	if (iArrayOfProperties)
       
   485 		{
       
   486 		iArrayOfProperties->ResetAndDestroy();
       
   487 		delete iArrayOfProperties;
       
   488 		}
       
   489 	delete iCurrentProperty;
       
   490 	delete iEntityName;
       
   491 	delete iOwnedLineReader;
       
   492 	delete iLargeDataBuf;
       
   493 	delete iDecodedValue;
       
   494 
       
   495 	// Close any TLS storage
       
   496 	if (iStaticUtils)
       
   497 		iStaticUtils->VersitTlsDataClose();
       
   498 	}
       
   499 
       
   500 EXPORT_C void CVersitParser::InternalizeL(RFile& aInputFile,TInt& aBytesThroughFile)
       
   501 /** Internalises a versit entity (vCard or vCalendar) and all of its
       
   502 sub-entities and properties from a file.
       
   503 
       
   504 Stores all date/time in same format as received
       
   505 
       
   506 @param aInputFile  The file from which to internalise the entity.
       
   507 @param aBytesThroughFile The number of bytes into the file at which to begin 
       
   508 reading. On return, is updated to contain the last position in the file which 
       
   509 was read.
       
   510 @leave KErrEof The file position specified is beyond the end of the file. */
       
   511 	{
       
   512 	TInt size;
       
   513 	if (aInputFile.Size(size)==KErrNone)
       
   514 		{
       
   515 		RFileReadStream stream(aInputFile,aBytesThroughFile);
       
   516 		TInt size=stream.Source()->SizeL();
       
   517 		TRAPD(err,InternalizeL(stream));
       
   518 		if (err==KErrNone)
       
   519 			TRAP(err,aBytesThroughFile+=(size-stream.Source()->SizeL()));
       
   520 		STATIC_CAST(RFileBuf*,stream.Source())->Reset();
       
   521 		stream.Close();
       
   522 		User::LeaveIfError(err);
       
   523 		}
       
   524 	}
       
   525 
       
   526 EXPORT_C void CVersitParser::InternalizeL(RReadStream& aStream)
       
   527 /** Internalises a Versit entity (vCard or vCalendar) contained in the incoming stream 
       
   528 and parses it, breaking it down into its constituent sub-entities (e.g. to-dos, 
       
   529 events, and nested vCards) and properties.
       
   530 
       
   531 The presence of this function means that the standard templated operator>>() 
       
   532 (defined in s32strm.h) is available to internalise objects of this class.
       
   533 
       
   534 This virtual function serves as a base function for derived classes to internalise an entity.
       
   535 
       
   536 @param aStream Stream from which the vCalendar should be internalised. */
       
   537 	{
       
   538 	iOwnedLineReader=CLineReader::NewL(aStream);
       
   539 	iOwnedLineReader->SetPlugIn(iPlugIn);
       
   540 	iLineReader=iOwnedLineReader;
       
   541 	
       
   542 	TRAPD(err,DoInternalizeL());
       
   543 
       
   544 	delete iDecodedValue;
       
   545 	iDecodedValue=NULL;
       
   546 	delete iOwnedLineReader;
       
   547 	iOwnedLineReader=NULL;
       
   548 	iLineReader=NULL;
       
   549 	
       
   550 	User::LeaveIfError(err);
       
   551 	}
       
   552 
       
   553 void CVersitParser::DoInternalizeL()
       
   554 	{
       
   555 	iParseBegin = TRUE;
       
   556 	ParseBeginL();
       
   557 	iParseBegin = FALSE;
       
   558 	
       
   559 	do
       
   560 		{
       
   561 		delete iCurrentProperty;
       
   562 		iCurrentProperty=NULL;
       
   563 		ParsePropertiesL();
       
   564 		} while(ParseEntityL());
       
   565 	ParseEndL();
       
   566 	}
       
   567 
       
   568 EXPORT_C void CVersitParser::InternalizeL(HBufC* aEntityName,CLineReader* aLineReader)
       
   569 /** Internalises a vCalendar or vCard sub-entity.
       
   570 
       
   571 (Assumes "BEGIN : <EntityName> CRLF" has been parsed).
       
   572 
       
   573 This virtual function serves as a base function for derived classes to parse a 
       
   574 sub-entity.
       
   575 
       
   576 @param aEntityName The entity name to be parsed. Ownership of aEntityName is taken by 
       
   577 the parser.
       
   578 @param aLineReader Pointer to a line reader which is used by the super-entity. */
       
   579 	{
       
   580 	iLineReader=aLineReader;
       
   581 
       
   582 	ParsePropertiesL();
       
   583 	ParseEndL(*aEntityName);
       
   584 	
       
   585 	delete iEntityName;
       
   586 	iEntityName = aEntityName;
       
   587 
       
   588 	iLineReader=NULL;
       
   589 	delete iDecodedValue;
       
   590 	iDecodedValue=NULL;
       
   591 	}
       
   592 
       
   593 EXPORT_C void CVersitParser::ExternalizeL(RFile& aOutputFile)
       
   594 /** Externalises a Versit entity (vCard or vCalendar) and all of its sub-entities 
       
   595 and properties to a file. 
       
   596 
       
   597 Adds a version property to the start of the current entity's array of properties 
       
   598 if the entity supports this.
       
   599 
       
   600 This is a thin layer over the CVersitParser::ExternalizeL(RWriteStream& aStream) 
       
   601 function to enable a versit entity to be externalised into an RFile.
       
   602 
       
   603 @param aOutputFile The file to which to write the entity. */
       
   604 	{
       
   605 	RFileWriteStream stream(aOutputFile);
       
   606 	CleanupClosePushL(stream);
       
   607 	ExternalizeL(stream);
       
   608 	CleanupStack::PopAndDestroy(&stream);
       
   609 	}
       
   610 
       
   611 EXPORT_C void CVersitParser::ExternalizeL(RWriteStream& aStream)
       
   612 /** Externalises a Versit entity (vCard or vCalendar) and all of its sub-entities 
       
   613 and properties to a write stream. 
       
   614 
       
   615 Adds a version property to the start of the current entity's array of properties 
       
   616 if the entity supports this. (If there isn't an array of properties then one is made).
       
   617 
       
   618 The presence of this function means that the standard templated operator<<() (defined 
       
   619 in s32strm.h) is available to externalise objects of this class.
       
   620 
       
   621 This virtual function serves as a base function for derived classes to externalise 
       
   622 an entity.
       
   623 
       
   624 @param aStream Stream to which the entity should be externalised. */
       
   625 	{
       
   626 	iWriteStream=&aStream;
       
   627 
       
   628 	if (SupportsVersion())
       
   629 		{
       
   630 		if (!iArrayOfProperties)
       
   631 			iArrayOfProperties = new(ELeave)CArrayPtrFlat<CParserProperty>(5);
       
   632 		TUid uid = TUid::Uid(KVersitPropertyHBufCUid);
       
   633 		
       
   634 		// get properties but don't take ownership of the elements of the array
       
   635 		CArrayPtr<CParserProperty>* properties = PropertyL(KVersitTokenVERSION, uid, EFalse);
       
   636 		if (properties)
       
   637 			delete properties;
       
   638 		else	//Need to add a version property
       
   639 			{
       
   640 			CParserPropertyValue* value = CParserPropertyValueHBufC::NewL(iDefaultVersion);
       
   641 			value->SetPlugIn(iPlugIn);
       
   642 			CleanupStack::PushL(value);
       
   643 			CParserProperty* property = CParserProperty::NewL(*value, KVersitTokenVERSION, NULL);
       
   644 			CleanupStack::Pop(value);
       
   645 			CleanupStack::PushL(property);
       
   646 			iArrayOfProperties->InsertL(0,property);
       
   647 			CleanupStack::Pop(property);
       
   648 			}
       
   649 		}
       
   650 	AppendBeginL();
       
   651 	if (iArrayOfProperties)
       
   652 		{
       
   653 		TInt noOfProperties=iArrayOfProperties->Count();
       
   654 		for (TInt ii=0; ii<noOfProperties; ii++)
       
   655 			{
       
   656 			(*iArrayOfProperties)[ii]->ExternalizeL(aStream, this);
       
   657 			}
       
   658 		}
       
   659 	if (iArrayOfEntities)
       
   660 		{
       
   661 		const TInt noOfEntities = iArrayOfEntities->Count();
       
   662 		for (TInt ii=0; ii<noOfEntities; ii++)
       
   663 			{
       
   664 			// Ensure that the entities defaults match this parser's
       
   665 			CVersitParser& entity = *iArrayOfEntities->At(ii);
       
   666 			//
       
   667 			entity.SetDefaultCharSet(DefaultCharSet());
       
   668 			entity.SetDefaultEncoding(DefaultEncoding());
       
   669 			//
       
   670 			entity.ExternalizeL(aStream);
       
   671 			}
       
   672 		}
       
   673 	AppendEndL();
       
   674 	iWriteStream = NULL;
       
   675 	}
       
   676 
       
   677 /*void CVersitParser::AddTimeZonePropertyL()		//Function that may be useful one day
       
   678 	{
       
   679 	TLocale locale;
       
   680 	TTimeIntervalSeconds offSet(locale.UniversalTimeOffset());
       
   681 	CParserPropertyValue* timeZone=new(ELeave)CParserPropertyValueTimeZone(offSet);
       
   682 	CleanupStack::PushL(timeZone);
       
   683 	CParserProperty* property = CParserProperty::NewL(*timeZone,KVersitTokenTZ,NULL);
       
   684 	CleanupStack::Pop(timeZone);
       
   685 	CleanupStack::PushL(property);
       
   686 	iArrayOfProperties->InsertL(0,property);
       
   687 	CleanupStack::Pop(property);
       
   688 	}*/
       
   689 
       
   690 EXPORT_C void CVersitParser::AddPropertyL(CParserProperty* aProperty,TBool aInternalizing)
       
   691 /** Appends a property to the current entity's array of properties. 
       
   692 
       
   693 This function may be used when building up a Versit parser object from 
       
   694 a client application. It is not called internally.
       
   695 
       
   696 @param aProperty Pointer to the property to add to the entity. 
       
   697 @param aInternalizing This parameter is used to distinguish between reading 
       
   698 an entity from a stream or file (i.e. internalising), in which case the argument 
       
   699 should have a value of ETrue, and building an entity "by hand" (e.g. creating 
       
   700 a vCard in the Contacts application), in which case the argument should have 
       
   701 a value of EFalse. */
       
   702 	{
       
   703 	if	(!aProperty)
       
   704 		return;
       
   705 
       
   706 	TUid tokenId=RecognizeToken(aProperty->Name());
       
   707 	CleanupStack::PushL(aProperty);
       
   708 	
       
   709 	if ((tokenId.iUid==KVersitTokenUnknownUid) && aProperty->Name().CompareF(KVersitTokenATTACH)==0)
       
   710 		{
       
   711 		tokenId.iUid = KVersitPropertyBinaryUid;//In vCal standard, default value is binary
       
   712 		CParserParam* valueParam = aProperty->Param(KVersitTokenVALUE);
       
   713 		if (valueParam)
       
   714 			{
       
   715 			TPtrC8 pParameterValue(valueParam->Value());
       
   716 			
       
   717 			if (pParameterValue.CompareF(KVersitTokenINLINE) && pParameterValue.CompareF(KVersitTokenBINARY))
       
   718 				{//If VALUE isn't specified as INLINE or BINARY, value is text type.
       
   719 				tokenId.iUid = KVersitPropertyHBufCUid;			
       
   720 				}
       
   721 			}
       
   722 		}
       
   723  	
       
   724  	aProperty->SetNameUid(tokenId);
       
   725 
       
   726 	if ((tokenId.iUid==KVersitTokenUnknownUid) && !aInternalizing)
       
   727 		{
       
   728 		//Do not prefix X-EPOC incase the property already has a prefix X- at the begining		
       
   729 		if(aProperty->NameBuf()->Find(KVersitTokenXDash)!=0)
       
   730 			{	
       
   731 			HBufC8*& name=aProperty->NameBuf();
       
   732 			HBufC8* newName=HBufC8::NewL(name->Length()+KVersitTokenXDashEPOC.iTypeLength);
       
   733 			TPtr8 ptr=newName->Des();
       
   734 			ptr=KVersitTokenXDashEPOC;
       
   735 			ptr+=*name;
       
   736 			delete name;
       
   737 			name=newName;
       
   738 			}
       
   739 		}
       
   740 
       
   741 	DoAddPropertyL(aProperty);
       
   742 	CleanupStack::Pop(aProperty);
       
   743 	}
       
   744 
       
   745 EXPORT_C void CVersitParser::DoAddPropertyL(CParserProperty* aProperty)
       
   746 	{
       
   747 	if	(!aProperty)
       
   748 		return;
       
   749 
       
   750 	if (!iArrayOfProperties)
       
   751 		iArrayOfProperties = new(ELeave)CArrayPtrFlat<CParserProperty>(5);
       
   752 
       
   753 	if (aProperty->Value())
       
   754 		aProperty->Value()->SetPlugIn(iPlugIn);
       
   755 	iArrayOfProperties->AppendL(aProperty);
       
   756 	}
       
   757 
       
   758 
       
   759 EXPORT_C void CVersitParser::AddEntityL(CVersitParser* aEntity)
       
   760 /** Adds a sub-entity (e.g. a to-do, event or a nested vCard) to the current entity.
       
   761 
       
   762 Sets the default encoding and character set to the default ones of the current 
       
   763 Versit parser, then adds the entity to the array of entities owned by the 
       
   764 parser.
       
   765 
       
   766 Note: This function may be used when building up a Versit parser object from 
       
   767 a client application.
       
   768 
       
   769 Called by ParseEntityL().
       
   770 
       
   771 @param aEntity The entity to be added into the array of entities. Ownership 
       
   772 of aEntity is taken at beginning of the function. */
       
   773 	{
       
   774 	CleanupStack::PushL(aEntity);
       
   775 
       
   776 	if	(!iArrayOfEntities)
       
   777 		iArrayOfEntities = new(ELeave)CArrayPtrFlat<CVersitParser>(5);
       
   778 
       
   779 	if	(aEntity)
       
   780 		{
       
   781 		// Ensure that the entity contains the same defaults as this parser
       
   782 		aEntity->SetDefaultCharSet(DefaultCharSet());
       
   783 		aEntity->SetDefaultEncoding(DefaultEncoding());
       
   784 		//
       
   785 		aEntity->SetLineCharacterSet(LineCharSet());
       
   786 		aEntity->SetLineEncoding(LineEncoding());
       
   787 		//
       
   788 		iArrayOfEntities->AppendL(aEntity);
       
   789 		}
       
   790 
       
   791 	CleanupStack::Pop(); //aEntity
       
   792 	}
       
   793 
       
   794 EXPORT_C CArrayPtr<CVersitParser>* CVersitParser::EntityL(const TDesC& aEntityName,TBool aTakeOwnership)
       
   795 /** Gets all sub-entities in the current entity, whose name matches the 
       
   796 name specified.
       
   797 
       
   798 @param aEntityName The sub-entity name of interest, e.g. KVersitVarTokenVEVENT or 
       
   799 KVersitVarTokenVTODO. All sub-entities which match this name are returned in the 
       
   800 array of pointers.
       
   801 @param aTakeOwnership If ETrue, the calling code takes ownership of each matching 
       
   802 sub-entity, in which case the sub-entities are deleted from the current object's 
       
   803 array of entities. If EFalse, ownership remains with the Versit parser.
       
   804 @return An array of pointers to all sub-entities with the specified name. 
       
   805 (Ownership is taken by the calling code). */
       
   806 	{
       
   807 	CArrayPtr<CVersitParser>* arrayOfNamedEntities = NULL;
       
   808 	if (iArrayOfEntities)
       
   809 		{
       
   810 		TInt entities=iArrayOfEntities->Count();
       
   811 		arrayOfNamedEntities=new(ELeave) CArrayPtrFlat<CVersitParser>(5);
       
   812 		//CleanupStack::PushL(TCleanupItem(ResetAndDestroyArrayOfEntities,arrayOfNamedEntities));
       
   813 		CleanupStack::PushL(arrayOfNamedEntities);
       
   814 		for (TInt ii=0; ii<entities; ii++)
       
   815 			{
       
   816 			if ((*iArrayOfEntities)[ii]->EntityName()==aEntityName)
       
   817 				{
       
   818 				arrayOfNamedEntities->AppendL((*iArrayOfEntities)[ii]);
       
   819 				}
       
   820 			}
       
   821 		CleanupStack::Pop(); //arrayOfNamedEntities
       
   822 		if (arrayOfNamedEntities->Count() == 0)
       
   823 			{
       
   824 			delete arrayOfNamedEntities;
       
   825 			arrayOfNamedEntities = NULL;
       
   826 			}
       
   827 		else if(aTakeOwnership)	
       
   828 			{
       
   829 			for (TInt ii = entities-1; ii>=0; --ii)
       
   830 				{
       
   831 				if ((*iArrayOfEntities)[ii]->EntityName()==aEntityName)
       
   832 					{
       
   833 					iArrayOfEntities->Delete(ii);
       
   834 					} // if
       
   835 				} // for
       
   836 			} // else if
       
   837 		}
       
   838 	return arrayOfNamedEntities;
       
   839 	}
       
   840 
       
   841 EXPORT_C CArrayPtr<CVersitParser>* CVersitParser::ArrayOfEntities(TBool aTakeOwnership)
       
   842 /** Gets the current entity's array of sub-entities. 
       
   843 
       
   844 Note: the current entity may be a top level entity, or may itself be a sub-entity.
       
   845 
       
   846 @param aTakeOwnership If ETrue, the calling code takes ownership of the array; 
       
   847 the array of entities owned by the current entity is then deleted. If EFalse, 
       
   848 ownership remains with the Versit parser. 
       
   849 @return Array of pointers to the current entity's array of sub-entities. */
       
   850 	{
       
   851 	CArrayPtr<CVersitParser>* arrayOfEntities=iArrayOfEntities;
       
   852 	if (aTakeOwnership)
       
   853 		iArrayOfEntities=NULL;
       
   854 	return arrayOfEntities;
       
   855 	}
       
   856 
       
   857 EXPORT_C CArrayPtr<CParserProperty>* CVersitParser::PropertyL(const TDesC8& aPropertyName,const TUid& aPropertyUid,TBool aTakeOwnership) const
       
   858 /** Gets all properties in the current entity's array of properties whose name and 
       
   859 value match the name and value specified.
       
   860 
       
   861 @param aPropertyName The property name of interest. Property names are defined 
       
   862 in vtoken.h. 
       
   863 @param aPropertyUid The ID of the property value of interest (which has the 
       
   864 format "K<Versit/Card/Cal>Property<Type>Uid"). The values are defined in file vuid.h.
       
   865 @param aTakeOwnership If ETrue, the calling code takes ownership of each matching 
       
   866 property; the property is then deleted from the current entity's array. If 
       
   867 EFalse, ownership remains with the entity. 
       
   868 @return An array of pointers to all properties with the name and value specified, 
       
   869 or NULL if there are none. */
       
   870 	{
       
   871 	CArrayPtr<CParserProperty>* arrayOfNamedProperties = NULL;
       
   872 	if (iArrayOfProperties)
       
   873 		{
       
   874 		const TInt properties = iArrayOfProperties->Count();
       
   875 		arrayOfNamedProperties = new(ELeave) CArrayPtrFlat<CParserProperty>(5);
       
   876 		//CleanupStack::PushL(TCleanupItem(ResetAndDestroyArrayOfProperties, arrayOfNamedProperties));
       
   877 		CleanupStack::PushL(arrayOfNamedProperties);
       
   878 		CParserProperty* parserProperty = NULL;
       
   879 		for (TInt ii = 0; ii < properties; ++ii)
       
   880 			{
       
   881 			parserProperty = (*iArrayOfProperties)[ii];
       
   882 			if (parserProperty->Value() && parserProperty->Name().CompareF(aPropertyName)==0)
       
   883 				{
       
   884 				if(parserProperty->Value()->Uid()==aPropertyUid || aPropertyUid == KNullUid)
       
   885 					{
       
   886 					arrayOfNamedProperties->AppendL(parserProperty);
       
   887 					}
       
   888 				}
       
   889 			}
       
   890 		CleanupStack::Pop(arrayOfNamedProperties);
       
   891 		if (arrayOfNamedProperties->Count() == 0)
       
   892 			{
       
   893 			delete arrayOfNamedProperties;
       
   894 			arrayOfNamedProperties = NULL;
       
   895 			}
       
   896 		else if (aTakeOwnership)
       
   897 			{
       
   898 			for (TInt ii = properties-1; ii>=0; --ii)
       
   899 				{
       
   900 				parserProperty = (*iArrayOfProperties)[ii];
       
   901 				if (parserProperty->Name().CompareF(aPropertyName)==0)
       
   902 					{
       
   903 					if (parserProperty->Value()->Uid()==aPropertyUid || aPropertyUid == KNullUid)
       
   904 						{
       
   905 						iArrayOfProperties->Delete(ii);
       
   906 						}
       
   907 					}
       
   908 				}
       
   909 			}
       
   910 		}
       
   911 	return arrayOfNamedProperties;
       
   912 	}
       
   913 
       
   914 EXPORT_C CArrayPtr<CParserProperty>* CVersitParser::ArrayOfProperties(TBool aTakeOwnership)
       
   915 /** Gets the current entity's array of properties.
       
   916 
       
   917 @param aTakeOwnership If ETrue, the calling code takes ownership of the array; 
       
   918 the entity's array of properties is then deleted . If EFalse, ownership 
       
   919 remains with the entity. 
       
   920 @return Array of pointers to the entity's properties. */
       
   921 	{
       
   922 	CArrayPtr<CParserProperty>* arrayOfProperties=iArrayOfProperties;
       
   923 	if (aTakeOwnership)
       
   924 		iArrayOfProperties=NULL;
       
   925 	return arrayOfProperties;
       
   926 	}
       
   927 
       
   928 EXPORT_C void CVersitParser::SetEntityNameL(const TDesC& aEntityName)
       
   929 /** Sets the name for the current entity to one of: VCARD, VCALENDAR, VEVENT or 
       
   930 VTODO.
       
   931 
       
   932 @param aEntityName The new name for the current parser entity. Any existing 
       
   933 name is first deleted. 
       
   934 @leave KErrNoMemory Memory is allocated for the new entity name on the heap, 
       
   935 so it can leave if there is insufficient memory available. */
       
   936 	{
       
   937 	delete iEntityName;
       
   938 	iEntityName = NULL;
       
   939 	iEntityName = aEntityName.AllocL();
       
   940 	}
       
   941 
       
   942 EXPORT_C TPtrC CVersitParser::EntityName() const
       
   943 /** Gets the current entity's name. 
       
   944 
       
   945 If no name has been set, returns an empty descriptor.
       
   946 
       
   947 @return The current entity's name. */
       
   948 	{
       
   949 	if (iEntityName)
       
   950 		return iEntityName->Des();
       
   951 	return KVersitTokenEmpty();
       
   952 	}
       
   953 
       
   954 EXPORT_C TBool CVersitParser::IsValidLabel(const TDesC& aLabel, TInt& aPos)
       
   955 /** Tests whether a property name is valid.
       
   956 
       
   957 The property name is invalid if it contains any of the following characters:-
       
   958 
       
   959 [] (left or right square bracket)
       
   960 
       
   961 = (equals sign)
       
   962 
       
   963 : (colon)
       
   964 
       
   965 . (dot)
       
   966 
       
   967 , (comma)
       
   968 
       
   969 @param aLabel The property name to test. 
       
   970 @param aPos On return, contains the character position within the property 
       
   971 name of the first invalid character found. 
       
   972 @return ETrue if valid, EFalse if invalid. */
       
   973 	{
       
   974 	return !(((aPos = aLabel.Locate(KVersitTokenLSquareBracketVal)) != KErrNotFound) ||
       
   975 		((aPos = aLabel.Locate(KVersitTokenRSquareBracketVal)) != KErrNotFound) ||
       
   976 		((aPos = aLabel.Locate(KVersitTokenEqualsVal)) != KErrNotFound) ||
       
   977 		((aPos = aLabel.Locate(KVersitTokenColonVal)) != KErrNotFound) ||
       
   978 		((aPos = aLabel.Locate(KVersitTokenPeriodVal)) != KErrNotFound) ||
       
   979 		((aPos = aLabel.Locate(KVersitTokenCommaVal)) != KErrNotFound));
       
   980 	}
       
   981 
       
   982 EXPORT_C CArrayPtr<CParserParam>* CVersitParser::ReadLineAndDecodeParamsLC(TInt& aValueStart,TInt& aNameLen)
       
   983 	{
       
   984 	//Read in line from stream skipping lines made up only of white space TChar
       
   985 	TInt err;
       
   986 	do
       
   987 		{
       
   988 		const TInt readLineResponse = iLineReader->ReadLineL(0,err);
       
   989 		if  (readLineResponse == CLineReader::ELineIsWhiteSpace || readLineResponse == CLineReader::ELineIsCRLFOnly)
       
   990 			{
       
   991 			aValueStart = 0;
       
   992 			}
       
   993 		else
       
   994 			{
       
   995 			TBool continueSearch;
       
   996 			do
       
   997 				{
       
   998 				continueSearch = EFalse;
       
   999 				aValueStart = BufPtr().Find(KVersitTokenColon) + 1;
       
  1000 				if (aValueStart == 0)	
       
  1001 					{
       
  1002 					continueSearch = iLineReader->AppendLineIfSpaceNextL();
       
  1003 					}
       
  1004 				}
       
  1005 			while (continueSearch && aValueStart == 0);
       
  1006 			}
       
  1007 		}
       
  1008 	while (aValueStart==0 && err!=KErrEof);
       
  1009 	//
       
  1010 	if (aValueStart==0)
       
  1011 		User::Leave(err);
       
  1012 	iFlags&=~ECharSetIdentified;
       
  1013 	
       
  1014 	if(iFlags & EUseDefaultCharSetForAllProperties)
       
  1015 		{
       
  1016 		SetLineCharacterSet(DefaultCharSet());
       
  1017 		iFlags|= ECharSetIdentified;
       
  1018 		}
       
  1019 		
       
  1020 	//Scan for semi-colon and split off params
       
  1021 	CArrayPtr<CParserParam>* arrayOfParams=NULL;
       
  1022 	aNameLen=BufPtr().Find(KVersitTokenSemiColon);		//First ";" can't be escaped
       
  1023 	TInt lenParams=aValueStart-aNameLen-2;
       
  1024 	if (aNameLen==KErrNotFound || lenParams<=0)
       
  1025 		{
       
  1026 		aNameLen=(lenParams==0&&aNameLen>=0 ? aNameLen:aValueStart-1);
       
  1027 		CleanupStack::PushL(TCleanupItem(ResetAndDestroyArrayOfParams,arrayOfParams));
       
  1028 		}
       
  1029 	else
       
  1030 		{
       
  1031 		TPtr8 params(&BufPtr()[aNameLen+1],lenParams,lenParams);
       
  1032 		arrayOfParams=GetPropertyParamsLC(params);
       
  1033 		AnalysesEncodingCharset(arrayOfParams);
       
  1034 		}
       
  1035 	return arrayOfParams;
       
  1036 	}
       
  1037 
       
  1038 EXPORT_C void CVersitParser::MakePropertyL(TPtr8& aPropName,TInt aValueStart)
       
  1039 	{
       
  1040 	VersitUtils::StripWhiteSpace(aPropName);
       
  1041 	TUid propertyUid=RecognizeToken(aPropName);
       
  1042 	iCurrentProperty->SetNameL(aPropName);
       
  1043 	//Deal with the value
       
  1044 	TInt lenValue=BufPtr().Length()-aValueStart;
       
  1045 	TPtr8 propValue(NULL,0);
       
  1046 	if (lenValue>0)
       
  1047 		propValue.Set(&BufPtr()[aValueStart],lenValue,lenValue);
       
  1048 	TBool beginOrEnd=VersitUtils::IsBeginOrEnd(propertyUid);
       
  1049 	TBool readMultiLine=!beginOrEnd;
       
  1050 	Versit::TVersitEncoding encoding=Versit::ENoEncoding;
       
  1051 	if (!readMultiLine)
       
  1052 		{
       
  1053 		encoding=LineEncoding();
       
  1054 		readMultiLine=(encoding==Versit::EBase64Encoding || encoding==Versit::EQuotedPrintableEncoding);
       
  1055 		}
       
  1056 	/**
       
  1057 		Ignore junk lines between vCal entities.
       
  1058 		Skip readMultiLine within ParseBegin.
       
  1059 	*/
       
  1060 	if (readMultiLine && !iParseBegin)
       
  1061 
       
  1062 		{
       
  1063 		CParserParam* valueParam = iCurrentProperty->Param(KVersitTokenVALUE);
       
  1064 		if (valueParam)
       
  1065 			{
       
  1066 			TPtrC8 pParameterValue(valueParam->Value());
       
  1067 			
       
  1068 			if (!pParameterValue.CompareF(KVersitTokenINLINE))
       
  1069 				{
       
  1070 				encoding = Versit::EBase64Encoding;				
       
  1071 				}
       
  1072 			}
       
  1073 
       
  1074 		TBool isBinary = ((propertyUid.iUid==KVersitPropertyBinaryUid) ||
       
  1075 						  ((propertyUid.iUid==KVCalPropertyExtendedAlarmUid) && (encoding==Versit::EBase64Encoding)));
       
  1076 		ReadMultiLineValueL(propValue, aValueStart, isBinary);
       
  1077 		}
       
  1078 	if (beginOrEnd)
       
  1079 		{
       
  1080 		VersitUtils::StripWhiteSpace(propValue);
       
  1081 		if (encoding!=Versit::EBase64Encoding)
       
  1082 			propValue.UpperCase();
       
  1083 		}
       
  1084 	iCurrentProperty->SetNameUid(propertyUid);
       
  1085 	
       
  1086 	HBufC* valueBuf=DecodePropertyValueL(propValue);
       
  1087 	CleanupStack::PushL(TCleanupItem(DestroyHBufC, &valueBuf));
       
  1088 	if (iPlugIn && (valueBuf != NULL))
       
  1089 		{
       
  1090 		TPtr ptr(valueBuf->Des());
       
  1091 	#if defined(__VC32__)    // workaround for VC6 bug
       
  1092 		ptr.Set(valueBuf->Des());
       
  1093 	#endif
       
  1094 		iPlugIn->RemoveEscaping(ptr);
       
  1095 		}
       
  1096 	CParserPropertyValue* value = MakePropertyValueL(propertyUid,valueBuf);
       
  1097 	delete iLargeDataBuf;
       
  1098 	iLargeDataBuf=NULL;
       
  1099 	iCurrentProperty->SetValue(value);
       
  1100 	CleanupStack::PopAndDestroy(&valueBuf);
       
  1101 
       
  1102 	}
       
  1103 
       
  1104 EXPORT_C void CVersitParser::ParsePropertyL()
       
  1105 	{
       
  1106 	TInt valueStart;
       
  1107 	TInt lenName;
       
  1108 	CArrayPtr<CParserParam>* arrayOfParams=ReadLineAndDecodeParamsLC(valueStart,lenName);
       
  1109 	delete iCurrentProperty;
       
  1110 	iCurrentProperty=NULL;
       
  1111 	iCurrentProperty=new(ELeave) CParserProperty(arrayOfParams);
       
  1112 	CleanupStack::Pop(arrayOfParams);
       
  1113 	if (lenName>0)
       
  1114 		{
       
  1115 		TPtr8 propName(&BufPtr()[0],lenName,lenName);
       
  1116 		MakePropertyL(propName,valueStart);
       
  1117 		}
       
  1118 	}
       
  1119 
       
  1120 EXPORT_C void CVersitParser::ReadMultiLineValueL(TPtr8& aValue,TInt aValueStart,TBool aBinaryData)
       
  1121 	{
       
  1122 	if (iLargeDataBuf)
       
  1123 		iLargeDataBuf->Reset();
       
  1124 	Versit::TVersitEncoding encoding=LineEncoding();
       
  1125 	TInt lineLen=BufPtr().Length();
       
  1126 	TInt err;
       
  1127 	TBool secondLine=ETrue;
       
  1128 	__ASSERT_DEBUG(encoding!=Versit::EEightBitEncoding, Panic(EVersitPanicUnexpectedEightBitEncoding));
       
  1129 	if (encoding!=Versit::EBase64Encoding)
       
  1130 		{
       
  1131 		if (encoding==Versit::EQuotedPrintableEncoding)
       
  1132 			{
       
  1133 			iLineReader->SetSkipWhiteSpaceAtStart(EFalse); // avoid space skiping for Quoted Printable encoding
       
  1134 			}
       
  1135 		TBool moreLinesToCome=ETrue;
       
  1136 		if (encoding!=Versit::EQuotedPrintableEncoding)
       
  1137 			moreLinesToCome=iLineReader->IsSpaceNextL();
       
  1138 		while (moreLinesToCome && (BufPtr()[lineLen-1]==KVersitTokenEqualsVal || encoding!=Versit::EQuotedPrintableEncoding))
       
  1139 			{
       
  1140 			if (secondLine)
       
  1141 				{
       
  1142 				lineLen-=aValueStart;
       
  1143 				BufPtr()=BufPtr().Mid(aValueStart,lineLen);
       
  1144 				secondLine=EFalse;
       
  1145 				}
       
  1146 			if (encoding==Versit::EQuotedPrintableEncoding)
       
  1147 				{
       
  1148 				--lineLen;
       
  1149 				moreLinesToCome=!iLineReader->ReadLineL(lineLen,err);
       
  1150 				}
       
  1151 			else if (lineLen==0)
       
  1152 				{
       
  1153 				iLineReader->ReadLineL(lineLen,err);
       
  1154 				moreLinesToCome=iLineReader->IsSpaceNextL();
       
  1155 				}
       
  1156 			else
       
  1157 				{
       
  1158 				moreLinesToCome=iLineReader->AppendLineIfSpaceNextL();
       
  1159 				}
       
  1160 			lineLen=BufPtr().Length();
       
  1161 			}
       
  1162 		iLineReader->SetSkipWhiteSpaceAtStart(ETrue); //The SetSkipWhiteSpaceAtStart function as been added for a defect fixing this line ensure that every other code calling ReadLineL behave the same than before. Stephane Lenclud.
       
  1163 		}
       
  1164 	else		// encoding == Versit::EBase64Encoding
       
  1165 		{
       
  1166 		if (aBinaryData)
       
  1167 			{
       
  1168 			if (!iLargeDataBuf)
       
  1169 				iLargeDataBuf=CBufSeg::NewL(128);
       
  1170 			}
       
  1171 		TInt bufLen=0;		//Initialise to stop warning "local variable may be used without having been initialized"
       
  1172 		TBool moreLinesToCome=ETrue;
       
  1173 
       
  1174 		if (iPlugIn)
       
  1175 			{
       
  1176 			TAny* extPlugIn  = NULL;
       
  1177 			iPlugIn->GetInterface(KUidVersitPluginExtensionBase64Termination, extPlugIn);
       
  1178 			if (extPlugIn && static_cast<MVersitPlugInExtensionBase64Ending*>(extPlugIn)->BlankLineAndLeadingSpaceNotRequired())
       
  1179 				{
       
  1180 				iLineReader->ReadBase64ValueL(aValueStart);
       
  1181 				if(aBinaryData)
       
  1182 					{
       
  1183 					iLargeDataBuf->InsertL(bufLen,BufPtr());
       
  1184 					}
       
  1185 				lineLen=BufPtr().Length();
       
  1186 				moreLinesToCome = EFalse;
       
  1187 				secondLine=EFalse;
       
  1188 				}
       
  1189 			}
       
  1190 
       
  1191 		while (moreLinesToCome)
       
  1192 			{
       
  1193 			if (secondLine)
       
  1194 				{
       
  1195 				lineLen-=aValueStart;
       
  1196 				TPtrC8 data=BufPtr().Mid(aValueStart,lineLen);
       
  1197 				if (aBinaryData)
       
  1198 					{
       
  1199 					iLargeDataBuf->InsertL(0,data);
       
  1200 					bufLen=lineLen;
       
  1201 					lineLen=0;
       
  1202 					}
       
  1203 				else
       
  1204 					BufPtr()=data;
       
  1205 				secondLine=EFalse;
       
  1206 				}
       
  1207 				
       
  1208 			if (iPlugIn && !iPlugIn->NeedsBlankLine())
       
  1209 				{
       
  1210 				moreLinesToCome=iLineReader->AppendLineIfSpaceNextL();
       
  1211 				}
       
  1212 			else
       
  1213 				{
       
  1214 				TPtrC8 lineData = BufPtr().Mid(0); //Grab a copy of last line, used to check if the end has been reached if only whitespace is present
       
  1215 				TInt lineEval = iLineReader->ReadLineL(lineLen,err);
       
  1216 				moreLinesToCome=(lineEval !=CLineReader::ELineIsCRLFOnly);
       
  1217 				if (lineEval == CLineReader::ELineIsWhiteSpace)
       
  1218 					{
       
  1219 					//White space lines are not really part of the spec, however can be present
       
  1220 					//through transmission errors. For the sake of robustness it is ignored, however if
       
  1221 					//it is present after the last line instead of CRLF then it is a problem. We can check 
       
  1222 					//for the other delimiter mentioned in the spec to see if the last line has been reached
       
  1223 					//by checking for the '=' character. This is not perfect as these are padding characters and
       
  1224 					//will not be present if the length of the data is a multiple of 3 but as the data is not
       
  1225 					//conformant with the spec then this is the best we can do to recover from the error 
       
  1226 					//which is present.
       
  1227 
       
  1228 					if ( lineData.LocateReverse('=') != KErrNotFound)
       
  1229 						{
       
  1230 						//Found an '=' so the end has been reached.
       
  1231 						moreLinesToCome = EFalse;
       
  1232 						}
       
  1233 					}
       
  1234 				}
       
  1235 			if (aBinaryData)
       
  1236 				{
       
  1237 				iLargeDataBuf->InsertL(bufLen,BufPtr());
       
  1238 				bufLen+=BufPtr().Length();
       
  1239 				}
       
  1240 			else
       
  1241 				lineLen=BufPtr().Length();
       
  1242 			}//while
       
  1243 		if (!aBinaryData && lineLen==0)
       
  1244 			{		//The bad ending, to the Base64 data, in other situations does not cause a crash
       
  1245 			BufPtr().Append(KVersitLineBreak);
       
  1246 			BufPtr().Append(KVersitTokenCRLF);
       
  1247 			lineLen=BufPtr().Length();
       
  1248 			}
       
  1249 		}//base64
       
  1250 	if (aBinaryData)
       
  1251 		{
       
  1252 		if (!iLargeDataBuf)
       
  1253 			iLargeDataBuf=CBufSeg::NewL(128);
       
  1254 		if (secondLine)
       
  1255 			iLargeDataBuf->InsertL(0,aValue);
       
  1256 		else if (encoding!=Versit::EBase64Encoding)
       
  1257 			iLargeDataBuf->InsertL(0,BufPtr());
       
  1258 		aValue.Set(NULL,0,0);
       
  1259 		}
       
  1260 	else
       
  1261 		{
       
  1262 		if (!secondLine && BufPtr().Length() > 0)
       
  1263 			aValue.Set(&BufPtr()[0],lineLen,lineLen);
       
  1264 		delete iLargeDataBuf;
       
  1265 		iLargeDataBuf=NULL;
       
  1266 		}
       
  1267 	}
       
  1268 
       
  1269 
       
  1270 
       
  1271 //
       
  1272 // Parsing
       
  1273 //
       
  1274 
       
  1275 
       
  1276 EXPORT_C void CVersitParser::ParseBeginL()
       
  1277 // Parse start of entity (and extract iEntityName)
       
  1278 	{
       
  1279 	ParsePropertyL();
       
  1280 	// Parse until token Begin or EOF is reached.	
       
  1281 	while (iCurrentProperty->NameUid().iUid!=KVersitTokenBeginUid)
       
  1282 		{
       
  1283 		delete iCurrentProperty;
       
  1284 		iCurrentProperty=NULL;
       
  1285 
       
  1286 		ParsePropertyL();
       
  1287 		}
       
  1288 
       
  1289 	delete iEntityName;
       
  1290 	iEntityName=NULL;
       
  1291 	iEntityName=STATIC_CAST(CParserPropertyValueHBufC*,iCurrentProperty->Value())->TakeValueOwnership();
       
  1292 	}
       
  1293 
       
  1294 EXPORT_C void CVersitParser::ParseEndL()
       
  1295 // Parse end of entity
       
  1296 	{
       
  1297 	ParseEndL(*iEntityName);
       
  1298 	}
       
  1299 	
       
  1300 void CVersitParser::ParseEndL(HBufC16& aEntityName)
       
  1301 // Parse end of entity
       
  1302 	{
       
  1303 	if (iCurrentProperty->NameUid().iUid!=KVersitTokenEndUid)
       
  1304 		{
       
  1305 		User::Leave(KErrNotFound);
       
  1306 		}
       
  1307 
       
  1308 	TBool result = (aEntityName==STATIC_CAST(CParserPropertyValueHBufC*,iCurrentProperty->Value())->Value());
       
  1309 	delete iCurrentProperty;
       
  1310 	iCurrentProperty=NULL;
       
  1311 	if	(!result)
       
  1312 		User::Leave(KErrNotFound);
       
  1313 	}
       
  1314 
       
  1315 EXPORT_C TBool CVersitParser::ParseEntityL()
       
  1316 //
       
  1317 //	Parse next entity in stream, and add to iArrayOfEntities
       
  1318 //
       
  1319 	{
       
  1320 	TBool entityWasFound = EFalse;
       
  1321 	TInt32 uid=0;
       
  1322 	if (iCurrentProperty)
       
  1323 		uid=iCurrentProperty->NameUid().iUid;
       
  1324 	if (uid==KVersitTokenBeginUid)
       
  1325 		{
       
  1326 		TInt uid = RecognizeEntityName();
       
  1327 		HBufC* entityName=STATIC_CAST(CParserPropertyValueHBufC*,iCurrentProperty->Value())->TakeValueOwnership();
       
  1328 		CleanupStack::PushL(entityName);
       
  1329 		CVersitParser* entity = MakeEntityL(uid,entityName);
       
  1330 		CleanupStack::Pop(entityName);
       
  1331 		AddEntityL(entity);
       
  1332 		
       
  1333 		entityWasFound = ETrue;
       
  1334 		}
       
  1335 
       
  1336 	// Returns whether or not an entity was found
       
  1337 	return entityWasFound;
       
  1338 	}
       
  1339 
       
  1340 EXPORT_C void CVersitParser::ParsePropertiesL()
       
  1341 //Parse all properties in stream
       
  1342 	{
       
  1343 #if defined(_DEBUG)
       
  1344 	TInt propCount = 0;
       
  1345 #endif
       
  1346 	FOREVER
       
  1347 		{
       
  1348 #if defined(_DEBUG)
       
  1349 		propCount++;
       
  1350 #endif
       
  1351 		// For every single property that is parsed, any decoding or character set conversion
       
  1352 		// will use the default character set and encoding type set during the call to this
       
  1353 		// class' constructor.
       
  1354 		// To ensure (after a property is read) that the default is restored, a call to this
       
  1355 		// method is made before each property is read.
       
  1356 		RestoreLineCodingDetailsToDefault();
       
  1357 		TRAPD(err, ParsePropertyL());
       
  1358 		if (VersitUtils::CheckAndIgnoreCustomErrorL(err))
       
  1359 			{
       
  1360 			delete iCurrentProperty;
       
  1361 			iCurrentProperty = NULL;
       
  1362 			}
       
  1363 		else
       
  1364 			{
       
  1365 			if (iCurrentProperty)
       
  1366 				{
       
  1367 				if (VersitUtils::IsBeginOrEnd(iCurrentProperty->NameUid()))
       
  1368 					return;
       
  1369 				DoAddPropertyL(iCurrentProperty);
       
  1370 				if (iObserver && iCurrentProperty->Name()==KVersitTokenVERSION)
       
  1371 					iObserver->VersionSet(this,STATIC_CAST(CParserPropertyValueHBufC*,iCurrentProperty->Value())->Value());
       
  1372 				iCurrentProperty=NULL;
       
  1373 				}
       
  1374 			else
       
  1375 				{
       
  1376 				User::Leave(KErrEof);
       
  1377 				}
       
  1378 			}
       
  1379 		}
       
  1380 	}
       
  1381 
       
  1382 
       
  1383 
       
  1384 EXPORT_C void CVersitParser::ConvertAllPropertyDateTimesToMachineLocalL(const TTimeIntervalSeconds& aIncrement,const CVersitDaylight* aDaylight)
       
  1385 /** Converts all date/time property values contained in the current entity's array 
       
  1386 of properties into machine local values.
       
  1387 
       
  1388 This conversion is needed because of differences in universal and local times 
       
  1389 due to time zones and daylight savings (seasonal time shifts).
       
  1390 
       
  1391 First, all of the date/times are converted to universal time, if they are 
       
  1392 not already:
       
  1393 
       
  1394 If daylight saving is in effect then the daylight savings rule (held in the 
       
  1395 aDaylight parameter) will be used to compensate for differences between universal 
       
  1396 and local times due to both time zones and the daylight saving. Otherwise, 
       
  1397 the aIncrement parameter is used to compensate for any difference due to time 
       
  1398 zones alone.
       
  1399 
       
  1400 Then, these universal time values are converted into machine local 
       
  1401 times by adding the universal time offset for the machine's locale.
       
  1402 
       
  1403 @param aIncrement A time interval in seconds which represents the negative 
       
  1404 of the time zone of the originating machine. For instance, if the time zone 
       
  1405 is +04:30, aIncrement should be set to -04:30.
       
  1406 @param aDaylight Pointer to the specification for daylight saving. If the date/time 
       
  1407 value is within the period for daylight saving, the value is modified by the 
       
  1408 daylight saving offset (which accounts for both the time zone and daylight 
       
  1409 saving rule).
       
  1410 @deprecated since 9.1
       
  1411  */
       
  1412 	{
       
  1413 	TUid uid;
       
  1414 	uid.iUid = KVersitTimePropertyUid;
       
  1415 	if (iArrayOfProperties)
       
  1416 		{
       
  1417 		CParserTimePropertyValue* timeValue;
       
  1418 		TInt properties = iArrayOfProperties->Count();
       
  1419 		for (TInt ii = 0; ii < properties; ii++)
       
  1420 			{
       
  1421 			CParserPropertyValue* value=(*iArrayOfProperties)[ii]->Value();
       
  1422 			if (value && value->SupportsInterface(uid))
       
  1423 				{
       
  1424 				timeValue = STATIC_CAST(CParserTimePropertyValue*, value);
       
  1425 				timeValue->ConvertAllDateTimesToUTCL(aIncrement, aDaylight);
       
  1426 				}
       
  1427 			}
       
  1428 		TLocale locale;
       
  1429 		TTimeIntervalSeconds localeIncrement(locale.UniversalTimeOffset());
       
  1430 		if ((iFlags&EImportSyncML) && aDaylight && localeIncrement.Int()==-aIncrement.Int())	//If Importing from a SyncML Server and working in same time zone which has a daylight rule
       
  1431 			ConvertAllUTCDateTimesToMachineLocalL(localeIncrement,aDaylight);
       
  1432 		else
       
  1433 			{
       
  1434 			AdjustAllPropertyDateTimesToMachineLocalL();
       
  1435 			}
       
  1436 		}
       
  1437 	}
       
  1438 
       
  1439 
       
  1440 /*
       
  1441  * Converts all date/time property values contained in the current
       
  1442  * array of properties into machine local values.
       
  1443  @deprecated since 9.1
       
  1444  */
       
  1445 EXPORT_C void CVersitParser::AdjustAllPropertyDateTimesToMachineLocalL()
       
  1446 	{
       
  1447 	if (iArrayOfProperties)
       
  1448 		{
       
  1449 		TUid uid;
       
  1450 		uid.iUid = KVersitTimePropertyUid;
       
  1451 		TInt properties = iArrayOfProperties->Count();
       
  1452 		CParserTimePropertyValue* timeValue;
       
  1453 		TLocale locale;
       
  1454 		TTimeIntervalSeconds localeIncrement(locale.UniversalTimeOffset());
       
  1455 		for (TInt jj = 0; jj < properties; jj++)
       
  1456 			{
       
  1457 			CParserPropertyValue* value=(*iArrayOfProperties)[jj]->Value();
       
  1458 			if (value && value->SupportsInterface(uid))
       
  1459 				{
       
  1460 				timeValue = STATIC_CAST(CParserTimePropertyValue*, value);
       
  1461 				timeValue->ConvertAllUTCDateTimesToMachineLocalL(localeIncrement);
       
  1462 				}
       
  1463 			}
       
  1464 		}
       
  1465 	}
       
  1466 
       
  1467 
       
  1468 void CVersitParser::ConvertAllUTCDateTimesToMachineLocalL(const TTimeIntervalSeconds& aIncrement,const CVersitDaylight* aDaylight)
       
  1469 	{
       
  1470 	CParserPropertyValue* value;
       
  1471 	CParserTimePropertyValue* timeValue;
       
  1472 	TInt properties=iArrayOfProperties->Count();
       
  1473 	TUid uid;
       
  1474 	uid.iUid = KVersitTimePropertyUid;
       
  1475 	for (TInt jj = 0; jj < properties; jj++)
       
  1476 		{
       
  1477 		value=(*iArrayOfProperties)[jj]->Value();
       
  1478 		if (value && value->SupportsInterface(uid))
       
  1479 			{
       
  1480 			timeValue = STATIC_CAST(CParserTimePropertyValue*, value);
       
  1481 			switch (timeValue->Uid().iUid)
       
  1482 				{
       
  1483 			case KVCalPropertyAlarmUid:
       
  1484 				{
       
  1485 				CVersitAlarm* alarm=STATIC_CAST(CParserPropertyValueAlarm*,timeValue)->Value();
       
  1486 				if (alarm && alarm->iRunTime)
       
  1487 					ConvertUTCDateTimeToMachineLocal(alarm->iRunTime,aIncrement,aDaylight);
       
  1488 				}
       
  1489 				break;
       
  1490 			case KVersitPropertyDateTimeUid:
       
  1491 				{
       
  1492 				TVersitDateTime* dateTime=STATIC_CAST(CParserPropertyValueDateTime*,timeValue)->Value();
       
  1493 				if (dateTime)
       
  1494 					ConvertUTCDateTimeToMachineLocal(dateTime,aIncrement,aDaylight);
       
  1495 				}
       
  1496 				break;
       
  1497 			case KVersitPropertyMultiDateTimeUid:
       
  1498 				{
       
  1499 				CArrayPtr<TVersitDateTime>* values=STATIC_CAST(CParserPropertyValueMultiDateTime*,timeValue)->Value();
       
  1500 				if (values)
       
  1501 					{
       
  1502 					TInt count=values->Count();
       
  1503 					for (TInt ii=0;ii<count; ii++)
       
  1504 						ConvertUTCDateTimeToMachineLocal((*values)[ii],aIncrement,aDaylight);
       
  1505 					}
       
  1506 				}
       
  1507 				break;
       
  1508 			default:
       
  1509 				timeValue->ConvertAllUTCDateTimesToMachineLocalL(aIncrement);
       
  1510 				}
       
  1511 			}
       
  1512 		}
       
  1513 	}
       
  1514 
       
  1515 void CVersitParser::ConvertUTCDateTimeToMachineLocal(TVersitDateTime* aDateTime,const TTimeIntervalSeconds& aIncrement,const CVersitDaylight* aDaylight)
       
  1516 	{
       
  1517 	if (aDateTime && aDateTime->iRelativeTime==TVersitDateTime::EIsUTC)
       
  1518 		{
       
  1519 		CParserTimePropertyValue::ConvertDateTime(aDateTime->iDateTime,aIncrement,aDaylight,EFalse);
       
  1520 		aDateTime->iRelativeTime=TVersitDateTime::EIsMachineLocal;
       
  1521 		}
       
  1522 	}
       
  1523 
       
  1524 
       
  1525 //
       
  1526 // Recognition
       
  1527 //
       
  1528 
       
  1529 EXPORT_C TBool CVersitParser::IsValidParameterValue(TInt& aPos,const TDesC& aParamValue)
       
  1530 /** Tests whether a property parameter name or value is valid.
       
  1531 
       
  1532 If the string aParamValue contains any punctuation characters, the string 
       
  1533 is invalid. Otherwise, it is valid. Punctuation characters are defined as 
       
  1534 any of the following:- 
       
  1535 
       
  1536 [] (left or right square bracket)
       
  1537 
       
  1538 = (equals sign)
       
  1539 
       
  1540 : (colon)
       
  1541 
       
  1542 ; (semi colon)
       
  1543 
       
  1544 . (dot)
       
  1545 
       
  1546 , (comma)
       
  1547 
       
  1548 @param aPos On return, contains the character position of the first invalid 
       
  1549 character in the property parameter name or value. 
       
  1550 @param aParamValue The property parameter name or value to test. 
       
  1551 @return ETrue if valid, EFalse if invalid. */
       
  1552 	{
       
  1553 	TInt length = aParamValue.Length();
       
  1554 	for (aPos = 0; aPos < length; aPos++)
       
  1555 		{
       
  1556 		if (IsPunctuationToken(aParamValue[aPos]))
       
  1557 			return EFalse;
       
  1558 		}
       
  1559 	return ETrue;
       
  1560 	}
       
  1561 
       
  1562 EXPORT_C CArrayPtr<CParserParam>* CVersitParser::GetPropertyParamsLC(TPtr8 aParams)
       
  1563 	{
       
  1564 	CArrayPtr<CParserParam>* arrayOfParams=new(ELeave)CArrayPtrFlat<CParserParam>(5);
       
  1565 	CleanupStack::PushL(TCleanupItem(ResetAndDestroyArrayOfParams,arrayOfParams));
       
  1566 	TUint8* currentChar=&aParams[0];
       
  1567 	TUint8* dest;
       
  1568 	TUint8* afterLastChar=currentChar+aParams.Length();
       
  1569 	TUint8* startField;
       
  1570 	TBool escaping;
       
  1571 	TInt len;
       
  1572 	while (currentChar<=afterLastChar)
       
  1573 		{
       
  1574 		startField=currentChar;
       
  1575 		escaping=EFalse;
       
  1576 		while (currentChar<afterLastChar && *currentChar!=KVersitTokenSemiColonVal && *currentChar!=KVersitTokenBackslashVal)
       
  1577 			++currentChar;
       
  1578 		dest=currentChar;
       
  1579 		if (*currentChar==KVersitTokenBackslashVal && currentChar<afterLastChar)
       
  1580 			{
       
  1581 			do	{
       
  1582 				if (!escaping)
       
  1583 					{
       
  1584 					if (*currentChar==KVersitTokenSemiColonVal)
       
  1585 						break;
       
  1586 					escaping=(*currentChar==KVersitTokenBackslashVal);
       
  1587 					if (escaping)
       
  1588 						{
       
  1589 						++currentChar;
       
  1590 						continue;
       
  1591 						}
       
  1592 					}
       
  1593 				else
       
  1594 					{
       
  1595 					if (*currentChar!=KVersitTokenBackslashVal && *currentChar!=KVersitTokenSemiColonVal)
       
  1596 						*dest++=KVersitTokenBackslashVal;
       
  1597 					escaping=EFalse;
       
  1598 					}
       
  1599 				*dest++=*currentChar++;
       
  1600 				} while(currentChar<afterLastChar);
       
  1601 			if (escaping)
       
  1602 				*dest++=KVersitTokenBackslashVal;
       
  1603 			}
       
  1604 		len=dest-startField;
       
  1605 		if (len>0)
       
  1606 			ParseParamL(arrayOfParams,TPtr8(startField,len,len));
       
  1607 		++currentChar;
       
  1608 		}
       
  1609 	return arrayOfParams;
       
  1610 	}
       
  1611 
       
  1612 EXPORT_C void CVersitParser::ParseParamL(CArrayPtr<CParserParam>* aArray,TPtr8 aParam)
       
  1613 	{
       
  1614 	TPtr8 paramName(aParam);
       
  1615 	TPtr8 paramValue(NULL,0);
       
  1616 	TInt equalsPos=aParam.Find(KVersitTokenEquals);
       
  1617 	if (equalsPos>KErrNotFound)
       
  1618 		{
       
  1619 		paramName.Set(&aParam[0],equalsPos,equalsPos);
       
  1620 		++equalsPos;
       
  1621 		TInt valLen=aParam.Length()-equalsPos;
       
  1622 			if (valLen>0)
       
  1623 				{
       
  1624 				paramValue.Set(&aParam[equalsPos],valLen,valLen);
       
  1625 				VersitUtils::StripWhiteSpace(paramValue);
       
  1626 			}
       
  1627 		}
       
  1628 	VersitUtils::StripWhiteSpace(paramName);
       
  1629 	CParserParam* newParam = CParserParam::NewL(paramName, paramValue);
       
  1630 	CleanupStack::PushL(newParam);
       
  1631 	aArray->AppendL(newParam);
       
  1632 	CleanupStack::Pop(newParam);
       
  1633 	}
       
  1634 
       
  1635 EXPORT_C void CVersitParser::AnalysesEncodingCharset(CArrayPtr<CParserParam>* aArrayOfParams)
       
  1636 //
       
  1637 // This method checks each parameter in turn to establish if any of the parameters (should some
       
  1638 // exist) contain references to the CHARSET parameter or the ENCODING parameter.
       
  1639 //
       
  1640 // Should references exist to CHARSET then a character set override is applied to the current
       
  1641 // property value during the decoding process.
       
  1642 //
       
  1643 // Note that it is  also valid syntax to simply indicate that the property value is encoded
       
  1644 // using QUOTED-PRINTABLE  simply by specifying QUOTED-PRINTABLE without following the normal
       
  1645 // PARAMETER_NAME=VALUE syntax (i.e the parameter might just consist of the PARAMETER_NAME
       
  1646 // part (in which case VALUE will be  null and PARAMETER_NAME will be QUOTED-PRINTABLE etc).
       
  1647 // 
       
  1648 // Method could leave while creating a UID 
       
  1649 //
       
  1650 	{
       
  1651 	CParserParam* parameter;
       
  1652 	TPtrC8 pParameterName;
       
  1653 	TPtrC8 pParameterValue;
       
  1654 	TInt noOfParams = (aArrayOfParams)? aArrayOfParams->Count() : 0;
       
  1655 	TInt tokenUidValue = 0;
       
  1656 
       
  1657 	//
       
  1658 	// Check each parameter for coding related tags, such as CHARSET, ENCODING, etc and
       
  1659 	// set up state ready for the decoding of the parameter value
       
  1660 	//
       
  1661 	for(TInt ii = 0; ii < noOfParams; ii++)
       
  1662 		{
       
  1663 		parameter = aArrayOfParams->At(ii);
       
  1664 		pParameterName.Set(parameter->Name());
       
  1665 		pParameterValue.Set(parameter->Value());
       
  1666 
       
  1667 		// Attempt to recognize this property parameter
       
  1668 		tokenUidValue = RecognizeToken(pParameterName).iUid;
       
  1669 
       
  1670 		// The parameter NAME is CHARSET
       
  1671 		if	(tokenUidValue == KVersitParamCharsetUid)
       
  1672 			{
       
  1673 			// Charset identifier found, so establish the encoding type (e.g UTF8, ISO8859-X etc).
       
  1674 			TUint charSetUid=KCharacterSetIdentifierAscii;
       
  1675 			charSetUid=UnicodeUtils().ConvertStandardNameL(pParameterValue); // Method could leave while creating a UID 
       
  1676 			if (charSetUid!=0)
       
  1677 				{
       
  1678 				SetLineCharacterSetId(charSetUid);
       
  1679 				iFlags|=ECharSetIdentified;
       
  1680 				}
       
  1681 
       
  1682 			// The CHARSET parameter of this property is no longer required so remove it from the array.
       
  1683 			delete parameter;
       
  1684 			aArrayOfParams->Delete(ii);
       
  1685 			--ii;
       
  1686 			--noOfParams;
       
  1687 			}
       
  1688 		// The parameter NAME is ENCODING
       
  1689 		else if (tokenUidValue == KVersitParamEncodingUid)
       
  1690 			{
       
  1691 			const TUint conversionUid = RecognizeToken(pParameterValue).iUid;
       
  1692 			SetLineEncoding(conversionUid);
       
  1693 			}
       
  1694 		// The parameter NAME is QUOTED-PRINTABLE
       
  1695 		else if (tokenUidValue == KVersitParamEncodingQuotedPrintableUid)
       
  1696 			{
       
  1697 			SetLineEncoding(Versit::EQuotedPrintableEncoding);
       
  1698 			}
       
  1699 		// The parameter NAME is BASE64
       
  1700 		else if (tokenUidValue == KVersitParamEncodingBase64Uid)
       
  1701 			{
       
  1702 			SetLineEncoding(Versit::EBase64Encoding);
       
  1703 			}
       
  1704 		} // end FOR
       
  1705 	}
       
  1706 
       
  1707 HBufC* CVersitParser::ConvertToUnicodeL(const TDesC8& aValue)
       
  1708 	{
       
  1709 	if (!(iFlags&ECharSetIdentified))
       
  1710 		{
       
  1711 		if (iFlags&EUseAutoDetection && !VersitUtils::IsBeginOrEnd(iCurrentProperty->NameUid())
       
  1712 																	&& iCurrentProperty->NameUid().iUid!=KVersitTokenVersionUid)
       
  1713 			SetLineCharacterSetId(UnicodeUtils().AutoDetectCharSetL(aValue,iAutoDetectCharSets));
       
  1714 		else
       
  1715 			SetLineCharacterSet(Versit::EUSAsciiCharSet);
       
  1716 		}
       
  1717 	if	(LineCharSet() != Versit::EUSAsciiCharSet)
       
  1718 		{
       
  1719 		HBufC* value = HBufC::NewLC(aValue.Size());
       
  1720 		TPtr ptr(value->Des());
       
  1721 
       
  1722 		if	(aValue.Length())
       
  1723 			{
       
  1724 			User::LeaveIfError(ConvertToUnicodeFromISOL(ptr, aValue, LineCharSetId()));
       
  1725 			__ASSERT_DEBUG(ptr.Length(), User::Invariant());
       
  1726 			}
       
  1727 
       
  1728 		CleanupStack::Pop(value);
       
  1729 		return value;
       
  1730 		}
       
  1731 	else
       
  1732 		return UnicodeUtils().WidenL(aValue);
       
  1733 	}
       
  1734 
       
  1735 EXPORT_C HBufC* CVersitParser::DecodePropertyValueL(const TDesC8& aValue)
       
  1736 //
       
  1737 // This method is used to decode the property value given that any
       
  1738 // parameters to the property have been established.
       
  1739 //
       
  1740 	{
       
  1741 	// If this property has an overridden encoding type, or the default encoding is not ENoEncoding
       
  1742 	// then do the decode here... otherwise leave it up to MakeXXXX instead.
       
  1743 	if	(LineEncoding() != Versit::ENoEncoding)
       
  1744 		{
       
  1745 		const TUid propertyEncodingUid = { LineEncodingId() };
       
  1746 		TRAPD(err,DecodePropertyValueL(aValue,propertyEncodingUid));
       
  1747 		if	(err != KErrNotSupported)
       
  1748 			{
       
  1749 			User::LeaveIfError(err);
       
  1750 			if (iLargeDataBuf)
       
  1751 				return NULL;
       
  1752 			return ConvertToUnicodeL(*iDecodedValue);
       
  1753 			}
       
  1754 		}
       
  1755 	if (iLargeDataBuf)
       
  1756 		return NULL;
       
  1757 	return ConvertToUnicodeL(aValue);
       
  1758 	}
       
  1759 
       
  1760 EXPORT_C void CVersitParser::DecodePropertyValueL(const TDesC8& aValue,const TUid& aEncodingUid)
       
  1761 	{
       
  1762 	CCnaConverterList* convList=CCnaConverterList::NewLC();
       
  1763 	CConverterBase* conv = convList->NewConverterL(aEncodingUid);
       
  1764 	if (!conv)
       
  1765 		User::Leave(KErrNotSupported);
       
  1766 	CleanupStack::PushL(conv);
       
  1767 
       
  1768 	CBufSeg* destBuf=NULL;		//Initialise to stop warning "local variable may be used without having been initialized"
       
  1769 	RBufReadStream bufRead;
       
  1770 	RBufWriteStream bufWrite;
       
  1771 	RDesReadStream desRead;
       
  1772 	RDesWriteStream desWrite;
       
  1773 	RReadStream* readStream;
       
  1774 	RWriteStream* writeStream;
       
  1775 	if (iLargeDataBuf)
       
  1776 		{
       
  1777 		destBuf=CBufSeg::NewL(128);
       
  1778 		CleanupStack::PushL(destBuf);
       
  1779 		bufRead.Open(*iLargeDataBuf);
       
  1780 		bufWrite.Open(*destBuf);
       
  1781 		readStream=&bufRead;
       
  1782 		writeStream=&bufWrite;
       
  1783 		}
       
  1784 	else
       
  1785 		{
       
  1786 		if (!iDecodedValue)
       
  1787 			iDecodedValue=HBufC8::NewL(aValue.Length());
       
  1788 		else
       
  1789 			{
       
  1790 			TPtr8 value=iDecodedValue->Des();
       
  1791 			if(value.MaxLength()<aValue.Length())
       
  1792 				iDecodedValue=iDecodedValue->ReAllocL(aValue.Length());
       
  1793 			}
       
  1794 		desRead.Open(aValue);
       
  1795 		TPtr8 ptr=iDecodedValue->Des();		//To stop warning: nonstandard extension used : 'argument' : conversion from 'class TPtr8' to 'class TDes8 &'
       
  1796 		desWrite.Open(ptr);
       
  1797 		readStream=&desRead;
       
  1798 		writeStream=&desWrite;
       
  1799 		}
       
  1800 	//
       
  1801 	conv->ConvertObjectL(*readStream,*writeStream);
       
  1802 	//
       
  1803 	writeStream->CommitL();
       
  1804 	readStream->Close();
       
  1805 	writeStream->Close();
       
  1806 	//
       
  1807 	if (iLargeDataBuf)
       
  1808 		{
       
  1809 		CleanupStack::Pop(destBuf);
       
  1810 		delete iLargeDataBuf;
       
  1811 		iLargeDataBuf=destBuf;
       
  1812 		}
       
  1813 	CleanupStack::PopAndDestroy(2, convList); // conv, convList
       
  1814 	}
       
  1815 
       
  1816 
       
  1817 EXPORT_C void CVersitParser::AppendBeginL()
       
  1818 // Write beginning of entity to stream
       
  1819 	{
       
  1820 	iWriteStream->WriteL(KVersitTokenBEGIN);
       
  1821 	AppendEntityNameL();
       
  1822 	}
       
  1823 
       
  1824 EXPORT_C void CVersitParser::AppendEndL()
       
  1825 // Write end of entity to stream
       
  1826 	{
       
  1827 	iWriteStream->WriteL(KVersitTokenEND);
       
  1828 	AppendEntityNameL();
       
  1829 	}
       
  1830 
       
  1831 void CVersitParser::AppendEntityNameL()
       
  1832 	{
       
  1833 	iWriteStream->WriteL(KVersitTokenColon);
       
  1834 	if (iEntityName)
       
  1835 		{
       
  1836 		UnicodeUtils().SetCurrentCharSetL(KCharacterSetIdentifierCodePage1252);
       
  1837 		HBufC8* narrow = UnicodeUtils().NarrowLC(*iEntityName);
       
  1838 		iWriteStream->WriteL(*narrow);
       
  1839 		CleanupStack::PopAndDestroy(narrow);
       
  1840 		}
       
  1841 	iWriteStream->WriteL(KVersitTokenCRLF);
       
  1842 	}
       
  1843 
       
  1844 EXPORT_C CVersitParser* CVersitParser::MakeEntityL(TInt /*aEntityUid*/,HBufC* /*aEntityName*/)
       
  1845 // Make an entity from iReadStream
       
  1846 	{
       
  1847 	User::Leave(KErrNotSupported); //entities not supported
       
  1848 	return NULL;
       
  1849 	}
       
  1850 
       
  1851 EXPORT_C CParserPropertyValue* CVersitParser::MakePropertyValueL(const TUid& aPropertyUid,HBufC16*& aValue)
       
  1852 // Every property value has a specific property UID type which identifies the type of
       
  1853 // container object the property value (returned from this method) is derived from.
       
  1854 	{
       
  1855 	if(!aValue && (aPropertyUid.iUid != KVersitPropertyBinaryUid || !iLargeDataBuf))
       
  1856 		{
       
  1857 		return NULL;
       
  1858 		}
       
  1859 
       
  1860 	CParserPropertyValue* value = NULL;
       
  1861 
       
  1862 	switch(aPropertyUid.iUid)
       
  1863 		{
       
  1864 		case KVersitPropertyCDesCArrayUid:
       
  1865 			{
       
  1866 			CDesCArray* array=MakePropertyValueCDesCArrayL(aValue->Des());
       
  1867 			CleanupStack::PushL(array);
       
  1868 			value=new(ELeave)CParserPropertyValueCDesCArray(array);
       
  1869 			CleanupStack::Pop(array);
       
  1870 			break;
       
  1871 			}
       
  1872 		case KVersitPropertyTimeZoneUid:
       
  1873 			{
       
  1874 			TPtr16 ptr=aValue->Des();
       
  1875 			VersitUtils::StripWhiteSpace(ptr);
       
  1876 			TTimeIntervalSeconds timeZone=DecodeTimeZoneL(ptr);
       
  1877 			value=new(ELeave)CParserPropertyValueTimeZone(timeZone);
       
  1878 			break;
       
  1879 			}
       
  1880 		case KVersitPropertyDaylightUid:
       
  1881 			{
       
  1882 			CVersitDaylight* daylight=MakePropertyValueDaylightL(aValue->Des());
       
  1883 			CleanupStack::PushL(daylight);
       
  1884 			value=new(ELeave)CParserPropertyValueDaylight(daylight);
       
  1885 			CleanupStack::Pop(daylight);
       
  1886 			break;
       
  1887 			}
       
  1888 		case KVersitPropertyDateTimeUid:
       
  1889 			{
       
  1890 			TPtr16 ptr=aValue->Des();
       
  1891 			if (ptr.Length()<=KVersitDatePropertySymbianConnectMessageMaximumLenght)
       
  1892 				{
       
  1893 				//date is not valid, exception implemented to satisfy symbian connect protocol
       
  1894 				value=MakeDefaultPropertyValueL(aValue);
       
  1895 				}
       
  1896 			else
       
  1897 				{
       
  1898 				TVersitDateTime* dateTime=DecodeDateTimeL(ptr);
       
  1899 				CleanupStack::PushL(dateTime);
       
  1900 				value=new(ELeave)CParserPropertyValueDateTime(dateTime);
       
  1901 				CleanupStack::Pop(dateTime);
       
  1902 				}
       
  1903 			break;
       
  1904 			}
       
  1905 		case KVersitPropertyDateUid:
       
  1906 			{
       
  1907 			TPtr16 ptr=aValue->Des();
       
  1908 			if (ptr.Length()<=KVersitDatePropertySymbianConnectMessageMaximumLenght)
       
  1909 				{
       
  1910 				//date is not valid, exception implemented to satisfy symbian connect protocol
       
  1911 				value=MakeDefaultPropertyValueL(aValue);
       
  1912 				}
       
  1913 			else
       
  1914 				{	
       
  1915 				TVersitDateTime* dateTime=DecodeDateTimeL(ptr);
       
  1916 				CleanupStack::PushL(dateTime);
       
  1917 				value=new(ELeave)CParserPropertyValueDate(dateTime);
       
  1918 				CleanupStack::Pop(dateTime);
       
  1919 				}
       
  1920 			break;
       
  1921 			}
       
  1922 		case KVersitPropertyMultiDateTimeUid:
       
  1923 			{
       
  1924 			CArrayPtr<TVersitDateTime>*	multiDateTime=MakePropertyValueMultiDateTimeL(aValue->Des());
       
  1925 			CleanupStack::PushL(TCleanupItem(ResetAndDestroyArrayOfDateTimes,multiDateTime));
       
  1926 			value=new(ELeave)CParserPropertyValueMultiDateTime(multiDateTime);
       
  1927 			CleanupStack::Pop(multiDateTime);
       
  1928 			break;
       
  1929 			}
       
  1930 		case KVersitPropertyIntUid:
       
  1931 			{
       
  1932 			TInt number;
       
  1933 			Val(*aValue, number);
       
  1934 			value=new(ELeave)CParserPropertyValueInt(number);
       
  1935 			break;
       
  1936 			}
       
  1937 		case KVersitPropertyBinaryUid:
       
  1938 			value=new(ELeave) CParserPropertyValueBinary(*iLargeDataBuf);
       
  1939 			iLargeDataBuf=NULL;
       
  1940 			break;
       
  1941 		default://KVersitPropertyHBufCUid
       
  1942 			{
       
  1943 			value=MakeDefaultPropertyValueL(aValue);
       
  1944 			}
       
  1945 		}
       
  1946 	return value;
       
  1947 	}
       
  1948 
       
  1949 CParserPropertyValueHBufC* CVersitParser::MakeDefaultPropertyValueL(HBufC16*& aValue)
       
  1950 /**
       
  1951  * Instantiates and gives ownership of a CParserPropertyValueHBufC object.
       
  1952  */
       
  1953 	{
       
  1954 	if(!aValue && !iLargeDataBuf)
       
  1955 		return NULL;
       
  1956 
       
  1957 	VersitUtils::RemoveEscapeChars(*aValue,LineCharSetId());
       
  1958 	CParserPropertyValueHBufC* returnedValue=new(ELeave) CParserPropertyValueHBufC(aValue);
       
  1959 	aValue=NULL;
       
  1960 	return returnedValue;
       
  1961 	}
       
  1962 
       
  1963 
       
  1964 EXPORT_C CDesCArray* CVersitParser::MakePropertyValueCDesCArrayL(TPtr16 aStringValue)
       
  1965 /** Parses a compound property value string. 
       
  1966 
       
  1967 The sub-values found are appended to an array, after removal of escape characters. 
       
  1968 The array is returned, and ownership is transferred to the caller.
       
  1969 
       
  1970 @param aStringValue Compound property value string.
       
  1971 @return Array of property values found in the string. */
       
  1972 	{
       
  1973     CDesCArray* arrayOfValues = VersitUtils::ParseForArrayPropertiesL(aStringValue, LineCharSetId());
       
  1974 	return arrayOfValues;
       
  1975 	}
       
  1976 
       
  1977 EXPORT_C TBool CVersitParser::FindFirstField(TPtr16& aField,TPtr16& aRemaining, TBool aTrimSpace)
       
  1978 	{
       
  1979 	TInt len=aRemaining.Length();
       
  1980 	TInt posSemicolon=aRemaining.Locate(KVersitTokenSemiColonVal);
       
  1981 	TInt startRest=posSemicolon+1;
       
  1982 	TBool ret=(posSemicolon==KErrNotFound);
       
  1983 	if (ret)
       
  1984 		{
       
  1985 		if (len==0)
       
  1986 			{
       
  1987 			aField.Set(NULL,0,0);
       
  1988 			return ETrue;
       
  1989 			}
       
  1990 		posSemicolon=len;
       
  1991 		startRest=len;
       
  1992 		}
       
  1993 	aField.Set(&aRemaining[0],posSemicolon,posSemicolon);
       
  1994 	len-=startRest;
       
  1995 	if (len==0)
       
  1996 		startRest=0;
       
  1997 	aRemaining.Set(&aRemaining[startRest],len,len);
       
  1998 	if(aTrimSpace)
       
  1999 		VersitUtils::StripWhiteSpace(aField);
       
  2000 	return ret;
       
  2001 	}
       
  2002 	
       
  2003 /** Sets up a pointer to the remaining field. Sets the original remaining field pointers length to 0. 
       
  2004 @param aField on return points to the data and length that aRemaining originally pointed to. 
       
  2005 @param aRemaining as input references a location that the descriptor is to represent. On return length is set to 0.
       
  2006 */
       
  2007 EXPORT_C void CVersitParser::FindRemainingField(TPtr16& aField,TPtr16& aRemaining)
       
  2008 	{
       
  2009 	TInt len=aRemaining.Length();
       
  2010 	aField.Set(&aRemaining[0],len,len);
       
  2011 	aRemaining.Set(&aRemaining[0], 0, 0);
       
  2012 	}
       
  2013 
       
  2014 EXPORT_C CVersitDaylight* CVersitParser::MakePropertyValueDaylightL(TPtr16 aDaylightValue)
       
  2015 	{
       
  2016 	if(aDaylightValue.MatchF(KVersitVarTokenFALSE)>KErrNotFound)
       
  2017 		return CVersitDaylight::NewL(EFalse, NULL, NULL, NULL, KVersitTokenEmpty, KVersitTokenEmpty);
       
  2018 
       
  2019 	TPtr16 field(NULL,0);
       
  2020 	FindFirstField(field,aDaylightValue);
       
  2021 	if(field.CompareC(KVersitVarTokenTRUE))
       
  2022 		return NULL;
       
  2023 
       
  2024 	FindFirstField(field,aDaylightValue);
       
  2025 	TTimeIntervalSeconds offset=0;
       
  2026 	if(field.Length()>0)
       
  2027 		offset = DecodeTimeZoneL(field);
       
  2028 
       
  2029 	FindFirstField(field,aDaylightValue);
       
  2030 	TVersitDateTime* startTime = NULL;
       
  2031 	if(field.Length()>0)
       
  2032 		startTime = DecodeDateTimeL(field);
       
  2033 	CleanupStack::PushL(startTime);
       
  2034 
       
  2035 	FindFirstField(field,aDaylightValue);
       
  2036 	TVersitDateTime* endTime = NULL;
       
  2037 	if(field.Length()>0)
       
  2038 		endTime = DecodeDateTimeL(field);
       
  2039 	CleanupStack::PushL(endTime);
       
  2040 
       
  2041 	FindFirstField(field,aDaylightValue);
       
  2042 	TPtr16 edt(NULL,0);
       
  2043 	FindFirstField(edt,aDaylightValue);
       
  2044 
       
  2045 	if(!startTime || !endTime)
       
  2046 		User::Leave(KVersitErrBadDateTime);
       
  2047 			
       
  2048 	CVersitDaylight* daylight = CVersitDaylight::NewL(ETrue, offset, startTime, endTime, field, edt);
       
  2049 	CleanupStack::Pop(2,startTime);
       
  2050 	return (daylight);
       
  2051 	}
       
  2052 
       
  2053 EXPORT_C CArrayPtr<TVersitDateTime>* CVersitParser::MakePropertyValueMultiDateTimeL(TPtr16 aDateTimeGroup)
       
  2054 // Make a property from aDateTimeGroup, with a CArrayPtr<TDateTime> value
       
  2055 	{
       
  2056 	VersitUtils::StripWhiteSpace(aDateTimeGroup);
       
  2057 	if(aDateTimeGroup.Length()==0)
       
  2058 		return NULL;
       
  2059 	CArrayPtr<TVersitDateTime>* arrayOfDateTimes=new(ELeave)CArrayPtrFlat<TVersitDateTime>(5);
       
  2060 	CleanupStack::PushL(TCleanupItem(ResetAndDestroyArrayOfDateTimes,arrayOfDateTimes));
       
  2061 	TPtr16 field(NULL,0);
       
  2062 	do
       
  2063 		{
       
  2064 		FindFirstField(field,aDateTimeGroup);
       
  2065 		if(field.Length()>0)
       
  2066 			{
       
  2067 			TVersitDateTime* dateTime = DecodeDateTimeL(field);
       
  2068 			CleanupStack::PushL(dateTime);
       
  2069 			arrayOfDateTimes->AppendL(dateTime);
       
  2070 			CleanupStack::Pop(dateTime);
       
  2071 			}
       
  2072 		}while (aDateTimeGroup.Length()!=0);
       
  2073 
       
  2074 	CleanupStack::Pop(arrayOfDateTimes); //arrayOfDateTimes
       
  2075 	return arrayOfDateTimes;
       
  2076 	}
       
  2077 
       
  2078 EXPORT_C TInt CVersitParser::Val(const TDesC& aString, TInt& aNumber)
       
  2079 // static
       
  2080 /** Converts a string into an integer, for example, it converts "438" to 438.
       
  2081 
       
  2082 @param aString The string to be converted. Every character contained in 
       
  2083 the string needs to be number presentable, i.e. between '0' and '9'.
       
  2084 @param aNumber On return, the integer corresponding to aString. 
       
  2085 @return KErrNone if the number has been converted from the string; 
       
  2086 KVersitErrNumberExpected otherwise. */
       
  2087 	{
       
  2088 	aNumber = 0;
       
  2089 	TInt length=aString.Length();
       
  2090 	for(TInt i=0;i<length;i++)
       
  2091 		{
       
  2092 		if(aString[i]<'0'||aString[i]>'9')
       
  2093 			return(KVersitErrNumberExpected);
       
  2094 		aNumber = aNumber * 10 + aString[i] - '0';
       
  2095 		}
       
  2096 	return KErrNone;
       
  2097 	}
       
  2098 
       
  2099 
       
  2100 EXPORT_C TVersitDateTime* CVersitParser::DecodeDateTimeL(TDes& aToken) const
       
  2101 // Extracts the date and time portion from aToken and returns it as a
       
  2102 // TVersitDateTime (Format YYYY(:)MM(:)DD(:)(THH(:)MM(:)SS(:)(Z))
       
  2103 	{
       
  2104 	const TInt KSymbianOSDefaultMidnightValue = 0;
       
  2105 	const TInt KVersitAlternativeMidnightValue = 24;
       
  2106 
       
  2107 	aToken.TrimAll();
       
  2108 	TInt length = aToken.Length();
       
  2109 	if (length==0)
       
  2110 		User::Leave(KVersitErrBadDateTime);
       
  2111 	TInt position = 0;
       
  2112 	if (length < 8)
       
  2113 		User::Leave(KVersitErrBadDateTime);
       
  2114 	TVersitDateTime::TRelativeTime relativeTime = TVersitDateTime::EIsVCardLocal;
       
  2115 	TInt year;
       
  2116 	User::LeaveIfError(Val(aToken.Left(4), year));
       
  2117 	position += 4;
       
  2118 	if(aToken[position] == KVersitTokenMinusVal)
       
  2119 		position++;
       
  2120 	TInt month;
       
  2121 	User::LeaveIfError(Val(aToken.Mid(position, 2), month));
       
  2122 	position += 2;
       
  2123 	if(aToken[position] == KVersitTokenMinusVal)
       
  2124 		position++;
       
  2125 	if (length < (position + 2))
       
  2126 		User::Leave(KVersitErrBadDateTime);
       
  2127 	TInt day;
       
  2128 	User::LeaveIfError(Val(aToken.Mid(position, 2), day));
       
  2129 	position += 2;
       
  2130 	//
       
  2131 	// Parse time aspect
       
  2132 	//
       
  2133 	TBool adjustDayToNextAvailable = EFalse;
       
  2134 	TInt hour = 0;
       
  2135 	TInt minute = 0;
       
  2136 	TInt second = 0;
       
  2137 
       
  2138 	//	position is now sitting left of the "T" in the date string YYYY(-)MM(-)DD(-)THH(:)MM(:SS)
       
  2139 	if (length >= (position + 5))
       
  2140 		{
       
  2141 		TBool parseSeconds = EFalse;
       
  2142 		
       
  2143 		// Time value can be in "HHMM" or "HHMMSS" format.
       
  2144 		if(length >= (position + 7))
       
  2145 			parseSeconds = ETrue;
       
  2146 
       
  2147 		if(aToken[position++] != KVersitTimePeriodTimeVal)
       
  2148 			User::Leave(KVersitErrBadDateTime);
       
  2149 			
       
  2150 		User::LeaveIfError(Val(aToken.Mid(position, 2), hour));
       
  2151 		// If the hour value is "24" then, this is deemed to be at the end
       
  2152 		// of the specified day. This can be thought of as synonymous with the
       
  2153  		// start of the next day.
       
  2154  		if	(hour == KVersitAlternativeMidnightValue)
       
  2155  			{
       
  2156  			adjustDayToNextAvailable = ETrue;
       
  2157  			hour = KSymbianOSDefaultMidnightValue;
       
  2158  			}
       
  2159 
       
  2160 		position += 2;
       
  2161 		if(aToken[position] == KVersitTokenColonVal)
       
  2162 			position++;
       
  2163 		
       
  2164 		if(length < position+2)
       
  2165 			User::Leave(KVersitErrBadDateTime);
       
  2166 		
       
  2167 		User::LeaveIfError(Val(aToken.Mid(position, 2), minute));
       
  2168 		position += 2;
       
  2169 
       
  2170 		if(parseSeconds)
       
  2171 			{
       
  2172 			if(aToken[position] == KVersitTokenColonVal)
       
  2173 				position++;
       
  2174 			if (length < (position + 2))
       
  2175 				User::Leave(KVersitErrBadDateTime);
       
  2176 			User::LeaveIfError(Val(aToken.Mid(position, 2), second));
       
  2177 			position += 2;
       
  2178 			}
       
  2179 
       
  2180 		if ((length > position) && (aToken[position] == KVersitTokenUniversalTimeVal))
       
  2181 			relativeTime = TVersitDateTime::EIsUTC;
       
  2182 		}
       
  2183 	TDateTime date;
       
  2184 	const TInt error = date.Set(year, (TMonth)(month - 1), day - 1, hour, minute, second, 0);
       
  2185 	if(error!=KErrNone)
       
  2186  		User::LeaveIfError(KVersitErrBadDateTime);
       
  2187 
       
  2188  	// In the instance whereby we need to treat 24 as being the start of the next
       
  2189  	// day, we should increment the day value by one.
       
  2190  	if	(adjustDayToNextAvailable)
       
  2191  		{
       
  2192  		const TInt KVersitSingleDay = 1;
       
  2193  		//
       
  2194  		TTime time(date);
       
  2195  		time += TTimeIntervalDays(KVersitSingleDay);
       
  2196  		date = time.DateTime();
       
  2197  		}
       
  2198 	return new(ELeave) TVersitDateTime(date, relativeTime);
       
  2199 	}
       
  2200 
       
  2201 EXPORT_C TTimeIntervalSeconds CVersitParser::DecodeTimeZoneL(const TDesC& aToken) const
       
  2202 // Extracts the date and time portion from aToken and returns it as a
       
  2203 // TVersitDateTime Format: (-)(+)HH((:)MM)
       
  2204 	{
       
  2205 	TInt length = aToken.Length();
       
  2206 	if (length < 1)
       
  2207 		User::Leave(KVersitErrBadTimeZone);
       
  2208 	TInt position = 0;
       
  2209 	TInt sign = 1;
       
  2210 	TInt hour = 0,minute = 0;
       
  2211 	if(aToken[position] == KVersitTokenMinusVal)
       
  2212 		{
       
  2213 		position++;
       
  2214 		sign = -1;
       
  2215 		}
       
  2216 	else if(aToken[position] == KVersitTokenPlusVal)
       
  2217 		position++;
       
  2218 	if(length-position<1)
       
  2219 		User::Leave(KVersitErrBadTimeZone);
       
  2220 	if((length-position)==1 || aToken.Mid(position+1,1)==KVersitTokenColonUnicode)
       
  2221 		{
       
  2222 		User::LeaveIfError(Val(aToken.Mid(position, 1), hour));
       
  2223 		position += 1;
       
  2224 		}
       
  2225 	else
       
  2226 		{
       
  2227 		User::LeaveIfError(Val(aToken.Mid(position, 2), hour));
       
  2228 		position += 2;
       
  2229 		}
       
  2230 
       
  2231 	if (length >= (position + 1))
       
  2232 		{
       
  2233 		if(aToken[position] == KVersitTokenColonVal)
       
  2234 			position++;
       
  2235 		if(length-1==position)
       
  2236 			User::LeaveIfError(Val(aToken.Mid(position, 1), minute));
       
  2237 		else if(length-1>position)
       
  2238 			User::LeaveIfError(Val(aToken.Mid(position, 2), minute));
       
  2239 		}
       
  2240 	return TTimeIntervalSeconds(sign * (hour * 3600 + minute * 60));
       
  2241 	}
       
  2242 
       
  2243 EXPORT_C TTime* CVersitParser::DecodeTimePeriodL(const TDesC& aToken) const
       
  2244 // Extracts the date and time portion from aToken and returns it as a
       
  2245 // TDateTime time period
       
  2246 	{
       
  2247 	TInt length = aToken.Length();
       
  2248 	TInt ii = 0;
       
  2249 	if (!length || (aToken[ii++] != KVersitTimePeriodBeginVal))
       
  2250 		User::Leave(KVersitErrBadTimePeriod);
       
  2251 	TInt number = 0;
       
  2252 	TInt year = 0;
       
  2253 	TInt month = 0;
       
  2254 	TInt week = 0;
       
  2255 	TInt day = 0;
       
  2256 	TInt hour = 0;
       
  2257 	TInt minute = 0;
       
  2258 	TInt second = 0;
       
  2259 	TBool isTimeOfDay = EFalse;
       
  2260 	while (ii < length)
       
  2261 		{
       
  2262 		TChar tokenChar = aToken[ii];
       
  2263 		if ((tokenChar >= '0') && (tokenChar <= '9'))
       
  2264 			{
       
  2265 			TInt numChars;
       
  2266 			number = GetNumberL(aToken.Right(length - ii),numChars);
       
  2267 			ii+=numChars;
       
  2268 			}
       
  2269 		else
       
  2270 			{
       
  2271 			if (isTimeOfDay)
       
  2272 				{
       
  2273 				if (tokenChar == KVersitTimePeriodHourVal)
       
  2274 					hour = number;
       
  2275 				else if (tokenChar == KVersitTimePeriodMinuteVal)
       
  2276 					minute = number;
       
  2277 				else if (tokenChar == KVersitTimePeriodSecondVal)
       
  2278 					second = number;
       
  2279 				}
       
  2280 			else
       
  2281 				{
       
  2282 				if (tokenChar == KVersitTimePeriodTimeVal)
       
  2283 					isTimeOfDay = ETrue;
       
  2284 				else if (tokenChar == KVersitTimePeriodYearVal)
       
  2285 					year = number;
       
  2286 				else if (tokenChar == KVersitTimePeriodMonthVal)
       
  2287 					month = number;
       
  2288 				else if (tokenChar == KVersitTimePeriodWeekVal)
       
  2289 					week = number;
       
  2290 				else if (tokenChar == KVersitTimePeriodDayVal)
       
  2291 					day = number;
       
  2292 				}
       
  2293 			ii++;
       
  2294 			number = 0;
       
  2295 			}
       
  2296 		}
       
  2297 	//TBuf<KVersitDefaultBufferSize> time;
       
  2298 	//_LIT(formatString, "%04d%02d%02d:%02d%02d%02d.");
       
  2299 	//time.Format(formatString, year, month, day, hour, minute, second);
       
  2300 	TDateTime dateTime(year,REINTERPRET_CAST(TMonth&,month),day,hour,minute,second,0);
       
  2301 	//TTime* timeVal = new(ELeave) TTime(time);
       
  2302 	TTime* timeVal = new(ELeave) TTime(dateTime);
       
  2303 	*timeVal += TTimeIntervalDays(week * 7);
       
  2304 	return timeVal;
       
  2305 	}
       
  2306 
       
  2307 EXPORT_C TInt CVersitParser::GetNumberL(const TDesC& aToken,TInt& aNumChars) const
       
  2308 // Converts aToken to an integer
       
  2309 	{
       
  2310 	TInt length = aToken.Length();
       
  2311 	TPtrC numBuf(aToken);
       
  2312 	TInt num;
       
  2313 	aNumChars = 0;
       
  2314 	while ((aNumChars < length) && (aToken[aNumChars] >= '0') && (aToken[aNumChars] <= '9'))
       
  2315 		++aNumChars;
       
  2316 	numBuf.Set(aToken.Left(aNumChars));
       
  2317 	User::LeaveIfError(Val(numBuf, num));
       
  2318 	return num;
       
  2319 	}
       
  2320 
       
  2321 EXPORT_C TUid CVersitParser::RecognizeToken(const TDesC8& aToken) const
       
  2322 /** Returns a UID for the specified token. 
       
  2323 
       
  2324 This function only recognizes generic Versit tokens. For example, if aToken 
       
  2325 contains the property name KVersitTokenBEGIN, the function returns KVersitTokenBeginUid. 
       
  2326 More specific recognition should occur in derived classes which implement 
       
  2327 this function, using this as the base recogniser.
       
  2328 
       
  2329 @param aToken The token to be recognized.
       
  2330 @return A defined UID value if the token has been recognized; KVersitTokenUnknownUid 
       
  2331 otherwise. */
       
  2332 	{
       
  2333 	TUid uid = TUid::Uid(KVersitTokenUnknownUid);
       
  2334 	TChar firstChar(aToken.Ptr()[0]);
       
  2335 	firstChar=firstChar.GetUpperCase();
       
  2336 	switch (firstChar)
       
  2337 		{
       
  2338 	case 'B':
       
  2339 		if (!aToken.CompareF(KVersitTokenBEGIN))
       
  2340 			uid.iUid = KVersitTokenBeginUid;
       
  2341 		else if (!aToken.CompareF(KVersitTokenBASE64))
       
  2342 			uid.iUid = KVersitParamEncodingBase64Uid;
       
  2343 		break;
       
  2344 	case 'C':
       
  2345 		if (!aToken.CompareF(KVersitTokenCHARSET))
       
  2346 			uid.iUid = KVersitParamCharsetUid;
       
  2347 		break;
       
  2348 	case 'E':
       
  2349 		if (!aToken.CompareF(KVersitTokenEND))
       
  2350 			uid.iUid = KVersitTokenEndUid;
       
  2351 		else if (!aToken.CompareF(KVersitTokenENCODING))
       
  2352 			uid.iUid = KVersitParamEncodingUid;
       
  2353 		break;
       
  2354 	case 'Q':
       
  2355 		if (!aToken.CompareF(KVersitTokenQUOTEDPRINTABLE))
       
  2356 			uid.iUid = KVersitParamEncodingQuotedPrintableUid;
       
  2357 		break;
       
  2358 	default:
       
  2359 		break;
       
  2360 		}
       
  2361 	return uid;
       
  2362 	}
       
  2363 
       
  2364 EXPORT_C TInt CVersitParser::RecognizeEntityName() const
       
  2365 // From CVersitParser
       
  2366 /** Tests the current entity to see if it is a vEvent or vTodo.
       
  2367 
       
  2368 This function is virtual. Actual testing only occurs in derived classes which 
       
  2369 implement this function.
       
  2370 
       
  2371 @return Zero. Derived classes' implementations would return a value that indicates 
       
  2372 the current entity's type. */
       
  2373 	{
       
  2374 	return 0;
       
  2375 	}
       
  2376 
       
  2377 EXPORT_C void CVersitParser::ResetAndDestroyArrayOfParams(TAny* aObject)
       
  2378 /** Destroys an array of parameters.
       
  2379 
       
  2380 @param aObject Pointer to the array of parameters to be destroyed. */
       
  2381 	{
       
  2382 	CArrayPtr<CParserParam>* array=REINTERPRET_CAST(CArrayPtr<CParserParam>*,aObject);
       
  2383 	if (array)
       
  2384 		array->ResetAndDestroy();
       
  2385 	delete array;
       
  2386 	}
       
  2387 
       
  2388 EXPORT_C void CVersitParser::ResetAndDestroyArrayOfProperties(TAny* aObject)
       
  2389 /** Destroys an array of properties.
       
  2390 
       
  2391 @param aObject Pointer to the array of properties to be destroyed. */
       
  2392 	{
       
  2393 	CArrayPtr<CParserProperty>* array=REINTERPRET_CAST(CArrayPtr<CParserProperty>*,aObject);
       
  2394 	if (array)
       
  2395 		array->ResetAndDestroy();
       
  2396 	delete array;
       
  2397 	}
       
  2398 
       
  2399 EXPORT_C void CVersitParser::ResetAndDestroyArrayOfEntities(TAny* aObject)
       
  2400 /** Destroys an array of entities. 
       
  2401 
       
  2402 @param aObject Pointer to the array of entities to be destroyed. */
       
  2403 	{
       
  2404 	CArrayPtr<CVersitParser>* array=REINTERPRET_CAST(CArrayPtr<CVersitParser>*,aObject);
       
  2405 	if (array)
       
  2406 		array->ResetAndDestroy();
       
  2407 	delete array;
       
  2408 	}
       
  2409 
       
  2410 EXPORT_C void CVersitParser::ResetAndDestroyArrayOfDateTimes(TAny* aObject)
       
  2411 /** Destroys an array of Versit dates and times.
       
  2412 
       
  2413 @param aObject Pointer to the array of Versit dates and times to be destroyed. */
       
  2414 	{
       
  2415 	CArrayPtr<TVersitDateTime>* array=REINTERPRET_CAST(CArrayPtr<TVersitDateTime>*,aObject);
       
  2416 	if (array)
       
  2417 		array->ResetAndDestroy();
       
  2418 	delete array;
       
  2419 	}
       
  2420 
       
  2421 TBool CVersitParser::IsPunctuationToken(TUint aChar)		//static function
       
  2422 	{
       
  2423 	return (aChar == KVersitTokenColonVal ||
       
  2424 			aChar == KVersitTokenSemiColonVal ||
       
  2425 			aChar == KVersitTokenEqualsVal ||
       
  2426 			aChar == KVersitTokenPeriodVal ||
       
  2427 			aChar == KVersitTokenCommaVal ||
       
  2428 			aChar == KVersitTokenLSquareBracketVal ||
       
  2429 			aChar == KVersitTokenRSquareBracketVal);
       
  2430 	}
       
  2431 
       
  2432 EXPORT_C TInt CVersitParser::ConvertFromUnicodeToISOL(TDes8& aIso, const TDesC16& aUnicode, CCnvCharacterSetConverter* aConverter)
       
  2433 /** Converts text in the Unicode character set (UCS-2) into a 
       
  2434 non-unicode (International Standards Organisation) character set.
       
  2435 
       
  2436 Which ISO character set the string is converted to is determined by 
       
  2437 the value of the character set identifier in the aConverter parameter.
       
  2438 
       
  2439 @param aIso On return, the converted text string in the specified ISO 
       
  2440 character set. 
       
  2441 @param aUnicode The Unicode text string to be converted.
       
  2442 @param aConverter The character set converter.
       
  2443 @return If no error occurs, this is the number of unconverted characters 
       
  2444 left at the end of the input descriptor. This is zero if the whole string 
       
  2445 is converted, but may be greater than zero (e.g. because the output 
       
  2446 descriptor is not long enough to hold all the text). Otherwise, one of 
       
  2447 the error values defined in TError in the CCnvCharacterSetConverter class, or 
       
  2448 KErrNotFound if aConverter does not point to a valid character 
       
  2449 set converter object. */
       
  2450 	{
       
  2451 	if	(aConverter)
       
  2452 		{
       
  2453 		// Do the conversion
       
  2454 		aConverter->SetReplacementForUnconvertibleUnicodeCharactersL(KReplacementChars);
       
  2455 		return aConverter->ConvertFromUnicode(aIso, aUnicode);
       
  2456 		}
       
  2457 	return KErrNotFound;
       
  2458 	}
       
  2459 
       
  2460 EXPORT_C TInt CVersitParser::ConvertToUnicodeFromISOL(TDes16& aUnicode, const TDesC8& aIso,TUint aCharacterSet)
       
  2461 /** Converts text in a non-Unicode character set into Unicode (UCS-2).
       
  2462 
       
  2463 @param aUnicode On return, the converted text string in the Unicode character set.
       
  2464 @param aIso  The non-Unicode text string to be converted.
       
  2465 @param aCharacterSet The non-Unicode character set in which aIso is encoded.
       
  2466 @return If no error occurs, the number of unconverted bytes left at the end of 
       
  2467 the input descriptor. This is zero if the whole string is converted; but it may 
       
  2468 be greater than zero, e.g. because the output descriptor is not long enough to 
       
  2469 hold all the text. Otherwise, one of the error values defined in TError in the 
       
  2470 CCnvCharacterSetConverter class, or KErrNotFound if aCharacterSet cannot be 
       
  2471 converted. */
       
  2472 	{
       
  2473 	CCnvCharacterSetConverter::TAvailability avail=UnicodeUtils().SetCurrentCharSetL(aCharacterSet);
       
  2474 	if	(avail == CCnvCharacterSetConverter::EAvailable)
       
  2475 		{
       
  2476 		// Do the conversion
       
  2477 		CCnvCharacterSetConverter& converter=UnicodeUtils().CharacterSetConverter();
       
  2478 		TInt ignore = 0;
       
  2479 		converter.SetReplacementForUnconvertibleUnicodeCharactersL(KReplacementChars);
       
  2480 		return converter.ConvertToUnicode(aUnicode, aIso, ignore);
       
  2481 		}
       
  2482 	return KErrNotFound;
       
  2483 	}
       
  2484 
       
  2485 EXPORT_C void CVersitParser::SetDefaultEncoding(Versit::TVersitEncoding aEncoding)
       
  2486 /** Sets the parser's default encoding to aEncoding.
       
  2487 
       
  2488 @param aEncoding An encoding. Cannot be 8-bit.
       
  2489 @panic Versit-Parser 7 aEncoding is Versit::EEightBitEncoding. */
       
  2490 	{
       
  2491 	// 8-bit is reserved for versit - it uses it when it needs to, but it's not
       
  2492 	// settable by 3rd parties.
       
  2493 	__ASSERT_ALWAYS(aEncoding!=Versit::EEightBitEncoding, Panic(EVersitPanicCannotSetEightBitEncoding));
       
  2494 	//
       
  2495 	iDefaultCodingDetails.iEncoding		= aEncoding;
       
  2496 	iDefaultCodingDetails.iEncodingUid	= MapVersitEncodingToConArcUid(aEncoding);
       
  2497 	}
       
  2498 
       
  2499 EXPORT_C void CVersitParser::SetDefaultCharSet(Versit::TVersitCharSet aCharSet)
       
  2500 /** Sets the default character set or transformation format. 
       
  2501 
       
  2502 This may be used to represent property values in Versit objects.
       
  2503 	
       
  2504 @param aCharSet The default character set. */
       
  2505 	{
       
  2506 	iDefaultCodingDetails.iCharSet		= aCharSet;
       
  2507 	iDefaultCodingDetails.iCharSetUid	= MapVersitCharsetToCharConvCharset(aCharSet);
       
  2508 	}
       
  2509 
       
  2510 EXPORT_C void CVersitParser::SetDefaultCharSetId(TUint aCharSetId)
       
  2511 /** Sets the default character set or transformation format.
       
  2512 
       
  2513 This may be used to represent property values in Versit objects. 
       
  2514 
       
  2515 @param aCharSetId The UID for the character set. These are defined in charconv.h. */
       
  2516 	{
       
  2517 	iDefaultCodingDetails.iCharSet		= VersitUtils::CharSet(aCharSetId);
       
  2518 	iDefaultCodingDetails.iCharSetUid	= aCharSetId;
       
  2519 	}
       
  2520 
       
  2521 EXPORT_C void CVersitParser::RestoreLineCodingDetailsToDefault()
       
  2522 	{
       
  2523 	// Set the [en|de]coding details for the current line back to the default values specified
       
  2524 	SetLineCharsetDetailsToDefault();
       
  2525 	SetLineEncodingDetailsToDefault();
       
  2526 	}
       
  2527 
       
  2528 EXPORT_C void CVersitParser::SetLineEncoding(Versit::TVersitEncoding aLineEncoding)
       
  2529 	{
       
  2530 	iCurrentPropertyCodingDetails.iEncoding		= aLineEncoding;
       
  2531 	iCurrentPropertyCodingDetails.iEncodingUid	= MapVersitEncodingToConArcUid(aLineEncoding);
       
  2532 	}
       
  2533 
       
  2534 EXPORT_C void CVersitParser::SetLineEncoding(TUint aVersitEncodingUid)
       
  2535 	{
       
  2536 	switch (aVersitEncodingUid)
       
  2537 		{
       
  2538 		case KQuotedPrintableToTextConverter:
       
  2539 		case KVersitParamEncodingQuotedPrintableUid:
       
  2540 			iCurrentPropertyCodingDetails.iEncoding		= Versit::EQuotedPrintableEncoding;
       
  2541 			iCurrentPropertyCodingDetails.iEncodingUid	= KQuotedPrintableToTextConverter;
       
  2542 			break;
       
  2543 		case KBase64ToTextConverter:
       
  2544 		case KVersitParamEncodingBase64Uid:
       
  2545 			iCurrentPropertyCodingDetails.iEncoding		= Versit::EBase64Encoding;
       
  2546 			iCurrentPropertyCodingDetails.iEncodingUid	= KBase64ToTextConverter;
       
  2547 			break;
       
  2548 		default:
       
  2549 			iCurrentPropertyCodingDetails.iEncoding		= Versit::ENoEncoding;
       
  2550 			iCurrentPropertyCodingDetails.iEncodingUid	= 0;
       
  2551 			break;
       
  2552 		}
       
  2553 	}
       
  2554 
       
  2555 EXPORT_C void CVersitParser::SetLineCharacterSet(Versit::TVersitCharSet aLineCharSet)
       
  2556 	{
       
  2557 	iCurrentPropertyCodingDetails.iCharSet		= aLineCharSet;
       
  2558 	iCurrentPropertyCodingDetails.iCharSetUid	= MapVersitCharsetToCharConvCharset(aLineCharSet);
       
  2559 	}
       
  2560 
       
  2561 EXPORT_C void CVersitParser::SetLineCharacterSetId(TUint aLineCharSetId)
       
  2562 	{
       
  2563 	iCurrentPropertyCodingDetails.iCharSet		= VersitUtils::CharSet(aLineCharSetId);
       
  2564 	iCurrentPropertyCodingDetails.iCharSetUid	= aLineCharSetId;
       
  2565 	}
       
  2566 
       
  2567 EXPORT_C void CVersitParser::SetLineCoding(Versit::TVersitCharSet aLineCharSet,Versit::TVersitEncoding aLineEncoding)
       
  2568 	{
       
  2569 	SetLineCharacterSet(aLineCharSet);
       
  2570 	SetLineEncoding(aLineEncoding);
       
  2571 	}
       
  2572 
       
  2573 
       
  2574 EXPORT_C Versit::TVersitEncoding CVersitParser::DefaultEncoding() const
       
  2575 /** Gets the parser's default encoding. 
       
  2576 
       
  2577 This value is initialised on construction, to ENoEncoding.
       
  2578 
       
  2579 @return The parser's default encoding. */
       
  2580 	{
       
  2581 	return iDefaultCodingDetails.iEncoding;
       
  2582 	}
       
  2583 
       
  2584 EXPORT_C Versit::TVersitCharSet CVersitParser::DefaultCharSet() const
       
  2585 /** Gets the default character set or transformation format. This may be used to 
       
  2586 represent property values in Versit objects.
       
  2587 
       
  2588 @return The default character set. */
       
  2589 	{
       
  2590 	return iDefaultCodingDetails.iCharSet;
       
  2591 	}
       
  2592 
       
  2593 EXPORT_C TUint CVersitParser::DefaultCharSetId() const
       
  2594 /** Gets the default character set or transformation format. 
       
  2595 
       
  2596 This may be used to represent property values in Versit objects.
       
  2597 
       
  2598 @return The default character set identifier. Possible values are defined in charconv.h. */
       
  2599 	{
       
  2600 	return iDefaultCodingDetails.iCharSetUid;
       
  2601 	}
       
  2602 
       
  2603 EXPORT_C Versit::TVersitEncoding CVersitParser::LineEncoding() const
       
  2604 	{
       
  2605 	return iCurrentPropertyCodingDetails.iEncoding;
       
  2606 	}
       
  2607 
       
  2608 EXPORT_C Versit::TVersitCharSet CVersitParser::LineCharSet() const
       
  2609 	{
       
  2610 	return iCurrentPropertyCodingDetails.iCharSet;
       
  2611 	}
       
  2612 
       
  2613 EXPORT_C TUint CVersitParser::LineEncodingId() const
       
  2614 	{
       
  2615 	return iCurrentPropertyCodingDetails.iEncodingUid;
       
  2616 	}
       
  2617 
       
  2618 EXPORT_C TUint CVersitParser::LineCharSetId() const
       
  2619 	{
       
  2620 	return iCurrentPropertyCodingDetails.iCharSetUid;
       
  2621 	}
       
  2622 
       
  2623 
       
  2624 TUint CVersitParser::MapVersitCharsetToCharConvCharset(Versit::TVersitCharSet aVersitSet)
       
  2625 // Converts between the Versit character set enumeration and the constant character set identifier that CharConv
       
  2626 // uses during the conversion process
       
  2627 	{
       
  2628 	return VersitUtils::CharConvCharSetUid(aVersitSet).iUid;
       
  2629 	}
       
  2630 
       
  2631 
       
  2632 TUint CVersitParser::MapVersitEncodingToConArcUid(Versit::TVersitEncoding aVersitEncoding)
       
  2633 // Map from a versit specific encoding enumeration...
       
  2634 	{
       
  2635 	switch(aVersitEncoding)
       
  2636 		{
       
  2637 		case Versit::EQuotedPrintableEncoding:
       
  2638 			return KQuotedPrintableToTextConverter;
       
  2639 		case Versit::EBase64Encoding:
       
  2640 			return KBase64ToTextConverter;
       
  2641 		default:
       
  2642 			return 0;
       
  2643 		}
       
  2644 	}
       
  2645 
       
  2646 
       
  2647 
       
  2648 void CVersitParser::SetLineCharsetDetailsToDefault()
       
  2649 	{
       
  2650 	iCurrentPropertyCodingDetails.iCharSet		= iDefaultCodingDetails.iCharSet;
       
  2651 	iCurrentPropertyCodingDetails.iCharSetUid	= iDefaultCodingDetails.iCharSetUid;
       
  2652 	}
       
  2653 
       
  2654 
       
  2655 void CVersitParser::SetLineEncodingDetailsToDefault()
       
  2656 	{
       
  2657 	iCurrentPropertyCodingDetails.iEncoding		= iDefaultCodingDetails.iEncoding;
       
  2658 	iCurrentPropertyCodingDetails.iEncodingUid	= iDefaultCodingDetails.iEncodingUid;
       
  2659 	}
       
  2660 
       
  2661 EXPORT_C void CVersitParser::SetCharacterConverter(Versit::TEncodingAndCharset& aEncodingAndCharset)
       
  2662 /** Sets a character converter suitable for converting strings between 
       
  2663 Unicode and the specified character set.
       
  2664 
       
  2665 The function finds a suitable converter for the character set 
       
  2666 specified in aEncodingAndCharset.iCharSetId, if one is available, 
       
  2667 and assigns it to aEncodingAndCharset.iConverter.
       
  2668 
       
  2669 If there is no converter available for the specified character set then iConverter 
       
  2670 is set to NULL.
       
  2671 
       
  2672 This function is only of use if executing a major change to the externalisation 
       
  2673 behaviour, particularly if overriding CParserProperty::ExternalizeL() - the 
       
  2674 function from which this function is called.
       
  2675 
       
  2676 @param aEncodingAndCharset A utility class from which the character set 
       
  2677 information is extracted (from its member iCharSetId) and to which the 
       
  2678 suitable character converter is set (to its member iConverter). */
       
  2679 	{
       
  2680 	CCnvCharacterSetConverter::TAvailability avail=CCnvCharacterSetConverter::ENotAvailable;
       
  2681 	TRAPD(err,avail=UnicodeUtils().SetCurrentCharSetL(aEncodingAndCharset.iCharSetId));
       
  2682 	UNUSED_VAR(err); // used to suppress build warnings
       
  2683 	if (avail==CCnvCharacterSetConverter::EAvailable)
       
  2684 		aEncodingAndCharset.iConverter=&UnicodeUtils().CharacterSetConverter();
       
  2685 	else
       
  2686 		aEncodingAndCharset.iConverter=NULL;
       
  2687 	}
       
  2688 
       
  2689 EXPORT_C void CVersitParser::SetAutoDetect(TBool aOn,const CArrayFix<CCnvCharacterSetConverter::SCharacterSet>* aAutoDetectCharSets/*=NULL*/)
       
  2690 /** Turns auto detection of character sets on or off. 
       
  2691 
       
  2692 If a property does not specify a character set, then it is possible to 
       
  2693 guess its character set. This function turns this behaviour on or off. 
       
  2694 When the behaviour is on, it also lets the caller specify a restricted 
       
  2695 set of character sets to be considered.
       
  2696 
       
  2697 Auto-detection of character sets is used (if auto detection is on) 
       
  2698 when converting a property value to Unicode while internalising a stream.
       
  2699 
       
  2700 @param aOn If ETrue, auto detection is turned on; if EFalse (the default value), 
       
  2701 auto detection is turned off
       
  2702 @param aAutoDetectCharSets If specified then auto detection will only consider 
       
  2703 the character sets listed. If NULL, all available character sets are considered. */
       
  2704 	{
       
  2705 	if (aOn)
       
  2706 		{
       
  2707 		iAutoDetectCharSets=aAutoDetectCharSets;
       
  2708 		iFlags|=EUseAutoDetection;
       
  2709 		}
       
  2710 	else
       
  2711 		iFlags&=~EUseAutoDetection;
       
  2712 	}
       
  2713 
       
  2714 
       
  2715 EXPORT_C TInt CVersitParser::SaveBinaryValuesToFilesL(TInt aSizeThreshold,const TDesC& aPath)
       
  2716 /** Saves all binary property values larger than a specified threshold to files, 
       
  2717 and sets each property value to be a URI representing the file, rather than 
       
  2718 the binary data iself.
       
  2719 
       
  2720 The files are created in the folder identified by aPath, and are assigned 
       
  2721 unique filenames that consist of the property name and some random numbers.
       
  2722 
       
  2723 Each new URI property value is prefixed with file:// and contains the path 
       
  2724 and filename of the file created.
       
  2725 
       
  2726 If a vCard contains any agent property values and if they contain binary data 
       
  2727 whose size exceeds the threshold, these property values are replaced with 
       
  2728 URI property values.
       
  2729 
       
  2730 The function sets up its own file server session, which is needed to create 
       
  2731 the files. It leaves if there is a problem creating any of the files.
       
  2732 
       
  2733 @param aSizeThreshold The threshold number of bytes for the binary data, above 
       
  2734 which the binary data is stored in a file.
       
  2735 @param aPath The path identifying the location in which the files are created. 
       
  2736 This must not be greater than 240 characters long or the function leaves with 
       
  2737 KErrArgument. If it doesn't end in a slash, then one is appended.
       
  2738 @return The number of files created. */
       
  2739 	{
       
  2740 	
       
  2741 	TInt files = 0;
       
  2742 	// create a file server session
       
  2743 	RFs fs;	
       
  2744 	User::LeaveIfError(fs.Connect());
       
  2745 	CleanupClosePushL(fs);
       
  2746 	
       
  2747 	// parse through all the properties		
       
  2748 	const TInt countofproperties = iArrayOfProperties->Count();
       
  2749 	for (TInt i = 0; i < countofproperties; i++)
       
  2750 		{
       
  2751 			files += iArrayOfProperties->At(i)->SaveBinaryValuesToFilesL(aSizeThreshold,aPath,fs);
       
  2752 		}
       
  2753 	
       
  2754 	// this never gets executed for a vcard since there are no entities for a vcard.
       
  2755 	// But since this implementation is in the generic parser class, the code had been added.
       
  2756 	if(iArrayOfEntities)
       
  2757 		{
       
  2758 			const TInt countofentities = iArrayOfEntities->Count();
       
  2759 			for (TInt i = 0; i < countofentities; i++)
       
  2760 				{
       
  2761 					files += iArrayOfEntities->At(i)->SaveBinaryValuesToFilesL(aSizeThreshold,aPath,fs);
       
  2762 				}
       
  2763 		}
       
  2764 
       
  2765 	CleanupStack::PopAndDestroy(&fs);
       
  2766 			
       
  2767 	return files;
       
  2768 	}
       
  2769 
       
  2770 
       
  2771 EXPORT_C TInt CVersitParser::LoadBinaryValuesFromFilesL()
       
  2772 /** Loads all files represented by URI property values and sets the binary data 
       
  2773 contained in the files to be the property values instead of the URIs.
       
  2774 
       
  2775 For every property in the parser, if its value is a URI containing file:// 
       
  2776 followed by a path and filename, then the file is opened and the binary data 
       
  2777 it contains is read into a CParserPropertyValueBinary object. This replaces 
       
  2778 the URI as the property value. The function also operates on any agents in 
       
  2779 the vCard that contain URI property values.
       
  2780 
       
  2781 The function creates its own file server session, which is needed to open 
       
  2782 the files. It leaves if there is a problem opening any of the files.
       
  2783 
       
  2784 @return The number of files that were read. */
       
  2785 	{
       
  2786 	
       
  2787 	TInt files = 0;
       
  2788 	// create a file server session
       
  2789 	RFs fs;
       
  2790 	User::LeaveIfError(fs.Connect());
       
  2791 	CleanupClosePushL(fs);
       
  2792 		
       
  2793 	// parse through all the properties	
       
  2794 	const TInt countofproperties = iArrayOfProperties->Count();
       
  2795 	for (TInt i = 0; i < countofproperties; i++)
       
  2796 		{
       
  2797 			files += iArrayOfProperties->At(i)->LoadBinaryValuesFromFilesL(fs);
       
  2798 		}
       
  2799 
       
  2800     // this never gets executed for a vcard since there are no entities for a vcard.
       
  2801 	// But since this implementation is in the generic parser class, the code had been added.
       
  2802 	if(iArrayOfEntities)
       
  2803 		{
       
  2804 			const TInt countofentities = iArrayOfEntities->Count();
       
  2805 			for (TInt i = 0; i < countofentities; i++)
       
  2806 				{
       
  2807 					files += iArrayOfEntities->At(i)->LoadBinaryValuesFromFilesL(fs);
       
  2808 				}
       
  2809 		}
       
  2810 		
       
  2811 	CleanupStack::PopAndDestroy(&fs);
       
  2812 			
       
  2813 	return files;
       
  2814 	}
       
  2815 
       
  2816 
       
  2817 EXPORT_C TInt CVersitParser::SaveBinaryValuesToFilesL(TInt aSizeThreshold,const TDesC& aPath,RFs& aFileSession)
       
  2818 /** Saves all binary property values larger than a specified threshold to files, 
       
  2819 and sets each property value to be a URI representing the file rather than 
       
  2820 the binary data iself.
       
  2821 
       
  2822 The files are created in the folder identified by aPath, and are assigned 
       
  2823 unique filenames that consist of the property name and some random numbers.
       
  2824 
       
  2825 Each new URI property value is prefixed with file:// and contains the path 
       
  2826 and filename of the file created.
       
  2827 
       
  2828 If a vCard contains any agent property values and if they contain binary data 
       
  2829 whose size exceeds the threshold, these property values are replaced with 
       
  2830 URI property values.
       
  2831 
       
  2832 The function uses the file server session supplied, which is needed to create 
       
  2833 the files. It leaves if there is a problem creating any of the files.
       
  2834 
       
  2835 @param aSizeThreshold The threshold number of bytes for the binary data, above 
       
  2836 which the binary data is stored in a file.
       
  2837 @param aPath The path identifying the location in which the files are created. 
       
  2838 This must not be greater than 240 characters long or the function leaves with 
       
  2839 KErrArgument. If it doesn't end in a slash, then one is appended.
       
  2840 @param aFileSession The file server session used to create the files.
       
  2841 @return The number of files created. */
       
  2842 	{
       
  2843 	
       
  2844 	TInt files = 0;
       
  2845 	
       
  2846 	const TInt countofproperties = iArrayOfProperties->Count();
       
  2847 	for (TInt i = 0; i < countofproperties; i++)
       
  2848 		{
       
  2849 			files += iArrayOfProperties->At(i)->SaveBinaryValuesToFilesL(aSizeThreshold,aPath,aFileSession);
       
  2850 		}
       
  2851 	 // this never gets executed for a vcard since there are no entities for a vcard.
       
  2852 	// But since this implementation is in the generic parser class, the code had been added.
       
  2853 	if(iArrayOfEntities)
       
  2854 		{
       
  2855 			const TInt countofentities = iArrayOfEntities->Count();
       
  2856 			for (TInt i = 0; i < countofentities; i++)
       
  2857 				{
       
  2858 					files += iArrayOfEntities->At(i)->SaveBinaryValuesToFilesL(aSizeThreshold,aPath,aFileSession);
       
  2859 				}
       
  2860 		}
       
  2861 
       
  2862 	return files;
       
  2863 	}
       
  2864 
       
  2865 
       
  2866 EXPORT_C TInt CVersitParser::LoadBinaryValuesFromFilesL(RFs& aFileSession)
       
  2867 /** Loads all files represented by URI property values and sets the binary data 
       
  2868 contained in the files to be the property values instead of the URIs.
       
  2869 
       
  2870 For every property in the parser, if its value is a URI containing file:// 
       
  2871 followed by a path and filename, then the file is opened and the binary data 
       
  2872 it contains is read into a CParserPropertyValueBinary object. This replaces 
       
  2873 the URI as the property value. The function also operates on any agents in 
       
  2874 the vCard that contain URI property values.
       
  2875 
       
  2876 The function uses the file server session supplied, which is needed to open 
       
  2877 the files. It leaves if there is a problem opening any of the files.
       
  2878 
       
  2879 @param aFileSession The file server session used to open the files.
       
  2880 @return The number of files that were read. */
       
  2881 	{
       
  2882 	
       
  2883 	TInt files = 0;
       
  2884 			
       
  2885 	const TInt countofproperties = iArrayOfProperties->Count();
       
  2886 	for (TInt i = 0; i < countofproperties; i++)
       
  2887 		{
       
  2888 			files += iArrayOfProperties->At(i)->LoadBinaryValuesFromFilesL(aFileSession);
       
  2889 		}
       
  2890 	 // this never gets executed for a vcard since there are no entities for a vcard.
       
  2891 	// But since this implementation is in the generic parser class, the code had been added.
       
  2892 	if(iArrayOfEntities)
       
  2893 		{
       
  2894 			const TInt countofentities = iArrayOfEntities->Count();
       
  2895 			for (TInt i = 0; i < countofentities; i++)
       
  2896 				{
       
  2897 					files += iArrayOfEntities->At(i)->LoadBinaryValuesFromFilesL(aFileSession);
       
  2898 				}
       
  2899 		}
       
  2900 		
       
  2901 	return files;
       
  2902 	}
       
  2903 
       
  2904 CVersitTLSContainer *CVersitTLSContainer::NewLC(const TInt aSize)
       
  2905 	{
       
  2906 	CVersitTLSContainer *ret = new (ELeave) CVersitTLSContainer();
       
  2907 	CleanupStack::PushL( ret );
       
  2908 	ret->iShiftJisEscape = HBufC::NewL(aSize);
       
  2909 	return ret;
       
  2910 	}
       
  2911 
       
  2912 CVersitTLSContainer::~CVersitTLSContainer()
       
  2913 	{
       
  2914 	delete iShiftJisEscape;
       
  2915 	iShiftJisEscape = NULL;
       
  2916 	}
       
  2917 
       
  2918 EXPORT_C void CVersitParser::Reserved1()
       
  2919 	{}
       
  2920 
       
  2921 EXPORT_C void CVersitParser::Reserved2()
       
  2922 	{}
       
  2923 
       
  2924 
       
  2925 //
       
  2926 // MVersitObserver
       
  2927 //
       
  2928 
       
  2929 EXPORT_C void MVersitObserver::Reserved1()
       
  2930 	{}
       
  2931 
       
  2932 EXPORT_C void MVersitObserver::Reserved2()
       
  2933 	{}
       
  2934 
       
  2935 
       
  2936 //
       
  2937 // MVersitPlugIn
       
  2938 //
       
  2939 EXPORT_C void MVersitPlugIn::GetInterface(TUid /*aInterfaceUid*/, TAny*& /*aInterface*/)
       
  2940 	{}
       
  2941 
       
  2942 EXPORT_C void MVersitPlugIn::Reserved2()
       
  2943 /**
       
  2944 Reserved function.
       
  2945 
       
  2946 @internalComponent
       
  2947 */
       
  2948 	{}
       
  2949 
       
  2950 
       
  2951 //
       
  2952 // Dll entry point
       
  2953 //
       
  2954 
       
  2955 EXPORT_C void Panic(TVersitParserPanic aPanic)
       
  2956 	{
       
  2957 	_LIT(KCategory,"Versit-Parser");
       
  2958 	User::Panic(KCategory,aPanic);
       
  2959 	}
       
  2960 
       
  2961 //
       
  2962 // class CLineReaderExtension
       
  2963 //
       
  2964 CLineReaderExtension::CLineReaderExtension()
       
  2965 	{}
       
  2966 	
       
  2967 CLineReaderExtension::~CLineReaderExtension()
       
  2968 	{
       
  2969 	delete iLineBase64Value;
       
  2970 	}
       
  2971 	
       
  2972 void CLineReaderExtension::DeleteBase64ValueBuffer()
       
  2973 	{
       
  2974 	delete iLineBase64Value;
       
  2975 	iLineBase64Value = NULL;
       
  2976 	}
       
  2977 
       
  2978 HBufC8* CLineReaderExtension::CreateBase64ValueBufferL()
       
  2979 	{
       
  2980 	if (!iLineBase64Value)
       
  2981 		{
       
  2982 		iLineBase64Value = HBufC8::NewL(CLineReader::EInitialLineSize);
       
  2983 		}
       
  2984 	return iLineBase64Value;
       
  2985 	}
       
  2986 	
       
  2987 HBufC8* CLineReaderExtension::Base64ValueBuffer()
       
  2988 	{
       
  2989 	return iLineBase64Value;
       
  2990 	}
       
  2991 	
       
  2992 CLineReaderExtension* CLineReaderExtension::NewL()
       
  2993 	{
       
  2994 	CLineReaderExtension* self=new(ELeave) CLineReaderExtension();
       
  2995 	return self;
       
  2996 	}
       
  2997