installationservices/refswinstallationplugin/source/sifrefpkgparser.cpp
branchRCL_3
changeset 26 8b7f4e561641
parent 25 7333d7932ef7
child 27 e8965914fac7
equal deleted inserted replaced
25:7333d7932ef7 26:8b7f4e561641
     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 * This file implements a package file parser for the Reference Installer.
       
    16 *
       
    17 */
       
    18 
       
    19 
       
    20 #include "sifrefpkgparser.h"
       
    21 #include <f32file.h>
       
    22 #include "usiflog.h"
       
    23 #include <usif/usiferror.h>
       
    24 
       
    25 using namespace Usif;
       
    26 
       
    27 /**
       
    28 A set of helper functions for the parser.
       
    29 */
       
    30 namespace
       
    31 	{
       
    32 	_LIT8(KTxtCRLF, "\r\n");
       
    33 	_LIT8(KTxtLanguages, "Languages");
       
    34 	_LIT8(KTxtComponentName, "ComponentName");
       
    35 	_LIT8(KTxtComponentVendor, "ComponentVendor");
       
    36 	_LIT8(KTxtComponentVersion, "ComponentVersion");
       
    37 	_LIT8(KTxtFile, "File");
       
    38 
       
    39 	/** Maximum length of a value string in a package file */
       
    40 	const TInt KMaxValueLength = 0xFF;
       
    41 
       
    42 	void SplitLineL(const TPtrC8& aLine, TPtrC8& aName, TPtrC8& aValue)
       
    43 		{
       
    44 		const TInt colon = aLine.Locate(':');
       
    45 		if (colon == KErrNotFound)
       
    46 			{
       
    47 			DEBUG_PRINTF2(_L8("Missing colon in line: %S"), &aLine);
       
    48 			User::Leave(KErrCorrupt);
       
    49 			}
       
    50 
       
    51 		aName.Set(aLine.Left(colon));
       
    52 		aValue.Set(aLine.Mid(colon+1));
       
    53 		}
       
    54 
       
    55 	void SplitValuesL(const TPtrC8& aValues, RCHBufCArray& aValueArray)
       
    56 		{
       
    57 		TPtrC8 values(aValues);
       
    58 		while (values.Size() > 0)
       
    59 			{
       
    60 			TInt quot = values.Locate('"');
       
    61 			if (quot == KErrNotFound)
       
    62 				{
       
    63 				return;
       
    64 				}
       
    65 			values.Set(values.Mid(quot+1));
       
    66 			quot = values.Locate('"');
       
    67 			if (quot == KErrNotFound)
       
    68 				{
       
    69 				DEBUG_PRINTF2(_L8("Missing closing quotation mark in line: %S"), &aValues);
       
    70 				User::Leave(KErrCorrupt);
       
    71 				}
       
    72 			TPtrC8 token(values.Left(quot));
       
    73 
       
    74 			HBufC* value = HBufC::NewLC(KMaxValueLength);
       
    75 			TPtr valPtr(value->Des());
       
    76 			valPtr.Copy(token);
       
    77 			aValueArray.AppendL(value);
       
    78 			CleanupStack::Pop(value);
       
    79 
       
    80 			values.Set(values.Mid(quot+1));
       
    81 			}
       
    82 		}
       
    83 
       
    84 	void ParseComponentVersionL(const TPtrC8& aStringVersion, TVersion& aVersion)
       
    85 		{
       
    86 		// Check if already defined
       
    87 		if (aVersion.iMajor || aVersion.iMinor || aVersion.iBuild)
       
    88 			{
       
    89 			DEBUG_PRINTF(_L8("Multiple definition of Component Version"));
       
    90 			User::Leave(KErrCorrupt);
       
    91 			}
       
    92 
       
    93 		// Convert the major version number of Component Version
       
    94 		TLex8 lex(aStringVersion);
       
    95 		lex.SkipSpace();
       
    96 		TInt err = lex.Val(aVersion.iMajor);
       
    97 		if (err != KErrNone)
       
    98 			{
       
    99 			DEBUG_PRINTF(_L8("Failed parsing the major version number of Component Version"));
       
   100 			User::LeaveIfError(err);
       
   101 			}
       
   102 		lex.Inc();
       
   103 
       
   104 		// Convert the minor version number of Component Version
       
   105 		err = lex.Val(aVersion.iMinor);
       
   106 		if (err != KErrNone)
       
   107 			{
       
   108 			DEBUG_PRINTF(_L8("Failed parsing the minor version number of Component Version"));
       
   109 			User::LeaveIfError(err);
       
   110 			}
       
   111 		lex.Inc();
       
   112 
       
   113 		// Convert the build version number of Component Version
       
   114 		err = lex.Val(aVersion.iBuild);
       
   115 		if (err != KErrNone)
       
   116 			{
       
   117 			DEBUG_PRINTF(_L8("Failed parsing the build version number of Component Version"));
       
   118 			User::LeaveIfError(err);
       
   119 			}
       
   120 		}
       
   121 
       
   122 	TLanguage LanguageMapL(TDesC& aLanguage)
       
   123 		{
       
   124 		if (aLanguage == _L("EN"))
       
   125 			{
       
   126 			return ELangEnglish;
       
   127 			}
       
   128 		else if (aLanguage == _L("HU"))
       
   129 			{
       
   130 			return ELangHungarian;
       
   131 			}
       
   132 		else if (aLanguage == _L("PL"))
       
   133 			{
       
   134 			return ELangPolish;
       
   135 			}
       
   136 
       
   137 		DEBUG_PRINTF2(_L8("Language %S is not supported by this Reference Installer"), &aLanguage);
       
   138 		User::Leave(KErrSifUnsupportedLanguage);
       
   139 		return ELangNone;// Suppress warning
       
   140 		}
       
   141 	}
       
   142 
       
   143 CSifRefPkgParser* CSifRefPkgParser::NewL(const TDesC& aFileName)
       
   144 	{
       
   145 	CSifRefPkgParser* self = new (ELeave) CSifRefPkgParser;
       
   146 	CleanupStack::PushL(self);
       
   147 	self->ParseL(aFileName);
       
   148 	CleanupStack::Pop(self);
       
   149 	return self;
       
   150 	}
       
   151 
       
   152 CSifRefPkgParser::CSifRefPkgParser(): iVersion(0, 0, 0)
       
   153 	{
       
   154 	}
       
   155 
       
   156 CSifRefPkgParser::~CSifRefPkgParser()
       
   157 	{
       
   158 	iLanguages.Close();
       
   159 	iComponentNames.Close();
       
   160 	iVendorNames.Close();
       
   161 	iFiles.Close();
       
   162 	}
       
   163 
       
   164 const RLanguageArray& CSifRefPkgParser::Languages() const
       
   165 	{
       
   166 	return iLanguages;
       
   167 	}
       
   168 
       
   169 const RCHBufCArray& CSifRefPkgParser::ComponentNames() const
       
   170 	{
       
   171 	return iComponentNames;
       
   172 	}
       
   173 
       
   174 const RCHBufCArray& CSifRefPkgParser::VendorNames() const
       
   175 	{
       
   176 	return iVendorNames;
       
   177 	}
       
   178 
       
   179 const TVersion& CSifRefPkgParser::Version() const
       
   180 	{
       
   181 	return iVersion;
       
   182 	}
       
   183 
       
   184 const RCHBufCArray& CSifRefPkgParser::Files() const
       
   185 	{
       
   186 	return iFiles;
       
   187 	}
       
   188 
       
   189 void CSifRefPkgParser::ParseL(const TDesC& aFileName)
       
   190 	{
       
   191 	RFs fs;
       
   192 	RFile file;
       
   193 	User::LeaveIfError(fs.Connect());
       
   194 	CleanupClosePushL(fs);
       
   195 	TInt err = file.Open(fs, aFileName, EFileShareReadersOnly);
       
   196 	if (err != KErrNone)
       
   197 		{
       
   198 		DEBUG_PRINTF3(_L8("Failed to open file: %S with error: %d"), &aFileName, err);
       
   199 		User::Leave(err);
       
   200 		}
       
   201 	CleanupClosePushL(file);
       
   202 
       
   203 	ParseL(file);
       
   204 
       
   205 	CleanupStack::PopAndDestroy(2, &fs);
       
   206 	}
       
   207 
       
   208 void CSifRefPkgParser::ParseL(RFile& aFileHandle)
       
   209 	{
       
   210 	// Read the file into the buffer 
       
   211 	TInt fileSize = 0;
       
   212 	User::LeaveIfError(aFileHandle.Size(fileSize));
       
   213 	HBufC8* buffer = HBufC8::NewLC(fileSize);
       
   214 	TPtr8 bufPtr = buffer->Des();
       
   215 	TInt err = aFileHandle.Read(bufPtr);
       
   216 	if (err != KErrNone)
       
   217 		{
       
   218 		DEBUG_PRINTF2(_L8("Failed to read reference package file with err %d"), err);
       
   219 		User::LeaveIfError(err);
       
   220 		}
       
   221 
       
   222 	// Iterate over the lines
       
   223 	TPtrC8 lines(*buffer);
       
   224 	const TInt crlfLen = TPtrC8(KTxtCRLF).Size();
       
   225 	while (lines.Size() > 0)
       
   226 		{
       
   227 		// Find next line
       
   228 		TPtrC8 line;
       
   229 		const TInt crlfPos = lines.Find(KTxtCRLF);
       
   230 		if (crlfPos != KErrNotFound)
       
   231 			{
       
   232 			line.Set(lines.Left(crlfPos));
       
   233 			lines.Set(lines.Mid(crlfPos+crlfLen));
       
   234 			}
       
   235 		else
       
   236 			{
       
   237 			if (lines.Size() > 0)
       
   238 				{
       
   239 				line.Set(lines);
       
   240 				lines.Set(TPtrC8());
       
   241 				}
       
   242 			}
       
   243 		
       
   244 		// Split the line into a pair of the name of a tag and its value
       
   245 		TPtrC8 name, value;
       
   246 		SplitLineL(line, name, value);
       
   247 		
       
   248 		// Hand over the pair to recognition
       
   249 		LineHandlerL(name, value);
       
   250 		}
       
   251 	CleanupStack::PopAndDestroy(buffer);
       
   252 	
       
   253 	// Check whether the file we have just parsed wasn't corrupted
       
   254 	CheckInvariantL();
       
   255 	}
       
   256 
       
   257 void CSifRefPkgParser::LineHandlerL(const TPtrC8& aName, const TPtrC8& aValue)
       
   258 	{
       
   259 	if (aName == KTxtLanguages)
       
   260 		{
       
   261 		if (iLanguages.Count() > 0)
       
   262 			{
       
   263 			DEBUG_PRINTF(_L8("Multiple definition of languages"));
       
   264 			User::Leave(KErrCorrupt);
       
   265 			}
       
   266 		RCHBufCArray languages;
       
   267 		CleanupClosePushL(languages);
       
   268 		SplitValuesL(aValue, languages);
       
   269 		const TInt count = languages.Count();
       
   270 		for (TInt i=0; i<count; ++i)
       
   271 			{
       
   272 			iLanguages.AppendL(LanguageMapL(*languages[i]));
       
   273 			}
       
   274 		CleanupStack::PopAndDestroy(&languages);
       
   275 		}
       
   276 	else if (aName == KTxtComponentName)
       
   277 		{
       
   278 		if (iComponentNames.Count() > 0)
       
   279 			{
       
   280 			DEBUG_PRINTF(_L8("Multiple definition of Component Name"));
       
   281 			User::Leave(KErrCorrupt);
       
   282 			}
       
   283 		SplitValuesL(aValue, iComponentNames);
       
   284 		}
       
   285 	else if (aName == KTxtComponentVendor)
       
   286 		{
       
   287 		if (iVendorNames.Count() > 0)
       
   288 			{
       
   289 			DEBUG_PRINTF(_L8("Multiple definition of Component Vendor"));
       
   290 			User::Leave(KErrCorrupt);
       
   291 			}
       
   292 		SplitValuesL(aValue, iVendorNames);
       
   293 		}
       
   294 	else if (aName == KTxtComponentVersion)
       
   295 		{
       
   296 		ParseComponentVersionL(aValue, iVersion);
       
   297 		}
       
   298 	else if (aName == KTxtFile)
       
   299 		{
       
   300 		HBufC* file = HBufC::NewLC(aValue.Size());
       
   301 		TPtr fileBuf = file->Des();
       
   302 		fileBuf.Copy(aValue);
       
   303 		fileBuf.Trim();
       
   304 		iFiles.AppendL(file);
       
   305 		CleanupStack::Pop(file);
       
   306 		}
       
   307 	else
       
   308 		{
       
   309 		DEBUG_PRINTF2(_L8("Failed due to unrecognized token: %S"), &aName);
       
   310 		User::Leave(KErrCorrupt);
       
   311 		}
       
   312 	}
       
   313 
       
   314 TInt CSifRefPkgParser::GetLanguageIndex(TLanguage aLanguage) const
       
   315 	{
       
   316 	const TInt count = iLanguages.Count();
       
   317 	for (TInt i=0; i<count; ++i)
       
   318 		{
       
   319 		if (iLanguages[i] == aLanguage)
       
   320 			{
       
   321 			return i;
       
   322 			}
       
   323 		}
       
   324 	return KErrNotFound;
       
   325 	}
       
   326 
       
   327 void CSifRefPkgParser::CheckInvariantL() const
       
   328 	{
       
   329 	if (iVersion.iMajor == 0 && iVersion.iMinor == 0 && iVersion.iBuild == 0)
       
   330 		{
       
   331 		DEBUG_PRINTF(_L8("Version not specified!"));
       
   332 		User::Leave(KErrCorrupt);
       
   333 		}
       
   334 	if (iLanguages.Count() == 0)
       
   335 		{
       
   336 		DEBUG_PRINTF(_L8("Language not specified!"));
       
   337 		User::Leave(KErrCorrupt);
       
   338 		}
       
   339 	if (iLanguages.Count() != iComponentNames.Count())
       
   340 		{
       
   341 		DEBUG_PRINTF(_L8("The number of languages and component names don't match!"));
       
   342 		User::Leave(KErrCorrupt);
       
   343 		}
       
   344 	if (iLanguages.Count() != iVendorNames.Count())
       
   345 		{
       
   346 		DEBUG_PRINTF(_L8("The number of languages and vendor names don't match!"));
       
   347 		User::Leave(KErrCorrupt);
       
   348 		}
       
   349 	}