omads/omadsextensions/dsutils/nsmlfolderutils/src/nsmlxmlparser.cpp
branchRCL_3
changeset 25 4f0867e42d62
parent 1 95fdac6ccb5c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/omads/omadsextensions/dsutils/nsmlfolderutils/src/nsmlxmlparser.cpp	Wed Sep 01 12:30:02 2010 +0100
@@ -0,0 +1,798 @@
+/*
+* Copyright (c) 2004 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Sources
+*
+*/
+
+
+// 1.2 Changes: nsmlxmlparser module added
+
+// ------------------------------------------------------------------------------------------------
+// Includes
+// ------------------------------------------------------------------------------------------------
+#include <s32buf.h>
+#include <s32file.h>
+#include <nsmlfolderparser.h>
+#include "nsmlparserconstants.h"
+
+
+// ------------------------------------------------------------------------------------------------
+// 
+// CNSmlXmlParser methods
+// 
+// ------------------------------------------------------------------------------------------------
+
+// ------------------------------------------------------------------------------------------------
+// Constructor
+// ------------------------------------------------------------------------------------------------
+EXPORT_C CNSmlXmlParser::CNSmlXmlParser()
+	{
+	}
+
+
+// ------------------------------------------------------------------------------------------------
+// Destructor.
+// ------------------------------------------------------------------------------------------------
+EXPORT_C CNSmlXmlParser::~CNSmlXmlParser()
+	{
+	if( iBuffer ) delete iBuffer;
+	if ( iCompleteBuffer ) delete iCompleteBuffer;
+	}
+
+
+// ------------------------------------------------------------------------------------------------
+// Parses the given string for cdata areas and entitys. If a cdata area is 
+// found, the data in it is skipped over. The entities outside cdata are converted 
+// into characters they represent (but only if cdata is found).
+// Note: This method is intended for processing the CDATA used right after <Data>. 
+// I.e. this method removes the cdata-elements used for wrapping the whole xml data 
+// and processes the string so that the inner cdatas used in the xml become valid.
+// THIS METHOD SHOULD BE CALLED RIGHT IN THE BEGINNING OF PARSING IF <Data>-BLOCK 
+// IS WRAPPED WITHIN CDATA.
+// ------------------------------------------------------------------------------------------------
+void CNSmlXmlParser::PreProcessL( HBufC8* aXml ) const
+	{
+	// take a modifiable pointer
+	TPtr8 xml = aXml->Des();
+
+	// the string used for searching and moving in the string
+	TPtrC8 searchString(*aXml);
+
+	// the current position in the original string
+	TInt searchStartPos = 0;
+
+	// find the first cdata start
+	TInt cdataStartPos = searchString.Find(KCDataStart);
+	
+	// If CDATA is not found from beginning then data is not inside CDATA and then
+	// preprocessing is not needed
+	if ( cdataStartPos != 0 )
+	    {
+	    return;
+	    }
+
+	TInt cdataEndPos = KErrNotFound;
+
+	// while cdata is found
+	while ( cdataStartPos != KErrNotFound )
+		{
+		cdataStartPos += searchStartPos;
+
+		// find an end of cdata before entities are converted
+		cdataEndPos = searchString.Find(KCDataEnd);
+
+		// convert entities between search start and cdata start
+		TInt entityChange = EntitiesToCharactersL(aXml, searchStartPos, cdataStartPos);
+		xml.Set(aXml->Des());
+		cdataStartPos += entityChange;
+
+		if ( cdataEndPos != KErrNotFound )
+			{
+			cdataEndPos += entityChange;
+			cdataEndPos += searchStartPos;
+
+			// if the end is before start -> error
+			if (cdataEndPos < cdataStartPos)
+				User::Leave( EInvalidCDataStructure );
+				
+			// remove cdata end
+			xml.Delete(cdataEndPos, KCDataEnd().Length());
+			// remove cdata start
+			xml.Delete(cdataStartPos, KCDataStart().Length());
+
+			searchStartPos = cdataEndPos - KCDataStart().Length();
+			searchString.Set( xml.Right(xml.Length() - searchStartPos) );
+			}
+		else 
+			{
+			// the end of cdata was not found or cdata end was before start -> error
+			User::Leave( EInvalidCDataStructure );
+			}
+
+		// find a new cdata start that is after the found end
+		cdataStartPos = searchString.Find(KCDataStart);
+
+		}
+
+	}
+
+
+// ------------------------------------------------------------------------------------------------
+// Return the TNSmlBoolean-value's string-representation.
+// ------------------------------------------------------------------------------------------------
+TPtrC8 CNSmlXmlParser::BooleanToString( const TNSmlBoolean aValue ) const
+	{
+	TPtrC8 str;
+	switch(aValue)
+		{
+		case EBooleanTrue:
+			{
+			str.Set(KStringTrue);
+			break;
+			}
+		case EBooleanFalse:
+			{
+			str.Set(KStringFalse);
+			break;
+			}
+		default:
+			{
+			str.Set(KStringEmpty);
+			}
+		}
+
+	return str;
+	}
+
+
+// ------------------------------------------------------------------------------------------------
+// Returns the TTime-value's string-representation.
+// ------------------------------------------------------------------------------------------------
+TBuf8<KDateTimeLength> CNSmlXmlParser::DateTimeToStringL( const TTime& aValue ) const
+	{
+	TBuf<KDateTimeLength> str;
+	
+	// aValue is not changed but Z character is added to the end of string.
+	// Messaging uses UTC times and that is reason why time is not changed.
+	aValue.FormatL( str, _L("%F%Y%M%DT%H%T%SZ") );
+
+	// from 16-bit to 8-bit
+	TBuf8<KDateTimeLength> dt;
+	dt.Copy(str);
+
+	return dt;
+	}
+
+
+// ------------------------------------------------------------------------------------------------
+// Returns the integer value's string-representation.
+// ------------------------------------------------------------------------------------------------
+TBuf8<KIntegerMaxLength> CNSmlXmlParser::IntegerToString( const TInt aValue ) const
+	{
+	TBuf8<KIntegerMaxLength> str;
+	str.AppendNum(aValue);
+	return str;
+	}
+
+
+// ------------------------------------------------------------------------------------------------
+// Returns the boolean representation of the string or leaves if error (EInvalidBooleanValue).
+// ------------------------------------------------------------------------------------------------
+TNSmlBoolean CNSmlXmlParser::StringToBooleanL( const TPtrC8& aValue ) const
+	{
+	if( aValue == KStringTrue )
+		return EBooleanTrue;
+	else if( aValue == KStringFalse || aValue == KStringEmpty )
+		return EBooleanFalse;
+	else
+		User::Leave(EInvalidBooleanValue);
+
+	return EBooleanMissing;
+	}
+
+	
+// ------------------------------------------------------------------------------------------------
+// Returns the integer representation of the string or leaves if error (EInvalidIntegerValue).
+// ------------------------------------------------------------------------------------------------
+TInt CNSmlXmlParser::StringToIntegerL( const TPtrC8& aValue ) const
+	{
+	if (aValue.Length() <= 0)
+		return 0;
+
+	// convert the data to an integer
+	TLex8 lex(aValue);
+	TUint uValue = 0;
+	TBool isNegative = EFalse;
+
+	TChar c = lex.Peek();
+
+	// check for a minus or plus sign
+	if ( c == '-' )
+		{
+		isNegative = ETrue;
+		lex.Inc();
+		}
+	else if ( c == '+' )
+		{
+		lex.Inc();
+		}
+
+	TRadix radix = EDecimal;
+	c = lex.Peek();
+
+	if (c == '0') // octal or hex
+		{
+		lex.Get();
+		c = lex.Get();
+		if ( c == 'x' || c == 'X' )
+			{
+			radix = EHex;
+			}
+		else
+			{
+			radix = EOctal;
+			lex.UnGet(); // back up
+			}
+		}
+
+	TInt err = lex.Val(uValue, radix);
+	if ( err != KErrNone )
+		User::Leave(EInvalidIntegerValue);
+
+	TInt value = uValue;
+
+	return isNegative ? value*(-1) : value;
+	}
+
+
+// ------------------------------------------------------------------------------------------------
+// Returns the TTime representation of the string or leaves if error (EInvalidDatetimeValue).
+// UTC times are not supported, i.e. datetimes that have Z-ending are treated as 
+// local times.
+// ------------------------------------------------------------------------------------------------
+TTime CNSmlXmlParser::StringToTTimeL( TPtrC8& aValue ) const
+	{
+	// check that there is data
+	if (aValue.Length() <= 0)
+		User::Leave( EInvalidDatetimeValue );
+
+	// format the data into a TTime
+
+	if (aValue[aValue.Length()-1] == 'Z')
+		{
+		// The datetime is in UTC, which is not supported
+		// no correction done, treat as local time
+		aValue.Set( aValue.Left( aValue.Length()-1 ) );
+		}
+
+	TDateTime datetime(0,(TMonth)0,0,0,0,0,0);
+
+	// read datetime and check errors
+
+	TInt error = KErrNone;
+
+	// read year
+	TPtrC8 str = aValue.Left(4);
+	TLex8 lex(str);
+	TInt value;
+	error = lex.Val(value);
+	CheckDatetimeErrorL( error );
+	error  = datetime.SetYear(value);
+	CheckDatetimeErrorL( error );
+
+	// read month
+	str.Set(aValue.Mid(4, 2));
+	lex.Assign(str);
+	error = lex.Val(value);
+	CheckDatetimeErrorL( error );
+	--value;
+	error = datetime.SetMonth((TMonth)value);
+	CheckDatetimeErrorL( error );
+
+	// read day
+	str.Set(aValue.Mid(6, 2));
+	lex.Assign(str);
+	error = lex.Val(value);
+	CheckDatetimeErrorL( error );
+	--value;
+	error = datetime.SetDay(value);
+	CheckDatetimeErrorL( error );
+
+	// Skip character 'T' and read hour
+	str.Set(aValue.Mid(9, 2));
+	lex.Assign(str);
+	error = lex.Val(value);
+	CheckDatetimeErrorL( error );
+	error = datetime.SetHour(value);
+	CheckDatetimeErrorL( error );
+
+	// minutes
+	str.Set(aValue.Mid(11, 2));
+	lex.Assign(str);
+	error = lex.Val(value);
+	CheckDatetimeErrorL( error );
+	error = datetime.SetMinute(value);
+	CheckDatetimeErrorL( error );
+
+	// seconds
+	str.Set(aValue.Mid(13, 2));
+	lex.Assign(str);
+	error = lex.Val(value);
+	CheckDatetimeErrorL( error );
+	error = datetime.SetSecond(value);
+	CheckDatetimeErrorL( error );
+
+	return TTime(datetime);
+	}
+
+
+// ------------------------------------------------------------------------------------------------
+// Adds start element, the value and end element to aPtr.
+// ------------------------------------------------------------------------------------------------
+void CNSmlXmlParser::AppendElement( TPtr8& aPtr, const TDesC8& aElementName, const TDesC8& aValue ) const
+	{
+	// start element
+	aPtr.Append(KElementStart);
+	aPtr.Append(aElementName);
+	aPtr.Append(KElementEnd);
+
+	// value
+	aPtr.Append(aValue);
+
+	// end element
+	aPtr.Append(KElementStart);
+	aPtr.Append(KCharacterSlash);
+	aPtr.Append(aElementName);
+	aPtr.Append(KElementEnd);
+	}
+
+
+// ------------------------------------------------------------------------------------------------
+// Forms an element using the given element name and appends it to the given string.
+// ------------------------------------------------------------------------------------------------
+void CNSmlXmlParser::AppendElement( TPtr8& aPtr, const TDesC8& aElementName ) const
+	{
+	aPtr.Append(KElementStart);
+	aPtr.Append(aElementName);
+	aPtr.Append(KElementEnd);
+	}
+
+
+// ------------------------------------------------------------------------------------------------
+// Forms an end element using the given element name and appends it to the given string.
+// ------------------------------------------------------------------------------------------------
+void CNSmlXmlParser::AppendEndElement( TPtr8& aPtr, const TDesC8& aElementName ) const
+	{
+	aPtr.Append(KElementStart);
+	aPtr.Append(KCharacterSlash);
+	aPtr.Append(aElementName);
+	aPtr.Append(KElementEnd);
+	}
+
+
+// ------------------------------------------------------------------------------------------------
+// Returns the total length of start and end tag.
+// ------------------------------------------------------------------------------------------------
+TInt CNSmlXmlParser::SizeOfElements( const TDesC8& aElementName ) const
+	{
+	TInt size = 0;
+
+	// start element plus end element ( 1 = length of '/' char )
+	size += 2*aElementName.Length() + 1;
+	size += 2*KElementStartEndWidth; // '<' and '>'
+
+	return size;
+	}
+
+
+// ------------------------------------------------------------------------------------------------
+// Returns the length of the given boolean element and it's data if it was a string.
+// ------------------------------------------------------------------------------------------------
+TInt CNSmlXmlParser::SizeOfBoolean( const TNSmlBoolean aValue, const TDesC8& aElementName ) const
+	{
+	TInt size = 0;
+	size += SizeOfElements( aElementName );
+	switch ( aValue )
+		{
+		case EBooleanTrue:
+			return size+4; // "true"
+		case EBooleanFalse:
+			return size+5; // "false"
+		default:
+			return 0;
+		}
+	}
+
+
+// ------------------------------------------------------------------------------------------------
+// Returns the length of the given datetime element and it's data if it was a string.
+// ------------------------------------------------------------------------------------------------
+TInt CNSmlXmlParser::SizeOfDatetime( const TDesC8& aElementName ) const
+	{
+	TInt size = SizeOfElements( aElementName ) + KDateTimeLength;
+	return size;
+	}
+
+
+// ------------------------------------------------------------------------------------------------
+// Returns the maximum length of the given integer element and it's data if it was a string.
+// ------------------------------------------------------------------------------------------------
+TInt CNSmlXmlParser::SizeOfInteger( const TDesC8& aElementName ) const
+	{
+	TInt size = SizeOfElements( aElementName ) + KIntegerMaxLength;
+	return size;
+	}
+
+
+// ------------------------------------------------------------------------------------------------
+// Returns the length of the given string element and it's data if it was a string.
+// ------------------------------------------------------------------------------------------------
+TInt CNSmlXmlParser::SizeOfString( const HBufC8* aValue, const TDesC8& aElementName ) const
+	{
+	TInt size = SizeOfElements( aElementName ) + aValue->Length();
+	return size;
+	}
+
+
+// ------------------------------------------------------------------------------------------------
+// Finds entities and replaces them with the characters they represent. Returns 
+// an integer indicating the size change in aXml.
+// ------------------------------------------------------------------------------------------------
+TInt CNSmlXmlParser::EntitiesToCharactersL( HBufC8*& aXml, TInt aStartPos, TInt aEndPos ) const
+	{
+	TInt change = 0;
+	TInt changeSum = 0;
+
+	change = ReplaceL(aXml, KEntityLT, KLessThan, aStartPos, aEndPos);
+	changeSum += change;
+	aEndPos += change;
+
+	change = ReplaceL(aXml, KEntityGT, KGreaterThan, aStartPos, aEndPos);
+	changeSum += change;
+	aEndPos += change;
+
+	change = ReplaceL(aXml, KEntityAMP, KAmpersand, aStartPos, aEndPos);
+	changeSum += change;
+	aEndPos += change;
+
+	change = ReplaceL(aXml, KEntityAPOS, KApostrophe, aStartPos, aEndPos);
+	changeSum += change;
+	aEndPos += change;
+
+	change = ReplaceL(aXml, KEntityQUOT, KQuotation, aStartPos, aEndPos);
+	changeSum += change;
+
+	return changeSum;
+	}
+
+
+// ------------------------------------------------------------------------------------------------
+// Finds special characters and replaces them with corresponding entities. Returns 
+// an integer indicating the size change in aXml.
+// ------------------------------------------------------------------------------------------------
+TInt CNSmlXmlParser::CharactersToEntitiesL( HBufC8*& aXml, TInt aStartPos, TInt aEndPos ) const
+	{
+	TInt change = 0;
+	TInt changeSum = 0;
+
+	// Note: this replace has to be the first one, since it changes 
+	// &-characters to &amp;s and all the other replaces generate 
+	// &-characters as they are entities.
+	change = ReplaceL(aXml, KAmpersand, KEntityAMP, aStartPos, aEndPos);
+	changeSum += change;
+	aEndPos += change;
+
+	change = ReplaceL(aXml, KLessThan, KEntityLT, aStartPos, aEndPos);
+	changeSum += change;
+	aEndPos += change;
+
+	change = ReplaceL(aXml, KGreaterThan, KEntityGT, aStartPos, aEndPos);
+	changeSum += change;
+	aEndPos += change;
+
+	change = ReplaceL(aXml, KApostrophe, KEntityAPOS, aStartPos, aEndPos);
+	changeSum += change;
+	aEndPos += change;
+
+	change = ReplaceL(aXml, KQuotation, KEntityQUOT, aStartPos, aEndPos);
+	changeSum += change;
+
+	return changeSum;
+	}
+
+
+// ------------------------------------------------------------------------------------------------
+// Returns ETrue if all the characters in the given text are whitespace 
+// characters, else EFalse.
+// ------------------------------------------------------------------------------------------------
+TBool CNSmlXmlParser::IsWhitespace( const TDesC8& aText ) const
+	{
+	// loop the string character by character
+	TText c;
+	for ( TInt i=0; i < aText.Length(); ++i )
+		{
+		c = aText[i];
+		switch( c )
+			{
+			case KWhitespaceEmpty:
+				break;
+			case KWhitespaceLineFeed:
+				break;
+			case KWhitespaceNewLine:
+				break;
+			case KWhitespaceTabular:
+				break;
+			case KWhitespaceLineFeedNewLine:
+				break;
+			default:
+				return EFalse;
+			}
+		}
+
+	return ETrue;
+	}
+
+
+// ------------------------------------------------------------------------------------------------
+// Leaves with EInvalidXmlError if the given string is not whitespace.
+// ------------------------------------------------------------------------------------------------
+void CNSmlXmlParser::LeaveIfNotWhiteSpaceL( const TDesC8& aText ) const
+	{
+	if ( !IsWhitespace( aText ) )
+		{
+		User::Leave( EInvalidXmlError );
+		}
+	}
+
+
+// ------------------------------------------------------------------------------------------------
+// Maps the given value to TNSmlParserGeneratorError.
+// ------------------------------------------------------------------------------------------------
+TNSmlParserGeneratorError CNSmlXmlParser::CheckError( const TInt error ) const
+	{
+	if ( error == KErrNoMemory )
+		{
+		return EOutOfMemory;
+		}
+	else if ( error < KErrNone )
+		{
+		// some system wide error, should not occur
+		return EUnknownError;
+		}
+	else if ( error != EErrorNone )
+		{
+		return (TNSmlParserGeneratorError)error;
+		}
+
+	return EErrorNone;
+	}
+
+
+// ------------------------------------------------------------------------------------------------
+// Parses the given xml and calls NextDataL and NextElementL methods when finds 
+// data or element. 
+// ------------------------------------------------------------------------------------------------
+void CNSmlXmlParser::ParseL( TPtrC8& aXml )
+	{
+
+	ResetBufferL(iBuffer);
+	ResetBufferL(iCompleteBuffer);
+
+	// boolean indicating if reading element name (true) or insides of 
+	// an element (false)
+	TBool readingElementName = EFalse;
+	TText c;
+
+	for( TInt i=0; i < aXml.Length(); ++i )
+		{
+		c = aXml[i];
+		switch(c)
+			{
+			case KElementStart:
+				// if currently reading element, error
+				if( readingElementName )
+					{
+					User::Leave(EInvalidXmlError);
+					}
+
+				if( aXml.Length()-i >= KCDataStart().Length() &&
+					!aXml.Mid(i, KCDataStart().Length()).Compare(KCDataStart()) )
+					{ // cdata
+					aXml.Set( aXml.Right( aXml.Length() - i ) );
+					TInt endPos = aXml.Find(KCDataEnd);
+
+					TPtrC8 cdata = _L8("");
+					if ( endPos == KErrNotFound )
+						{
+						User::Leave(EInvalidCDataStructure);
+						}
+
+					cdata.Set( aXml.Mid( KCDataStart().Length(), endPos - KCDataStart().Length() ) );
+					aXml.Set( aXml.Right( aXml.Length() - endPos - KCDataEnd().Length() ) );
+
+					i = -1;
+
+					// add current buffer to complete buffer
+					EntitiesToCharactersL( iBuffer, 0, iBuffer->Length() );
+					AddToCompleteL(*iBuffer);
+					ResetBufferL(iBuffer);
+					AddToCompleteL(cdata);
+					}
+#ifndef __NO_XML_COMMENTS_
+				else if( aXml.Length()-i >= KCommentStart().Length() &&
+					!aXml.Mid(i, KCommentStart().Length()).Compare(KCommentStart()) )
+					{ // comment
+					aXml.Set( aXml.Right( aXml.Length() - i ) );
+					TInt endPos = aXml.Find(KCommentEnd);
+
+					if ( endPos != KErrNotFound )
+						{
+						aXml.Set( aXml.Right( aXml.Length() - endPos - KCommentEnd().Length() ) );
+						}
+					else
+						{
+						User::Leave(EInvalidXmlError);
+						}
+
+					i = -1;
+					}
+#endif
+				else 
+					{
+					// send the buffer
+					EntitiesToCharactersL( iBuffer, 0, iBuffer->Length() );
+					AddToCompleteL(*iBuffer);
+					NextDataL(*iCompleteBuffer);
+					ResetBufferL(iBuffer);
+					ResetBufferL(iCompleteBuffer);
+					readingElementName = ETrue;
+					}
+
+				break;
+			case KElementEnd:
+				// stop reading element name
+				if( !readingElementName )
+					{
+					User::Leave(EInvalidXmlError);
+					}
+				else 
+					{
+					NextElementL(*iBuffer);
+					ResetBufferL(iBuffer);
+					readingElementName = EFalse;
+					}
+				break;
+			default:
+				// add char to buffer
+				AddToBufferL(c, iBuffer);
+				break;
+			}
+		}
+
+	EntitiesToCharactersL( iBuffer, 0, iBuffer->Length() );
+	AddToCompleteL(*iBuffer);
+	NextDataL(*iCompleteBuffer);
+	}
+
+
+// ------------------------------------------------------------------------------------------------
+// Adds the given string to iCompleteBuffer
+// ------------------------------------------------------------------------------------------------
+void CNSmlXmlParser::AddToCompleteL( const TPtrC8 aStr )
+	{
+	if(!iCompleteBuffer)
+		{
+		iCompleteBuffer = HBufC8::NewL(aStr.Length());
+		}
+
+	TPtr8 ptr = iCompleteBuffer->Des();
+	if( ptr.MaxLength() < iCompleteBuffer->Length()+aStr.Length() )
+		{
+		iCompleteBuffer = iCompleteBuffer->ReAllocL(iCompleteBuffer->Length()+aStr.Length());
+		ptr.Set(iCompleteBuffer->Des());
+		}
+
+	ptr.Append(aStr);
+	}
+
+
+// ------------------------------------------------------------------------------------------------
+// Deletes the given buffer and initializes it again to length 10
+// ------------------------------------------------------------------------------------------------
+void CNSmlXmlParser::ResetBufferL( HBufC8*& aBuf ) const
+	{
+	if( aBuf )
+		{
+		delete aBuf;
+		aBuf = NULL;
+		}
+
+	aBuf = HBufC8::NewL(10);
+	}
+
+
+// ------------------------------------------------------------------------------------------------
+// Adds the given char to given buffer
+// ------------------------------------------------------------------------------------------------
+void CNSmlXmlParser::AddToBufferL( const TText c, HBufC8*& aBuf ) const
+	{
+	TPtr8 ptr = aBuf->Des();
+	if( ptr.MaxLength() == aBuf->Length()+1 )
+		{
+		aBuf = aBuf->ReAllocL(aBuf->Length()+10);
+		ptr.Set(aBuf->Des());
+		}
+
+	TChar str = c;
+	ptr.Append(str);
+	}
+
+
+
+// ------------------------------------------------------------------------------------------------
+// Replaces all occurances of aTarget in aText with aItem. Returns an integer indicating 
+// the size change in aText. aStartPos and aEndPos indicate the start and end positions 
+// of aText to be parsed (if whole string should be parsed, use 0 and aText.Length()).
+// ------------------------------------------------------------------------------------------------
+TInt CNSmlXmlParser::ReplaceL( HBufC8*& aText, const TDesC8& aTarget, const TDesC8& aItem, TInt aStartPos, TInt aEndPos ) const
+	{
+	TInt change = 0;
+	TInt searchPos = aStartPos;
+	TPtrC8 text = aText->Mid(aStartPos, aEndPos-aStartPos);
+	TInt pos = text.Find(aTarget);
+
+	while ( pos != KErrNotFound )
+		{
+		pos += searchPos;
+
+		TInt currentChange = aItem.Length() - aTarget.Length();
+		change += currentChange;
+		aEndPos += currentChange;
+		searchPos = pos;
+
+		if ( currentChange > 0 )
+			{
+			searchPos += currentChange;
+
+			// check that aText is large enough
+			if ( aText->Des().MaxLength() < aText->Length()+currentChange )
+				{
+				aText = aText->ReAllocL(aText->Length()+currentChange);
+				}
+			}
+
+		// the actual replace
+		aText->Des().Replace(pos, aTarget.Length(), aItem);
+
+		text.Set( aText->Mid(searchPos, aEndPos-searchPos) );
+		pos = text.Find(aTarget);
+		}
+
+	return change;
+	}
+
+
+// ------------------------------------------------------------------------------------------------
+// 
+// ------------------------------------------------------------------------------------------------
+void CNSmlXmlParser::CheckDatetimeErrorL( const TInt error ) const
+	{
+	if ( error != KErrNone )
+		{
+		User::Leave( EInvalidDatetimeValue );
+		}
+	}
+
+//End of File
+