Salome HOME
Merge from V5_1_main 14/05/2010
[modules/kernel.git] / src / Basics / Basics_DirUtils.cxx
1 //  Copyright (C) 2007-2010  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 //  This library is free software; you can redistribute it and/or
4 //  modify it under the terms of the GNU Lesser General Public
5 //  License as published by the Free Software Foundation; either
6 //  version 2.1 of the License.
7 //
8 //  This library is distributed in the hope that it will be useful,
9 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
10 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 //  Lesser General Public License for more details.
12 //
13 //  You should have received a copy of the GNU Lesser General Public
14 //  License along with this library; if not, write to the Free Software
15 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 //  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19
20 //  File   : Basics_DirUtils.cxx
21 //  Autor  : Alexander A. BORODIN
22 //  Module : SALOME
23 //
24 #include "Basics_DirUtils.hxx"
25 #include <stdio.h>
26 #include <errno.h>
27 #include <stdlib.h>
28
29 #ifndef WIN32
30 # include <sys/stat.h>
31 # include <dirent.h>
32 #else
33 # include <windows.h>
34 # include <time.h>
35 #endif
36
37 #ifdef WIN32
38 # define _separator_ '\\'
39 #else
40 # define _separator_ '/'
41 #endif
42
43 namespace Kernel_Utils
44 {
45   std::string GetBaseName( const std::string& file_path )
46   {
47     int pos = file_path.rfind( _separator_ );
48     if ( pos >= 0 )
49       return pos < (int)file_path.size()-1 ? file_path.substr( pos+1 ) : "";
50     return file_path;
51   }
52
53   std::string GetTmpDirByEnv( const std::string& tmp_path_env )
54   {
55     std::string dir;
56     char* val = getenv( tmp_path_env.c_str() );
57     val ? dir = std::string( val ) : "";
58     return GetTmpDirByPath( dir );
59   }
60
61   std::string GetTmpDirByPath( const std::string& tmp_path )
62   {
63     std::string aTmpDir = tmp_path;
64     if ( aTmpDir == "" )
65       {
66 #ifdef WIN32
67         char *Tmp_dir = getenv("TEMP");
68         if( Tmp_dir == NULL )
69           {
70             Tmp_dir = getenv("TMP");
71             if (Tmp_dir == NULL)
72               aTmpDir = std::string("C:\\");
73             else 
74               aTmpDir = std::string(Tmp_dir);
75           }
76         else
77           aTmpDir = std::string(Tmp_dir);
78 #else
79         aTmpDir = std::string("/tmp/");
80 #endif
81       }
82     
83     if(aTmpDir[aTmpDir.size()-1] != _separator_)
84       aTmpDir+=_separator_;
85     
86     srand((unsigned int)time(NULL));
87     int aRND = 999 + (int)(100000.0*rand()/(RAND_MAX+1.0)); //Get a random number to present a name of a sub directory
88     char buffer[127];
89     sprintf(buffer, "%d", aRND);
90     std::string aSubDir(buffer);
91     if(aSubDir.size() <= 1) aSubDir = std::string("123409876");
92     
93     aTmpDir += aSubDir; //Get RND sub directory
94     
95     std::string aDir = aTmpDir;
96     
97     if(IsExists(aDir)) {
98       for(aRND = 0; IsExists(aDir); aRND++) {
99         sprintf(buffer, "%d", aRND);
100         aDir = aTmpDir+buffer;  //Build a unique directory name
101       }
102     }
103     
104     if(aDir[aDir.size()-1] != _separator_) aDir += _separator_;
105     
106 #ifdef WIN32
107     CreateDirectory(aDir.c_str(), NULL);
108 #else
109     mkdir(aDir.c_str(), 0x1ff); 
110 #endif
111     
112     return aDir;
113   }
114   
115   //============================================================================
116   // function : GetTempDir
117   // purpose  : Returns a temp directory to store created files like "/tmp/sub_dir/" 
118   //============================================================================ 
119   std::string GetTmpDir()
120   {
121     return GetTmpDirByPath( "" );
122   }
123
124   //============================================================================
125   // function : GetTempFileName
126   // purpose  : Returns the unique temporary file name without any extension /tmp/something/file for Unix or c:\something\file for WIN32
127   //============================================================================ 
128   std::string GetTmpFileName()
129   {
130     std::string tmpDir = GetTmpDir();
131     std::string aFilePath = "";
132     if(IsExists(tmpDir)) {
133       srand((unsigned int)time(NULL));
134       int aRND = 999 + (int)(100000.0*rand()/(RAND_MAX+1.0)); //Get a random number to present a name of a sub directory
135       char buffer[127];
136       sprintf(buffer, "%d", aRND);
137       std::string aSubDir(buffer);
138       if(aSubDir.size() <= 1) aSubDir = std::string("123409876");
139       
140       aFilePath = tmpDir;
141       for(aRND = 0; IsExists(aFilePath); aRND++) {
142         sprintf(buffer, "%d", aRND);
143         aFilePath = tmpDir+buffer;  //Build a unique file name
144       }
145     }
146     return aFilePath;
147   }
148   
149   //============================================================================
150   // function : IsExists
151   // purpose  : Returns True(False) if the path (not)exists
152   //============================================================================ 
153   bool IsExists(const std::string& thePath) 
154   {
155 #ifdef WIN32 
156     if (  GetFileAttributes (  thePath.c_str()  ) == 0xFFFFFFFF  ) { 
157       if (  GetLastError () == ERROR_FILE_NOT_FOUND  ) {
158         return false;
159       }
160     }
161 #else 
162     int status = access ( thePath.c_str() , F_OK ); 
163     if (status != 0) return false;
164 #endif
165     return true;
166   }
167
168   //============================================================================
169   // function : GetDirByPath
170   // purpose  : Returns directory by path and converts it to native system format
171   //============================================================================ 
172   std::string GetDirByPath(const std::string& thePath)
173   {
174     if (thePath.empty())
175       return "";
176     std::string path = thePath;
177     std::string::size_type length = path.length();
178
179     //detect all separators in Unix format
180     for ( unsigned int i = 0; i < length; i++ )
181     {
182       if( path[i] == '/' )
183         path[i] = '|';
184     }
185
186     //detect all separators in Windows format
187     for ( unsigned int i = 0; i < length; i++ )
188     {
189       if( path[i] == '\\' )
190         path[i] = '|';
191     }
192
193
194     std::string::size_type pos = path.rfind('|');
195     if ( pos == std::string::npos )
196     {
197 #ifdef WIN32
198       //check for disk letter ( C: )
199       if ( path.length() == 2 && path[1] == ':' )
200         path += _separator_;
201 #else
202       //not valid path
203       return "";
204 #endif
205     }
206     else
207     {
208       //remove right subdirectory or filename from path
209       path = path.substr( 0, pos );
210     }
211
212     length = path.length();
213     for ( unsigned int i = 0; i < length; i++ )
214     {
215       if( path[i] == '|' )
216         path[i] = _separator_;
217     }
218     return path;
219   }
220
221   //============================================================================
222   // function : IsEmptyDir
223   // purpose  : Returns True(False) if the path (not) empty
224   //            Also returns False if the path is not valid
225   //============================================================================ 
226   bool IsEmptyDir(const std::string& thePath) 
227   {
228     if ( thePath.empty() || !IsExists(thePath))
229       return false;
230
231     bool result = false;
232
233 #ifdef WIN32
234     WIN32_FIND_DATA aFileData;
235     HANDLE hFile = FindFirstFile( thePath.c_str(), &aFileData );
236     if ( hFile == INVALID_HANDLE_VALUE )
237     {
238       //empty dir
239       result = true;
240     }
241     else
242     {
243       //close serching. path is not empty
244       FindClose( hFile );
245     }
246 #else
247     DIR *dp;
248     struct dirent *dirp;
249     if((dp  = opendir(thePath.c_str())) == NULL)
250     {
251       //Could not open directory
252       return false;
253     }
254     else
255     {
256       result = true; //empty if no file found
257       while ((dirp = readdir(dp)) != NULL && result )
258         {
259           std::string file_name(dirp->d_name);
260           result = file_name.empty() || file_name == "." || file_name == ".."; //if any file - break and return false
261         }
262         closedir(dp);
263     }
264 #endif
265     return result;
266   }
267 }