openModeller  Version 1.5.0
os_specific_win.cpp
Go to the documentation of this file.
1 
30 #ifdef WIN32
31 // avoid warnings caused by problems in VC headers
32 #define _SCL_SECURE_NO_DEPRECATE
33 #endif
34 
35 #include <os_specific.hh>
36 #include <openmodeller/Log.hh>
38 #include <openmodeller/Settings.hh>
39 
40 #include <stdio.h>
41 #include <fstream>
42 #include <windows.h>
43 #include <direct.h>
44 #include <cpl_conv.h> // for setting gdal options
45 #include <proj_api.h> // for setting proj options
46 
47 using std::vector;
48 using std::string;
49 
50 /****************************************************************/
51 /********************* Dynamic Linking Loader *******************/
52 
53 /****************/
54 /*** dll Open ***/
56 dllOpen( char const *dll_file_name )
57 {
58 #ifdef MINGW_QT
59  //Added by Tim because under mingw wchar is expected
60  return LoadLibraryA( dll_file_name );
61 #else
62  return LoadLibraryA( dll_file_name );
63 #endif
64 }
65 
66 
67 /********************/
68 /*** dll Function ***/
69 void *
70 dllFunction( DLLHandle handle, char const *function_name )
71 {
72  return (void *) GetProcAddress( handle, function_name );
73 }
74 
75 
76 /*****************/
77 /*** dll Close ***/
78 int
80 {
81  return FreeLibrary( handle );
82 }
83 
84 
85 /*****************/
86 /*** dll Error ***/
87 const char *
89 {
90  char * szBuf = NULL;
91  long error = GetLastError();
92 
93  if (error)
94  {
95  szBuf = new char[1024];
96  FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
97  NULL, error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &szBuf, 0, NULL );
98  }
99  return szBuf;
100 }
101 
102 /*********************************/
103 /*** set up External Resources ***/
105 {
106  // Get directory where the .exe resides
107  char initial_path[FILENAME_MAX];
108 
109  int bytes = GetModuleFileName( NULL, initial_path, FILENAME_MAX );
110 
111  if ( bytes == 0 ) {
112 
113  return;
114  }
115 
116  // Remove file name from path
117  string initial_path_str( initial_path );
118 
119  size_t last_sep;
120 
121  last_sep = initial_path_str.find_last_of("/\\");
122 
123  if ( ! last_sep ) {
124 
125  return;
126  }
127 
128  string path = initial_path_str.substr( 0, last_sep+1 );
129 
130  // Set algorithms path
131  string alg_path = path;
132  alg_path.append( "algs" );
134 
135  // Set data path
136  string data_path = path;
137  data_path.append( "data" );
138  omDataPath( data_path );
139 
140  // Set GDAL_DATA for openModeller lib
141  string gdal_data_path = path;
142  gdal_data_path.append( "gdal" );
143  CPLSetConfigOption( "GDAL_DATA", gdal_data_path.c_str() );
144 
145  // Set PROJ_LIB for openModeller lib
146  string proj_data_path = path;
147  proj_data_path.append( "nad" );
148  const char * char_path = proj_data_path.c_str();
149  const char ** paths;
150  paths = &char_path;
151  pj_set_searchpath( 1, paths );
152 }
153 
154 /********************/
155 /*** om Data Path ***/
156 std::string omDataPath( std::string dir )
157 {
158  static string data_path;
159 
160  // Set default directory, if specified through parameter
161  if ( ! dir.empty() ) {
162 
163  data_path = dir;
164 
165  return data_path;
166  }
167 
168  // Check configuration
169  if ( Settings::count( "DATA_DIRECTORY" ) == 1 ) {
170 
171  return Settings::get( "DATA_DIRECTORY" );
172  }
173 
174  // Check env variable
175  char *env = getenv( "OM_DATA_DIR" );
176 
177  if ( env != 0 ) {
178 
179  string om_data_path = (char const *)env;
180 
181  if ( ! om_data_path.empty() ) {
182 
183  return om_data_path;
184  }
185  }
186 
187  // Finally compiler constant
188  return OM_DATA_DIR;
189 }
190 
191 /***************************/
192 /*** initial Plugin Path ***/
193 vector<string>
195 {
196  Log::instance()->debug( "Determining algorithms plugin path\n" );
197 
198  vector<string> entries;
199 
200  // Default location can be set programatically
201  std::string default_dir = AlgorithmFactory::getDefaultAlgDir();
202 
203  if ( ! default_dir.empty() ) {
204 
205  Log::instance()->debug( "Using programatic setting for algorithms location\n" );
206 
207  entries.push_back( default_dir );
208  return entries;
209  }
210 
211  // Otherwise check configuration
212  if ( Settings::count( "ALGS_DIRECTORY" ) == 1 ) {
213 
214  Log::instance()->debug( "Using configuration setting for algorithms location\n" );
215  entries.push_back( Settings::get( "ALGS_DIRECTORY" ) );
216  return entries;
217  }
218 
219  // Or environment variable
220  char *env = getenv( "OM_ALGS_DIR" );
221 
222  if ( env != 0 ) {
223 
224  string envpath( (char const *)env );
225 
226  // Ignore empty string
227  if ( ! envpath.empty() ) {
228 
229  Log::instance()->debug( "Using environment setting for algorithms location\n" );
230 
231  // Parse the OM_ALGS_DIR with semi-colon (';') delimiters just like all other
232  // Windows path structures.
233 
234  // string::size_type start marks the beginning of the substring.
235  // initial value is beginning of string, iterate value is one past the ';'
236  for ( string::size_type start = 0; start < envpath.length() ; ) {
237 
238  // Find the next ';' after start
239  string::size_type it = envpath.find( ';', start );
240 
241  // If no ';' is found..
242  if ( it == string::npos ) {
243 
244  // the substring is (start, end-of-string)
245  entries.push_back( envpath.substr( start ) );
246  break;
247  }
248  // Else, test that the substring is non empty.
249  else if ( it > start ) {
250 
251  string::size_type len = it - start;
252  entries.push_back( envpath.substr( start, len ) );
253  }
254 
255  // move the start of the next substring to one after the ':'
256  start = it+1;
257  }
258 
259  return entries;
260  }
261  }
262 
263  // Finally compiler constant
264  Log::instance()->debug( "Using default algorithms location\n" );
265 
266  entries.reserve(1);
267  entries.push_back( OM_ALGS_DIR );
268  return entries;
269 }
270 
271 /****************************************************************/
272 /********************* Scan Directory Entries *******************/
273 
274 #include <io.h>
275 #include <string.h>
276 #include <stdlib.h>
277 
278 
279 /****************/
280 /*** scan Dir ***/
281 
282 vector<string>
283 scanDirectory( string dir )
284 {
285  string filepattern(dir);
286  long dirhandle;
287  struct _finddata_t fileinfo;
288 
289  vector<string> entries;
290 
291  // check for empty string
292  if (!dir.length())
293  {
294  return entries;
295  }
296 
297  // check for slashes at the end of directory name
298  if ( (filepattern.find_last_of("/") != filepattern.length() - 1) &&
299  (filepattern.find_last_of("\\") != filepattern.length() - 1) )
300  filepattern.append("\\");
301 
302  // Windows findfirst and findnext calls.
303  filepattern.append("*.dll");
304  dirhandle = _findfirst(filepattern.c_str(), &fileinfo);
305 
306  if (dirhandle == -1L)
307  return entries;
308 
309  int nent = 1;
310  while (!_findnext(dirhandle, &fileinfo))
311  { nent++; }
312 
313  // Directory path size - not used so remove this!
314  //int dir_size = dir.size();
315 
316  // Windows findfirst and findnext calls.
317  dirhandle = _findfirst(filepattern.c_str(), &fileinfo);
318 
319  if (dirhandle == -1L)
320  return entries;
321 
322  // Copy from windows structure to the return structure.
323  for ( int i = 0; i < nent; i++ )
324  {
325  char *found = fileinfo.name;
326 
327  string name = dir;
328  name += "\\";
329  name += found;
330 
331  entries.push_back(name);
332 
333  _findnext(dirhandle, &fileinfo);
334  }
335 
336  _findclose(dirhandle);
337 
338  return entries;
339 }
340 
341 
342 
343 
344 /****************************************************************/
345 /*********************** Random Generation **********************/
346 
347 #include <time.h>
348 
349 
350 /*******************/
351 /*** init Random ***/
352 dllexp int initRandom()
353 {
354  unsigned int seed;
355  seed = (unsigned int) time( NULL );
356  srand( seed );
357  return 1;
358 }
359 
360 /*******************/
361 /*** init Random ***/
362 dllexp int
363 initRandom( unsigned int new_seed )
364 {
365  static unsigned int seed = 0;
366 
367  if ( seed && !new_seed ) {
368 
369  // reseeding rand can decrease the randomness, so avoid doing it
370  return 1;
371  }
372 
373  if ( new_seed ) {
374 
375  seed = new_seed;
376  }
377  else {
378 
379  seed = (unsigned int) time( NULL );
380  }
381 
382  Log::instance()->debug( "Setting random seed %u\n", seed );
383 
384  srand( seed );
385 
386  return 1;
387 }
388 
389 /*****************************************/
390 /*** rand_r implementation for Windows ***/
391 dllexp int
392 rand_r( unsigned * seed )
393 {
394  * seed = (* seed) * 1103515245 + 12345;
395  return ((unsigned)(*seed / 65536) % 32768);
396 }
397 
398 /************************/
399 /*** get Working path ***/
400 std::string
402 {
403  char temp[MAX_PATH];
404  return ( _getcwd(temp, MAX_PATH) ? std::string( temp ) : std::string("") );
405 }
406 
407 /*******************/
408 /*** path Exists ***/
409 bool
410 pathExists( const std::string path )
411 {
412  DWORD ftyp = GetFileAttributesA( path.c_str() );
413 
414  if ( ftyp == INVALID_FILE_ATTRIBUTES ) {
415 
416  return false; // something is wrong with the path
417  }
418 
419  if ( ftyp & FILE_ATTRIBUTE_DIRECTORY ) {
420 
421  return true; // this is a directory
422  }
423 
424  return false; // not a directoy
425 }
426 
427 /*******************/
428 /*** create Path ***/
429 bool
430 createPath( const std::string path )
431 {
432  static const std::string separators("\\/");
433 
434  DWORD file_attr = ::GetFileAttributes( (LPCSTR) path.c_str() );
435 
436  // If the specified directory name doesn't exist
437  if ( file_attr == INVALID_FILE_ATTRIBUTES ) {
438 
439  // Recursively do it all again for the parent directory, if any
440  std::size_t slash_idx = path.find_last_of( separators.c_str() );
441 
442  if ( slash_idx != std::string::npos ) {
443 
444  createPath( path.substr(0, slash_idx) );
445  }
446 
447  // Create the last directory on the path (the recursive calls will have taken
448  // care of the parent directories by now)
449  ::CreateDirectory( (LPCSTR) path.c_str(), NULL );
450  return pathExists( path );
451  }
452 
453  // Specified directory name already exists as a file or directory
454  return false;
455 }
static std::string getDefaultAlgDir()
dllexp int rand_r(unsigned *seed)
static Log * instance()
Returns the instance pointer, creating the object on the first call.
Definition: Log.cpp:45
void setupExternalResources()
DLLHandle dllOpen(char const *dll_file_name)
unsigned long DWORD
Definition: Utilities.h:75
static std::string get(const std::string &key)
Definition: Settings.cpp:112
dllexp int initRandom()
const char * dllError(DLLHandle)
static void setDefaultAlgDir(std::string const dir)
bool createPath(const std::string path)
static int count(const std::string &key)
Definition: Settings.cpp:127
vector< string > scanDirectory(string dir)
void * dllFunction(DLLHandle handle, char const *function_name)
std::string omDataPath(std::string dir)
vector< string > initialPluginPath()
std::string getWorkingPath()
int dllClose(DLLHandle handle)
bool pathExists(const std::string path)
void * DLLHandle
Definition: os_specific.hh:81
void debug(const char *format,...)
'Debug' level.
Definition: Log.cpp:237
static char error[256]
Definition: FileParser.cpp:42