--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/connectivitymodules/SeCon/services/csc/src/capparser.cpp Fri Mar 19 09:27:26 2010 +0200
@@ -0,0 +1,766 @@
+/*
+* Copyright (c) 2005-2008 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: CapParser implementation
+*
+*/
+
+
+// INCLUDE FILES
+
+#include "capparser.h"
+#include "caputils.h"
+
+const char KFind1 = '&';
+const char KFind2 = '<';
+const char KFind3 = '>';
+const char KFind4 = '"';
+const char KFind5 = '\'';
+
+_LIT( KReplace1, "&" );
+_LIT( KReplace2, "<" );
+_LIT( KReplace3, ">" );
+_LIT( KReplace4, """ );
+_LIT( KReplace5, "'" );
+
+// ============================= MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CapParser::GetTagL(TDes& aText, TInt aId)
+// Returns capability element tag (eg. "Memory")
+// -----------------------------------------------------------------------------
+//
+void CapParser::GetTagL(TDes& aText, TInt aId)
+ {
+ aText=KNullDesC;
+
+ TInt count=NUMXMLTOKENS;
+ for (TInt i=0; i<count; i++)
+ {
+ TXmlToken t=KXmlTokens[i];
+ if (t.id==aId)
+ {
+ aText=t.tag;
+ return;
+ }
+ }
+ User::Leave(KErrNotFound);
+ }
+
+// -----------------------------------------------------------------------------
+// CapParser::ElementId(const TDesC& aText)
+// Returns capability element id (eg. EMemory).
+// -----------------------------------------------------------------------------
+//
+TInt CapParser::ElementId(const TDesC& aText)
+ {
+ TBuf<KTagSize>buf;
+ TInt count=NUMXMLTOKENS;
+ for (TInt i=0; i<count; i++)
+ {
+ TXmlToken t=KXmlTokens[i];
+ buf=t.tag;
+ if (buf.Compare(aText)==0)
+ {
+ return t.id;
+ }
+ }
+ return KErrNotFound;
+ }
+
+// -----------------------------------------------------------------------------
+// CapParser::ParseElement(const TDesC& aText, TInt& aId, TInt& aType)
+// Parses element's id and type (eg. "<Memory>" -> EMemory, EElementBegin)
+// -----------------------------------------------------------------------------
+//
+void CapParser::ParseElement(const TDesC& aText, TInt& aId, TInt& aType)
+ {
+ TXmlParser parse;
+ aId=KErrNotFound;
+
+ parse.Set(aText);
+ aType=parse.Type();
+ if (aType==TXmlParser::EElementUnknown)
+ {
+ return;
+ }
+
+ TPtrC ptr=parse.Tag();
+ aId=ElementId(ptr);
+ }
+
+// -----------------------------------------------------------------------------
+// CapParser::MakeElementL(TDes& aText, TInt aId, const TDesC& aValue)
+// Constructs element with value (eg. "<Free>23456</Free>").
+// -----------------------------------------------------------------------------
+//
+void CapParser::MakeElementL(TDes& aText, TInt aId, const TDesC& aValue)
+ {
+ aText=KNullDesC;
+ ReplaceSpecialCharsL( aText, aValue );
+
+ TBuf<KTagSize> buf;
+ MakeElementL( buf, aId, TXmlParser::EElementBegin );
+
+ TInt len = aText.Length() + buf.Length() + buf.Length() + 1;
+ if ( len > aText.MaxLength())
+ {
+ User::Leave(KErrTooBig);
+ }
+
+ aText.Insert( 0, buf );
+ MakeElementL( buf, aId, TXmlParser::EElementEnd );
+ aText.Append( buf );
+ }
+
+// -----------------------------------------------------------------------------
+// CapParser::MakeElementL(TDes& aText, TInt aId, TInt aType)
+// Constructs element without value (eg. "<Memory>" or "</Memory>").
+// -----------------------------------------------------------------------------
+//
+void CapParser::MakeElementL(TDes& aText, TInt aId, TInt aType)
+ {
+ _LIT(KFormat1, "<%S>");
+ _LIT(KFormat2, "</%S>");
+ _LIT(KFormat3, "<%S/>");
+
+ aText=KNullDesC;
+ TBuf<KTagSize> buf;
+ GetTagL(buf, aId);
+
+ switch(aType)
+ {
+ case TXmlParser::EElementBegin:
+ aText.Format(KFormat1, &buf);
+ break;
+ case TXmlParser::EElementEnd:
+ aText.Format(KFormat2, &buf);
+ break;
+ case TXmlParser::EElementEmpty:
+ aText.Format(KFormat3, &buf);
+ break;
+ default:
+ CapUtil::Panic(KErrArgument);
+ break;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CapParser::MakeElementL(TDes& aText, TInt aId, const TDesC& aVersion,
+// const TDesC& aDate)
+// Constructs element with attributes "Version" and "Date"(eg.
+// "<FW Version="2.2"/>").
+// -----------------------------------------------------------------------------
+//
+void CapParser::MakeElementL(TDes& aText, TInt aId, const TDesC& aVersion,
+ const TDesC& aDate)
+ {
+ _LIT(KFormat1, "<%S %S=\"%S\" %S=\"%S\"/>");
+ _LIT(KFormat2, "<%S %S=\"%S\"/>");
+
+ aText=KNullDesC;
+
+ TBuf<KTagSize> element;
+ TBuf<KTagSize> versionTag;
+ TBuf<KTagSize> dateTag;
+
+ GetTagL(element, aId);
+ GetTagL(versionTag, EAttVersion);
+ GetTagL(dateTag, EAttDate);
+
+ if (aDate.Length()>0)
+ {
+ aText.Format(KFormat1, &element, &versionTag, &aVersion, &dateTag,
+ &aDate);
+ }
+ else
+ {
+ aText.Format(KFormat2, &element, &versionTag, &aVersion);
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CapParser::ReplaceSpecialCharsL( TDes& aText, const TDesC& aValue )
+// Replaces special characters to xml compliant.
+// -----------------------------------------------------------------------------
+//
+void CapParser::ReplaceSpecialCharsL( TDes& aText, const TDesC& aValue )
+ {
+ if ( aValue.Length() > aText.MaxLength() )
+ {
+ User::Leave(KErrTooBig);
+ }
+ aText.Copy( aValue );
+
+ //Replace special characters
+ for( TInt i = 0; i < aText.Length(); i++ )
+ {
+ switch( aText[i] )
+ {
+ case KFind1:
+ if ( aText.Length()+KReplace1().Length()-1 > aText.MaxLength() )
+ {
+ User::Leave(KErrTooBig);
+ }
+ aText.Replace( i, 1, KReplace1 );
+ i+=KReplace1().Length()-1;
+ break;
+ case KFind2:
+ if ( aText.Length()+KReplace2().Length()-1 > aText.MaxLength() )
+ {
+ User::Leave(KErrTooBig);
+ }
+ aText.Replace( i, 1, KReplace2 );
+ i+=KReplace2().Length()-1;
+ break;
+ case KFind3:
+ if ( aText.Length()+KReplace3().Length()-1 > aText.MaxLength() )
+ {
+ User::Leave(KErrTooBig);
+ }
+ aText.Replace( i, 1, KReplace3 );
+ i+=KReplace3().Length()-1;
+ break;
+ case KFind4:
+ if ( aText.Length()+KReplace4().Length()-1 > aText.MaxLength() )
+ {
+ User::Leave(KErrTooBig);
+ }
+ aText.Replace( i, 1, KReplace4 );
+ i+=KReplace4().Length()-1;
+ break;
+ case KFind5:
+ if ( aText.Length()+KReplace5().Length()-1 > aText.MaxLength() )
+ {
+ User::Leave(KErrTooBig);
+ }
+ aText.Replace( i, 1, KReplace5 );
+ i+=KReplace5().Length()-1;
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// TXmlParser::Set(const TDesC& aText)
+// Sets a tag
+// -----------------------------------------------------------------------------
+//
+void TXmlParser::Set(const TDesC& aText)
+ {
+ iOriginal.Set(aText);
+ TrimOriginal();
+ Init();
+ Parse();
+ }
+
+// -----------------------------------------------------------------------------
+// TXmlParser::Init()
+// Inits the parser
+// -----------------------------------------------------------------------------
+//
+void TXmlParser::Init()
+ {
+ iType=EElementUnknown;
+ iTag.Set(KNullDesC);
+ iValue.Set(KNullDesC);
+ }
+
+// -----------------------------------------------------------------------------
+// TXmlParser::GetTag(TDes& aText) const
+// Gets the tag
+// -----------------------------------------------------------------------------
+//
+void TXmlParser::GetTag(TDes& aText) const
+ {
+ StrCopy(aText, iTag);
+ }
+
+// -----------------------------------------------------------------------------
+// TXmlParser::Tag() const
+// Returns a pointer to a tag
+// -----------------------------------------------------------------------------
+//
+TPtrC TXmlParser::Tag() const
+ {
+ return iTag;
+ }
+
+// -----------------------------------------------------------------------------
+// TXmlParser::Type() const
+// Returns type
+// -----------------------------------------------------------------------------
+//
+TInt TXmlParser::Type() const
+ {
+ return iType;
+ }
+
+// -----------------------------------------------------------------------------
+// TXmlParser::Parse()
+// Parses xml-element.
+// -----------------------------------------------------------------------------
+//
+void TXmlParser::Parse()
+ {
+ iType=EElementUnknown;
+
+ // this must be the first check
+ if (ElementUnknown())
+ {
+ return;
+ }
+
+ if (ElementBegin())
+ {
+ return;
+ }
+
+ if (ElementEnd())
+ {
+ return;
+ }
+
+ if (ElementValue())
+ {
+ return;
+ }
+
+ if (ElementComment())
+ {
+ return;
+ }
+
+ if (ElementDocType())
+ {
+ return;
+ }
+
+ if (ElementVersion())
+ {
+ return;
+ }
+
+ if (ElementEmpty())
+ {
+ return;
+ }
+
+ if (ElementAtt())
+ {
+ return;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// TXmlParser::ElementUnknown()
+// Parses unknown elements
+// -----------------------------------------------------------------------------
+//
+TBool TXmlParser::ElementUnknown()
+ {
+ TPtrC str=Str();
+ TInt len=str.Length();
+ const TInt KXmlElementMinLength = 3;
+ if ( len < KXmlElementMinLength )
+ {
+ return ETrue; // too short to be xml element
+ }
+
+
+ iFirst=str.Locate('<');
+ iLast=str.LocateReverse('>');
+ iSlash=str.LocateReverse('/');
+
+ if (iFirst!=0 || iLast!=len-1)
+ {
+ return ETrue; // first char must be "<" and last ">"
+ }
+
+ return EFalse;
+ }
+
+// -----------------------------------------------------------------------------
+// TXmlParser::ElementBegin()
+// Parses beginning tag (eg. <General>)
+// -----------------------------------------------------------------------------
+//
+TBool TXmlParser::ElementBegin()
+ {
+ TPtrC str=Str();
+
+ if (iSlash!=KErrNotFound)
+ {
+ return EFalse;
+ }
+
+ // remove possible attributes
+ TInt pos=str.Locate(' ');
+ if (pos==KErrNotFound)
+ {
+ pos=iLast;
+ }
+
+ TPtrC ptr=SubStr(iFirst, pos);
+
+ if (!ValidTag(ptr))
+ {
+ return EFalse;
+ }
+
+ iType=EElementBegin;
+ iTag.Set(ptr);
+
+ return ETrue;
+ }
+
+// -----------------------------------------------------------------------------
+// TXmlParser::ElementEnd()
+// Parses ending tag (eg. </General>)
+// -----------------------------------------------------------------------------
+//
+TBool TXmlParser::ElementEnd()
+ {
+ if (iSlash!=iFirst+1)
+ {
+ return EFalse;
+ }
+
+ TPtrC ptr=SubStr(iSlash, iLast);
+ if (!ValidTag(ptr))
+ {
+ return EFalse;
+ }
+
+ iType=EElementEnd;
+ iTag.Set(ptr);
+ return ETrue;
+ }
+
+// -----------------------------------------------------------------------------
+// TXmlParser::ElementValue()
+// Parses value (eg. <Language>en</Language>)
+// -----------------------------------------------------------------------------
+//
+TBool TXmlParser::ElementValue()
+ {
+ TPtrC str=Str();
+
+ TInt pos1=str.Locate('>');
+ TInt pos2=str.LocateReverse('<');
+
+ if (pos1<pos2 && iSlash==pos2+1)
+ {
+ TPtrC ptr1=SubStr(iFirst, pos1);
+ TPtrC ptr2=SubStr(iSlash, iLast);
+ if (!ValidTag(ptr1) || ptr1.Compare(ptr2)!=0)
+ {
+ return EFalse;
+ }
+
+ iType=EElementValue;
+ iTag.Set(ptr1);
+ iValue.Set(SubStr(pos1, pos2));
+ return ETrue;
+ }
+ return EFalse;
+ }
+
+// -----------------------------------------------------------------------------
+// TXmlParser::ElementEmpty()
+// Parses empty element (eg. <CaseSenN/>)
+// -----------------------------------------------------------------------------
+//
+TBool TXmlParser::ElementEmpty()
+ {
+ if (iSlash!=iLast-1)
+ {
+ return EFalse;
+ }
+
+ TPtrC ptr=SubStr(iFirst, iSlash);
+ if (!ValidTag(ptr))
+ {
+ return EFalse;
+ }
+
+ iType=EElementEmpty;
+ iTag.Set(ptr);
+ return ETrue;
+ }
+
+// -----------------------------------------------------------------------------
+// TXmlParser::ElementVersion()
+// Identifies version element ("<?xml version="1.0" ?>")
+// -----------------------------------------------------------------------------
+//
+TBool TXmlParser::ElementVersion()
+ {
+ TPtrC str=Str();
+
+ if ( str.Length()>=3 && str[1]=='?' && str[2]=='x')
+ {
+ iType=EElementVersion;
+ return ETrue;
+ }
+ return EFalse;
+ }
+
+// -----------------------------------------------------------------------------
+// TXmlParser::ElementDocType()
+// Identifies document type element
+// ("<!DOCTYPE Capability SYSTEM "obex-capability.dtd">").
+// -----------------------------------------------------------------------------
+//
+TBool TXmlParser::ElementDocType()
+ {
+ TPtrC str=Str();
+ const TInt KElementMinLength = 10;
+ if ( str.Length() < KElementMinLength )
+ {
+ return EFalse;
+ }
+
+ if (str[1]=='!' && str[2]=='D' && str[3]=='O' && str[4]=='C')
+ {
+ iType=EElementDocType;
+ return ETrue;
+ }
+ return EFalse;
+ }
+
+// -----------------------------------------------------------------------------
+// TXmlParser::ElementComment()
+// Identifies comment element ("<!-- OBEX Capability Object -->").
+// -----------------------------------------------------------------------------
+//
+TBool TXmlParser::ElementComment()
+ {
+ TPtrC str=Str();
+
+ if (str.Length()<7)
+ {
+ return EFalse;
+ }
+
+ if (str[1]=='!' && str[2]=='-' && str[3]=='-')
+ {
+ iType=EElementComment;
+ return ETrue;
+ }
+
+ return EFalse;
+ }
+
+// -----------------------------------------------------------------------------
+// TXmlParser::ElementAtt()
+// Parses attribute element (eg. <HW Version="1.5"/>)
+// Note: Attribute values cannot contain equals (=) or quotations (")
+// -----------------------------------------------------------------------------
+//
+TBool TXmlParser::ElementAtt()
+ {
+ TPtrC str=Str();
+ TInt num1=Count(str, '=');
+ TInt num2=Count(str, '"');
+ TInt pos=str.Locate(' '); // find end of tag
+
+ if (iSlash==iLast-1 && num1>0 && num2==(2*num1) && pos!=KErrNotFound)
+ {
+ TPtrC ptr1=SubStr(iFirst, pos);
+ if (!ValidTag(ptr1))
+ {
+ return EFalse;
+ }
+
+ iType=EElementAtt;
+ iTag.Set(ptr1);
+ TPtrC ptr2=SubStr(pos, iSlash);
+ iValue.Set(ptr2);
+ return ETrue;
+ }
+ return EFalse;
+ }
+
+// -----------------------------------------------------------------------------
+// TXmlParser::Str() const
+// Locates the position of the given character
+// -----------------------------------------------------------------------------
+//
+TPtrC TXmlParser::Str() const
+ {
+ return iText;
+ }
+
+// -----------------------------------------------------------------------------
+// TXmlParser::FirstNonSpace(const TDesC& aText)
+// Returns the position of the first non space character
+// -----------------------------------------------------------------------------
+//
+TInt TXmlParser::FirstNonSpace(const TDesC& aText)
+ {
+ TInt len=aText.Length();
+ for (TInt i=0; i<len; i++)
+ {
+ TChar c=aText[i];
+ if (!c.IsSpace())
+ {
+ return i;
+ }
+ }
+ return KErrNotFound;
+ }
+
+// -----------------------------------------------------------------------------
+// TXmlParser::LastNonSpace(const TDesC& aText)
+// Returns the position of the last non space character
+// -----------------------------------------------------------------------------
+//
+TInt TXmlParser::LastNonSpace(const TDesC& aText)
+ {
+ TInt last=aText.Length()-1;
+ for (TInt i=last; i>=0; i--)
+ {
+ TChar c=aText[i];
+ if (!c.IsSpace())
+ {
+ return i;
+ }
+ }
+ return KErrNotFound;
+ }
+
+// -----------------------------------------------------------------------------
+// TXmlParser::SubStr(const TDesC& aText, TInt pos1, TInt pos2)
+// Function returns a sub-string between aPos1 and aPos2
+// -----------------------------------------------------------------------------
+//
+TPtrC TXmlParser::SubStr(const TDesC& aText, TInt pos1, TInt pos2)
+ {
+ if (pos1<0 || pos2>=aText.Length() || pos1>=pos2)
+ {
+ return TPtrC(); // return empty descriptor
+ }
+
+ TInt len=pos2-pos1;
+ return aText.Mid(pos1+1, len-1);
+ }
+
+// -----------------------------------------------------------------------------
+// TXmlParser::SubStr(TInt pos1, TInt pos2)
+// Function returns a sub-string between aPos1 and aPos2
+// -----------------------------------------------------------------------------
+//
+TPtrC TXmlParser::SubStr(TInt pos1, TInt pos2)
+ {
+ TPtrC str=Str();
+ return SubStr(str, pos1, pos2);
+ }
+
+// -----------------------------------------------------------------------------
+// TXmlParser::StrCopy(TDes& aTarget, const TDesC& aSource)
+// Function performs string copy with length checking.
+// -----------------------------------------------------------------------------
+//
+void TXmlParser::StrCopy(TDes& aTarget, const TDesC& aSource)
+ {
+ TInt len=aTarget.MaxLength();
+ if(len<aSource.Length())
+ {
+ aTarget.Copy(aSource.Left(len));
+ }
+ else
+ {
+ aTarget.Copy(aSource);
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// TXmlParser::Count(const TDesC& aText, const TChar aChar)
+// Returns the number of characters (aChar)
+// -----------------------------------------------------------------------------
+//
+TInt TXmlParser::Count(const TDesC& aText, const TChar aChar)
+ {
+ TInt count=0;
+ TInt len=aText.Length();
+
+ for (TInt i=0; i<len; i++)
+ {
+ TChar ch=aText[i];
+ if (ch == aChar)
+ {
+ count++;
+ }
+ }
+ return count;
+ }
+
+// -----------------------------------------------------------------------------
+// TXmlParser::TrimOriginal()
+// Trimmer function
+// -----------------------------------------------------------------------------
+//
+void TXmlParser::TrimOriginal()
+ {
+ // trim iOriginal and place into iText
+ iText.Set(KNullDesC);
+ TInt first=FirstNonSpace(iOriginal);
+ TInt last=LastNonSpace(iOriginal);
+ if(first!=KErrNotFound && last!=KErrNotFound && last>first+1)
+ {
+ TPtrC ptr=iOriginal.Mid(first, last-first+1);
+ iText.Set(ptr);
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// TXmlParser::ValidChar(const TChar aChar)
+// Validates the character
+// -----------------------------------------------------------------------------
+//
+TBool TXmlParser::ValidChar(const TChar aChar)
+ {
+ if (aChar >= 'A' && aChar <= 'Z')
+ {
+ return ETrue;
+ }
+ if (aChar >= 'a' && aChar <= 'z')
+ {
+ return ETrue;
+ }
+
+ return EFalse;
+ }
+
+// -----------------------------------------------------------------------------
+// TXmlParser::ValidTag(const TDesC& aText)
+// Validates the tag
+// -----------------------------------------------------------------------------
+//
+TBool TXmlParser::ValidTag(const TDesC& aText)
+ {
+ TInt len=aText.Length();
+ for (TInt i=0; i<len; i++)
+ {
+ if (!ValidChar(aText[i]))
+ {
+ return EFalse;
+ }
+ }
+ return ETrue;
+ }
+
+// End of file