diff -r 000000000000 -r f453ebb75370 gfxconversion/mifconv/src/mifconv_util.cpp --- /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 // for stat +#ifdef WIN32 + #include // for _getcwd, _chdir, _mkdir +#else + #include +#endif +#include // for _MAX_PATH +#include + +#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; + } +