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