diff -r 000000000000 -r b497e44ab2fc omaprovisioning/provisioning/ProvisioningParser/Src/CWPWbxmlParser.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omaprovisioning/provisioning/ProvisioningParser/Src/CWPWbxmlParser.cpp Thu Dec 17 09:07:52 2009 +0200 @@ -0,0 +1,551 @@ +/* +* 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: CWPWbxmlParser parses WBXML data using builder design pattern +* +*/ + + +// INCLUDE FILES +#include // included for free() +#include "MWPBuilder.h" +#include "CWPWbxmlParser.h" +#include "OMAProvisioningDictionary.h" +#include "ProvisioningDebug.h" +#include + +// EXTERNAL DATA STRUCTURES +extern "C" NW_WBXML_Dictionary_t NW_omawapprovisioning_WBXMLDictionary; + +// CONSTANTS +const NW_Uint16 KParseError = 0xffff; +const NW_Uint16 KParseStatusOk = 0; +const TUint KWapProvisioningDocToken = 0x05; +const TUint KCharacteristicToken = 0x06; +const NW_Uint16 KTokenValueMask = 0xff; +//const TUint16 KTokenPageMask = 0xff00; // Commented to remove warning in armv5 +const TUint KAttribValMin = 128; +const TUint KParmNameToken = 0x05; +const TUint KCharTypeToken = 0x50; +const TUint KParmStartValueToken = 0x06; +const TUint KParmToken = 0x07; +const TUint KFromTag = 0x0201; +//const TUint KMaxBandwidthTag = 0x0202; // Commented to remove warning in armv5 +//const TUint KMaxUdpPortTag = 0x0203; // Commented to remove warning in armv5 +//const TUint KMinUdpPortTag = 0x0204; // Commented to remove warning in armv5 +//const NW_Int32 publicID = 0x0b; // Commented to remove warning in armv5 +const TUint KDictionaryCount = 1; +const TInt KHeaderLength = 4; +// binary values of the clashing names in different code pages +//const TInt KDuplicateTagTable[]={ 0x06,0x07 }; +const TInt KDuplicateCharacteristicTable[]={ 0x53,0x58 }; +const TInt KDuplicateParmAttributeStartTable[]={ 0x07, 0x14, 0x1C, + 0x22, 0x23, 0x24 }; +//const TInt KDuplicateAddrtypeValueTable[]={ 0x86, 0x87, 0x88 }; // Commented to remove warning in armv5 + +_LIT(KFromStr,"FROM"); +//_LIT(KMaxBandwidthStr,"MAX-BANDWIDTH"); // Commented to remove warning in armv5 +//_LIT(KMaxUdpPortStr,"MAX-UDP-PORT"); // Commented to remove warning in armv5 +//_LIT(KMinUdpPortStr,"MIN-UDP-PORT"); // Commented to remove warning in armv5 + +// ============================ MEMBER FUNCTIONS =============================== + + +// ----------------------------------------------------------------------------- +// CWPNameValuePair::CWPNameValuePair +// C++ default constructor. +// ----------------------------------------------------------------------------- +// +CWPNameValuePair::CWPNameValuePair() + { + } + +// ----------------------------------------------------------------------------- +// CWPNameValuePair::~CWPNameValuePair +// Destructor +// ----------------------------------------------------------------------------- +// +CWPNameValuePair::~CWPNameValuePair() + { + delete iValue; + } + +// --------------------------------------------------------- +// CWPStringPair::SetValue +// --------------------------------------------------------- +// +void CWPNameValuePair::SetValue( HBufC* aValue ) + { + delete iValue; + iValue = aValue; + } + +const TDesC& CWPNameValuePair::Value() const + { + if ( iValue ) + { + return *iValue; + } + else + { + return KNullDesC; + } + } + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CWPWbxmlParser::CWPWbxmlParser +// C++ default constructor can NOT contain any code, that +// might leave. +// ----------------------------------------------------------------------------- +// +CWPWbxmlParser::CWPWbxmlParser() + { + } + +// ----------------------------------------------------------------------------- +// CWPWbxmlParser::ConstructL +// Symbian 2nd phase constructor can leave. +// ----------------------------------------------------------------------------- +// +void CWPWbxmlParser::ConstructL() + { + + iDocNode = NULL; + // A dictionary containing OMA provisioning WBXML tokens: + iDictionary[0] = &NW_omawapprovisioning_WBXMLDictionary; + TInt err = NW_WBXML_Dictionary_initialize ( KDictionaryCount, iDictionary ); + switch( err ) + { + case NW_STAT_OUT_OF_MEMORY: + { + User::Leave( KErrNoMemory ); + break; + } + case NW_STAT_FAILURE: + { + User::Leave( KErrGeneral ); + break; + } + default: + break; + } + + } + +// ----------------------------------------------------------------------------- +// CWPWbxmlParser::NewL +// Two-phased constructor. +// ----------------------------------------------------------------------------- +// +EXPORT_C CWPWbxmlParser* CWPWbxmlParser::NewL() + { + CWPWbxmlParser* self = new( ELeave ) CWPWbxmlParser; + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + return self; + } + +// Destructor +CWPWbxmlParser::~CWPWbxmlParser() + { + delete iParameterName; + NW_WBXML_Dictionary_destroy(); // deletes iDictionary + } + +void CWPWbxmlParser::Cleanup( TAny *aPtr ) + { + NW_TinyDom_ParserDelete( STATIC_CAST( Parser_t* , aPtr ) ); + } + + +// ----------------------------------------------------------------------------- +// CWPWbxmlParser::ParseL +// Two-phased constructor. +// ----------------------------------------------------------------------------- +// +EXPORT_C void CWPWbxmlParser::ParseL( const TDesC8& aDocument, + MWPBuilder& aRoot ) + { + NW_TinyDom_Handle_t handle; + FLOG( _L( "[ProvisioningParser] CWPWbxmlParser::ParseL begin" ) ); + + NW_Int32 bufferLength( aDocument.Size() ); + if( bufferLength <= KHeaderLength ) + { + FLOG( _L( "[ProvisioningParser] CWPWbxmlParser::ParseL leaving" ) ); + User::Leave( KErrCorrupt ); + } + NW_Byte* buffer = CONST_CAST( NW_Byte*, aDocument.Ptr() ); + // create a tree from a wbxml buffer + iDocNode = NW_DOM_DocumentNode_BuildWBXMLTree(&handle, + buffer, + bufferLength, + NW_FALSE, + NW_FALSE); + + if( !iDocNode ) + { + User::Leave( KErrCorrupt ); + FLOG( _L( "[ProvisioningParser] CWPWbxmlParser::ParseL error branch" ) ); + } + else + { + FLOG( _L( "[ProvisioningParser] CWPWbxmlParser::ParseL okey branch" ) ); + + CleanupStack::PushL( TCleanupItem( Cleanup, &handle ) ) ; + // traverse tree and build data into engine + ParseDocumentL( iDocNode, aRoot ) ; + CleanupStack::PopAndDestroy(); // via handle + } + FLOG( _L( "[ProvisioningParser] CWPWbxmlParser::ParseL end" ) ); + } + + +// ----------------------------------------------------------------------------- +// CWPWbxmlParser::ParseDocumentL +// Parses DOM document +// ----------------------------------------------------------------------------- +// +NW_Uint16 CWPWbxmlParser::ParseDocumentL( NW_DOM_DocumentNode_t *aDocument, + MWPBuilder& aRoot ) + { + FLOG( _L( "[ProvisioningParser] CWPWbxmlParser::ParseDocumentL begin" ) ); + NW_Uint32 encoding( NW_DOM_DocumentNode_getCharacterEncoding( aDocument ) ); + NW_DOM_ElementNode_t* elem = + NW_DOM_DocumentNode_getDocumentElement( aDocument ); + FLOG( _L( "[ProvisioningParser] CWPWbxmlParser::ParseDocumentL end" ) ); + return ParseNodeL( elem, encoding, aRoot ); + } + +// ----------------------------------------------------------------------------- +// CWPWbxmlParser::ParseNode +// Parses DOM tree Node recursively +// ----------------------------------------------------------------------------- +// +NW_Uint16 CWPWbxmlParser::ParseNodeL( NW_DOM_Node_t* aNode, NW_Uint32 aEncoding, + MWPBuilder& aRoot) + { + FLOG( _L( "[ProvisioningParser] CWPWbxmlParser::ParesNodeL begin" ) ); + NW_DOM_Node_t* node = aNode; + if( !node ) + { + User::Leave( KErrGeneral ); + } + else + { + NW_Uint32 type = NW_DOM_Node_getNodeType( aNode ); + if ( type != NW_DOM_ELEMENT_NODE ) + { + User::Leave( KErrGeneral ); + } + } + NW_Uint16 errCode( KParseStatusOk ); + // traverse tree by simulating a stack + while( node ) + { + ParseElementL( node, aEncoding, aRoot ); + if( NW_DOM_Node_hasChildNodes( node ) ) + { + node = NW_DOM_Node_getFirstChild( node ); + } + else // leaf reached, find parent level + { + while( NW_DOM_Node_getNextSibling( node ) == NULL && node != aNode ) + { + NW_Uint32 tagToken = NW_DOM_ElementNode_getTagToken( node ); + if( tagToken == KCharacteristicToken ) + { + aRoot.EndCharacteristicL(); + } + + if(tagToken==0) + User::Leave(KErrCorrupt); + node = NW_DOM_Node_getParentNode( node ); + } + // always end leaf characteristic + NW_Uint32 tagToken = NW_DOM_ElementNode_getTagToken( node ); + if( tagToken == KCharacteristicToken ) + { + aRoot.EndCharacteristicL(); + } + node = NW_DOM_Node_getNextSibling( node ); + } // end leaf + } // end outer while + FLOG( _L( "[ProvisioningParser] CWPWbxmlParser::ParseNodeL end" ) ); + return errCode; + } + +// ----------------------------------------------------------------------------- +// CWPWbxmlParser::ParseElement +// Parses DOM tree element into Engine data model using builder pattern. +// ----------------------------------------------------------------------------- +// +void CWPWbxmlParser::ParseElementL( NW_DOM_ElementNode_t* aElement, + NW_Uint32 aEncoding, MWPBuilder& aRoot ) + { + FLOG( _L( "[ProvisioningParser] CWPWbxmlParser::ParseElementL begin" ) ); + NW_Uint32 token = NW_DOM_ElementNode_getTagToken( aElement ); + NW_Uint16 parmNameToken( 0 ); + NW_TinyTree_t* tiny_tree = NW_TinyTree_Node_findTree( aElement ) ; + NW_TinyDom_getParser( tiny_tree ); + if ( NW_DOM_ElementNode_hasAttributes( aElement ) ) + { + NW_DOM_AttributeListIterator_t listIter; + NW_Status_t status = + NW_DOM_ElementNode_getAttributeListIterator( aElement, &listIter ); + if( status != NW_STAT_SUCCESS ) + { + User::Leave( KErrCorrupt ); + } + TBool isFirstPart( ETrue ); // only one iteration + TBool isLastPartProcessed( EFalse ); + TBool unknownNameFound( EFalse ); + NW_DOM_AttributeHandle_t attrHandle; + while ( NW_DOM_AttributeListIterator_getNextAttribute( &listIter, + &attrHandle ) + == NW_STAT_WBXML_ITERATE_MORE ) + { + CWPNameValuePair* pair = new( ELeave ) CWPNameValuePair(); + CleanupStack::PushL( pair ); + NW_Uint16 attribToken( KParseError ); + attribToken = ParseAttributeL( &attrHandle, + aEncoding, + *pair ); + + if( attribToken == KParseError ) + { + // syntactically invalid attribute + User::Leave( KErrCorrupt ); + } + + // extract code page from token + NW_Uint16 codePage( + STATIC_CAST( NW_Uint16, ( ( attribToken >> 8 ) & KTokenValueMask + ) ) ); + NW_Uint16 extractedValue ( + STATIC_CAST( NW_Uint16, ( attribToken & KTokenValueMask ) + ) ); + // process attributes based on current element token + switch( token ) + { + case KWapProvisioningDocToken: + { + FLOG( _L( "[ProvisioningParser] ParseElementL: prov doc found" ) ); + break; // start of document + } + case KCharacteristicToken: + { + FLOG( _L( "[ProvisioningParser] characteristic token found" ) ); + // check if the name clashes with a name in code page zero + if ( attribToken == KCharTypeToken && pair ) + { + aRoot.StartCharacteristicL( pair->Value() ); + } + else { + if( codePage != 0 ) + { + TInt numElements( STATIC_CAST( TInt, ( + sizeof ( KDuplicateCharacteristicTable ) / + sizeof ( KDuplicateCharacteristicTable[0] ) ) ) ); + for( TInt i( 0 ); i < numElements; i++ ) + { + if ( extractedValue == + KDuplicateCharacteristicTable[i] ) + { + attribToken = extractedValue; + FTRACE(RDebug::Print(_L("[ProvisioningParser] characteristic: id %d"), extractedValue)); + break; // end for + } + } + } // end codepage not 0 + aRoot.StartCharacteristicL( attribToken ); + } + break; + } + // Note: parameters are constructed in two phases: + // 1. the attribute value prefix token of the parm is stored + // 2. the value of the attribute is read and stored + // with the prefix. + case KParmToken: + { + FLOG( _L( "[ProvisioningParser] parameter token found" ) ); + // process the first part of the parameter attribute + if( isFirstPart && attribToken > 0 && + extractedValue < KAttribValMin ) + { + if( extractedValue == KParmNameToken && pair ) + { + if( pair->Value().Compare( KFromStr ) ==0 ) + { + parmNameToken = KFromTag; + } + + // unknown parameter name. + else + { + unknownNameFound = ETrue; + delete iParameterName; + iParameterName = NULL; + iParameterName = (pair->Value()).AllocL(); + } + } + // set parameter name token for storing it in step 2. + else + { + parmNameToken = attribToken; + } + FTRACE(RDebug::Print(_L("[ProvisioningParser] parameter id %d"), parmNameToken)); + + // check if the name clashes with a name in code page 0 + if( codePage != 0 ) + { + TInt numElements( STATIC_CAST( TInt, ( + sizeof ( KDuplicateParmAttributeStartTable ) / + sizeof ( KDuplicateParmAttributeStartTable[0] )) + )); + for( TInt i(0); i < numElements ; i++ ) + { + if ( extractedValue == + KDuplicateParmAttributeStartTable[i] ) + { + parmNameToken = extractedValue; + break; // end for + } + } + } // end codepage not 0 + isFirstPart = EFalse; + break; + } + // process the second part of the attribute (value) + else if(!isFirstPart && (extractedValue == KParmStartValueToken + || extractedValue >= KAttribValMin ) ) + { + if( !unknownNameFound ) + { + aRoot.ParameterL( parmNameToken, pair->Value() ); + } + else if ( unknownNameFound ) + { + aRoot.ParameterL( *iParameterName , pair->Value() ); + delete iParameterName; + iParameterName = NULL; + } + isLastPartProcessed=ETrue; + } + break; + } + default: // error no corresponding element exists + { + break; + } + } // end switch + CleanupStack::PopAndDestroy(); // pair + } // end while + // if this parameter consisted of only one attribute, then + // store it + if( parmNameToken && !isLastPartProcessed ) + { + aRoot.ParameterL( parmNameToken, KNullDesC ); + } + else if( iParameterName && !isLastPartProcessed ) + { + aRoot.ParameterL( *iParameterName, KNullDesC ); + delete iParameterName; + iParameterName = NULL; + } + + } + + FLOG( _L( "[ProvisioningParser] CWPWbxmlParser::ParseElementL end" ) ); + // end if has attributes. + } + +// ----------------------------------------------------------------------------- +// CWPWbxmlParser::ParseAttribute +// Constructs HBufCs containing attribute name and value +// ----------------------------------------------------------------------------- +// +NW_Uint16 CWPWbxmlParser::ParseAttributeL( NW_DOM_AttributeHandle_t* aAttrHandle, + NW_Uint32 aEncoding, + CWPNameValuePair& aPair ) + { + FLOG( _L( "[ProvisioningParser] CWPWbxmlParser::ParseAttributeL begin" ) ); + NW_Uint16 getStatus( KParseError ); + // All tokenised attributes must begin with a single attribute start token + // and may be followed by zero or more attribute value, string, entity, + // opaque, or extension tokens. + // 1. process attribute name + TUint16 token( NW_DOM_AttributeHandle_getToken( aAttrHandle ) ); + // 2. process attribute value (only one allowed) + NW_String_t strValue; + NW_Status_t status = NW_DOM_AttributeHandle_getValue( aAttrHandle, &strValue ); + if( status == NW_STAT_SUCCESS ) + { + getStatus = KParseStatusOk; + } + aPair.SetValue( ProcessAttributePartL( &strValue, aEncoding, getStatus ) ); + + FLOG( _L( "[ProvisioningParser] CWPWbxmlParser::ParseAttributeL end" ) ); + return token; + } +// ----------------------------------------------------------------------------- +// CWPWbxmlParser::ProcessAttributePartL +// Constructs HBufCs containing attribute name and value +// ----------------------------------------------------------------------------- +// +HBufC* CWPWbxmlParser::ProcessAttributePartL( NW_String_t* aString, + NW_Uint32 aEncoding, + NW_Uint16 aStatus ) + { + FLOG( _L( "[ProvisioningParser] CWPWbxmlParser::ProcessAttributePartL begin" ) ); + + NW_Ucs2 *ucs2Value = NULL; + HBufC* attribute = NULL; + if ( aStatus == KParseStatusOk ) + { + NW_String_stringToUCS2Char( aString, aEncoding, &ucs2Value ); + if ( !ucs2Value ) + { + NW_String_deleteStorage( aString ); + //User::Leave( KErrCorrupt ); + attribute = HBufC::NewL(1); + TPtr aptr(attribute->Des()); + aptr.Append(_L("")); + return attribute; + } + TPtrC attribValuePtr( ucs2Value ); + attribute = attribValuePtr.Alloc(); + if( !attribute ) // mem alloc failed + { + free( ucs2Value ); + NW_String_deleteStorage( aString ); + User::Leave( KErrNoMemory ); + } + } + else + { + NW_String_deleteStorage( aString ); + User::Leave( KErrCorrupt ); + } + // clean attribute value + free( ucs2Value ); + NW_String_deleteStorage( aString ); + + FLOG( _L( "[ProvisioningParser] CWPWbxmlParser::ProcessAttributePartL end" ) ); + return attribute; + } + +// End of File