gfxconversion/mifconv/src/mifconv_util.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 utilities.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include "mifconv.h"
       
    20 #include "mifconv_util.h"
       
    21 #include "mifconv_exception.h"
       
    22 #include "mifconv_argumentmanager.h"
       
    23 #include <sys/stat.h>   // for stat
       
    24 #ifdef WIN32
       
    25     #include <direct.h>     // for _getcwd, _chdir, _mkdir
       
    26 #else
       
    27     #include <unistd.h>
       
    28 #endif
       
    29 #include <stdlib.h>     // for _MAX_PATH
       
    30 #include <stdio.h>
       
    31 
       
    32 #ifndef _MAX_PATH
       
    33 #define _MAX_PATH   (260)
       
    34 #endif
       
    35 
       
    36 MifConvUtil::MifConvDebugMode MifConvUtil::iDebugMode = DebugMode_Unknown;
       
    37 MifConvString MifConvUtil::iDebugFile = "";
       
    38 MifConvString MifConvUtil::iTempDirectory = "";
       
    39 
       
    40 /**
       
    41  *
       
    42  */
       
    43 MifConvString MifConvUtil::FileExtension( const MifConvString& fileName )
       
    44 {	
       
    45 	size_t indexOfDot; // index of '.' character in the given string
       
    46 
       
    47 	// Find last occurence of the '.' character
       
    48 	if( ( indexOfDot = fileName.find_last_of('.') ) == MifConvString::npos )
       
    49 	{
       
    50 		// Not found, return empty string
       
    51 		return MifConvString("");
       
    52 	}
       
    53 
       
    54 	// Return the substring starting after the '.' character
       
    55 	return MifConvString( fileName.begin()+indexOfDot+1, fileName.end() );
       
    56 }
       
    57 
       
    58 /**
       
    59  *
       
    60  */
       
    61 MifConvString MifConvUtil::FilenameWithoutExtension( const MifConvString& fileName )
       
    62 {	
       
    63 	size_t indexOfDot; // index of '.' character in the given string
       
    64 
       
    65 	// Find last occurence of the '.' character
       
    66 	if( ( indexOfDot = fileName.find_last_of('.') ) == MifConvString::npos )
       
    67 	{
       
    68 		// Not found, return the whole name
       
    69 		return fileName;
       
    70 	}
       
    71 
       
    72 	// Return the substring preceding the last '.' character
       
    73 	return MifConvString( fileName.begin(), fileName.begin() + indexOfDot );
       
    74 }
       
    75 
       
    76 /**
       
    77  *
       
    78  */
       
    79 MifConvString MifConvUtil::FilenameWithoutPath( const MifConvString& fileName )
       
    80 {	
       
    81 	size_t indexOfDirSeparator; // index of directory separator in the given string
       
    82 
       
    83 	// Find last occurence of the '.' character
       
    84 	if( ( indexOfDirSeparator = fileName.find_last_of(DIR_SEPARATOR2) ) == MifConvString::npos )
       
    85 	{
       
    86 		// Not found, return the whole name
       
    87 		return fileName;
       
    88 	}
       
    89 
       
    90 	// Return the substring beginnig after the last directory separator
       
    91 	return MifConvString( fileName.begin()+indexOfDirSeparator+1, fileName.end() );
       
    92 }
       
    93 
       
    94 /**
       
    95  *
       
    96  */
       
    97 bool MifConvUtil::FileExists( const MifConvString& fileName )
       
    98 {
       
    99   struct stat fileInfo;   
       
   100   int retVal = 0; 
       
   101 
       
   102   // Try to get file attributes to see if the file exists or not:
       
   103   retVal = stat( fileName.c_str(), &fileInfo); 
       
   104   return retVal == 0;
       
   105 }
       
   106 
       
   107 /**
       
   108  *
       
   109  */
       
   110 size_t MifConvUtil::FileSize( const MifConvString& fileName )
       
   111 {
       
   112   struct stat fileInfo;   
       
   113   int retVal = 0; 
       
   114 
       
   115   // Try to get file attributes to see if the file exists or not:
       
   116   retVal = stat( fileName.c_str(), &fileInfo); 
       
   117   if( retVal != 0 )
       
   118   {
       
   119       THROW_ERROR_COMMON("File not found: " + fileName, MifConvString(__FILE__), __LINE__);
       
   120   }
       
   121 
       
   122   return fileInfo.st_size;
       
   123 }
       
   124 
       
   125 /**
       
   126  *
       
   127  */
       
   128 MifConvFileData MifConvUtil::FileContents( const MifConvString& fileName )
       
   129 {
       
   130     unsigned int fileLen = (unsigned int) (MifConvUtil::FileSize(fileName)/sizeof(char));
       
   131     
       
   132     ifstream fs( fileName.c_str(), FILE_IN_BINARY_NOCREATE_FLAGS );
       
   133     if (!fs.is_open())
       
   134     {
       
   135         THROW_ERROR_COMMON("Unable to open file for reading! " + fileName, MifConvString(__FILE__), __LINE__);
       
   136     }
       
   137     char* buffer = new char[fileLen];
       
   138     fs.read(buffer, fileLen);
       
   139     return MifConvFileData(buffer, fileLen);
       
   140 }
       
   141 
       
   142 /**
       
   143  *
       
   144  */
       
   145 void MifConvUtil::ReplaceChar( MifConvString& str, char replaceFrom, char replaceTo)
       
   146 {
       
   147     if( str.length() > 0 )
       
   148     {        
       
   149         MifConvString::size_type index = 0;
       
   150         while( (index = str.find(replaceFrom, index)) != MifConvString::npos )
       
   151         {     
       
   152             str.replace(index,1,1,replaceTo);
       
   153         }
       
   154     }
       
   155 }
       
   156 
       
   157 /**
       
   158  *
       
   159  */
       
   160 void MifConvUtil::SplitPath( const MifConvString& sourcePath, MifConvString& drive, MifConvString& path)
       
   161     {    
       
   162         if( sourcePath.length() > 0 )
       
   163         {
       
   164             size_t driveSeparatorPos = sourcePath.find(':');
       
   165             if( driveSeparatorPos != MifConvString::npos )
       
   166             {
       
   167                 drive = MifConvString(sourcePath.begin(), sourcePath.begin() + driveSeparatorPos );
       
   168                 path = MifConvString(sourcePath.begin() + driveSeparatorPos + 1, sourcePath.end() );
       
   169             }
       
   170             else
       
   171             {
       
   172                 path = sourcePath;
       
   173             }
       
   174         }
       
   175         else
       
   176         {
       
   177             drive = MifConvString("");
       
   178             path = MifConvString("");
       
   179         }
       
   180 }
       
   181 
       
   182 /**
       
   183  *
       
   184  */
       
   185 MifConvString MifConvUtil::CurrentPath()
       
   186 {
       
   187     char temp[_MAX_PATH];
       
   188 #ifdef WIN32    
       
   189     _getcwd(temp, _MAX_PATH);    
       
   190 #else
       
   191     getcwd(temp, _MAX_PATH);
       
   192 #endif
       
   193     return MifConvString(temp);
       
   194 }
       
   195 
       
   196 /**
       
   197  *
       
   198  */
       
   199 int MifConvUtil::CompareIgnoreCase( const MifConvString& lhs, const MifConvString& rhs )
       
   200 {
       
   201     MifConvString lhsCopy(lhs);
       
   202     MifConvString rhsCopy(rhs);
       
   203 
       
   204     return ToLower(lhsCopy).compare(ToLower(rhsCopy));
       
   205 }
       
   206 
       
   207 /**
       
   208  *
       
   209  */
       
   210 MifConvString& MifConvUtil::ToLower( MifConvString& str )
       
   211 {
       
   212     MifConvString::iterator it(str.begin());
       
   213     for(; it != str.end(); ++it)
       
   214     {
       
   215         *it = (char) tolower((unsigned char)*it);
       
   216     }
       
   217     return str;
       
   218 }
       
   219 
       
   220 /**
       
   221  *
       
   222  */
       
   223 void MifConvUtil::EnsurePathExists( const MifConvString& destFileName, bool ignoreLast )
       
   224     {
       
   225     MifConvString currentPath;
       
   226     MifConvString tmpDrive;    
       
   227     MifConvString tmpPath;
       
   228 
       
   229     // Parse a drive of a destination path; if any
       
   230     SplitPath( destFileName, tmpDrive, tmpPath );
       
   231 
       
   232     // Save current directory    
       
   233     currentPath = CurrentPath();
       
   234 
       
   235     // Change drive if needed:
       
   236     if( tmpDrive.length() > 0 )
       
   237     {        
       
   238         tmpDrive += ":";
       
   239         tmpDrive += DIR_SEPARATOR;
       
   240         ChangeDirectory(tmpDrive);        
       
   241     }
       
   242 
       
   243     // Split desination path to separate directories:
       
   244     MifConvStringList destDirList;
       
   245 
       
   246     // Check if the root is given first and add it to dir list:
       
   247     if( tmpPath.length() > 0 && tmpPath.at(0) == DIR_SEPARATOR2 )
       
   248     {
       
   249         destDirList.push_back(DIR_SEPARATOR);
       
   250     }
       
   251 
       
   252     // Add other directories to destination dir list:
       
   253     SplitString( tmpPath, DIR_SEPARATOR, destDirList );
       
   254 
       
   255     // Remove last component from the list if it should be ignored:
       
   256     if( ignoreLast )
       
   257     {
       
   258         destDirList.pop_back();
       
   259     }
       
   260 
       
   261     unsigned int i = 0;
       
   262     while( i < destDirList.size() )
       
   263     {        
       
   264         const MifConvString& dir = destDirList[i++];         
       
   265         if( !FileExists(dir) )
       
   266         {
       
   267             if( !CreateDirectory( dir ) )
       
   268             {
       
   269                 // Change back to original directory:
       
   270                 ChangeDirectory( currentPath );
       
   271                 THROW_ERROR_COMMON("Directory " + tmpPath + " cannot be created", MifConvString(__FILE__), __LINE__);
       
   272             }
       
   273         }
       
   274         ChangeDirectory( dir );        
       
   275     }
       
   276 
       
   277     // Change back to original directory:
       
   278     ChangeDirectory( currentPath );
       
   279 }
       
   280 
       
   281 /**
       
   282  *
       
   283  */
       
   284 void MifConvUtil::RemoveDuplicateDirSeparators( MifConvString& str )
       
   285 {    
       
   286     MifConvString searchString(DIR_SEPARATOR);
       
   287     searchString += DIR_SEPARATOR;
       
   288     size_t pos = str.find(searchString);
       
   289 
       
   290     while(pos != MifConvString::npos)
       
   291     {
       
   292         str.erase(pos, 1);
       
   293         pos = str.find(searchString); 
       
   294     }
       
   295 }
       
   296 
       
   297 /**
       
   298  *
       
   299  */
       
   300 bool MifConvUtil::CreateDirectory( const MifConvString& path )
       
   301 {    
       
   302 #ifdef WIN32
       
   303     return _mkdir( path.c_str() ) == 0;
       
   304 #else
       
   305     return mkdir( path.c_str(), 0777 ) == 0;
       
   306 #endif
       
   307 }
       
   308 
       
   309 /**
       
   310  *
       
   311  */
       
   312 void MifConvUtil::SplitString( const MifConvString& str, const MifConvString& separator, MifConvStringList& components )
       
   313 {
       
   314     size_t beginPos = 0;
       
   315     size_t endPos = 0;
       
   316 
       
   317     while( (endPos = str.find(separator, beginPos)) != MifConvString::npos )
       
   318     {
       
   319         if( endPos - beginPos > 0 )
       
   320         {
       
   321             components.push_back( MifConvString( str.begin()+beginPos, str.begin()+endPos ) );            
       
   322         }
       
   323         beginPos = endPos+1;
       
   324     }
       
   325     if( str.begin()+beginPos != str.end() )
       
   326     {
       
   327         components.push_back( MifConvString(str.begin()+beginPos, str.end()) );
       
   328     }
       
   329 }
       
   330 
       
   331 /**
       
   332  *
       
   333  */
       
   334 MifConvString MifConvUtil::UnadornedFilename( const MifConvString& filename )
       
   335 {    
       
   336     MifConvStringList splitted;
       
   337     SplitString(filename, DIR_SEPARATOR, splitted);
       
   338 
       
   339     MifConvString tmp(splitted.back());
       
   340     splitted.clear();
       
   341     SplitString(tmp, INCORRECT_DIR_SEPARATOR, splitted);
       
   342 
       
   343     tmp = splitted.back();
       
   344     splitted.clear();
       
   345     SplitString(tmp, FILE_EXTENSION_SEPARATOR, splitted);
       
   346 
       
   347     MifConvString fixedname;
       
   348     
       
   349     if( splitted.size() > 0 )
       
   350     {
       
   351         fixedname = ToLower(splitted[0]);
       
   352         if( fixedname.length() > 0 )
       
   353         {
       
   354             fixedname[0] = (char) toupper( fixedname[0] );
       
   355         }
       
   356     }
       
   357     return fixedname;
       
   358 }
       
   359 
       
   360 /**
       
   361  *
       
   362  */
       
   363 void MifConvUtil::FindAndSetBitmapMaskFile( MifConvSourceFile& srcFile )
       
   364 {
       
   365     if( srcFile.MaskDepth() == IconMaskDepth_Undefined )
       
   366     {
       
   367         return; // No mask file
       
   368     }
       
   369     MifConvString fileExtension(FileExtension( srcFile.Filename() ));
       
   370 
       
   371     if( CompareIgnoreCase(fileExtension, BMP_FILE_EXTENSION) != 0 )
       
   372     {
       
   373         return;
       
   374     }
       
   375 
       
   376     MifConvString maskFilename(FilenameWithoutExtension(srcFile.Filename()));
       
   377 
       
   378     if( srcFile.MaskDepth() == IconMaskDepth_1 )
       
   379     {
       
   380         maskFilename += "_mask.bmp";
       
   381     }
       
   382     else if( srcFile.MaskDepth() == IconMaskDepth_8 )
       
   383     {
       
   384         maskFilename += "_mask_soft.bmp";
       
   385     }
       
   386     else
       
   387     {
       
   388         THROW_ERROR_COMMON("Invalid mask depth\n", MifConvString(__FILE__), __LINE__);
       
   389     }
       
   390 
       
   391     if( !FileExists(maskFilename) )
       
   392     {
       
   393         cerr << endl << "*** WARNING! Missing bitmap: " << maskFilename << endl;
       
   394     }
       
   395 
       
   396     srcFile.SetBmpMaskFilename( maskFilename );
       
   397 }
       
   398 
       
   399 /**
       
   400  *
       
   401  */
       
   402 MifConvString MifConvUtil::TemporaryFilename()
       
   403 {
       
   404     MifConvString tmp(tmpnam(NULL));
       
   405     MifConvString::iterator i = tmp.begin();
       
   406 
       
   407     if( *i == '.' )
       
   408     {
       
   409         ++i;
       
   410     }
       
   411 
       
   412     if( *i == DIR_SEPARATOR2 || *i == INCORRECT_DIR_SEPARATOR2 )
       
   413     {
       
   414         ++i;
       
   415     }
       
   416 
       
   417     return MifConvString(i, tmp.end());
       
   418 }
       
   419 
       
   420 /**
       
   421  *
       
   422  */
       
   423 bool MifConvUtil::CopyFile(const MifConvString& from, const MifConvString& to)
       
   424 {
       
   425     bool retval = false;
       
   426     ifstream in(from.c_str(), ios::binary);    
       
   427     if( in )
       
   428     {
       
   429         ofstream out(to.c_str(), ios::binary);        
       
   430         if( out )
       
   431         {
       
   432             out << in.rdbuf();
       
   433             retval = out.good();
       
   434             out.close();
       
   435         }
       
   436         in.close();
       
   437     }
       
   438     return retval;
       
   439 } 
       
   440 
       
   441 /**
       
   442  *
       
   443  */
       
   444 bool MifConvUtil::IsWhiteSpace(char c)
       
   445 {
       
   446     return c == ' ' || c == '\n' || c == '\r' || c == '\t';
       
   447 }
       
   448 
       
   449 /**
       
   450  *
       
   451  */
       
   452 void MifConvUtil::ChangeDirectory( const MifConvString& dirName )
       
   453 {
       
   454 #ifdef WIN32
       
   455     _chdir( dirName.c_str() );
       
   456 #else
       
   457     chdir( dirName.c_str() );
       
   458 #endif
       
   459 }
       
   460 
       
   461 /**
       
   462  *
       
   463  */
       
   464 int MifConvUtil::RemoveDirectory( const MifConvString& dirName )
       
   465 {
       
   466 #ifdef WIN32
       
   467     return _rmdir( dirName.c_str() );
       
   468 #else
       
   469     return rmdir( dirName.c_str() );
       
   470 #endif
       
   471 }
       
   472 
       
   473 /**
       
   474  *
       
   475  */
       
   476 void MifConvUtil::RemoveFile( const MifConvString& fileName, int maxTries, bool noException )
       
   477 {
       
   478     for( int i = 0; i < maxTries; ++i )
       
   479     {    
       
   480 #ifdef WIN32
       
   481         int ret = _unlink(fileName.c_str());
       
   482 #else
       
   483         int ret = unlink(fileName.c_str());
       
   484 #endif
       
   485         
       
   486         if( ret == 0 )
       
   487         {        
       
   488             // Delete was successful
       
   489             return;
       
   490         }
       
   491         
       
   492         // Delete was not successful
       
   493         if( i >= maxTries-1 )
       
   494         {
       
   495             // Max amount of tries exceeded -> print warning or throw an exception
       
   496             if( noException )
       
   497             {
       
   498                 MifConvString debugStr("WARNING: Cannot remove file " + fileName);
       
   499                 DebugLog(debugStr);
       
   500             }
       
   501             else
       
   502             {
       
   503                 THROW_ERROR_COMMON("Cannot remove file " + fileName, MifConvString(__FILE__), __LINE__);
       
   504             }
       
   505         }       
       
   506     }
       
   507 }
       
   508 
       
   509 /**
       
   510  *
       
   511  */
       
   512 MifConvString MifConvUtil::DebugFile()
       
   513 {
       
   514     char* tmpPtr = getenv(MIFCONV_DEBUG_FILE_ENV.c_str());
       
   515     if( tmpPtr )
       
   516     {
       
   517         return MifConvString(tmpPtr);        
       
   518     }
       
   519     return MifConvString();
       
   520 }
       
   521 
       
   522 /**
       
   523  *
       
   524  */
       
   525 void MifConvUtil::DebugLog(const MifConvString& debugStr)
       
   526 {
       
   527     if( iDebugMode == DebugMode_Unknown )
       
   528     {      
       
   529         iDebugFile = MifConvUtil::DebugFile();
       
   530         if( iDebugFile.length() > 0 )
       
   531         {
       
   532             iDebugMode = DebugMode_Debug;            
       
   533         }
       
   534         else
       
   535         {
       
   536             iDebugMode = DebugMode_NoDebug;
       
   537         }
       
   538     }
       
   539 
       
   540     if( iDebugMode == DebugMode_Debug )
       
   541     {
       
   542         ios_base::openmode file_flags;
       
   543         if( MifConvUtil::FileExists(iDebugFile) )
       
   544         {                
       
   545             file_flags = ios::out|ios::app;
       
   546         }
       
   547         else
       
   548         {             
       
   549             file_flags = ios::out|ios::trunc;
       
   550         }
       
   551         fstream debugLog(iDebugFile.c_str(), file_flags);
       
   552         if(debugLog.is_open())
       
   553         { 
       
   554             debugLog << debugStr << endl;
       
   555             debugLog.close();
       
   556         }
       
   557     }      
       
   558 }
       
   559 
       
   560 /**
       
   561  *
       
   562  */
       
   563 const MifConvString& MifConvUtil::DefaultTempDirectory()
       
   564     {
       
   565     if( iTempDirectory.length() == 0 )
       
   566         {
       
   567         char* tmpPtr = getenv(SBS_BUILD_DIR_ENV.c_str());
       
   568         if( tmpPtr && MifConvString(tmpPtr).length() > 0 )
       
   569             {
       
   570             iTempDirectory = MifConvString(tmpPtr);
       
   571             
       
   572             if( iTempDirectory.at(iTempDirectory.length()-1) != DIR_SEPARATOR2 )
       
   573                 {                
       
   574                 iTempDirectory += DIR_SEPARATOR;
       
   575                 }
       
   576             
       
   577             iTempDirectory += EPOC_ICON_BUILD_PATH_POSTFIX + 
       
   578                 MifConvString(DIR_SEPARATOR) + 
       
   579                 MifConvString("temp");
       
   580             }
       
   581         else
       
   582             {
       
   583             iTempDirectory = MifConvArgumentManager::Instance()->EpocRoot() + 
       
   584                 EPOC_BUILD_PATH + 
       
   585                 MifConvString(DIR_SEPARATOR) + 
       
   586                 EPOC_ICON_BUILD_PATH_POSTFIX + 
       
   587                 MifConvString(DIR_SEPARATOR) + 
       
   588                 MifConvString("temp");
       
   589             }
       
   590         }
       
   591     return iTempDirectory;
       
   592     }
       
   593