libraries/iosrv/client/pod_lexer.cpp
changeset 0 7f656887cf89
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libraries/iosrv/client/pod_lexer.cpp	Wed Jun 23 15:52:26 2010 +0100
@@ -0,0 +1,229 @@
+// pod_lexer.cpp
+// 
+// Copyright (c) 2009 - 2010 Accenture. All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of the "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:
+// Accenture - Initial contribution
+//
+
+#include "pod_lexer.h"
+
+
+TPodLexer::TPodLexer(const TDesC& aString)
+	: iLex(aString), iAttributes(0), iAttributeStackIndex(0)
+	{
+	}
+
+void TPodLexer::NextTokenL(TPtrC& aToken, TTokenType& aTokenType, TUint& aAttributes, TBool& aEop, TBool& aEos)
+	{
+	aTokenType = ETextBlock;
+	iScratch.Zero();
+	TBool finished(EFalse);
+	TBool setAttributes(ETrue);
+	while (!iLex.Eos() && !finished && (iScratch.Length() < (iScratch.MaxLength() - 1)))
+		{
+		iLex.Mark();
+		TUint16 sequenceIdentifier;
+		if ((iAttributeStackIndex > 0) && (iLex.Peek() == '>'))
+			{
+			if (iScratch.Length() > 0)
+				{
+				aAttributes = iAttributes;
+				setAttributes = EFalse;
+				finished = ETrue;
+				}
+			else
+				{
+				iLex.Get();
+				aTokenType = EAttributePop;
+				aAttributes = PopAttribute();
+				setAttributes = EFalse;
+				finished = ETrue;
+				}
+			}
+		else if (IsInteriorSequenceStart(sequenceIdentifier))
+			{
+			if (iScratch.Length() > 0)
+				{
+				iLex.UnGetToMark();
+				finished = ETrue;
+				}
+			else
+				{
+				switch (sequenceIdentifier)
+					{
+					case 'B':
+						PushAttribute(EBold);
+						aAttributes = EBold;
+						setAttributes = EFalse;
+						aTokenType = EAttributePush;
+						finished = ETrue;
+						break;
+					case 'C':
+						PushAttribute(ECode);
+						aAttributes = ECode;
+						setAttributes = EFalse;
+						aTokenType = EAttributePush;
+						finished = ETrue;
+						break;
+					case 'E':
+						if (iLex.Remainder().Length() >= 3)
+							{
+							if (iLex.Remainder().Left(3) == _L("gt>"))
+								{
+								iLex.Inc(3);
+								iScratch.Append('>');
+								}
+							else if (iLex.Remainder().Left(3) == _L("lt>"))
+								{
+								iLex.Inc(3);
+								iScratch.Append('<');
+								}
+							else
+								{
+								TUint num;
+								TInt err = iLex.Val(num);
+								if (err == KErrNone)
+									{
+									iScratch.Append(num);
+									}
+								else
+									{
+									User::Leave(err);
+									}
+								}
+							}
+						break;
+					case 'F':
+						PushAttribute(EFileName);
+						aAttributes = EFileName;
+						setAttributes = EFalse;
+						aTokenType = EAttributePush;
+						finished = ETrue;
+						break;
+					case 'I':
+						PushAttribute(EItalic);
+						aAttributes = EItalic;
+						setAttributes = EFalse;
+						aTokenType = EAttributePush;
+						finished = ETrue;
+						break;
+					case 'L':
+						iLex.Mark();
+						SkipToClosingAngleBracket();
+						iLex.UnGet();
+						iScratch.Copy(iLex.MarkedToken());
+						iLex.Get();
+						aTokenType = ELink;
+						finished = ETrue;
+						break;
+					case 'S':
+					case 'X':
+						PushAttribute(ENull);
+						aAttributes = ENull;
+						setAttributes = EFalse;
+						aTokenType = EAttributePush;
+						finished = ETrue;
+						break;
+					case 'Z':
+						if (iLex.Peek() == '>')
+							{
+							iLex.Inc();
+							iLex.Mark();
+							}
+						else
+							{
+							User::Leave(KErrArgument);
+							}
+						break;
+					}
+				}
+			}
+		else
+			{
+			iScratch.Append(iLex.Get());
+			}
+		}
+
+	if (setAttributes)
+		{
+		aAttributes = iAttributes;
+		}
+	aToken.Set(iScratch);
+	aEop = Eop();
+	aEos = iLex.Eos();
+	}
+
+TInt TPodLexer::SkipToClosingAngleBracket()
+	{
+	TInt numSkippedChars = 0;
+	while (!iLex.Eos())
+		{
+		TUint16 sequenceIdentifier;
+		if (IsInteriorSequenceStart(sequenceIdentifier))
+			{
+			numSkippedChars = SkipToClosingAngleBracket();
+			}
+		else if (iLex.Get() == '>')
+			{
+			break;
+			}
+		else
+			{
+			++numSkippedChars;
+			}
+		}
+	return numSkippedChars;
+	}
+
+TBool TPodLexer::Eop()
+	{
+	_LIT(KParagraphEnd, "\r\n\r\n");
+	return ((iLex.Remainder().Length() >= 4) && (iLex.Remainder().Left(4) == KParagraphEnd));
+	}
+
+TBool TPodLexer::IsInteriorSequenceStart(TUint16& aSequenceIdentifier)
+	{
+	if (iLex.Remainder().Length() >= 2)
+		{
+		TUint16 first = iLex.Get();
+		TUint16 second = iLex.Get();
+		if (second == '<')
+			{
+			switch (first)
+				{
+				case 'B':
+				case 'C':
+				case 'E':
+				case 'F':
+				case 'I':
+				case 'L':
+				case 'S':
+				case 'X':
+				case 'Z':
+					aSequenceIdentifier = first;
+					return ETrue;
+				}
+			}
+		iLex.Inc(-2);
+		}
+	return EFalse;
+	}
+
+void TPodLexer::PushAttribute(TAttribute aAttribute)
+	{
+	iAttributes |= aAttribute;
+	iAttributeStack[iAttributeStackIndex++] = aAttribute;
+	}
+
+TPodLexer::TAttribute TPodLexer::PopAttribute()
+	{
+	TAttribute poppedAttribute = iAttributeStack[--iAttributeStackIndex];
+	iAttributes &= ~poppedAttribute;
+	return poppedAttribute;
+	}
+