omaprovisioning/provisioning/ProvisioningParser/Src/CWPWbxmlParser.cpp
changeset 0 b497e44ab2fc
child 2 5594fba90824
equal deleted inserted replaced
-1:000000000000 0:b497e44ab2fc
       
     1 /*
       
     2 * Copyright (c) 2002 Nokia Corporation and/or its subsidiary(-ies). 
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  CWPWbxmlParser parses WBXML data using builder design pattern
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 // INCLUDE FILES
       
    20 #include <stdlib.h>  // included for free()
       
    21 #include "MWPBuilder.h"
       
    22 #include "CWPWbxmlParser.h"
       
    23 #include "OMAProvisioningDictionary.h"
       
    24 #include "ProvisioningDebug.h"
       
    25 #include <nw_cXML_Parser.h>
       
    26 
       
    27 // EXTERNAL DATA STRUCTURES
       
    28 extern "C" NW_WBXML_Dictionary_t NW_omawapprovisioning_WBXMLDictionary;
       
    29 
       
    30 // CONSTANTS
       
    31 const NW_Uint16 KParseError = 0xffff;
       
    32 const NW_Uint16 KParseStatusOk = 0;
       
    33 const TUint KWapProvisioningDocToken = 0x05;
       
    34 const TUint KCharacteristicToken = 0x06;
       
    35 const NW_Uint16 KTokenValueMask = 0xff;
       
    36 //const TUint16 KTokenPageMask = 0xff00; // Commented to remove warning in armv5
       
    37 const TUint KAttribValMin = 128;
       
    38 const TUint KParmNameToken = 0x05;
       
    39 const TUint KCharTypeToken = 0x50;
       
    40 const TUint KParmStartValueToken = 0x06;
       
    41 const TUint KParmToken = 0x07;
       
    42 const TUint KFromTag = 0x0201;
       
    43 //const TUint KMaxBandwidthTag = 0x0202; // Commented to remove warning in armv5
       
    44 //const TUint KMaxUdpPortTag = 0x0203; // Commented to remove warning in armv5
       
    45 //const TUint KMinUdpPortTag = 0x0204; // Commented to remove warning in armv5
       
    46 //const NW_Int32 publicID = 0x0b; // Commented to remove warning in armv5
       
    47 const TUint KDictionaryCount = 1;
       
    48 const TInt KHeaderLength = 4;
       
    49 // binary values of the clashing names in different code pages
       
    50 //const TInt KDuplicateTagTable[]={ 0x06,0x07 };
       
    51 const TInt KDuplicateCharacteristicTable[]={ 0x53,0x58 };
       
    52 const TInt KDuplicateParmAttributeStartTable[]={ 0x07, 0x14, 0x1C,
       
    53 												 0x22, 0x23, 0x24 };
       
    54 //const TInt KDuplicateAddrtypeValueTable[]={ 0x86, 0x87, 0x88 }; // Commented to remove warning in armv5
       
    55 
       
    56 _LIT(KFromStr,"FROM");
       
    57 //_LIT(KMaxBandwidthStr,"MAX-BANDWIDTH"); // Commented to remove warning in armv5
       
    58 //_LIT(KMaxUdpPortStr,"MAX-UDP-PORT"); // Commented to remove warning in armv5
       
    59 //_LIT(KMinUdpPortStr,"MIN-UDP-PORT"); // Commented to remove warning in armv5
       
    60 
       
    61 // ============================ MEMBER FUNCTIONS ===============================
       
    62 
       
    63 
       
    64 // -----------------------------------------------------------------------------
       
    65 // CWPNameValuePair::CWPNameValuePair
       
    66 // C++ default constructor.
       
    67 // -----------------------------------------------------------------------------
       
    68 //
       
    69 CWPNameValuePair::CWPNameValuePair()
       
    70 	{
       
    71 	}
       
    72 
       
    73 // -----------------------------------------------------------------------------
       
    74 // CWPNameValuePair::~CWPNameValuePair
       
    75 // Destructor
       
    76 // -----------------------------------------------------------------------------
       
    77 //
       
    78 CWPNameValuePair::~CWPNameValuePair()
       
    79 	{
       
    80 	delete iValue;
       
    81 	}
       
    82 
       
    83 // ---------------------------------------------------------
       
    84 // CWPStringPair::SetValue
       
    85 // ---------------------------------------------------------
       
    86 //
       
    87 void CWPNameValuePair::SetValue( HBufC* aValue )
       
    88 	{
       
    89 	delete iValue;
       
    90 	iValue = aValue;
       
    91 	}
       
    92 
       
    93 const TDesC& CWPNameValuePair::Value() const
       
    94 	{
       
    95 	if ( iValue )
       
    96 		{
       
    97 		return *iValue;
       
    98 		}
       
    99 	else
       
   100 		{
       
   101 		return KNullDesC;
       
   102 		}
       
   103 	}
       
   104 
       
   105 // ============================ MEMBER FUNCTIONS ===============================
       
   106 
       
   107 // -----------------------------------------------------------------------------
       
   108 // CWPWbxmlParser::CWPWbxmlParser
       
   109 // C++ default constructor can NOT contain any code, that
       
   110 // might leave.
       
   111 // -----------------------------------------------------------------------------
       
   112 //
       
   113 CWPWbxmlParser::CWPWbxmlParser()
       
   114 	{
       
   115 	}
       
   116 
       
   117 // -----------------------------------------------------------------------------
       
   118 // CWPWbxmlParser::ConstructL
       
   119 // Symbian 2nd phase constructor can leave.
       
   120 // -----------------------------------------------------------------------------
       
   121 //
       
   122 void CWPWbxmlParser::ConstructL()
       
   123 	{
       
   124 
       
   125 	iDocNode = NULL;	
       
   126 	// A dictionary containing OMA provisioning WBXML tokens:
       
   127 	iDictionary[0] = &NW_omawapprovisioning_WBXMLDictionary;
       
   128 	TInt err = NW_WBXML_Dictionary_initialize ( KDictionaryCount, iDictionary );
       
   129 	switch( err )
       
   130 		{
       
   131 		case NW_STAT_OUT_OF_MEMORY:
       
   132 			{
       
   133 			User::Leave( KErrNoMemory ); 
       
   134 			break;
       
   135 			}		
       
   136 		case NW_STAT_FAILURE:
       
   137 			{
       
   138 			User::Leave( KErrGeneral ); 
       
   139 			break;
       
   140 			}
       
   141 		default:
       
   142 		break;
       
   143 		}
       
   144 
       
   145 	}
       
   146 
       
   147 // -----------------------------------------------------------------------------
       
   148 // CWPWbxmlParser::NewL
       
   149 // Two-phased constructor.
       
   150 // -----------------------------------------------------------------------------
       
   151 //
       
   152 EXPORT_C CWPWbxmlParser* CWPWbxmlParser::NewL()
       
   153 	{
       
   154 	CWPWbxmlParser* self = new( ELeave ) CWPWbxmlParser; 
       
   155 	CleanupStack::PushL(self);
       
   156 	self->ConstructL();
       
   157 	CleanupStack::Pop(self);
       
   158 	return self;
       
   159 	}
       
   160 
       
   161 // Destructor
       
   162 CWPWbxmlParser::~CWPWbxmlParser()
       
   163 	{ 
       
   164 	delete iParameterName;
       
   165 	NW_WBXML_Dictionary_destroy(); // deletes iDictionary
       
   166 	}
       
   167 
       
   168 void CWPWbxmlParser::Cleanup( TAny *aPtr )
       
   169 	{
       
   170 	NW_TinyDom_ParserDelete( STATIC_CAST( Parser_t* , aPtr ) );
       
   171 	}
       
   172 
       
   173 
       
   174 // -----------------------------------------------------------------------------
       
   175 // CWPWbxmlParser::ParseL
       
   176 // Two-phased constructor.
       
   177 // -----------------------------------------------------------------------------
       
   178 //
       
   179 EXPORT_C void CWPWbxmlParser::ParseL( const TDesC8& aDocument,
       
   180 									 MWPBuilder& aRoot )
       
   181 	{	
       
   182 	NW_TinyDom_Handle_t handle; 
       
   183 	FLOG( _L( "[ProvisioningParser] CWPWbxmlParser::ParseL begin" ) );
       
   184 
       
   185 	NW_Int32 bufferLength( aDocument.Size() );
       
   186 	if( bufferLength <= KHeaderLength )
       
   187 		{
       
   188 		FLOG( _L( "[ProvisioningParser] CWPWbxmlParser::ParseL leaving" ) );
       
   189 		User::Leave( KErrCorrupt );
       
   190 		}
       
   191 	NW_Byte* buffer = CONST_CAST( NW_Byte*, aDocument.Ptr() ); 	
       
   192 	// create a tree from a wbxml buffer
       
   193     iDocNode = NW_DOM_DocumentNode_BuildWBXMLTree(&handle, 
       
   194                                            buffer,
       
   195                                            bufferLength,
       
   196                                            NW_FALSE,
       
   197                                            NW_FALSE);
       
   198 
       
   199 	if( !iDocNode )
       
   200 		{
       
   201 		User::Leave( KErrCorrupt );
       
   202 		FLOG( _L( "[ProvisioningParser] CWPWbxmlParser::ParseL error branch" ) );
       
   203 		}
       
   204 	else
       
   205 		{ 
       
   206 		FLOG( _L( "[ProvisioningParser] CWPWbxmlParser::ParseL okey branch" ) ); 
       
   207 
       
   208        	CleanupStack::PushL( TCleanupItem( Cleanup, &handle ) ) ;
       
   209 		// traverse tree and build data into engine	
       
   210 		ParseDocumentL( iDocNode, aRoot ) ; 
       
   211     	CleanupStack::PopAndDestroy(); // via handle
       
   212 		}
       
   213 	FLOG( _L( "[ProvisioningParser] CWPWbxmlParser::ParseL end" ) );
       
   214 	}
       
   215 
       
   216 
       
   217 // -----------------------------------------------------------------------------
       
   218 // CWPWbxmlParser::ParseDocumentL
       
   219 // Parses DOM document
       
   220 // -----------------------------------------------------------------------------
       
   221 //
       
   222 NW_Uint16 CWPWbxmlParser::ParseDocumentL( NW_DOM_DocumentNode_t *aDocument,
       
   223 									MWPBuilder& aRoot )
       
   224 	{
       
   225 	FLOG( _L( "[ProvisioningParser] CWPWbxmlParser::ParseDocumentL begin" ) );
       
   226 	NW_Uint32 encoding( NW_DOM_DocumentNode_getCharacterEncoding( aDocument ) );
       
   227 	NW_DOM_ElementNode_t* elem = 
       
   228 							NW_DOM_DocumentNode_getDocumentElement( aDocument );
       
   229 	FLOG( _L( "[ProvisioningParser] CWPWbxmlParser::ParseDocumentL end" ) );
       
   230 	return ParseNodeL( elem, encoding, aRoot );
       
   231 	}
       
   232 
       
   233 // -----------------------------------------------------------------------------
       
   234 // CWPWbxmlParser::ParseNode
       
   235 // Parses DOM tree Node recursively
       
   236 // -----------------------------------------------------------------------------
       
   237 //
       
   238 NW_Uint16 CWPWbxmlParser::ParseNodeL( NW_DOM_Node_t* aNode, NW_Uint32 aEncoding,
       
   239 										MWPBuilder& aRoot)
       
   240 	{
       
   241 	FLOG( _L( "[ProvisioningParser] CWPWbxmlParser::ParesNodeL begin" ) );
       
   242 	NW_DOM_Node_t* node = aNode;
       
   243 	if( !node )
       
   244 		{
       
   245 		User::Leave( KErrGeneral );
       
   246 		}
       
   247 	else
       
   248 		{
       
   249 		NW_Uint32 type = NW_DOM_Node_getNodeType( aNode );
       
   250 		if ( type != NW_DOM_ELEMENT_NODE )
       
   251 			{
       
   252 			User::Leave( KErrGeneral );
       
   253 			}
       
   254 		}
       
   255 	NW_Uint16 errCode( KParseStatusOk );
       
   256 	// traverse tree by simulating a stack
       
   257 	while( node )
       
   258 		{
       
   259 		ParseElementL( node, aEncoding, aRoot );
       
   260 		if( NW_DOM_Node_hasChildNodes( node ) )
       
   261 			{
       
   262 			node = NW_DOM_Node_getFirstChild( node );
       
   263 			}
       
   264 		else // leaf reached, find parent level
       
   265 			{
       
   266 			while( NW_DOM_Node_getNextSibling( node ) == NULL && node != aNode )
       
   267 				{
       
   268 				NW_Uint32 tagToken = NW_DOM_ElementNode_getTagToken( node ); 
       
   269 				if( tagToken == KCharacteristicToken )
       
   270 					{
       
   271 					aRoot.EndCharacteristicL(); 
       
   272 					}
       
   273 			
       
   274 				if(tagToken==0)
       
   275 				User::Leave(KErrCorrupt);
       
   276 				node =  NW_DOM_Node_getParentNode( node );
       
   277 				}
       
   278 			// always end leaf characteristic
       
   279 			NW_Uint32 tagToken = NW_DOM_ElementNode_getTagToken( node ); 
       
   280 			if( tagToken == KCharacteristicToken )
       
   281 				{
       
   282 				aRoot.EndCharacteristicL(); 
       
   283 				}
       
   284 			node = NW_DOM_Node_getNextSibling( node );
       
   285 			} // end leaf
       
   286 		} // end outer while
       
   287 	FLOG( _L( "[ProvisioningParser] CWPWbxmlParser::ParseNodeL end" ) );
       
   288 	return errCode; 
       
   289 	}
       
   290 
       
   291 // -----------------------------------------------------------------------------
       
   292 // CWPWbxmlParser::ParseElement
       
   293 // Parses DOM tree element into Engine data model using builder pattern.
       
   294 // -----------------------------------------------------------------------------
       
   295 //
       
   296 void CWPWbxmlParser::ParseElementL( NW_DOM_ElementNode_t* aElement,
       
   297 								  NW_Uint32 aEncoding, MWPBuilder& aRoot )
       
   298 	{
       
   299 	FLOG( _L( "[ProvisioningParser] CWPWbxmlParser::ParseElementL begin" ) );
       
   300 	NW_Uint32 token = NW_DOM_ElementNode_getTagToken( aElement );			
       
   301 	NW_Uint16 parmNameToken( 0 );
       
   302 	NW_TinyTree_t* tiny_tree =  NW_TinyTree_Node_findTree( aElement ) ;
       
   303 	NW_TinyDom_getParser( tiny_tree );
       
   304 	if ( NW_DOM_ElementNode_hasAttributes( aElement ) )
       
   305 		{
       
   306 		NW_DOM_AttributeListIterator_t listIter;
       
   307 		NW_Status_t status = 
       
   308 			NW_DOM_ElementNode_getAttributeListIterator( aElement, &listIter );
       
   309 		if( status != NW_STAT_SUCCESS )
       
   310 			{
       
   311 			User::Leave( KErrCorrupt );
       
   312 			}
       
   313 		TBool isFirstPart( ETrue ); // only one iteration
       
   314 		TBool isLastPartProcessed( EFalse );
       
   315 		TBool unknownNameFound( EFalse );
       
   316 		NW_DOM_AttributeHandle_t attrHandle;
       
   317 		while ( NW_DOM_AttributeListIterator_getNextAttribute( &listIter,
       
   318 															   &attrHandle )
       
   319 												== NW_STAT_WBXML_ITERATE_MORE )
       
   320 			{
       
   321 			CWPNameValuePair* pair = new( ELeave ) CWPNameValuePair();
       
   322 			CleanupStack::PushL( pair );
       
   323 			NW_Uint16 attribToken( KParseError );	
       
   324 			attribToken = ParseAttributeL( &attrHandle,
       
   325 													aEncoding,
       
   326 													 *pair );
       
   327 
       
   328 			if(  attribToken == KParseError  )
       
   329 				{
       
   330 				// syntactically invalid attribute
       
   331 				User::Leave( KErrCorrupt );
       
   332 				}
       
   333 
       
   334 			// extract code page from token
       
   335 			NW_Uint16 codePage(
       
   336 				STATIC_CAST( NW_Uint16, ( ( attribToken >> 8 ) & KTokenValueMask 
       
   337 									   ) ) );
       
   338 			NW_Uint16 extractedValue (
       
   339 				STATIC_CAST( NW_Uint16, ( attribToken & KTokenValueMask )
       
   340 										) );
       
   341 			// process attributes based on current element token
       
   342 			switch( token )
       
   343 				{
       
   344 				case KWapProvisioningDocToken:
       
   345 					{
       
   346 					FLOG( _L( "[ProvisioningParser] ParseElementL: prov doc found" ) );
       
   347 					break; // start of document
       
   348 					}
       
   349 				case KCharacteristicToken: 
       
   350 					{
       
   351 					FLOG( _L( "[ProvisioningParser] characteristic token found" ) );
       
   352 					// check if the name clashes with a name in code page zero
       
   353 					if ( attribToken == KCharTypeToken && pair )
       
   354 						{
       
   355 						aRoot.StartCharacteristicL( pair->Value() );
       
   356 						}
       
   357 					else {
       
   358 						if(  codePage != 0  )
       
   359 							{
       
   360 							TInt numElements(	STATIC_CAST( TInt, (
       
   361 								sizeof ( KDuplicateCharacteristicTable ) /
       
   362 								sizeof ( KDuplicateCharacteristicTable[0] )	) ) );
       
   363 							for( TInt i( 0 ); i < numElements; i++ ) 
       
   364 								{
       
   365 								if ( extractedValue ==
       
   366 										KDuplicateCharacteristicTable[i] )
       
   367 									{
       
   368 									attribToken = extractedValue;
       
   369 									FTRACE(RDebug::Print(_L("[ProvisioningParser] characteristic: id %d"), extractedValue));        
       
   370 									break; // end for
       
   371 									}
       
   372 								}
       
   373 							} // end codepage not 0
       
   374 						aRoot.StartCharacteristicL( attribToken ); 
       
   375 					}
       
   376 					break;
       
   377 					}
       
   378 				// Note: parameters are constructed in two phases:
       
   379 				// 1. the attribute value prefix token of the parm is stored
       
   380 				// 2. the value of the attribute is read and stored
       
   381 				//		with the prefix.
       
   382 				case KParmToken:
       
   383 					{
       
   384 					FLOG( _L( "[ProvisioningParser] parameter token found" ) );
       
   385 					// process the first part of the parameter attribute
       
   386 					if( isFirstPart && attribToken > 0 &&
       
   387 						 extractedValue  < KAttribValMin ) 
       
   388 						{						
       
   389 						if( extractedValue == KParmNameToken && pair )
       
   390 							{
       
   391 							if( pair->Value().Compare( KFromStr ) ==0 )
       
   392 								{							
       
   393 								parmNameToken = KFromTag;
       
   394 								}
       
   395 
       
   396 							// unknown parameter name.
       
   397 							else
       
   398 								{
       
   399 								unknownNameFound = ETrue;
       
   400 								delete iParameterName;
       
   401 								iParameterName = NULL;
       
   402 								iParameterName = (pair->Value()).AllocL();
       
   403 								}
       
   404 						}
       
   405 						// set parameter name token for storing it in step 2.
       
   406 						else
       
   407 							{
       
   408 							parmNameToken = attribToken; 
       
   409 							}
       
   410 						FTRACE(RDebug::Print(_L("[ProvisioningParser] parameter id %d"), parmNameToken));        
       
   411 
       
   412 						// check if the name clashes with a name in code page 0
       
   413 						if(  codePage != 0  )
       
   414 							{
       
   415 							TInt numElements( STATIC_CAST( TInt, (
       
   416 								sizeof ( KDuplicateParmAttributeStartTable ) /
       
   417 								sizeof ( KDuplicateParmAttributeStartTable[0] ))
       
   418 								));
       
   419 							for( TInt i(0); i < numElements ; i++ ) 
       
   420 								{
       
   421 								if ( extractedValue ==
       
   422 										KDuplicateParmAttributeStartTable[i] )
       
   423 									{
       
   424 									parmNameToken = extractedValue;
       
   425 									break; // end for
       
   426 									}
       
   427 								}
       
   428 							} // end codepage not 0	
       
   429 						isFirstPart = EFalse;
       
   430 						break;
       
   431 						}
       
   432 					// process the second part of the attribute (value)
       
   433 					else if(!isFirstPart && (extractedValue == KParmStartValueToken
       
   434 								|| extractedValue >= KAttribValMin ) )
       
   435 						{
       
   436 						if( !unknownNameFound )							
       
   437 							{
       
   438 							aRoot.ParameterL( parmNameToken, pair->Value() );
       
   439 							}
       
   440 						else if ( unknownNameFound ) 							 
       
   441 							{
       
   442 							aRoot.ParameterL( *iParameterName , pair->Value() );
       
   443 							delete iParameterName;
       
   444 							iParameterName = NULL;
       
   445 							}
       
   446 						isLastPartProcessed=ETrue;
       
   447 						}
       
   448 					break;
       
   449 					}
       
   450 				default: // error no corresponding element exists
       
   451 					{
       
   452 					break;
       
   453 					}
       
   454 				} // end switch
       
   455 			CleanupStack::PopAndDestroy(); // pair
       
   456 			} // end while 	
       
   457 			// if this parameter consisted of only one attribute, then
       
   458 			// store it
       
   459 			if( parmNameToken && !isLastPartProcessed )
       
   460 				{
       
   461 				aRoot.ParameterL( parmNameToken, KNullDesC ); 
       
   462 				}
       
   463 			else if( iParameterName && !isLastPartProcessed )
       
   464 				{
       
   465 				aRoot.ParameterL( *iParameterName, KNullDesC );
       
   466 				delete iParameterName;
       
   467 				iParameterName = NULL;
       
   468 				}
       
   469 
       
   470 		} 
       
   471 		
       
   472 		FLOG( _L( "[ProvisioningParser] CWPWbxmlParser::ParseElementL end" ) );
       
   473 		// end if has attributes.
       
   474 	}
       
   475 
       
   476 // -----------------------------------------------------------------------------
       
   477 // CWPWbxmlParser::ParseAttribute
       
   478 // Constructs HBufCs containing attribute name and value
       
   479 // -----------------------------------------------------------------------------
       
   480 //
       
   481 NW_Uint16 CWPWbxmlParser::ParseAttributeL( NW_DOM_AttributeHandle_t* aAttrHandle,
       
   482 											NW_Uint32 aEncoding,
       
   483 											 CWPNameValuePair& aPair )
       
   484 	{	
       
   485 	FLOG( _L( "[ProvisioningParser] CWPWbxmlParser::ParseAttributeL begin" ) );	
       
   486 	NW_Uint16 getStatus( KParseError );
       
   487 	// All tokenised attributes must begin with a single attribute start token 
       
   488 	// and may be followed by zero or more attribute value, string, entity, 
       
   489 	// opaque, or extension tokens.
       
   490 	// 1. process attribute name
       
   491 	TUint16 token( NW_DOM_AttributeHandle_getToken( aAttrHandle ) ); 
       
   492 	// 2. process attribute value (only one allowed)
       
   493 	NW_String_t strValue;
       
   494 	NW_Status_t status = NW_DOM_AttributeHandle_getValue( aAttrHandle, &strValue );
       
   495 	if( status == NW_STAT_SUCCESS )
       
   496 		{
       
   497 		getStatus = KParseStatusOk;
       
   498 		}
       
   499 	aPair.SetValue( ProcessAttributePartL( &strValue, aEncoding, getStatus ) );
       
   500 	
       
   501 	FLOG( _L( "[ProvisioningParser] CWPWbxmlParser::ParseAttributeL end" ) ); 
       
   502 	return token;
       
   503 	}
       
   504 // -----------------------------------------------------------------------------
       
   505 // CWPWbxmlParser::ProcessAttributePartL
       
   506 // Constructs HBufCs containing attribute name and value
       
   507 // -----------------------------------------------------------------------------
       
   508 //
       
   509 HBufC* CWPWbxmlParser::ProcessAttributePartL( NW_String_t* aString,
       
   510 											  NW_Uint32 aEncoding,
       
   511 											  NW_Uint16 aStatus )
       
   512 	{
       
   513 	FLOG( _L( "[ProvisioningParser] CWPWbxmlParser::ProcessAttributePartL begin" ) );
       
   514 	
       
   515 	NW_Ucs2 *ucs2Value = NULL;
       
   516 	HBufC* attribute = NULL;
       
   517 	if ( aStatus == KParseStatusOk ) 
       
   518 		{
       
   519 		NW_String_stringToUCS2Char( aString, aEncoding, &ucs2Value ); 
       
   520 		if ( !ucs2Value )
       
   521 			{
       
   522 			NW_String_deleteStorage( aString );
       
   523 			//User::Leave( KErrCorrupt );
       
   524 			attribute = HBufC::NewL(1);
       
   525 			TPtr aptr(attribute->Des());
       
   526 			aptr.Append(_L(""));
       
   527 			return attribute;
       
   528 			}
       
   529 		TPtrC attribValuePtr( ucs2Value );
       
   530 		attribute = attribValuePtr.Alloc();		
       
   531 		if( !attribute ) // mem alloc failed
       
   532 			{
       
   533 			free( ucs2Value ); 
       
   534 			NW_String_deleteStorage( aString );
       
   535 			User::Leave( KErrNoMemory );
       
   536 			}
       
   537 		}
       
   538 	else
       
   539 		{
       
   540 		NW_String_deleteStorage( aString );
       
   541 		User::Leave( KErrCorrupt );
       
   542 		}
       
   543 	// clean attribute value
       
   544 	free( ucs2Value ); 
       
   545 	NW_String_deleteStorage( aString );
       
   546 
       
   547 	FLOG( _L( "[ProvisioningParser] CWPWbxmlParser::ProcessAttributePartL end" ) );
       
   548 	return attribute;
       
   549 	}
       
   550 
       
   551 //  End of File