installationservices/swi/source/sislauncher/server/swtypereginfoparser.cpp
changeset 0 ba25891c3a9e
child 42 d17dc5398051
equal deleted inserted replaced
-1:000000000000 0:ba25891c3a9e
       
     1 /*
       
     2 * Copyright (c) 2008-2009 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 the License "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: 
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include "swtypereginfoparser.h"
       
    20 #include <scs/cleanuputils.h>
       
    21 #include <xml/parser.h>
       
    22 #include <xml/parserfeature.h>
       
    23 #include <swi/sisinstallerrors.h>
       
    24 
       
    25 using namespace Swi;
       
    26 
       
    27 namespace
       
    28 	{
       
    29 	_LIT8(KXmlMimeType, "text/xml");
       
    30 	
       
    31 	_LIT8(KNodeSoftwareTypeRegistrationData, "LayeredExecutionEnvironments");
       
    32 	_LIT8(KNodeSoftwareType, "softwareType");
       
    33 	_LIT8(KNodeLocalizedName, "localizedName");
       
    34 	_LIT8(KNodeMimeType, "mimeType");
       
    35 	_LIT8(KNodeSifPluginUid, "sifPluginUid");
       
    36 	_LIT8(KNodeInstallerSecureId, "installerSecureId");
       
    37 	_LIT8(KNodeExecutionLayerSecureId, "executionLayerSecureId");
       
    38 	
       
    39 	_LIT8(KAttrSoftwareTypeName, "name");
       
    40 	_LIT8(KAttrLanguage, "language");
       
    41 
       
    42 // ##########################################################################################
       
    43 
       
    44 	TUint Str2IntL(const TDesC8& aStr, TRadix aRadix = EDecimal)
       
    45 		{
       
    46 		TLex8 lex(aStr);
       
    47 		TUint i(0);
       
    48 		if (lex.Val(i, aRadix) != KErrNone)
       
    49 			{
       
    50 			User::Leave(KErrInvalidSoftwareTypeRegistrationFile);
       
    51 			}
       
    52 		return i;
       
    53 		}
       
    54 
       
    55 	TUint Str2IntL(const TDesC& aStr, TRadix aRadix = EDecimal)
       
    56 		{
       
    57 		TLex lex(aStr);
       
    58 		TUint i(0);
       
    59 		if (lex.Val(i, aRadix) != KErrNone)
       
    60 			{
       
    61 			User::Leave(KErrInvalidSoftwareTypeRegistrationFile);
       
    62 			}
       
    63 		return i;
       
    64 		}
       
    65 
       
    66 	TUid Str2UidL(const TDesC8& aStr)
       
    67 		{
       
    68 		TUid uid = TUid::Uid(Str2IntL(aStr, EHex));
       
    69 		return uid;
       
    70 		}
       
    71 
       
    72 	HBufC* AttributeLC(const Xml::RAttributeArray& aAttributes, const TDesC8& aAttrName)
       
    73 		{
       
    74 		HBufC* attrValue = NULL;
       
    75 
       
    76 		TInt numAttrs = aAttributes.Count();
       
    77 		for(TInt i=0; i<numAttrs; ++i)
       
    78 			{
       
    79 			const Xml::RAttribute& attribute = aAttributes[i];
       
    80 			const Xml::RTagInfo& nameInfo = attribute.Attribute();
       
    81 			const TDesC8& localName8 = nameInfo.LocalName().DesC();
       
    82 			if (aAttrName == localName8)
       
    83 				{
       
    84 				const TDesC8& value8 = attribute.Value().DesC();
       
    85 				attrValue = ConvertBufferTo16bitL(value8);
       
    86 				CleanupStack::PushL(attrValue);
       
    87 				break;
       
    88 				}
       
    89 			}
       
    90 		
       
    91 		if (attrValue == NULL)
       
    92 			{
       
    93 			User::Leave(KErrInvalidSoftwareTypeRegistrationFile);
       
    94 			}
       
    95 		
       
    96 		return attrValue;
       
    97 		}
       
    98 	}
       
    99 
       
   100 // ##########################################################################################
       
   101 
       
   102 CSoftwareTypeRegInfoParser* CSoftwareTypeRegInfoParser::NewL()
       
   103 	{
       
   104 	CSoftwareTypeRegInfoParser* self = new (ELeave) CSoftwareTypeRegInfoParser();
       
   105 	CleanupStack::PushL(self);
       
   106 	self->iNodes.AppendL(ENodeNone);
       
   107 	CleanupStack::Pop();
       
   108 	return self;
       
   109 	}
       
   110 
       
   111 CSoftwareTypeRegInfoParser::CSoftwareTypeRegInfoParser()
       
   112 	{
       
   113 	}
       
   114 
       
   115 CSoftwareTypeRegInfoParser::~CSoftwareTypeRegInfoParser()
       
   116 	{
       
   117 	delete iContentChunks;
       
   118 	iNodes.Close();
       
   119 	}
       
   120 
       
   121 void CSoftwareTypeRegInfoParser::ParseL(const TDesC8& aDocument, RPointerArray<CSoftwareTypeRegInfo>& aSwTypeRegInfoArray)
       
   122 	{
       
   123 	iSwTypeRegInfoArray = &aSwTypeRegInfoArray;
       
   124 	
       
   125 	Xml::CParser* parser = Xml::CParser::NewLC(KXmlMimeType, *this);
       
   126 	parser->EnableFeature(Xml::ESendFullContentInOneChunk); // Use ESendFullContentInOneChunk if the parser supports it
       
   127 	parser->ParseL(aDocument);
       
   128 	parser->ParseEndL();
       
   129 	CleanupStack::PopAndDestroy(parser);
       
   130 
       
   131 	if (iContentChunks != NULL)
       
   132 		{
       
   133 		iContentChunks->Des().Zero();
       
   134 		}
       
   135 	iNodes.Reset();
       
   136 	}
       
   137 
       
   138 void CSoftwareTypeRegInfoParser::OnStartDocumentL(const Xml::RDocumentParameters& /*aDocParam*/, TInt aErrorCode)
       
   139 	{
       
   140 	User::LeaveIfError(aErrorCode);
       
   141 	}
       
   142 
       
   143 void CSoftwareTypeRegInfoParser::OnEndDocumentL(TInt aErrorCode)
       
   144 	{
       
   145 	User::LeaveIfError(aErrorCode);
       
   146 	}
       
   147 
       
   148 void CSoftwareTypeRegInfoParser::PushNodeL(TXmlNode aNew, TXmlNode aExpectedParent)
       
   149 	{
       
   150 	ASSERT(iNodes.Count() > 0);
       
   151 
       
   152 	const TXmlNode parent = iNodes[iNodes.Count()-1];
       
   153 	if (aExpectedParent != parent)
       
   154 		{
       
   155 		User::Leave(KErrInvalidSoftwareTypeRegistrationFile);
       
   156 		}
       
   157 	iNodes.AppendL(aNew);
       
   158 	}
       
   159 
       
   160 void CSoftwareTypeRegInfoParser::OnStartElementL(const Xml::RTagInfo& aElement, const Xml::RAttributeArray& aAttributes, TInt aErrorCode)
       
   161 	{
       
   162 	User::LeaveIfError(aErrorCode);
       
   163 	ASSERT(iSwTypeRegInfoArray != NULL);
       
   164 
       
   165 	const TDesC8& localName8 = aElement.LocalName().DesC();
       
   166 	const TXmlNode node = ElementNameToNode(localName8);
       
   167 
       
   168 	switch (node)
       
   169 		{
       
   170 		case ENodeSoftwareTypeRegistrationData:
       
   171 			PushNodeL(ENodeSoftwareTypeRegistrationData, ENodeNone);
       
   172 			break;
       
   173 		
       
   174 		case ENodeSoftwareType:
       
   175 			{
       
   176 			PushNodeL(ENodeSoftwareType, ENodeSoftwareTypeRegistrationData);
       
   177 			HBufC* softwareTypeName = AttributeLC(aAttributes, KAttrSoftwareTypeName);
       
   178 			CSoftwareTypeRegInfo* regInfo = CSoftwareTypeRegInfo::NewL(*softwareTypeName);
       
   179 			CleanupStack::PushL(regInfo);
       
   180 			iSwTypeRegInfoArray->AppendL(regInfo);
       
   181 			CleanupStack::Pop();
       
   182 			CleanupStack::PopAndDestroy(softwareTypeName);
       
   183 			}
       
   184 			break;
       
   185 		
       
   186 		case ENodeLocalizedName:
       
   187 			{
       
   188 			ASSERT(iSwTypeRegInfoArray->Count() > 0);
       
   189 			PushNodeL(ENodeLocalizedName, ENodeSoftwareType);
       
   190 			HBufC* language = AttributeLC(aAttributes, KAttrLanguage);
       
   191 			iLocalizedNameLanguage = static_cast<TLanguage>(Str2IntL(*language));
       
   192 			CleanupStack::PopAndDestroy(language);
       
   193 			}
       
   194 			break;
       
   195 		
       
   196 		case ENodeMimeType:
       
   197 			ASSERT(iSwTypeRegInfoArray->Count() > 0);
       
   198 			PushNodeL(ENodeMimeType, ENodeSoftwareType);
       
   199 			break;
       
   200 		
       
   201 		case ENodeSifPluginUid:
       
   202 			ASSERT(iSwTypeRegInfoArray->Count() > 0);
       
   203 			PushNodeL(ENodeSifPluginUid, ENodeSoftwareType);
       
   204 			break;
       
   205 		
       
   206 		case ENodeInstallerSecureId:
       
   207 			ASSERT(iSwTypeRegInfoArray->Count() > 0);
       
   208 			PushNodeL(ENodeInstallerSecureId, ENodeSoftwareType);
       
   209 			break;
       
   210 		
       
   211 		case ENodeExecutionLayerSecureId:
       
   212 			ASSERT(iSwTypeRegInfoArray->Count() > 0);
       
   213 			PushNodeL(ENodeExecutionLayerSecureId, ENodeSoftwareType);
       
   214 			break;
       
   215 
       
   216 		default:
       
   217 			User::Leave(KErrInvalidSoftwareTypeRegistrationFile);
       
   218 		}
       
   219 	
       
   220 	if (iContentChunks != NULL)
       
   221 		{
       
   222 		iContentChunks->Des().Zero();
       
   223 		}
       
   224 	}
       
   225 
       
   226 void CSoftwareTypeRegInfoParser::OnEndElementL(const Xml::RTagInfo& aElement, TInt aErrorCode)
       
   227 	{
       
   228 	ASSERT(iSwTypeRegInfoArray != NULL);
       
   229 	User::LeaveIfError(aErrorCode);
       
   230 
       
   231 	const TInt lastIdx = iNodes.Count()-1;
       
   232 	const TXmlNode node = ElementNameToNode(aElement.LocalName().DesC());
       
   233 	const TXmlNode lastNode = iNodes[lastIdx];
       
   234 	if (node != lastNode)
       
   235 		{
       
   236 		User::Leave(KErrInvalidSoftwareTypeRegistrationFile);
       
   237 		}
       
   238 	iNodes.Remove(lastIdx);
       
   239 
       
   240 	RPointerArray<CSoftwareTypeRegInfo>& infoArray = *iSwTypeRegInfoArray;
       
   241 	switch (node)
       
   242 		{
       
   243 		case ENodeLocalizedName:
       
   244 			{
       
   245 			ASSERT(iSwTypeRegInfoArray->Count() > 0);
       
   246 			CSoftwareTypeRegInfo& regInfo = *infoArray[infoArray.Count()-1];
       
   247 			HBufC* name = ConvertBufferTo16bitL(*iContentChunks);
       
   248 			CleanupStack::PushL(name);
       
   249 			name->Des().TrimAll();
       
   250 			regInfo.SetLocalizedSoftwareTypeNameL(iLocalizedNameLanguage, *name);
       
   251 			CleanupStack::PopAndDestroy(name);
       
   252 			}
       
   253 			break;
       
   254 
       
   255 		case ENodeMimeType:
       
   256 			{
       
   257 			ASSERT(iSwTypeRegInfoArray->Count() > 0);
       
   258 			CSoftwareTypeRegInfo& regInfo = *infoArray[infoArray.Count()-1];
       
   259 			HBufC* mimeType = ConvertBufferTo16bitL(*iContentChunks);
       
   260 			CleanupStack::PushL(mimeType);
       
   261 			mimeType->Des().TrimAll();
       
   262 			regInfo.SetMimeTypeL(*mimeType);
       
   263 			CleanupStack::PopAndDestroy(mimeType);
       
   264 			}
       
   265 			break;
       
   266 		
       
   267 		case ENodeSifPluginUid:
       
   268 			{
       
   269 			ASSERT(iSwTypeRegInfoArray->Count() > 0);
       
   270 			iContentChunks->Des().TrimAll();
       
   271 			CSoftwareTypeRegInfo& regInfo = *infoArray[infoArray.Count()-1];
       
   272 			regInfo.SetSifPluginUid(Str2UidL(*iContentChunks));
       
   273 			}
       
   274 			break;
       
   275 		
       
   276 		case ENodeInstallerSecureId:
       
   277 			{
       
   278 			ASSERT(iSwTypeRegInfoArray->Count() > 0);
       
   279 			iContentChunks->Des().TrimAll();
       
   280 			CSoftwareTypeRegInfo& regInfo = *infoArray[infoArray.Count()-1];
       
   281 			regInfo.SetInstallerSecureId(Str2UidL(*iContentChunks));
       
   282 			}
       
   283 			break;
       
   284 		
       
   285 		case ENodeExecutionLayerSecureId:
       
   286 			{
       
   287 			ASSERT(iSwTypeRegInfoArray->Count() > 0);
       
   288 			iContentChunks->Des().TrimAll();
       
   289 			CSoftwareTypeRegInfo& regInfo = *infoArray[infoArray.Count()-1];
       
   290 			regInfo.SetExecutionLayerSecureId(Str2UidL(*iContentChunks));
       
   291 			}
       
   292 			break;
       
   293 		}
       
   294 	
       
   295 	if (iContentChunks != NULL)
       
   296 		{
       
   297 		iContentChunks->Des().Zero();
       
   298 		}
       
   299 	}
       
   300 
       
   301 void CSoftwareTypeRegInfoParser::OnContentL(const TDesC8& aBytes, TInt aErrorCode)
       
   302 	{
       
   303 	User::LeaveIfError(aErrorCode);
       
   304 	ASSERT(iNodes.Count() > 0);
       
   305 
       
   306 	switch (iNodes[iNodes.Count()-1])
       
   307 		{
       
   308 		case ENodeSoftwareTypeRegistrationData:
       
   309 		case ENodeSoftwareType:
       
   310 			break;
       
   311 		
       
   312 		case ENodeLocalizedName:
       
   313 		case ENodeMimeType:
       
   314 		case ENodeSifPluginUid:
       
   315 		case ENodeInstallerSecureId:
       
   316 		case ENodeExecutionLayerSecureId:
       
   317 			AddContentChunkL(aBytes);
       
   318 			break;
       
   319 
       
   320 		default:
       
   321 			User::Leave(KErrInvalidSoftwareTypeRegistrationFile);
       
   322 		}
       
   323 	}
       
   324 
       
   325 void CSoftwareTypeRegInfoParser::OnStartPrefixMappingL(const RString& /*aPrefix*/, const RString& /*aUri*/, TInt aErrorCode)
       
   326 	{
       
   327 	User::LeaveIfError(aErrorCode);
       
   328 	}
       
   329 
       
   330 void CSoftwareTypeRegInfoParser::OnEndPrefixMappingL(const RString& /*aPrefix*/, TInt aErrorCode)
       
   331 	{
       
   332 	User::LeaveIfError(aErrorCode);
       
   333 	}
       
   334 
       
   335 void CSoftwareTypeRegInfoParser::OnIgnorableWhiteSpaceL(const TDesC8& /*aBytes*/, TInt aErrorCode)
       
   336 	{
       
   337 	User::LeaveIfError(aErrorCode);
       
   338 	}
       
   339 
       
   340 void CSoftwareTypeRegInfoParser::OnSkippedEntityL(const RString& /*aName*/, TInt aErrorCode)
       
   341 	{
       
   342 	User::LeaveIfError(aErrorCode);
       
   343 	}
       
   344 
       
   345 void CSoftwareTypeRegInfoParser::OnProcessingInstructionL(const TDesC8& /*aTarget*/, const TDesC8& /*aData*/, TInt aErrorCode)
       
   346 	{
       
   347 	User::LeaveIfError(aErrorCode);
       
   348 	}
       
   349 
       
   350 void CSoftwareTypeRegInfoParser::OnError(TInt /*aErrorCode*/)
       
   351 	{
       
   352 	}
       
   353 
       
   354 TAny* CSoftwareTypeRegInfoParser::GetExtendedInterface(const TInt32 /*aUid*/)
       
   355 	{
       
   356 	return NULL;
       
   357 	}
       
   358 
       
   359 CSoftwareTypeRegInfoParser::TXmlNode CSoftwareTypeRegInfoParser::ElementNameToNode(const TDesC8& aName) const
       
   360 	{
       
   361 	if (aName == KNodeLocalizedName)
       
   362 		{
       
   363 		return ENodeLocalizedName;
       
   364 		}
       
   365 	else if (aName == KNodeMimeType)
       
   366 		{
       
   367 		return ENodeMimeType;
       
   368 		}
       
   369 	else if (aName == KNodeSifPluginUid)
       
   370 		{
       
   371 		return ENodeSifPluginUid;
       
   372 		}
       
   373 	else if (aName == KNodeInstallerSecureId)
       
   374 		{
       
   375 		return ENodeInstallerSecureId;
       
   376 		}
       
   377 	else if (aName == KNodeExecutionLayerSecureId)
       
   378 		{
       
   379 		return ENodeExecutionLayerSecureId;
       
   380 		}
       
   381 	else if (aName == KNodeSoftwareType)
       
   382 		{
       
   383 		return ENodeSoftwareType;
       
   384 		}
       
   385 	else if (aName == KNodeSoftwareTypeRegistrationData)
       
   386 		{
       
   387 		return ENodeSoftwareTypeRegistrationData;
       
   388 		}
       
   389 	else
       
   390 		{
       
   391 		return ENodeNone;
       
   392 		}
       
   393 	}
       
   394 	
       
   395 void CSoftwareTypeRegInfoParser::AddContentChunkL(const TDesC8& aChunk)
       
   396 	{
       
   397 	if (iContentChunks == NULL)
       
   398 		{
       
   399 		iContentChunks = HBufC8::NewL(aChunk.Length());
       
   400 		iContentChunks->Des().Copy(aChunk);
       
   401 		}
       
   402 	else
       
   403 		{
       
   404 		const TInt newLen = iContentChunks->Des().MaxLength() + aChunk.Length();
       
   405 		iContentChunks = iContentChunks->ReAlloc(newLen);
       
   406 		iContentChunks->Des().Append(aChunk);
       
   407 		}
       
   408 	}