diff -r 000000000000 -r b497e44ab2fc syncmlfw/common/xml/src/XMLParser.cpp --- /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 + +#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 + +