openModeller
Version 1.4.0
|
00001 00030 #ifdef WIN32 00031 // avoid warnings caused by problems in VC headers 00032 #define _SCL_SECURE_NO_DEPRECATE 00033 #endif 00034 00035 #include <os_specific.hh> 00036 #include <openmodeller/Log.hh> 00037 #include <openmodeller/AlgorithmFactory.hh> 00038 #include <openmodeller/Settings.hh> 00039 00040 #include <stdio.h> 00041 #include <fstream> 00042 #include <windows.h> 00043 #include <direct.h> 00044 #include <cpl_conv.h> // for setting gdal options 00045 #include <proj_api.h> // for setting proj options 00046 00047 using std::vector; 00048 using std::string; 00049 00050 /****************************************************************/ 00051 /********************* Dynamic Linking Loader *******************/ 00052 00053 /****************/ 00054 /*** dll Open ***/ 00055 DLLHandle 00056 dllOpen( char const *dll_file_name ) 00057 { 00058 #ifdef MINGW_QT 00059 //Added by Tim because under mingw wchar is expected 00060 return LoadLibraryA( dll_file_name ); 00061 #else 00062 return LoadLibraryA( dll_file_name ); 00063 #endif 00064 } 00065 00066 00067 /********************/ 00068 /*** dll Function ***/ 00069 void * 00070 dllFunction( DLLHandle handle, char const *function_name ) 00071 { 00072 return (void *) GetProcAddress( handle, function_name ); 00073 } 00074 00075 00076 /*****************/ 00077 /*** dll Close ***/ 00078 int 00079 dllClose( DLLHandle handle ) 00080 { 00081 return FreeLibrary( handle ); 00082 } 00083 00084 00085 /*****************/ 00086 /*** dll Error ***/ 00087 const char * 00088 dllError( DLLHandle ) 00089 { 00090 char * szBuf = NULL; 00091 long error = GetLastError(); 00092 00093 if (error) 00094 { 00095 szBuf = new char[1024]; 00096 FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, 00097 NULL, error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &szBuf, 0, NULL ); 00098 } 00099 return szBuf; 00100 } 00101 00102 /*********************************/ 00103 /*** set up External Resources ***/ 00104 void setupExternalResources() 00105 { 00106 // Get directory where the .exe resides 00107 char initial_path[FILENAME_MAX]; 00108 00109 int bytes = GetModuleFileName( NULL, initial_path, FILENAME_MAX ); 00110 00111 if ( bytes == 0 ) { 00112 00113 return; 00114 } 00115 00116 // Remove file name from path 00117 string initial_path_str( initial_path ); 00118 00119 size_t last_sep; 00120 00121 last_sep = initial_path_str.find_last_of("/\\"); 00122 00123 if ( ! last_sep ) { 00124 00125 return; 00126 } 00127 00128 string path = initial_path_str.substr( 0, last_sep+1 ); 00129 00130 // Set algorithms path 00131 string alg_path = path; 00132 alg_path.append( "algs" ); 00133 AlgorithmFactory::setDefaultAlgDir( alg_path ); 00134 00135 // Set data path 00136 string data_path = path; 00137 data_path.append( "data" ); 00138 omDataPath( data_path ); 00139 00140 // Set GDAL_DATA for openModeller lib 00141 string gdal_data_path = path; 00142 gdal_data_path.append( "gdal" ); 00143 CPLSetConfigOption( "GDAL_DATA", gdal_data_path.c_str() ); 00144 00145 // Set PROJ_LIB for openModeller lib 00146 string proj_data_path = path; 00147 proj_data_path.append( "nad" ); 00148 const char * char_path = proj_data_path.c_str(); 00149 const char ** paths; 00150 paths = &char_path; 00151 pj_set_searchpath( 1, paths ); 00152 } 00153 00154 /********************/ 00155 /*** om Data Path ***/ 00156 std::string omDataPath( std::string dir ) 00157 { 00158 static string data_path; 00159 00160 // Set default directory, if specified through parameter 00161 if ( ! dir.empty() ) { 00162 00163 data_path = dir; 00164 00165 return data_path; 00166 } 00167 00168 // Check configuration 00169 if ( Settings::count( "DATA_DIRECTORY" ) == 1 ) { 00170 00171 return Settings::get( "DATA_DIRECTORY" ); 00172 } 00173 00174 // Check env variable 00175 char *env = getenv( "OM_DATA_DIR" ); 00176 00177 if ( env != 0 ) { 00178 00179 string om_data_path = (char const *)env; 00180 00181 if ( ! om_data_path.empty() ) { 00182 00183 return om_data_path; 00184 } 00185 } 00186 00187 // Finally compiler constant 00188 return OM_DATA_DIR; 00189 } 00190 00191 /***************************/ 00192 /*** initial Plugin Path ***/ 00193 vector<string> 00194 initialPluginPath() 00195 { 00196 Log::instance()->debug( "Determining algorithms plugin path\n" ); 00197 00198 vector<string> entries; 00199 00200 // Default location can be set programatically 00201 std::string default_dir = AlgorithmFactory::getDefaultAlgDir(); 00202 00203 if ( ! default_dir.empty() ) { 00204 00205 Log::instance()->debug( "Using programatic setting for algorithms location\n" ); 00206 00207 entries.push_back( default_dir ); 00208 return entries; 00209 } 00210 00211 // Otherwise check configuration 00212 if ( Settings::count( "ALGS_DIRECTORY" ) == 1 ) { 00213 00214 Log::instance()->debug( "Using configuration setting for algorithms location\n" ); 00215 entries.push_back( Settings::get( "ALGS_DIRECTORY" ) ); 00216 return entries; 00217 } 00218 00219 // Or environment variable 00220 char *env = getenv( "OM_ALGS_DIR" ); 00221 00222 if ( env != 0 ) { 00223 00224 string envpath( (char const *)env ); 00225 00226 // Ignore empty string 00227 if ( ! envpath.empty() ) { 00228 00229 Log::instance()->debug( "Using environment setting for algorithms location\n" ); 00230 00231 // Parse the OM_ALGS_DIR with semi-colon (';') delimiters just like all other 00232 // Windows path structures. 00233 00234 // string::size_type start marks the beginning of the substring. 00235 // initial value is beginning of string, iterate value is one past the ';' 00236 for ( string::size_type start = 0; start < envpath.length() ; ) { 00237 00238 // Find the next ';' after start 00239 string::size_type it = envpath.find( ';', start ); 00240 00241 // If no ';' is found.. 00242 if ( it == string::npos ) { 00243 00244 // the substring is (start, end-of-string) 00245 entries.push_back( envpath.substr( start ) ); 00246 break; 00247 } 00248 // Else, test that the substring is non empty. 00249 else if ( it > start ) { 00250 00251 string::size_type len = it - start; 00252 entries.push_back( envpath.substr( start, len ) ); 00253 } 00254 00255 // move the start of the next substring to one after the ':' 00256 start = it+1; 00257 } 00258 00259 return entries; 00260 } 00261 } 00262 00263 // Finally compiler constant 00264 Log::instance()->debug( "Using default algorithms location\n" ); 00265 00266 entries.reserve(1); 00267 entries.push_back( OM_ALGS_DIR ); 00268 return entries; 00269 } 00270 00271 /****************************************************************/ 00272 /********************* Scan Directory Entries *******************/ 00273 00274 #include <io.h> 00275 #include <string.h> 00276 #include <stdlib.h> 00277 00278 00279 /****************/ 00280 /*** scan Dir ***/ 00281 00282 vector<string> 00283 scanDirectory( string dir ) 00284 { 00285 string filepattern(dir); 00286 long dirhandle; 00287 struct _finddata_t fileinfo; 00288 00289 vector<string> entries; 00290 00291 // check for empty string 00292 if (!dir.length()) 00293 { 00294 return entries; 00295 } 00296 00297 // check for slashes at the end of directory name 00298 if ( (filepattern.find_last_of("/") != filepattern.length() - 1) && 00299 (filepattern.find_last_of("\\") != filepattern.length() - 1) ) 00300 filepattern.append("\\"); 00301 00302 // Windows findfirst and findnext calls. 00303 filepattern.append("*.dll"); 00304 dirhandle = _findfirst(filepattern.c_str(), &fileinfo); 00305 00306 if (dirhandle == -1L) 00307 return entries; 00308 00309 int nent = 1; 00310 while (!_findnext(dirhandle, &fileinfo)) 00311 { nent++; } 00312 00313 // Directory path size - not used so remove this! 00314 //int dir_size = dir.size(); 00315 00316 // Windows findfirst and findnext calls. 00317 dirhandle = _findfirst(filepattern.c_str(), &fileinfo); 00318 00319 if (dirhandle == -1L) 00320 return entries; 00321 00322 // Copy from windows structure to the return structure. 00323 for ( int i = 0; i < nent; i++ ) 00324 { 00325 char *found = fileinfo.name; 00326 00327 string name = dir; 00328 name += "\\"; 00329 name += found; 00330 00331 entries.push_back(name); 00332 00333 _findnext(dirhandle, &fileinfo); 00334 } 00335 00336 _findclose(dirhandle); 00337 00338 return entries; 00339 } 00340 00341 00342 00343 00344 /****************************************************************/ 00345 /*********************** Random Generation **********************/ 00346 00347 #include <time.h> 00348 00349 00350 /*******************/ 00351 /*** init Random ***/ 00352 dllexp int initRandom() 00353 { 00354 unsigned int seed; 00355 seed = (unsigned int) time( NULL ); 00356 srand( seed ); 00357 return 1; 00358 } 00359 00360 /*******************/ 00361 /*** init Random ***/ 00362 dllexp int 00363 initRandom( unsigned int new_seed ) 00364 { 00365 static unsigned int seed = 0; 00366 00367 if ( seed && !new_seed ) { 00368 00369 // reseeding rand can decrease the randomness, so avoid doing it 00370 return 1; 00371 } 00372 00373 if ( new_seed ) { 00374 00375 seed = new_seed; 00376 } 00377 else { 00378 00379 seed = (unsigned int) time( NULL ); 00380 } 00381 00382 Log::instance()->debug( "Setting random seed %u\n", seed ); 00383 00384 srand( seed ); 00385 00386 return 1; 00387 } 00388 00389 /*****************************************/ 00390 /*** rand_r implementation for Windows ***/ 00391 dllexp int 00392 rand_r( unsigned * seed ) 00393 { 00394 * seed = (* seed) * 1103515245 + 12345; 00395 return ((unsigned)(*seed / 65536) % 32768); 00396 } 00397 00398 /************************/ 00399 /*** get Working path ***/ 00400 std::string 00401 getWorkingPath() 00402 { 00403 char temp[MAX_PATH]; 00404 return ( _getcwd(temp, MAX_PATH) ? std::string( temp ) : std::string("") ); 00405 } 00406 00407 /*******************/ 00408 /*** path Exists ***/ 00409 bool 00410 pathExists( const std::string path ) 00411 { 00412 DWORD ftyp = GetFileAttributesA( path.c_str() ); 00413 00414 if ( ftyp == INVALID_FILE_ATTRIBUTES ) { 00415 00416 return false; // something is wrong with the path 00417 } 00418 00419 if ( ftyp & FILE_ATTRIBUTE_DIRECTORY ) { 00420 00421 return true; // this is a directory 00422 } 00423 00424 return false; // not a directoy 00425 } 00426 00427 /*******************/ 00428 /*** create Path ***/ 00429 bool 00430 createPath( const std::string path ) 00431 { 00432 static const std::string separators("\\/"); 00433 00434 DWORD file_attr = ::GetFileAttributes( (LPCSTR) path.c_str() ); 00435 00436 // If the specified directory name doesn't exist 00437 if ( file_attr == INVALID_FILE_ATTRIBUTES ) { 00438 00439 // Recursively do it all again for the parent directory, if any 00440 std::size_t slash_idx = path.find_last_of( separators.c_str() ); 00441 00442 if ( slash_idx != std::string::npos ) { 00443 00444 createPath( path.substr(0, slash_idx) ); 00445 } 00446 00447 // Create the last directory on the path (the recursive calls will have taken 00448 // care of the parent directories by now) 00449 ::CreateDirectory( (LPCSTR) path.c_str(), NULL ); 00450 return pathExists( path ); 00451 } 00452 00453 // Specified directory name already exists as a file or directory 00454 return false; 00455 }