--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/syncmlfw/common/xml/src/XMLParser.cpp Thu Dec 17 09:07:52 2009 +0200
@@ -0,0 +1,416 @@
+/*
+* Copyright (c) 2002 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: XML parser
+*
+*/
+
+
+// ------------------------------------------------------------------------------------------------
+// Includes
+// ------------------------------------------------------------------------------------------------
+#include <s32mem.h>
+
+#include "XMLParser.h"
+#include "WBXMLAttributes.h"
+
+// ------------------------------------------------------------------------------------------------
+// Local functions
+// ------------------------------------------------------------------------------------------------
+LOCAL_D void doPanic( const TDesC& aMsg, TInt aReason )
+ {
+ User::Panic(aMsg, aReason);
+ }
+
+// ------------------------------------------------------------------------------------------------
+// CXMLParser
+// ------------------------------------------------------------------------------------------------
+EXPORT_C CXMLParser* CXMLParser::NewL()
+ {
+ CXMLParser* self = new (ELeave) CXMLParser();
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop(); // self
+ return self;
+ }
+
+// ------------------------------------------------------------------------------------------------
+void CXMLParser::ConstructL()
+ {
+ iBuffer = CBufFlat::NewL(32);
+ }
+
+// ------------------------------------------------------------------------------------------------
+EXPORT_C CXMLParser::~CXMLParser()
+ {
+ delete iBuffer;
+ delete iStringTable;
+ iStack.Reset();
+ }
+
+// ------------------------------------------------------------------------------------------------
+EXPORT_C void CXMLParser::SetDocumentHandler( MWBXMLDocumentHandler* aHandler )
+ {
+ iDocHandler = aHandler;
+ }
+
+// ------------------------------------------------------------------------------------------------
+EXPORT_C void CXMLParser::SetExtensionHandler( MWBXMLExtensionHandler* aHandler )
+ {
+ iExtHandler = aHandler;
+ }
+
+// ------------------------------------------------------------------------------------------------
+EXPORT_C void CXMLParser::SetDocumentL( RReadStream& aInput )
+ {
+ iInput = aInput;
+ iStack.Reset();
+ iDocHdrParsed = EFalse;
+ if( iDocHandler )
+ {
+ iDocHandler->DocumentChangedL();
+ }
+ }
+
+// ------------------------------------------------------------------------------------------------
+EXPORT_C TWBXMLParserError CXMLParser::ParseL()
+ {
+ __ASSERT_ALWAYS(iDocHandler, doPanic(KXMLNoDocHandler, KErrGeneral));
+ __ASSERT_ALWAYS(iExtHandler, doPanic(KXMLNoExtHandler, KErrGeneral));
+ if( !iDocHdrParsed )
+ {
+ TWBXMLParserError result(KWBXMLParserErrorOk);
+ TRAPD(err, result = doParseDocumentHeaderL());
+ if( err == KErrEof )
+ {
+ return KWBXMLParserErrorEofTooEarly;
+ }
+ return result;
+ }
+ return doParseDocumentBodyL();
+ }
+
+// ------------------------------------------------------------------------------------------------
+TWBXMLParserError CXMLParser::doParseDocumentHeaderL()
+ {
+ iDocHdrParsed = ETrue;
+
+ // Version
+ TUint8 version = readUint8L();
+
+ // PublicId
+ TInt32 publicId = readMUint32L();
+
+ if( publicId == 0 )
+ {
+ publicId = readMUint32L();
+ }
+ else
+ {
+ publicId = -publicId;
+ }
+
+ // Charset
+ TUint32 charSet = readMUint32L();
+
+ // String table
+ readStringTableL();
+
+ // Document begings now
+ if( publicId < 0 )
+ {
+ iDocHandler->StartDocumentL(version, -publicId, charSet);
+ }
+ else
+ {
+ iDocHandler->StartDocumentL(version, stringTableString(publicId), charSet);
+ }
+
+ return KWBXMLParserErrorOk;
+ }
+
+// ------------------------------------------------------------------------------------------------
+TWBXMLParserError CXMLParser::doParseDocumentBodyL()
+ {
+ TUint8 id(0);
+
+ TRAPD(err, id = readUint8L());
+
+ if( err != KErrNone )
+ {
+ if( err == KErrEof )
+ {
+ iDocHandler->EndDocumentL();
+ if( iStack.Count() > 0 )
+ {
+ return KWBXMLParserErrorEofTooEarly;
+ }
+ return KWBXMLParserErrorEof;
+ }
+ User::Leave(err);
+ }
+
+ switch (id)
+ {
+ case SWITCH_PAGE:
+ {
+ TUint8 cp = readUint8L();
+ if( cp != iCodePage )
+ {
+ iDocHandler->CodePageSwitchL(cp);
+ iCodePage = cp;
+ }
+ }
+ break;
+
+ case END:
+ {
+ if( !iStack.Count() )
+ {
+ User::Leave(KErrParserErrorInvalidDocument);
+ }
+ TXMLStackItem si(iStack.operator[](iStack.Count() - 1));
+ if( si.CodePage() != iCodePage )
+ {
+ iDocHandler->CodePageSwitchL(si.CodePage());
+ iCodePage = si.CodePage();
+ }
+ iDocHandler->EndElementL(si.Tag());
+ iStack.Remove(iStack.Count() - 1);
+ }
+ break;
+
+ case ENTITY:
+ {
+ TUint8 b = readUint8L();
+ iDocHandler->CharactersL(TPtrC8(&b, 1));
+ }
+ break;
+
+ case STR_I:
+ {
+ iDocHandler->CharactersL(readStrIL());
+ }
+ break;
+
+ case EXT_I_0:
+ case EXT_I_1:
+ case EXT_I_2:
+ case EXT_T_0:
+ case EXT_T_1:
+ case EXT_T_2:
+ case EXT_0:
+ case EXT_1:
+ case EXT_2:
+ case OPAQUE:
+ handleExtensionsL(id);
+ break;
+
+ case STR_T:
+ iDocHandler->CharactersL(stringTableString(readMUint32L()));
+ break;
+
+ case PI:
+ User::Leave(KErrNotSupported);
+ break;
+
+ default:
+ handleElementL(id);
+ break;
+ }
+
+ return KWBXMLParserErrorOk;
+ }
+
+// ------------------------------------------------------------------------------------------------
+TUint32 CXMLParser::readMUint32L()
+ {
+ TUint32 result = 0;
+ TUint8 c;
+
+ do {
+ c = readUint8L();
+ result = (result << 7) | (c & 0x7f);
+ } while ( c & 0x80 );
+
+ return result;
+ }
+
+// ------------------------------------------------------------------------------------------------
+TUint8 CXMLParser::readUint8L()
+ {
+ return iInput.ReadUint8L();
+ }
+
+// ------------------------------------------------------------------------------------------------
+TPtrC8 CXMLParser::readStrIL()
+ {
+ iBuffer->Reset();
+ RBufWriteStream bws(*iBuffer);
+ TUint8 c;
+ while( (c = readUint8L()) != 0 )
+ {
+ bws.WriteUint8L(c);
+ }
+ bws.CommitL();
+ return iBuffer->Ptr(0);
+ }
+
+// ------------------------------------------------------------------------------------------------
+TPtrC8 CXMLParser::readOpaqueL()
+ {
+ iBuffer->Reset();
+ RBufWriteStream bws(*iBuffer);
+ bws.WriteL(iInput, readMUint32L());
+ bws.CommitL();
+ return iBuffer->Ptr(0);
+ }
+
+// ------------------------------------------------------------------------------------------------
+TPtrC8 CXMLParser::stringTableString( TUint32 aIndex )
+ {
+ TPtrC8 temp(iStringTable->Mid(aIndex));
+ TInt pos = temp.Find(KXMLNull());
+ if( pos != KErrNotFound )
+ {
+ return temp.Mid(0, pos);
+ }
+ return temp;
+ }
+
+// ------------------------------------------------------------------------------------------------
+void CXMLParser::readStringTableL()
+ {
+ delete iStringTable;
+ iStringTable = 0;
+ TUint32 strTblLen = readMUint32L();
+ if( strTblLen > 0 )
+ {
+ iStringTable = HBufC8::NewL(strTblLen);
+ TPtr8 ptr = iStringTable->Des();
+ iInput.ReadL(ptr, strTblLen);
+ }
+ }
+
+// ------------------------------------------------------------------------------------------------
+void CXMLParser::handleExtensionsL( TUint8 aId )
+ {
+ switch( aId )
+ {
+ case EXT_I_0:
+ case EXT_I_1:
+ case EXT_I_2:
+ iExtHandler->Ext_IL(TUint8(aId - EXT_I_0), readStrIL());
+ break;
+
+ case EXT_T_0:
+ case EXT_T_1:
+ case EXT_T_2:
+ iExtHandler->Ext_TL(TUint8(aId - EXT_T_0), readMUint32L());
+ break;
+
+ case EXT_0:
+ case EXT_1:
+ case EXT_2:
+ iExtHandler->ExtL(TUint8(aId - EXT_0));
+ break;
+
+ case OPAQUE:
+ iExtHandler->OpaqueL(readOpaqueL());
+ break;
+
+ default:
+ User::Leave( KWBXMLParserErrorInvalidTag );
+ }
+ }
+
+// ------------------------------------- -----------------------------------------------------------
+void CXMLParser::handleElementL( TUint8 aId )
+ {
+ TUint8 aTag = TUint8(aId & 0x3f);
+
+ CWBXMLAttributes* attr = CWBXMLAttributes::NewLC();
+
+ if( aId & 0x80 )
+ {
+ readAttributesL(attr);
+ }
+
+ iDocHandler->StartElementL(aTag, *attr);
+
+ if( aId & 0x40 )
+ {
+ TXMLStackItem si(aTag, iCodePage);
+ iStack.Append(si);
+ }
+ else
+ {
+ iDocHandler->EndElementL(aTag);
+ }
+
+ CleanupStack::PopAndDestroy(); // attr
+ }
+
+// ------------------------------------------------------------------------------------------------
+void CXMLParser::readAttributesL( CWBXMLAttributes* aAttributes )
+ {
+ TUint8 id = readUint8L();
+ while( id != END )
+ {
+ iBuffer->Reset();
+ RBufWriteStream bws(*iBuffer);
+ TUint8 name = id;
+ id = readUint8L();
+ while( id > 0x80 || id == ENTITY || id == STR_I || id == STR_T || (id >= EXT_I_0 && id <= EXT_I_2) || (id >= EXT_T_0 && id <= EXT_T_2) )
+ {
+ switch (id)
+ {
+ case ENTITY:
+ bws.WriteUint8L(readUint8L());
+ break;
+
+ case STR_I:
+ bws.WriteL(readStrIL());
+ break;
+
+ case EXT_I_0:
+ case EXT_I_1:
+ case EXT_I_2:
+ case EXT_T_0:
+ case EXT_T_1:
+ case EXT_T_2:
+ case EXT_0:
+ case EXT_1:
+ case EXT_2:
+ case OPAQUE:
+ handleExtensionsL(id);
+ break;
+
+ case STR_T:
+ bws.WriteL(stringTableString(readUint8L()));
+ break;
+
+ default:
+ bws.WriteUint8L(id);
+ break;
+ }
+ id = readUint8L();
+ }
+ bws.CommitL();
+ aAttributes->AddAttributeL(name, iBuffer->Ptr(0));
+ }
+ }
+
+//End of File
+
+