gfxconversion/mifconv/src/mifconv_util.cpp
changeset 0 f453ebb75370
child 2 1f6339ced17d
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gfxconversion/mifconv/src/mifconv_util.cpp	Tue Feb 02 01:11:11 2010 +0200
@@ -0,0 +1,593 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Mifconv utilities.
+*
+*/
+
+
+#include "mifconv.h"
+#include "mifconv_util.h"
+#include "mifconv_exception.h"
+#include "mifconv_argumentmanager.h"
+#include <sys/stat.h>   // for stat
+#ifdef WIN32
+    #include <direct.h>     // for _getcwd, _chdir, _mkdir
+#else
+    #include <unistd.h>
+#endif
+#include <stdlib.h>     // for _MAX_PATH
+#include <stdio.h>
+
+#ifndef _MAX_PATH
+#define _MAX_PATH   (260)
+#endif
+
+MifConvUtil::MifConvDebugMode MifConvUtil::iDebugMode = DebugMode_Unknown;
+MifConvString MifConvUtil::iDebugFile = "";
+MifConvString MifConvUtil::iTempDirectory = "";
+
+/**
+ *
+ */
+MifConvString MifConvUtil::FileExtension( const MifConvString& fileName )
+{	
+	size_t indexOfDot; // index of '.' character in the given string
+
+	// Find last occurence of the '.' character
+	if( ( indexOfDot = fileName.find_last_of('.') ) == MifConvString::npos )
+	{
+		// Not found, return empty string
+		return MifConvString("");
+	}
+
+	// Return the substring starting after the '.' character
+	return MifConvString( fileName.begin()+indexOfDot+1, fileName.end() );
+}
+
+/**
+ *
+ */
+MifConvString MifConvUtil::FilenameWithoutExtension( const MifConvString& fileName )
+{	
+	size_t indexOfDot; // index of '.' character in the given string
+
+	// Find last occurence of the '.' character
+	if( ( indexOfDot = fileName.find_last_of('.') ) == MifConvString::npos )
+	{
+		// Not found, return the whole name
+		return fileName;
+	}
+
+	// Return the substring preceding the last '.' character
+	return MifConvString( fileName.begin(), fileName.begin() + indexOfDot );
+}
+
+/**
+ *
+ */
+MifConvString MifConvUtil::FilenameWithoutPath( const MifConvString& fileName )
+{	
+	size_t indexOfDirSeparator; // index of directory separator in the given string
+
+	// Find last occurence of the '.' character
+	if( ( indexOfDirSeparator = fileName.find_last_of(DIR_SEPARATOR2) ) == MifConvString::npos )
+	{
+		// Not found, return the whole name
+		return fileName;
+	}
+
+	// Return the substring beginnig after the last directory separator
+	return MifConvString( fileName.begin()+indexOfDirSeparator+1, fileName.end() );
+}
+
+/**
+ *
+ */
+bool MifConvUtil::FileExists( const MifConvString& fileName )
+{
+  struct stat fileInfo;   
+  int retVal = 0; 
+
+  // Try to get file attributes to see if the file exists or not:
+  retVal = stat( fileName.c_str(), &fileInfo); 
+  return retVal == 0;
+}
+
+/**
+ *
+ */
+size_t MifConvUtil::FileSize( const MifConvString& fileName )
+{
+  struct stat fileInfo;   
+  int retVal = 0; 
+
+  // Try to get file attributes to see if the file exists or not:
+  retVal = stat( fileName.c_str(), &fileInfo); 
+  if( retVal != 0 )
+  {
+      THROW_ERROR_COMMON("File not found: " + fileName, MifConvString(__FILE__), __LINE__);
+  }
+
+  return fileInfo.st_size;
+}
+
+/**
+ *
+ */
+MifConvFileData MifConvUtil::FileContents( const MifConvString& fileName )
+{
+    unsigned int fileLen = (unsigned int) (MifConvUtil::FileSize(fileName)/sizeof(char));
+    
+    ifstream fs( fileName.c_str(), FILE_IN_BINARY_NOCREATE_FLAGS );
+    if (!fs.is_open())
+    {
+        THROW_ERROR_COMMON("Unable to open file for reading! " + fileName, MifConvString(__FILE__), __LINE__);
+    }
+    char* buffer = new char[fileLen];
+    fs.read(buffer, fileLen);
+    return MifConvFileData(buffer, fileLen);
+}
+
+/**
+ *
+ */
+void MifConvUtil::ReplaceChar( MifConvString& str, char replaceFrom, char replaceTo)
+{
+    if( str.length() > 0 )
+    {        
+        MifConvString::size_type index = 0;
+        while( (index = str.find(replaceFrom, index)) != MifConvString::npos )
+        {     
+            str.replace(index,1,1,replaceTo);
+        }
+    }
+}
+
+/**
+ *
+ */
+void MifConvUtil::SplitPath( const MifConvString& sourcePath, MifConvString& drive, MifConvString& path)
+    {    
+        if( sourcePath.length() > 0 )
+        {
+            size_t driveSeparatorPos = sourcePath.find(':');
+            if( driveSeparatorPos != MifConvString::npos )
+            {
+                drive = MifConvString(sourcePath.begin(), sourcePath.begin() + driveSeparatorPos );
+                path = MifConvString(sourcePath.begin() + driveSeparatorPos + 1, sourcePath.end() );
+            }
+            else
+            {
+                path = sourcePath;
+            }
+        }
+        else
+        {
+            drive = MifConvString("");
+            path = MifConvString("");
+        }
+}
+
+/**
+ *
+ */
+MifConvString MifConvUtil::CurrentPath()
+{
+    char temp[_MAX_PATH];
+#ifdef WIN32    
+    _getcwd(temp, _MAX_PATH);    
+#else
+    getcwd(temp, _MAX_PATH);
+#endif
+    return MifConvString(temp);
+}
+
+/**
+ *
+ */
+int MifConvUtil::CompareIgnoreCase( const MifConvString& lhs, const MifConvString& rhs )
+{
+    MifConvString lhsCopy(lhs);
+    MifConvString rhsCopy(rhs);
+
+    return ToLower(lhsCopy).compare(ToLower(rhsCopy));
+}
+
+/**
+ *
+ */
+MifConvString& MifConvUtil::ToLower( MifConvString& str )
+{
+    MifConvString::iterator it(str.begin());
+    for(; it != str.end(); ++it)
+    {
+        *it = (char) tolower((unsigned char)*it);
+    }
+    return str;
+}
+
+/**
+ *
+ */
+void MifConvUtil::EnsurePathExists( const MifConvString& destFileName, bool ignoreLast )
+    {
+    MifConvString currentPath;
+    MifConvString tmpDrive;    
+    MifConvString tmpPath;
+
+    // Parse a drive of a destination path; if any
+    SplitPath( destFileName, tmpDrive, tmpPath );
+
+    // Save current directory    
+    currentPath = CurrentPath();
+
+    // Change drive if needed:
+    if( tmpDrive.length() > 0 )
+    {        
+        tmpDrive += ":";
+        tmpDrive += DIR_SEPARATOR;
+        ChangeDirectory(tmpDrive);        
+    }
+
+    // Split desination path to separate directories:
+    MifConvStringList destDirList;
+
+    // Check if the root is given first and add it to dir list:
+    if( tmpPath.length() > 0 && tmpPath.at(0) == DIR_SEPARATOR2 )
+    {
+        destDirList.push_back(DIR_SEPARATOR);
+    }
+
+    // Add other directories to destination dir list:
+    SplitString( tmpPath, DIR_SEPARATOR, destDirList );
+
+    // Remove last component from the list if it should be ignored:
+    if( ignoreLast )
+    {
+        destDirList.pop_back();
+    }
+
+    unsigned int i = 0;
+    while( i < destDirList.size() )
+    {        
+        const MifConvString& dir = destDirList[i++];         
+        if( !FileExists(dir) )
+        {
+            if( !CreateDirectory( dir ) )
+            {
+                // Change back to original directory:
+                ChangeDirectory( currentPath );
+                THROW_ERROR_COMMON("Directory " + tmpPath + " cannot be created", MifConvString(__FILE__), __LINE__);
+            }
+        }
+        ChangeDirectory( dir );        
+    }
+
+    // Change back to original directory:
+    ChangeDirectory( currentPath );
+}
+
+/**
+ *
+ */
+void MifConvUtil::RemoveDuplicateDirSeparators( MifConvString& str )
+{    
+    MifConvString searchString(DIR_SEPARATOR);
+    searchString += DIR_SEPARATOR;
+    size_t pos = str.find(searchString);
+
+    while(pos != MifConvString::npos)
+    {
+        str.erase(pos, 1);
+        pos = str.find(searchString); 
+    }
+}
+
+/**
+ *
+ */
+bool MifConvUtil::CreateDirectory( const MifConvString& path )
+{    
+#ifdef WIN32
+    return _mkdir( path.c_str() ) == 0;
+#else
+    return mkdir( path.c_str(), 0777 ) == 0;
+#endif
+}
+
+/**
+ *
+ */
+void MifConvUtil::SplitString( const MifConvString& str, const MifConvString& separator, MifConvStringList& components )
+{
+    size_t beginPos = 0;
+    size_t endPos = 0;
+
+    while( (endPos = str.find(separator, beginPos)) != MifConvString::npos )
+    {
+        if( endPos - beginPos > 0 )
+        {
+            components.push_back( MifConvString( str.begin()+beginPos, str.begin()+endPos ) );            
+        }
+        beginPos = endPos+1;
+    }
+    if( str.begin()+beginPos != str.end() )
+    {
+        components.push_back( MifConvString(str.begin()+beginPos, str.end()) );
+    }
+}
+
+/**
+ *
+ */
+MifConvString MifConvUtil::UnadornedFilename( const MifConvString& filename )
+{    
+    MifConvStringList splitted;
+    SplitString(filename, DIR_SEPARATOR, splitted);
+
+    MifConvString tmp(splitted.back());
+    splitted.clear();
+    SplitString(tmp, INCORRECT_DIR_SEPARATOR, splitted);
+
+    tmp = splitted.back();
+    splitted.clear();
+    SplitString(tmp, FILE_EXTENSION_SEPARATOR, splitted);
+
+    MifConvString fixedname;
+    
+    if( splitted.size() > 0 )
+    {
+        fixedname = ToLower(splitted[0]);
+        if( fixedname.length() > 0 )
+        {
+            fixedname[0] = (char) toupper( fixedname[0] );
+        }
+    }
+    return fixedname;
+}
+
+/**
+ *
+ */
+void MifConvUtil::FindAndSetBitmapMaskFile( MifConvSourceFile& srcFile )
+{
+    if( srcFile.MaskDepth() == IconMaskDepth_Undefined )
+    {
+        return; // No mask file
+    }
+    MifConvString fileExtension(FileExtension( srcFile.Filename() ));
+
+    if( CompareIgnoreCase(fileExtension, BMP_FILE_EXTENSION) != 0 )
+    {
+        return;
+    }
+
+    MifConvString maskFilename(FilenameWithoutExtension(srcFile.Filename()));
+
+    if( srcFile.MaskDepth() == IconMaskDepth_1 )
+    {
+        maskFilename += "_mask.bmp";
+    }
+    else if( srcFile.MaskDepth() == IconMaskDepth_8 )
+    {
+        maskFilename += "_mask_soft.bmp";
+    }
+    else
+    {
+        THROW_ERROR_COMMON("Invalid mask depth\n", MifConvString(__FILE__), __LINE__);
+    }
+
+    if( !FileExists(maskFilename) )
+    {
+        cerr << endl << "*** WARNING! Missing bitmap: " << maskFilename << endl;
+    }
+
+    srcFile.SetBmpMaskFilename( maskFilename );
+}
+
+/**
+ *
+ */
+MifConvString MifConvUtil::TemporaryFilename()
+{
+    MifConvString tmp(tmpnam(NULL));
+    MifConvString::iterator i = tmp.begin();
+
+    if( *i == '.' )
+    {
+        ++i;
+    }
+
+    if( *i == DIR_SEPARATOR2 || *i == INCORRECT_DIR_SEPARATOR2 )
+    {
+        ++i;
+    }
+
+    return MifConvString(i, tmp.end());
+}
+
+/**
+ *
+ */
+bool MifConvUtil::CopyFile(const MifConvString& from, const MifConvString& to)
+{
+    bool retval = false;
+    ifstream in(from.c_str(), ios::binary);    
+    if( in )
+    {
+        ofstream out(to.c_str(), ios::binary);        
+        if( out )
+        {
+            out << in.rdbuf();
+            retval = out.good();
+            out.close();
+        }
+        in.close();
+    }
+    return retval;
+} 
+
+/**
+ *
+ */
+bool MifConvUtil::IsWhiteSpace(char c)
+{
+    return c == ' ' || c == '\n' || c == '\r' || c == '\t';
+}
+
+/**
+ *
+ */
+void MifConvUtil::ChangeDirectory( const MifConvString& dirName )
+{
+#ifdef WIN32
+    _chdir( dirName.c_str() );
+#else
+    chdir( dirName.c_str() );
+#endif
+}
+
+/**
+ *
+ */
+int MifConvUtil::RemoveDirectory( const MifConvString& dirName )
+{
+#ifdef WIN32
+    return _rmdir( dirName.c_str() );
+#else
+    return rmdir( dirName.c_str() );
+#endif
+}
+
+/**
+ *
+ */
+void MifConvUtil::RemoveFile( const MifConvString& fileName, int maxTries, bool noException )
+{
+    for( int i = 0; i < maxTries; ++i )
+    {    
+#ifdef WIN32
+        int ret = _unlink(fileName.c_str());
+#else
+        int ret = unlink(fileName.c_str());
+#endif
+        
+        if( ret == 0 )
+        {        
+            // Delete was successful
+            return;
+        }
+        
+        // Delete was not successful
+        if( i >= maxTries-1 )
+        {
+            // Max amount of tries exceeded -> print warning or throw an exception
+            if( noException )
+            {
+                MifConvString debugStr("WARNING: Cannot remove file " + fileName);
+                DebugLog(debugStr);
+            }
+            else
+            {
+                THROW_ERROR_COMMON("Cannot remove file " + fileName, MifConvString(__FILE__), __LINE__);
+            }
+        }       
+    }
+}
+
+/**
+ *
+ */
+MifConvString MifConvUtil::DebugFile()
+{
+    char* tmpPtr = getenv(MIFCONV_DEBUG_FILE_ENV.c_str());
+    if( tmpPtr )
+    {
+        return MifConvString(tmpPtr);        
+    }
+    return MifConvString();
+}
+
+/**
+ *
+ */
+void MifConvUtil::DebugLog(const MifConvString& debugStr)
+{
+    if( iDebugMode == DebugMode_Unknown )
+    {      
+        iDebugFile = MifConvUtil::DebugFile();
+        if( iDebugFile.length() > 0 )
+        {
+            iDebugMode = DebugMode_Debug;            
+        }
+        else
+        {
+            iDebugMode = DebugMode_NoDebug;
+        }
+    }
+
+    if( iDebugMode == DebugMode_Debug )
+    {
+        ios_base::openmode file_flags;
+        if( MifConvUtil::FileExists(iDebugFile) )
+        {                
+            file_flags = ios::out|ios::app;
+        }
+        else
+        {             
+            file_flags = ios::out|ios::trunc;
+        }
+        fstream debugLog(iDebugFile.c_str(), file_flags);
+        if(debugLog.is_open())
+        { 
+            debugLog << debugStr << endl;
+            debugLog.close();
+        }
+    }      
+}
+
+/**
+ *
+ */
+const MifConvString& MifConvUtil::DefaultTempDirectory()
+    {
+    if( iTempDirectory.length() == 0 )
+        {
+        char* tmpPtr = getenv(SBS_BUILD_DIR_ENV.c_str());
+        if( tmpPtr && MifConvString(tmpPtr).length() > 0 )
+            {
+            iTempDirectory = MifConvString(tmpPtr);
+            
+            if( iTempDirectory.at(iTempDirectory.length()-1) != DIR_SEPARATOR2 )
+                {                
+                iTempDirectory += DIR_SEPARATOR;
+                }
+            
+            iTempDirectory += EPOC_ICON_BUILD_PATH_POSTFIX + 
+                MifConvString(DIR_SEPARATOR) + 
+                MifConvString("temp");
+            }
+        else
+            {
+            iTempDirectory = MifConvArgumentManager::Instance()->EpocRoot() + 
+                EPOC_BUILD_PATH + 
+                MifConvString(DIR_SEPARATOR) + 
+                EPOC_ICON_BUILD_PATH_POSTFIX + 
+                MifConvString(DIR_SEPARATOR) + 
+                MifConvString("temp");
+            }
+        }
+    return iTempDirectory;
+    }
+