gfxconversion/mifconv/src/mifconv_argumentmanager.cpp
changeset 0 f453ebb75370
child 2 1f6339ced17d
equal deleted inserted replaced
-1:000000000000 0:f453ebb75370
       
     1 /*
       
     2 * Copyright (c) 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 "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:  Mifconv argument manager class.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include "mifconv.h"
       
    20 #include "mifconv_argumentmanager.h"
       
    21 #include "mifconv_exception.h"
       
    22 #include "mifconv_util.h"
       
    23 
       
    24 // Static singleton initialization
       
    25 MifConvArgumentManager* MifConvArgumentManager::iInstance = 0;
       
    26 
       
    27 /**
       
    28  * Returns pointer to the singleton object
       
    29  */
       
    30 MifConvArgumentManager* MifConvArgumentManager::Instance()
       
    31 {
       
    32     if( iInstance == 0 )
       
    33     {
       
    34         iInstance = new MifConvArgumentManager();
       
    35     }
       
    36     return iInstance;
       
    37 }
       
    38 
       
    39 /**
       
    40  * Free the allocated memory
       
    41  */
       
    42 void MifConvArgumentManager::Reset()
       
    43 {
       
    44     delete iInstance;
       
    45     iInstance = 0;
       
    46 }
       
    47 
       
    48 /**
       
    49  *
       
    50  */
       
    51 inline void MifConvArgumentManager::THROW_USAGE_EXCEPTION() const
       
    52 {
       
    53 	MifConvString usageStr;
       
    54 	SetUsageString(usageStr);
       
    55 	throw MifConvException(usageStr, MifConvString(__FILE__), __LINE__);
       
    56 }
       
    57 
       
    58 inline void MifConvArgumentManager::THROW_ERROR( const MifConvString& errorMsg, const MifConvString& file, int line ) const
       
    59 {    
       
    60     throw MifConvException( MifConvString("ERROR: " + errorMsg + "\nType mifconv -? for help\n"), file, line);
       
    61 }
       
    62 
       
    63 /**
       
    64  *
       
    65  */
       
    66 MifConvArgumentManager::MifConvArgumentManager()
       
    67 :
       
    68 iEpocRoot(DEFAULT_EPOCROOT)
       
    69 {
       
    70     GetMifEnv();
       
    71 }
       
    72 
       
    73 /**
       
    74  *
       
    75  */
       
    76 MifConvArgumentManager::~MifConvArgumentManager()
       
    77 {}
       
    78 
       
    79 /**
       
    80  * This function checks if the given argument is boolean type of argument.
       
    81  * Boolean type arguments are listed in a <code>MifConvBooleanArguments</code> table
       
    82  * and this function checks if the given string matches any of those. Returns the length
       
    83  * of the argument name if found, zero otherwise.
       
    84  */
       
    85 size_t MifConvArgumentManager::IsBooleanArgument( const MifConvString& argName ) const
       
    86 {
       
    87 	if( IsArgument(argName) )
       
    88 	{
       
    89 		try {
       
    90 			int tblSize = sizeof(MifConvBooleanArguments) / sizeof(MifConvString);
       
    91 			for( int i = 0; i < tblSize; ++i )
       
    92 			{
       
    93 				size_t tmpLen = MifConvBooleanArguments[i].length();
       
    94 				if( argName.length() > tmpLen )
       
    95 				{
       
    96                     if( MifConvUtil::CompareIgnoreCase(MifConvString(argName.begin()+1, argName.begin() + 1 + tmpLen), MifConvBooleanArguments[i]) == 0 )
       
    97 					{
       
    98 						return tmpLen;
       
    99 					}
       
   100 				}
       
   101 			}
       
   102 		}
       
   103 		catch(...)
       
   104 		{
       
   105 			THROW_USAGE_EXCEPTION();
       
   106 		}
       
   107 	}
       
   108 	return 0;
       
   109 }
       
   110 
       
   111 /**
       
   112  * This function checks if the given argument is a help argument.
       
   113  * Help arguments are listed in a <code>MifConvHelpArguments</code> table
       
   114  * and this function checks if the given string matches any of those. Returns the length
       
   115  * of the argument name if found, zero otherwise.
       
   116  */
       
   117 size_t MifConvArgumentManager::IsHelpArgument( const MifConvString& argName ) const
       
   118 {
       
   119 	if( IsArgument(argName) )
       
   120 	{
       
   121 		try {
       
   122 			int tblSize = sizeof(MifConvHelpArguments) / sizeof(MifConvString);
       
   123 			for( int i = 0; i < tblSize; ++i )
       
   124 			{
       
   125 				size_t tmpLen = MifConvHelpArguments[i].length();
       
   126 
       
   127                 // Following check separates -H from -Hheadername.mbg parameter:
       
   128                 if( argName.length() == tmpLen+1 )
       
   129 				{
       
   130                     if( MifConvUtil::CompareIgnoreCase(MifConvString(argName.begin()+1, argName.begin() + 1 + tmpLen), MifConvHelpArguments[i]) == 0 )
       
   131 					{
       
   132 						return tmpLen;
       
   133 					}
       
   134 				}
       
   135 			}
       
   136 		}
       
   137 		catch(...)
       
   138 		{
       
   139 			THROW_USAGE_EXCEPTION();
       
   140 		}
       
   141 	}
       
   142 	return 0;
       
   143 }
       
   144 
       
   145 /**
       
   146  * This function checks if the given argument is string type of argument.
       
   147  * String type arguments are listed in a <code>MifConvStringArguments</code> table
       
   148  * and this function checks if the given string matches any of those. Returns the length
       
   149  * of the argument name if found, zero otherwise.
       
   150  */
       
   151 size_t MifConvArgumentManager::IsStringArgument( const MifConvString& argName ) const
       
   152 {    
       
   153 	if( IsArgument(argName) )
       
   154 	{
       
   155 		try {
       
   156 			int tblSize = sizeof(MifConvStringArguments) / sizeof(MifConvString);
       
   157 			for( int i = 0; i < tblSize; ++i )
       
   158 			{
       
   159 				size_t tmpLen = MifConvStringArguments[i].length();
       
   160 				if( argName.length() > tmpLen )
       
   161 				{
       
   162                     if( MifConvUtil::CompareIgnoreCase(MifConvString(argName.begin()+1, argName.begin()+1+tmpLen), MifConvStringArguments[i]) == 0 )
       
   163 					{
       
   164 						return tmpLen;
       
   165 					}
       
   166 				}				
       
   167 			}
       
   168 		}
       
   169 		catch(...)
       
   170 		{
       
   171 			THROW_USAGE_EXCEPTION();
       
   172 		}
       
   173 	}
       
   174 	return 0;
       
   175 }
       
   176 
       
   177 /**
       
   178  * This function checks if the given argument is string list type of argument.
       
   179  * String list type arguments are listed in a <code>MifConvStringListArguments</code> table
       
   180  * and this function checks if the given string matches any of those. Returns the length
       
   181  * of the argument name if found, zero otherwise.
       
   182  */
       
   183 size_t MifConvArgumentManager::IsStringListArgument( const MifConvString& argName ) const
       
   184 {
       
   185 	if( IsArgument(argName) )
       
   186 	{
       
   187 		try {
       
   188 			int tblSize = sizeof(MifConvStringListArguments) / sizeof(MifConvString);
       
   189 			for( int i = 0; i < tblSize; ++i )
       
   190 			{
       
   191 				size_t tmpLen = MifConvStringListArguments[i].length();
       
   192 				if( argName.length() > tmpLen )
       
   193 				{
       
   194                     if( MifConvUtil::CompareIgnoreCase(MifConvString(argName.begin()+1, argName.begin()+1+tmpLen), MifConvStringListArguments[i]) == 0 )
       
   195 					{
       
   196 						return tmpLen;
       
   197 					}
       
   198 				}				
       
   199 			}
       
   200 		}
       
   201 		catch(...)
       
   202 		{
       
   203 			THROW_USAGE_EXCEPTION();
       
   204 		}
       
   205 	}
       
   206 	return 0;
       
   207 }
       
   208 
       
   209 /**
       
   210  *
       
   211  */
       
   212 bool MifConvArgumentManager::IsDepthArgument( const MifConvString& argName ) const
       
   213 {
       
   214 	if( IsArgument(argName) )
       
   215 	{
       
   216 		try {
       
   217 			int tblSize = sizeof(MifConvDepthArguments) / sizeof(MifConvString);
       
   218 			for( int i = 0; i < tblSize; ++i )
       
   219 			{
       
   220 				size_t tmpLen = MifConvDepthArguments[i].length();
       
   221                 if( argName.length() > tmpLen )
       
   222 				{
       
   223                     MifConvString trimmedArgument(argName.begin()+1, argName.begin() + 1 + tmpLen);                
       
   224                     if( MifConvUtil::CompareIgnoreCase(trimmedArgument, MifConvDepthArguments[i]) == 0 )
       
   225 					{
       
   226 						return true;
       
   227 					}                    
       
   228 				}
       
   229 			}
       
   230 		}
       
   231 		catch(...)
       
   232 		{
       
   233 			THROW_USAGE_EXCEPTION();
       
   234 		}
       
   235 	}
       
   236 	return false;
       
   237 }
       
   238 
       
   239 /**
       
   240  *
       
   241  */
       
   242 bool MifConvArgumentManager::IsAnimatedFlag( const MifConvString& argName ) const
       
   243 {
       
   244 	return IsArgument( argName ) && argName.length() > MifConvAnimatedIconArg.length() && 
       
   245         MifConvUtil::CompareIgnoreCase(MifConvString(argName.begin()+1, argName.end() ), MifConvAnimatedIconArg ) == 0;
       
   246 }
       
   247 
       
   248 /**
       
   249  *
       
   250  */
       
   251 void MifConvArgumentManager::SetTargetFile( const MifConvString& arg )
       
   252 {
       
   253 	iTargetFile = arg;
       
   254 }
       
   255 
       
   256 /**
       
   257  *
       
   258  */
       
   259 const MifConvString& MifConvArgumentManager::TargetFile() const
       
   260 {
       
   261 	return iTargetFile;
       
   262 }
       
   263 
       
   264 /**
       
   265  *
       
   266  */
       
   267 IconDisplayMode MifConvArgumentManager::ConvertToDisplayMode(IconDepth depth) const
       
   268 {
       
   269     MifConvIconDisplayModeMap::const_iterator i = iDisplayModeMap.find(depth);
       
   270     if( i != iDisplayModeMap.end() )
       
   271         return i->second;
       
   272 
       
   273     return DisplayMode_None;    
       
   274 }
       
   275 
       
   276 /**
       
   277  *
       
   278  */
       
   279 IconDisplayMode MifConvArgumentManager::ConvertToMaskDisplayMode(IconMaskDepth depth) const
       
   280 {
       
   281     MifConvMaskIconDisplayModeMap::const_iterator i = iMaskDisplayModeMap.find(depth);
       
   282     if( i != iMaskDisplayModeMap.end() )
       
   283         return i->second;
       
   284 
       
   285     return DisplayMode_None;    
       
   286 }
       
   287 
       
   288 /**
       
   289  *
       
   290  */
       
   291 IconDepth MifConvArgumentManager::ConvertToDepth( const MifConvString& depthStr ) const
       
   292 {
       
   293     MifConvIconDepthMap::const_iterator i = iDepthMap.find(depthStr);
       
   294     if( i != iDepthMap.end() )
       
   295         return i->second;
       
   296 
       
   297     return IconDepth_Undefined;    
       
   298 }
       
   299 /**
       
   300  *
       
   301  */
       
   302 IconMaskDepth MifConvArgumentManager::ConvertToMaskDepth( const MifConvString depthStr ) const
       
   303 {
       
   304     MifConvIconMaskDepthMap::const_iterator i = iMaskDepthMap.find(depthStr);
       
   305     if( i != iMaskDepthMap.end() )
       
   306         return i->second;
       
   307 
       
   308     return IconMaskDepth_Undefined;    
       
   309 }
       
   310 
       
   311 /**
       
   312  *
       
   313  */
       
   314 void MifConvArgumentManager::Init( const MifConvStringList& argList )
       
   315 {	    
       
   316     // Build maps for mapping depth, mask and displaymode constants:
       
   317     PopulateDepthAndMaskMaps();
       
   318     // Allocate search paths where to search source files:    
       
   319     MifConvString epocRoot(EpocRoot());
       
   320          
       
   321     // Global icons folder can contain only .svg files:
       
   322     iSearchRules.push_back(MifConvSourceSearchRule(MifConvString(epocRoot + S60_ICONS_PATH), vector<MifConvString>(1, SVG_FILE_EXTENSION)));
       
   323     // Global bitmaps folder can contain only .bmp files:
       
   324     iSearchRules.push_back(MifConvSourceSearchRule(MifConvString(epocRoot + S60_BITMAPS_PATH), vector<MifConvString>(1, BMP_FILE_EXTENSION)));
       
   325     // EPOCROOT, if given in environment variables:
       
   326     if( epocRoot.length() > 0 )
       
   327     {
       
   328         iSearchRules.push_back(MifConvSourceSearchRule(epocRoot+EPOC32_PATH, vector<MifConvString>(1, MIFCONV_WILDCARD)));
       
   329     }
       
   330 
       
   331     AddArguments(argList);
       
   332 
       
   333     // check if the parameter file is given:
       
   334     const MifConvString& paramFilename = StringValue(MifConvParameterFileArg);
       
   335     if( paramFilename.length() > 0 )
       
   336     {
       
   337         // Add arguments from the parameter file:
       
   338         MifConvStringList paramListFromFile;
       
   339         ReadParameterFile( paramFilename, paramListFromFile );
       
   340         if( paramListFromFile.size() > 0 )
       
   341         {
       
   342             AddArguments(paramListFromFile, true);
       
   343         }
       
   344     }
       
   345     // Resolve file type extensions using given flags and investigating the existing files:
       
   346 	FinalizeArguments();
       
   347 }
       
   348 
       
   349 /**
       
   350  * Read string argument value:
       
   351  */
       
   352 MifConvString MifConvArgumentManager::ReadStringArgument(const MifConvStringList& argList, MifConvStringList::const_iterator& i, unsigned int argNameLen)
       
   353 {    
       
   354     // Take the actual argument value, for example /TmyTempDir --> myTempDir    
       
   355     MifConvString argValue((*i).begin() + argNameLen, (*i).end());
       
   356     if( argValue.length() > 0 )
       
   357     {
       
   358         // String arguments can have spaces when they are enclosed with " marks (For example directory names).
       
   359         if( argValue[0] == '\"' )
       
   360         {
       
   361             MifConvString quotedArgValue(argValue);
       
   362             // Check if the last char is also ":
       
   363             if( quotedArgValue[ quotedArgValue.length()-1 ] == '\"' )
       
   364             {                
       
   365                 return quotedArgValue;
       
   366             }
       
   367 
       
   368             // See if the next string ends with \" mark, for example "My Folder" is presented with following argument list:
       
   369             // argList[0] = "My
       
   370             // argList[1] = Folder"
       
   371             while(++i != argList.end())
       
   372             {
       
   373                 MifConvString nextString((*i).begin(), (*i).end());
       
   374                 quotedArgValue += " " + nextString;
       
   375                 if( nextString[ nextString.length()-1 ] == '\"' )
       
   376                 {                    
       
   377                     return "\"" + quotedArgValue + "\"";
       
   378                 }
       
   379             }
       
   380         }
       
   381     }    
       
   382     return argValue;
       
   383 }
       
   384 
       
   385 /**
       
   386  * Read string argument value:
       
   387  */
       
   388 void MifConvArgumentManager::ReadStringListArgument(MifConvStringList::const_iterator& i, unsigned int argNameLen, MifConvStringList& StringValueList)
       
   389 {    
       
   390     // Take the actual argument value, for example /imyInputDir;myTempDir --> myTempDir    
       
   391     MifConvString argValue((*i).begin() + argNameLen, (*i).end());    
       
   392     MifConvUtil::SplitString( argValue, STRING_LIST_ARGUMENT_SEPARATOR, StringValueList );
       
   393 }
       
   394 
       
   395 /**
       
   396  *
       
   397  */
       
   398 void MifConvArgumentManager::AddArguments( const MifConvStringList& argList, bool paramsFromFile )
       
   399 {
       
   400 	MifConvStringList::const_iterator i = argList.begin();
       
   401 
       
   402 	if( i == argList.end() )
       
   403 	{		
       
   404         THROW_ERROR("No arguments", MifConvString(__FILE__), __LINE__);	
       
   405 	}
       
   406 
       
   407     // Check if help is needed:
       
   408     while( i != argList.end() )
       
   409     {
       
   410         if( IsHelpArgument(*i) )
       
   411         {
       
   412             THROW_USAGE_EXCEPTION();
       
   413         }
       
   414         ++i;
       
   415     }
       
   416 
       
   417     i = argList.begin();
       
   418 
       
   419 	while( i != argList.end() )
       
   420 	{	        
       
   421 		unsigned int argLen = 0;
       
   422 		if( i == argList.begin() && paramsFromFile == false )
       
   423 		{
       
   424 			// First command line argument must be the target file.
       
   425             // If the given list (argList) is read from the file, then
       
   426             // the first one is not target file.
       
   427 			if( !IsArgument(*i) )
       
   428 			{           
       
   429 			    MifConvString targetFile(ReadStringArgument( argList, i, 0 ));			    
       
   430 			    // Make sure that the file extension is .mif:
       
   431 			    targetFile = MifConvUtil::FilenameWithoutExtension(targetFile);
       
   432 			    targetFile += MifConvString(FILE_EXTENSION_SEPARATOR) + MifConvString(MIF_FILE_EXTENSION);
       
   433 				SetTargetFile(targetFile);                
       
   434 			}
       
   435 			else
       
   436 			{
       
   437                 THROW_ERROR( "Target file must be given as first argument.", MifConvString(__FILE__), __LINE__ );                
       
   438 			}
       
   439 			++i;
       
   440             if( i == argList.end() )
       
   441             {
       
   442                 THROW_ERROR("Missing arguments", MifConvString(__FILE__), __LINE__);
       
   443             }
       
   444 		}
       
   445 		else if( IsBooleanArgument(*i) )
       
   446 		{
       
   447 			// Insert boolean type argument to the boolean arguments list:
       
   448 			MifConvString argName((*i).begin()+1, (*i).end());
       
   449             MifConvUtil::ToLower(argName); // Lower the cases to make comparison easier later
       
   450             std::pair<BooleanArgMap::iterator, bool> res = iBooleanArguments.insert(std::make_pair<MifConvString, MifConvBooleanArgument>(
       
   451 				argName, MifConvBooleanArgument( argName, true )));
       
   452             if( res.second == false )
       
   453             {
       
   454                 // parameter already exists in the map, update the value:
       
   455                 res.first->second = MifConvBooleanArgument( argName, true );
       
   456             }
       
   457 			++i;
       
   458 		}
       
   459 		else if( (argLen = (unsigned int) IsStringArgument(*i) ) > 0 )
       
   460 		{			
       
   461 			MifConvString argName((*i).begin()+1, (*i).begin() + 1 + argLen);
       
   462             MifConvUtil::ToLower(argName); // Lower the cases to make comparison easier later			
       
   463             MifConvString argValue(ReadStringArgument( argList, i, argLen+1 ));            
       
   464 			if( argValue.length() == 0 )
       
   465 			{
       
   466 				// Do not accept string arguments with zero length (E.g. "/H")
       
   467                 THROW_ERROR( "Missing argument value for " + *i, MifConvString(__FILE__), __LINE__ );                
       
   468 			}
       
   469 			// Insert string type argument to the string arguments list:
       
   470 			std::pair<StringArgMap::iterator, bool> res = iStringArguments.insert(std::make_pair<MifConvString, MifConvStringArgument>(
       
   471 				argName, MifConvStringArgument( argName, argValue )));
       
   472             if( res.second == false )
       
   473             {
       
   474                 // parameter already exists in the map, update the value:
       
   475                 res.first->second = MifConvStringArgument( argName, argValue );
       
   476             }
       
   477 			++i;
       
   478 		}
       
   479         else if( (argLen = (unsigned int) IsStringListArgument(*i)) > 0 )
       
   480         {
       
   481             MifConvString argName((*i).begin()+1, (*i).begin() + 1 + argLen);
       
   482             MifConvUtil::ToLower(argName); // Lower the cases to make comparison easier later			
       
   483             MifConvStringList argValue;
       
   484             ReadStringListArgument( i, argLen+1, argValue );
       
   485 
       
   486             if( argValue.size() == 0 )
       
   487 			{
       
   488 				// Do not accept string arguments with zero length (E.g. "/H")
       
   489                 THROW_ERROR( "Missing argument value for " + *i, MifConvString(__FILE__), __LINE__ );                
       
   490 			}
       
   491 			// Insert string list type argument to the string arguments list:
       
   492 			std::pair<StringListArgMap::iterator, bool> res = iStringListArguments.insert(std::make_pair<MifConvString, MifConvStringListArgument>(
       
   493 				argName, MifConvStringListArgument( argName, argValue )));
       
   494             if( res.second == false )
       
   495             {
       
   496                 // parameter already exists in the map, update the value:
       
   497                 res.first->second = MifConvStringListArgument( argName, argValue );
       
   498             }
       
   499 			++i;
       
   500         }
       
   501 		else if( IsDepthArgument(*i) )
       
   502 		{
       
   503 			// Let's build source file argument...
       
   504 			// ... first is depth and mask:
       
   505 			MifConvString depthAndMask(*i);
       
   506             MifConvUtil::ToLower(depthAndMask); // Lower the cases to make comparison easier later
       
   507 			++i;
       
   508             // Check that there is still an argument:
       
   509             if( i == argList.end() )
       
   510             {
       
   511                 THROW_ERROR( "Missing source file argument.", MifConvString(__FILE__), __LINE__ );                
       
   512             }
       
   513 
       
   514 			// Then we check if animated flag is given next:
       
   515 			bool isAnimated = IsAnimatedFlag(*i);
       
   516 
       
   517 			if( isAnimated )
       
   518 			{
       
   519 				// This was an animated flag, so next must be filename:
       
   520 				++i;
       
   521                 // Check that there is still an argument:
       
   522                 if( i == argList.end() )
       
   523                 {
       
   524                     THROW_ERROR( "Missing source file argument.", MifConvString(__FILE__), __LINE__ );
       
   525                     //THROW_USAGE_EXCEPTION();
       
   526                 }
       
   527 			}
       
   528 			
       
   529 			// One more check... Check that the next string is not an argument (starting with '-' or '/')
       
   530 			// It should be a filename for the source icon.
       
   531 			if( IsArgument(*i) )
       
   532 			{
       
   533                 THROW_ERROR( "Missing source file argument.", MifConvString(__FILE__), __LINE__ );                
       
   534 			}
       
   535 
       
   536             MifConvSourceFile srcFile;
       
   537             srcFile.SetDepthAndMask(depthAndMask);
       
   538             srcFile.SetDisplayMode(ConvertToDisplayMode(srcFile.Depth()));
       
   539             srcFile.SetMaskDisplayMode(ConvertToMaskDisplayMode(srcFile.MaskDepth()));
       
   540             srcFile.SetFilename(ReadStringArgument( argList, i, 0 ));
       
   541             srcFile.SetAnimated(isAnimated);
       
   542             iSourceFiles.push_back(srcFile);			
       
   543 			++i;
       
   544 		}
       
   545 		else if( IsAnimatedFlag(*i) )
       
   546 		{
       
   547 			// Icon animated flag found
       
   548 			// Let's see if the next is depth argument:
       
   549 			++i;
       
   550 			MifConvString depthAndMask;
       
   551 			if( IsDepthArgument(*i) )
       
   552 			{
       
   553 				depthAndMask = *i;
       
   554                 MifConvUtil::ToLower(depthAndMask);
       
   555 				++i;
       
   556 			}
       
   557 
       
   558 			// One more check... Check that the next string is not an argument (starting with '-' or '/')
       
   559 			if( IsArgument(*i) )
       
   560 			{
       
   561                 THROW_ERROR( "Missing source file argument.", MifConvString(__FILE__), __LINE__ );                
       
   562 			}
       
   563 
       
   564             MifConvSourceFile srcFile;
       
   565             srcFile.SetDepthAndMask(depthAndMask);
       
   566             srcFile.SetDisplayMode(ConvertToDisplayMode(srcFile.Depth()));
       
   567             srcFile.SetMaskDisplayMode(ConvertToMaskDisplayMode(srcFile.MaskDepth()));
       
   568             srcFile.SetFilename(*i);
       
   569             srcFile.SetAnimated(true);
       
   570             iSourceFiles.push_back(srcFile);
       
   571 			++i;
       
   572 		}
       
   573 		else
       
   574 		{
       
   575             THROW_ERROR( "Invalid argument: " + *i, MifConvString(__FILE__), __LINE__ );            
       
   576         }
       
   577 	}
       
   578 }
       
   579 
       
   580 /**
       
   581  * Resolves correct type for the source file. Sets also mask filenames for bmp-files:
       
   582  */
       
   583 void MifConvArgumentManager::ResolveSourceFileTypes()
       
   584 {
       
   585     bool extensionFlag = BooleanValue(MifConvUseExtensionArg);
       
   586 
       
   587     // check if the input directory is given:
       
   588     const MifConvStringList& inputDirList = StringListValue(MifConvIconSourceDirectory);
       
   589 
       
   590     // Add user-defined input directory to search directory list, put MIFCONV_WILDCARD
       
   591     // as filetype rule, because user defined directory can contain all supported filetypes:
       
   592     int indexcounter = 0;
       
   593     for( MifConvStringList::const_iterator iDir = inputDirList.begin(); iDir != inputDirList.end(); ++iDir )
       
   594     {
       
   595         MifConvSourceSearchRule customRule(*iDir, MifConvStringList(1, MIFCONV_WILDCARD));
       
   596         MifConvUtil::ReplaceChar(customRule.SearchPath(), INCORRECT_DIR_SEPARATOR2, DIR_SEPARATOR2);
       
   597         MifConvUtil::RemoveDuplicateDirSeparators(customRule.SearchPath());
       
   598         iSearchRules.insert(iSearchRules.begin()+indexcounter, customRule);
       
   599         
       
   600         ++indexcounter;
       
   601     }
       
   602     
       
   603     for( MifConvSourceFileList::iterator src = iSourceFiles.begin(); src != iSourceFiles.end(); ++ src )
       
   604     {
       
   605         if( extensionFlag )
       
   606         {
       
   607             MifConvString extension = MifConvUtil::FileExtension(src->Filename());
       
   608             if( !FindAndSetPathAndType( *src, extension ) )
       
   609             {                 
       
   610                 THROW_ERROR_COMMON("File not found " + src->Filename(), MifConvString(__FILE__), __LINE__ );
       
   611             }
       
   612         }
       
   613         else
       
   614         {
       
   615             // "Use extension" -flag not given, so resolve extensions for source files
       
   616             if( !FindAndSetPathAndType( *src, SVGB_BINARY_FILE_EXTENSION ) )
       
   617             { 
       
   618                 if( !FindAndSetPathAndType( *src, SVG_FILE_EXTENSION ) )
       
   619                 {                
       
   620                     if( !FindAndSetPathAndType( *src, BMP_FILE_EXTENSION ) )
       
   621                     {                
       
   622                         THROW_ERROR_COMMON("File not found " + src->Filename(), MifConvString(__FILE__), __LINE__ );
       
   623                     }
       
   624                 }
       
   625             }
       
   626         }
       
   627     }
       
   628 }
       
   629 
       
   630 /**
       
   631  *
       
   632  */
       
   633 void MifConvArgumentManager::GetMifEnv()
       
   634 {    
       
   635     // Read EPOCROOT environment variable
       
   636     char* tmpPtr = 0;
       
   637     tmpPtr = getenv(EPOCROOT_ENV.c_str());
       
   638     if( tmpPtr )
       
   639     {        
       
   640         iEpocRoot = MifConvString(tmpPtr);
       
   641         MifConvUtil::ReplaceChar(iEpocRoot, INCORRECT_DIR_SEPARATOR2, DIR_SEPARATOR2);
       
   642         // Make sure that the last char is directory separator
       
   643         if( iEpocRoot.length() > 0 && iEpocRoot.at( iEpocRoot.length()-1) != DIR_SEPARATOR2 )
       
   644         {
       
   645             iEpocRoot += DIR_SEPARATOR;
       
   646         }
       
   647     }
       
   648 }
       
   649 
       
   650 /**
       
   651  *
       
   652  */
       
   653 const MifConvString& MifConvArgumentManager::EpocRoot() const
       
   654 {
       
   655     return iEpocRoot;
       
   656 }
       
   657 
       
   658 /**
       
   659  *
       
   660  */
       
   661 bool MifConvArgumentManager::FindAndSetPathAndType( MifConvSourceFile& srcFile, const MifConvString& extension )
       
   662 {    
       
   663     // Search the filename first "as is":
       
   664     MifConvString tmp( MifConvUtil::FilenameWithoutExtension( srcFile.Filename() ) + MifConvString(FILE_EXTENSION_SEPARATOR) + extension );     
       
   665     if( MifConvUtil::FileExists(tmp) )
       
   666     {
       
   667         srcFile.SetFilename(tmp);
       
   668         MifConvUtil::FindAndSetBitmapMaskFile(srcFile);
       
   669         return true;
       
   670     }
       
   671 
       
   672     // If the absolute path was given, return false, because the file was not found with given path and filename. 
       
   673     // Otherwise continue searching.
       
   674     if( //(srcFile.Filename().length() > 0 && srcFile.Filename().at(0) == DIR_SEPARATOR2) ||
       
   675         (srcFile.Filename().length() > 1 && srcFile.Filename().at(1) == ':') )
       
   676     {        
       
   677         return false;
       
   678     }
       
   679 
       
   680     // Search from the pre-defined locations:        
       
   681     for( SearchRules::iterator i = iSearchRules.begin(); i != iSearchRules.end(); ++i )
       
   682     {
       
   683         bool validPath = false;
       
   684         const MifConvStringList& allowedTypes = i->AllowedFileTypes();
       
   685 
       
   686         // See if the file with given extension is allowed to locate in search path.
       
   687         // For example, epoc32\s60\icons folder can contain only .svg files and epoc32\s60\bitmaps 
       
   688         // can contain only .bmp files:
       
   689         for( MifConvStringList::const_iterator typeIter = allowedTypes.begin(); typeIter != allowedTypes.end(); ++typeIter )
       
   690         {
       
   691             if( *typeIter == MIFCONV_WILDCARD || *typeIter == extension )
       
   692             {        
       
   693                 validPath = true;
       
   694                 break;
       
   695             }
       
   696         }
       
   697 
       
   698         if( validPath )
       
   699         {            
       
   700             MifConvString searchPath(i->SearchPath());
       
   701 
       
   702             // Make sure that the last char is directory separator
       
   703             if( searchPath.length() > 0 && searchPath.at( searchPath.length()-1) != DIR_SEPARATOR2 )
       
   704             {
       
   705                 searchPath += DIR_SEPARATOR;
       
   706             }
       
   707 
       
   708             searchPath += MifConvUtil::FilenameWithoutExtension( srcFile.Filename() ) + MifConvString(FILE_EXTENSION_SEPARATOR) + extension;
       
   709 
       
   710             MifConvUtil::RemoveDuplicateDirSeparators(searchPath);
       
   711 
       
   712             if( MifConvUtil::FileExists( searchPath ) )
       
   713             {
       
   714                 srcFile.SetFilename(searchPath);
       
   715                 MifConvUtil::FindAndSetBitmapMaskFile(srcFile);                
       
   716                 return true; 
       
   717             }  
       
   718         }            
       
   719     }
       
   720     return false;
       
   721 }
       
   722 
       
   723 /**
       
   724  *
       
   725  */
       
   726 void MifConvArgumentManager::ProcessArgumentPaths()
       
   727 {
       
   728 	// Fix directory separators first:
       
   729     for( StringArgMap::iterator i = iStringArguments.begin(); i != iStringArguments.end(); ++i )
       
   730     {
       
   731         MifConvString tmp = i->second.Value();
       
   732         MifConvUtil::ReplaceChar(tmp, INCORRECT_DIR_SEPARATOR2, DIR_SEPARATOR2);
       
   733         MifConvUtil::RemoveDuplicateDirSeparators(tmp);
       
   734         i->second.SetValue(tmp);
       
   735     }
       
   736 
       
   737     // Fix directory separators in source filenames also:
       
   738     for( MifConvSourceFileList::iterator j = iSourceFiles.begin(); j != iSourceFiles.end(); ++j )
       
   739     {
       
   740         MifConvString tmp = j->Filename();
       
   741         MifConvUtil::ReplaceChar(tmp, INCORRECT_DIR_SEPARATOR2, DIR_SEPARATOR2);
       
   742         MifConvUtil::RemoveDuplicateDirSeparators(tmp);
       
   743         j->SetFilename(tmp);
       
   744     }
       
   745     
       
   746     // Fix directory separators in search rule directories also:
       
   747     for( SearchRules::iterator k = iSearchRules.begin(); k != iSearchRules.end(); ++k )
       
   748     {
       
   749         MifConvString& tmp = k->SearchPath();
       
   750         MifConvUtil::ReplaceChar(tmp, INCORRECT_DIR_SEPARATOR2, DIR_SEPARATOR2);
       
   751         MifConvUtil::RemoveDuplicateDirSeparators(tmp);
       
   752     }
       
   753 
       
   754     // Fix target file also:
       
   755     MifConvUtil::ReplaceChar(iTargetFile, INCORRECT_DIR_SEPARATOR2, DIR_SEPARATOR2);
       
   756     MifConvUtil::RemoveDuplicateDirSeparators(iTargetFile);
       
   757 }
       
   758 
       
   759 /**
       
   760  *
       
   761  */
       
   762 void MifConvArgumentManager::FinalizeArguments()
       
   763 {
       
   764 	ProcessArgumentPaths();
       
   765 	ResolveSourceFileTypes();
       
   766 }
       
   767 
       
   768 /**
       
   769  *
       
   770  */
       
   771 void MifConvArgumentManager::SetUsageString( MifConvString& usageStr ) const
       
   772 {
       
   773 	usageStr = "";
       
   774 
       
   775     usageStr += "Copyright (c) " + MifConvYears + " Nokia Corporation and/or its subsidiary(-ies). All rights reserved.\n";
       
   776     usageStr += "\n";
       
   777     usageStr += "Usage: mifconv <MIFFILE> [-F<file>] <options> <sources>]\n";
       
   778     usageStr += "\n";
       
   779     usageStr += "Where:\n";
       
   780     usageStr += "  MIFFILE            Specifies the target MIF file to be created\n";
       
   781     usageStr += "  -F<file>           Specifies a parameter file, which can contain any of the options\n";
       
   782     usageStr += "                        and sources separated by spaces or newlines\n";
       
   783     usageStr += "\n";
       
   784     usageStr += "Options:\n";
       
   785     usageStr += "  -H<file>           Specifies a name of the MIF header file (default extension MBG)\n";
       
   786     usageStr += "  -I<dir;dir;...>    Specifies a set of custom source directories where source files\n";
       
   787     usageStr += "                        will be searched. As a fallback, global source directories are\n";
       
   788     usageStr += "                        used\n";
       
   789     usageStr += "  -E                 Specifies that source icons are only loaded with given file\n";
       
   790     usageStr += "                        extensions. By default, Mifconv prefers source icons with\n";
       
   791     usageStr += "                        extension .SVG over .BMP, regardless of which is given as\n";
       
   792     usageStr += "                        a parameter\n";
       
   793     usageStr += "  -X                 Disables SVG compression. If this flag is set, SVG icons are\n";
       
   794     usageStr += "                        added to MIF file without compressing them first\n";
       
   795     usageStr += "  -P<file>           Specifies a path to custom palette file for bitmap files\n";
       
   796     usageStr += "  -T<dir>            Specifies a path where temporary files are created\n";
       
   797     usageStr += "  -B<file>           Specifies a path for non-default BMConv utility\n";
       
   798     usageStr += "  -S<file>           Specifies a path for non-default SVGTBinenCode utility\n";
       
   799     usageStr += "  -V<string>         Specifies a non-platform default format version of SVGT binary\n";
       
   800     usageStr += "                        conversion. It can be any of the following value:\n";
       
   801     usageStr += "                             1      BGR / float encoding\n";
       
   802     usageStr += "                             2      BGR / fixed point encoding\n";
       
   803     usageStr += "                             3      RGB / fixed point encoding\n";
       
   804     usageStr += "                             4      RGB / float encoding\n";
       
   805     usageStr += "Sources:\n";
       
   806     usageStr += "  [-A] <DEPTH[,MASK]> <FILE> [ [-A] <DEPTH[,MASK]> <FILE> ... ]\n";
       
   807     usageStr += "        [-A]         Specifies animated flag for the icon\n";
       
   808     usageStr += "        [DEPTH]      Specifies icon depth, it can be any of these values\n";
       
   809     usageStr += "                        -1,-2,-4,-8,-c4,-c8,-c12,-c16,-c24,-c32\n";
       
   810     usageStr += "        [MASK]       Specifies icon mask depth, it can be any of these values\n";
       
   811     usageStr += "                        1,8\n";
       
   812     usageStr += "        [FILE]       Specifies path to the input file, supported file extensions are\n";
       
   813     usageStr += "                        SVG, SVGB, BMP\n";
       
   814     usageStr += "\n";
       
   815     usageStr += "Other info:\n";
       
   816 #ifdef WIN32
       
   817     usageStr += "  * '-' or '/' can be used as parameter switch prefix\n";
       
   818 #endif    
       
   819     usageStr += "  * Value of icon mask and depth is meaningful only for bitmap files, but the mask\n";
       
   820     usageStr += "    value defines if mask entry will be available or not in the header file\n";
       
   821     usageStr += "  * If mask parameter is defined for a BMP file, Mifconv automatically pics\n";
       
   822     usageStr += "    a file ending _mask_soft for value 8 and _mask for value 1 of mask\n";
       
   823     usageStr += "\n";
       
   824     usageStr += "Examples:\n";
       
   825     usageStr += "  mifconv mybuttons.mif -Hmybuttons.mbg -c8,8 button1 -c8,8 button2\n";
       
   826 }
       
   827 
       
   828 /**
       
   829  *
       
   830  */
       
   831 const MifConvString& MifConvArgumentManager::StringValue( const MifConvString& argName ) const
       
   832 {
       
   833 	StringArgMap::const_iterator i = iStringArguments.find(argName);
       
   834 	if( i != iStringArguments.end() )
       
   835 	{
       
   836 		return i->second.Value();
       
   837 	}
       
   838 	
       
   839 	return iDummyString;
       
   840 }
       
   841 
       
   842 /**
       
   843  *
       
   844  */
       
   845 const MifConvStringList& MifConvArgumentManager::StringListValue( const MifConvString& argName ) const
       
   846 {
       
   847 	StringListArgMap::const_iterator i = iStringListArguments.find(argName);
       
   848 	if( i != iStringListArguments.end() )
       
   849 	{
       
   850 		return i->second.Value();
       
   851 	}
       
   852 	
       
   853 	return iDummyStringList;
       
   854 }
       
   855 
       
   856 /**
       
   857  *
       
   858  */
       
   859 bool MifConvArgumentManager::BooleanValue( const MifConvString& argName ) const
       
   860 {
       
   861 	BooleanArgMap::const_iterator i = iBooleanArguments.find(argName);
       
   862 	if( i != iBooleanArguments.end() )
       
   863 	{
       
   864 		return i->second.Value();
       
   865 	}
       
   866 	
       
   867 	return false;
       
   868 }
       
   869 
       
   870 /**
       
   871  *
       
   872  */
       
   873 const MifConvSourceFileList& MifConvArgumentManager::SourceFiles() const
       
   874 {
       
   875 	return iSourceFiles;
       
   876 }
       
   877 
       
   878 /**
       
   879  *
       
   880  */
       
   881 bool MifConvArgumentManager::IsArgument( const MifConvString& str ) const
       
   882 {
       
   883 	try {
       
   884 		return str.at(0) == OPTION_PREFIX1_CHAR || str.at(0) == OPTION_PREFIX2_CHAR;
       
   885 	}
       
   886 	catch(...)
       
   887 	{
       
   888 		THROW_ERROR("Zero or corrupted string in MifConvArgumentManager::IsArgument()\n", MifConvString(__FILE__), __LINE__);
       
   889 	}
       
   890 	return false;
       
   891 }
       
   892 
       
   893 /**
       
   894  *
       
   895  */
       
   896 void MifConvArgumentManager::PopulateDepthAndMaskMaps()
       
   897 {
       
   898     // Insert value-string pairs for the icon depths:
       
   899     iDepthMap.insert(std::make_pair(MifConvDepth_1,    IconDepth_1));
       
   900     iDepthMap.insert(std::make_pair(MifConvDepth_2,    IconDepth_2));
       
   901     iDepthMap.insert(std::make_pair(MifConvDepth_4,    IconDepth_4));
       
   902     iDepthMap.insert(std::make_pair(MifConvDepth_8,    IconDepth_8));
       
   903     iDepthMap.insert(std::make_pair(MifConvDepth_c4,   IconDepth_c4));
       
   904     iDepthMap.insert(std::make_pair(MifConvDepth_c8,   IconDepth_c8));
       
   905     iDepthMap.insert(std::make_pair(MifConvDepth_c12,  IconDepth_c12));
       
   906     iDepthMap.insert(std::make_pair(MifConvDepth_c16,  IconDepth_c16));
       
   907     iDepthMap.insert(std::make_pair(MifConvDepth_c24,  IconDepth_c24));
       
   908     iDepthMap.insert(std::make_pair(MifConvDepth_c32,  IconDepth_c32));
       
   909     
       
   910     // Insert value-string pairs for the icon masks:
       
   911     iMaskDepthMap.insert(std::make_pair(MifConvMaskDepth_1, IconMaskDepth_1));
       
   912     iMaskDepthMap.insert(std::make_pair(MifConvMaskDepth_8, IconMaskDepth_8));
       
   913 
       
   914     // Insert value-pairs for display modes:
       
   915     iDisplayModeMap.insert(std::make_pair(IconDepth_1,      DisplayMode_Gray2));
       
   916     iDisplayModeMap.insert(std::make_pair(IconDepth_2,      DisplayMode_Gray4));
       
   917     iDisplayModeMap.insert(std::make_pair(IconDepth_4,      DisplayMode_Gray16));
       
   918     iDisplayModeMap.insert(std::make_pair(IconDepth_8,      DisplayMode_Gray256));
       
   919     iDisplayModeMap.insert(std::make_pair(IconDepth_c4,     DisplayMode_Color16));
       
   920     iDisplayModeMap.insert(std::make_pair(IconDepth_c8,     DisplayMode_Color256));
       
   921     iDisplayModeMap.insert(std::make_pair(IconDepth_c12,    DisplayMode_Color4K));
       
   922     iDisplayModeMap.insert(std::make_pair(IconDepth_c16,    DisplayMode_Color64K));
       
   923     iDisplayModeMap.insert(std::make_pair(IconDepth_c24,    DisplayMode_Color16M));
       
   924     iDisplayModeMap.insert(std::make_pair(IconDepth_c32,    DisplayMode_Color16MU));
       
   925 
       
   926     iMaskDisplayModeMap.insert(std::make_pair(IconMaskDepth_1,  DisplayMode_Gray2));
       
   927     iMaskDisplayModeMap.insert(std::make_pair(IconMaskDepth_8,  DisplayMode_Gray256));
       
   928 }
       
   929 
       
   930 /**
       
   931  *
       
   932  */
       
   933 void MifConvArgumentManager::ReadParameterFile(const MifConvString& paramFilename, MifConvStringList& paramList)
       
   934 {
       
   935     // Check if the file exists:
       
   936     if( MifConvUtil::FileExists(paramFilename) == false )
       
   937     {
       
   938         THROW_ERROR_COMMON("Unable to open file for reading! " + paramFilename, MifConvString(__FILE__), __LINE__ );
       
   939     }
       
   940 
       
   941     MifConvFileData paramFileData = MifConvUtil::FileContents(paramFilename);    
       
   942 
       
   943     MifConvString tmpString;
       
   944     for(size_t i = 0; i < paramFileData.second; ++i )
       
   945     {
       
   946         if( MifConvUtil::IsWhiteSpace(paramFileData.first[i]) == false )
       
   947         {
       
   948             tmpString += paramFileData.first[i];
       
   949         }
       
   950         else if( tmpString.length() > 0 )
       
   951         {
       
   952             paramList.push_back( tmpString );            
       
   953             tmpString = MifConvString();       
       
   954         }
       
   955     }
       
   956 
       
   957     if( tmpString.length() > 0 )
       
   958     {
       
   959         paramList.push_back( tmpString );
       
   960         tmpString = MifConvString();
       
   961     }
       
   962     delete[] paramFileData.first;
       
   963 }
       
   964 
       
   965 /**
       
   966  * Helper class for source search rules
       
   967  */
       
   968 
       
   969 MifConvSourceSearchRule::MifConvSourceSearchRule(const MifConvString& path, const MifConvStringList& types)
       
   970 :
       
   971 iSearchPath(path),
       
   972 iAllowedFileTypes(types)
       
   973 {}
       
   974 
       
   975 MifConvSourceSearchRule::~MifConvSourceSearchRule()
       
   976 {}
       
   977 
       
   978 const MifConvString& MifConvSourceSearchRule::SearchPath() const 
       
   979 { 
       
   980     return iSearchPath; 
       
   981 }
       
   982 
       
   983 MifConvString& MifConvSourceSearchRule::SearchPath() 
       
   984 { 
       
   985     return iSearchPath; 
       
   986 }
       
   987 
       
   988 const MifConvStringList& MifConvSourceSearchRule::AllowedFileTypes() const
       
   989 {
       
   990     return iAllowedFileTypes;
       
   991 }