Salome HOME
IMP NPAL13547: Checkbox to kill SALOME completely.
[modules/kernel.git] / src / TOOLSDS / SALOMEDS_Tool.cxx
1 // Copyright (C) 2005  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
2 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
3 // 
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either 
7 // version 2.1 of the License.
8 // 
9 // This library is distributed in the hope that it will be useful 
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
12 // Lesser General Public License for more details.
13 //
14 // You should have received a copy of the GNU Lesser General Public  
15 // License along with this library; if not, write to the Free Software 
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
17 //
18 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 //
20 //  File      : SALOMEDS_Tool.cxx
21 //  Created   : Mon Oct 21 16:24:34 2002
22 //  Author    : Sergey RUIN
23
24 //  Project   : SALOME
25 //  Module    : SALOMEDS
26
27 #include "SALOMEDS_Tool.hxx"
28
29 #include "utilities.h"
30
31 #ifndef WNT
32 #include <sys/time.h>
33 #include <sys/stat.h>
34 #include <sys/types.h>
35 #include <iostream.h> 
36 #include <fstream.h>
37 #include <pwd.h> 
38 #include <unistd.h>
39 #else
40 #include <time.h>
41 #include <lmcons.h>
42 #endif
43
44 #include <stdlib.h>
45
46 #include <SALOMEconfig.h>
47 #include CORBA_SERVER_HEADER(SALOMEDS_Attributes)
48
49 using namespace std;
50
51 bool Exists(const string thePath) 
52 {
53 #ifdef WNT 
54   if (  GetFileAttributes (  thePath.c_str()  ) == 0xFFFFFFFF  ) { 
55     if (  GetLastError () != ERROR_FILE_NOT_FOUND  ) {
56       return false;
57     }
58   }
59 #else 
60   int status = access ( thePath.c_str() , F_OK ); 
61   if (status != 0) return false;
62 #endif
63   return true;
64 }
65
66
67 //============================================================================
68 // function : GetTempDir
69 // purpose  : Return a temp directory to store created files like "/tmp/sub_dir/" 
70 //============================================================================ 
71 std::string SALOMEDS_Tool::GetTmpDir()
72 {
73   //Find a temporary directory to store a file
74
75   string aTmpDir = "";
76
77   char *Tmp_dir = getenv("SALOME_TMP_DIR");
78   if(Tmp_dir != NULL) {
79     aTmpDir = string(Tmp_dir);
80 #ifdef WIN32
81     if(aTmpDir[aTmpDir.size()-1] != '\\') aTmpDir+='\\';
82 #else
83     if(aTmpDir[aTmpDir.size()-1] != '/') aTmpDir+='/';
84 #endif      
85   }
86   else {
87 #ifdef WIN32
88     aTmpDir = string("C:\\");
89 #else
90     aTmpDir = string("/tmp/");
91 #endif
92   }
93
94   srand((unsigned int)time(NULL));
95   int aRND = 999 + (int)(100000.0*rand()/(RAND_MAX+1.0)); //Get a random number to present a name of a sub directory
96   char buffer[127];
97   sprintf(buffer, "%d", aRND);
98   string aSubDir(buffer);
99   if(aSubDir.size() <= 1) aSubDir = string("123409876");
100
101   aTmpDir += aSubDir; //Get RND sub directory
102
103   string aDir = aTmpDir;
104
105   if(Exists(aDir)) {
106     for(aRND = 0; Exists(aDir); aRND++) {
107       sprintf(buffer, "%d", aRND);
108       aDir = aTmpDir+buffer;  //Build a unique directory name
109     }
110   }
111
112 #ifdef WIN32
113   if(aDir[aDir.size()-1] != '\\') aDir+='\\';
114 #else
115   if(aDir[aTmpDir.size()-1] != '/') aDir+='/';
116 #endif
117
118
119 #ifdef WNT
120   CreateDirectory(aDir.c_str(), NULL);
121 #else
122   mkdir(aDir.c_str(), 0x1ff); 
123 #endif
124
125   return aDir;
126 }
127
128 //============================================================================
129 // function : RemoveTemporaryFiles
130 // purpose  : Removes files listed in theFileList
131 //============================================================================
132 void SALOMEDS_Tool::RemoveTemporaryFiles(const std::string& theDirectory, 
133                                          const SALOMEDS::ListOfFileNames& theFiles,
134                                          const bool IsDirDeleted)
135 {
136   string aDirName = theDirectory;
137
138   int i, aLength = theFiles.length();
139   for(i=1; i<=aLength; i++) {
140     string aFile(aDirName);
141     aFile += theFiles[i-1];
142     if(!Exists(aFile)) continue;
143
144 #ifdef WNT
145     DeleteFile(aFile.c_str());
146 #else 
147     unlink(aFile.c_str());
148 #endif
149   }
150
151   if(IsDirDeleted) {
152     if(Exists(aDirName)) {
153 #ifdef WNT
154       RemoveDirectory(aDireName.c_str());
155 #else
156       rmdir(aDirName.c_str());
157 #endif
158     }
159   }
160
161 }
162
163 //============================================================================
164 // function : PutFilesToStream
165 // purpose  : converts the files from a list 'theFiles' to the stream
166 //============================================================================
167 namespace
168 {
169   SALOMEDS::TMPFile* 
170   PutFilesToStream(const std::string& theFromDirectory,
171                    const SALOMEDS::ListOfFileNames& theFiles,
172                    const SALOMEDS::ListOfFileNames& theFileNames,
173                    const int theNamesOnly)
174   {
175     int i, aLength = theFiles.length();
176     if(aLength == 0)
177       return (new SALOMEDS::TMPFile);
178     
179     //Get a temporary directory for saved a file
180     string aTmpDir = theFromDirectory;
181     
182     long aBufferSize = 0;
183     long aCurrentPos;
184     
185     int aNbFiles = 0;
186     int* aFileNameSize= new int[aLength];
187     long* aFileSize= new long[aLength];
188     
189     //Determine the required size of the buffer
190     
191     for(i=0; i<aLength; i++) {
192       
193       //Check if the file exists
194       
195       if (!theNamesOnly) { // mpv 15.01.2003: if only file names must be stroed, then size of files is zero
196         string aFullPath = aTmpDir + const_cast<char*>(theFiles[i].in());   
197         if(!Exists(aFullPath)) continue;
198 #ifdef WNT
199         ifstream aFile(aFullPath.c_str(), ios::binary);
200 #else
201         ifstream aFile(aFullPath.c_str());
202 #endif
203         aFile.seekg(0, ios::end);
204         aFileSize[i] = aFile.tellg();
205         aBufferSize += aFileSize[i];              //Add a space to store the file
206       }
207       aFileNameSize[i] = strlen(theFileNames[i])+1;
208       aBufferSize += aFileNameSize[i];          //Add a space to store the file name
209       aBufferSize += (theNamesOnly)?4:12;       //Add 4 bytes: a length of the file name,
210       //    8 bytes: length of the file itself
211       aNbFiles++;
212     } 
213     
214     aBufferSize += 4;      //4 bytes for a number of the files that will be written to the stream;
215     unsigned char* aBuffer = new unsigned char[aBufferSize];  
216     if(aBuffer == NULL)
217       return (new SALOMEDS::TMPFile);
218     
219     //Initialize 4 bytes of the buffer by 0
220     memset(aBuffer, 0, 4); 
221     //Copy the number of files that will be written to the stream
222     memcpy(aBuffer, &aNbFiles, ((sizeof(int) > 4) ? 4 : sizeof(int))); 
223     
224     
225     aCurrentPos = 4;
226     
227     for(i=0; i<aLength; i++) {
228       ifstream *aFile;
229       if (!theNamesOnly) { // mpv 15.01.2003: we don't open any file if theNamesOnly = true
230         string aFullPath = aTmpDir + const_cast<char*>(theFiles[i].in());
231         if(!Exists(aFullPath)) continue;
232 #ifdef WNT
233         aFile = new ifstream(aFullPath.c_str(), ios::binary);
234 #else
235         aFile = new ifstream(aFullPath.c_str());
236 #endif  
237       }
238       //Initialize 4 bytes of the buffer by 0
239       memset((aBuffer + aCurrentPos), 0, 4); 
240       //Copy the length of the file name to the buffer
241       memcpy((aBuffer + aCurrentPos), (aFileNameSize + i), ((sizeof(int) > 4) ? 4 : sizeof(int))); 
242       aCurrentPos += 4;
243       
244       //Copy the file name to the buffer
245       memcpy((aBuffer + aCurrentPos), theFileNames[i], aFileNameSize[i]);
246       aCurrentPos += aFileNameSize[i];
247       
248       if (!theNamesOnly) { // mpv 15.01.2003: we don't copy file content to the buffer if !theNamesOnly
249         //Initialize 8 bytes of the buffer by 0
250         memset((aBuffer + aCurrentPos), 0, 8); 
251         //Copy the length of the file to the buffer
252         memcpy((aBuffer + aCurrentPos), (aFileSize + i), ((sizeof(long) > 8) ? 8 : sizeof(long)));
253         aCurrentPos += 8;
254         
255         aFile->seekg(0, ios::beg);
256         aFile->read((char *)(aBuffer + aCurrentPos), aFileSize[i]);
257         aFile->close();
258         delete(aFile);
259         aCurrentPos += aFileSize[i];
260       }
261     }
262     
263     delete[] aFileNameSize;
264     delete[] aFileSize;
265     
266     
267     CORBA::Octet* anOctetBuf =  (CORBA::Octet*)aBuffer;
268     
269     return (new SALOMEDS::TMPFile(aBufferSize, aBufferSize, anOctetBuf, 1));
270   }
271   
272 }
273
274
275 SALOMEDS::TMPFile* 
276 SALOMEDS_Tool::PutFilesToStream(const std::string& theFromDirectory,
277                                 const SALOMEDS::ListOfFileNames& theFiles,
278                                 const int theNamesOnly)
279 {
280   SALOMEDS::ListOfFileNames aFileNames(theFiles);
281   return ::PutFilesToStream(theFromDirectory,theFiles,aFileNames,theNamesOnly);
282 }
283
284
285 SALOMEDS::TMPFile* 
286 SALOMEDS_Tool::PutFilesToStream(const SALOMEDS::ListOfFileNames& theFiles,
287                                 const SALOMEDS::ListOfFileNames& theFileNames)
288 {
289   return ::PutFilesToStream("",theFiles,theFileNames,0);
290 }
291
292 //============================================================================
293 // function : PutStreamToFile
294 // purpose  : converts the stream "theStream" to the files
295 //============================================================================
296 SALOMEDS::ListOfFileNames_var 
297 SALOMEDS_Tool::PutStreamToFiles(const SALOMEDS::TMPFile& theStream,
298                                 const std::string& theToDirectory,
299                                 const int theNamesOnly)
300 {
301   SALOMEDS::ListOfFileNames_var aFiles = new SALOMEDS::ListOfFileNames;
302
303   if(theStream.length() == 0)
304     return aFiles;
305
306   //Get a temporary directory for saving a file
307   string aTmpDir = theToDirectory;
308
309   unsigned char *aBuffer = (unsigned char*)theStream.NP_data();
310
311   if(aBuffer == NULL)
312     return aFiles;
313
314   long aFileSize, aCurrentPos = 4;
315   int i, aFileNameSize, aNbFiles = 0;
316
317   //Copy the number of files in the stream
318   memcpy(&aNbFiles, aBuffer, sizeof(int)); 
319
320   aFiles->length(aNbFiles);
321
322   for(i=0; i<aNbFiles; i++) {
323
324     //Put a length of the file name to aFileNameSize
325     memcpy(&aFileNameSize, (aBuffer + aCurrentPos), ((sizeof(int) > 4) ? 4 : sizeof(int))); 
326     aCurrentPos += 4;
327
328     char *aFileName = new char[aFileNameSize];
329     //Put a file name to aFileName
330     memcpy(aFileName, (aBuffer + aCurrentPos), aFileNameSize); 
331     aCurrentPos += aFileNameSize;
332  
333     //Put a length of the file to aFileSize
334     if (!theNamesOnly) {
335       memcpy(&aFileSize, (aBuffer + aCurrentPos), ((sizeof(long) > 8) ? 8 : sizeof(long)));
336       aCurrentPos += 8;    
337       
338       string aFullPath = aTmpDir + aFileName;
339 #ifdef WNT
340       ofstream aFile(aFullPath.c_str(), ios::binary);
341 #else
342       ofstream aFile(aFullPath.c_str());
343 #endif
344       aFile.write((char *)(aBuffer+aCurrentPos), aFileSize); 
345       aFile.close();  
346       aCurrentPos += aFileSize;
347     }
348     aFiles[i] = CORBA::string_dup(aFileName);
349     delete[] aFileName;
350   }
351
352   return aFiles;
353 }
354
355 //============================================================================
356 // function : GetNameFromPath
357 // purpose  : Returns the name by the path
358 //============================================================================
359 std::string SALOMEDS_Tool::GetNameFromPath(const std::string& thePath) {
360   if (thePath.empty()) return "";
361   string aPath = thePath;
362   bool isFound = false;
363   int pos = aPath.rfind('/');
364   if(pos > 0) {
365     aPath = aPath.substr(pos+1, aPath.size());
366     isFound = true;
367   }    
368   if(!isFound) {
369     pos = aPath.rfind('\\'); 
370     if(pos > 0) {
371       aPath = aPath.substr(pos+1, aPath.size()); 
372       isFound = true;
373     }  
374   }  
375   if(!isFound) {  
376     pos = aPath.rfind('|');
377     if(pos > 0) aPath =  aPath.substr(pos+1, aPath.size()); 
378   }
379
380   pos = aPath.rfind('.'); 
381   if(pos > 0)  aPath = aPath.substr(0, pos); //Remove extension
382     
383   return aPath;
384 }
385
386 //============================================================================
387 // function : GetDirFromPath
388 // purpose  : Returns the dir by the path
389 //============================================================================
390 std::string SALOMEDS_Tool::GetDirFromPath(const std::string& thePath) {
391   if (thePath.empty()) return "";
392
393   int pos = thePath.rfind('/');
394   string path;
395   if(pos > 0) {
396     path = thePath.substr(0, pos+1);
397   }
398   if(path.empty()) {
399     pos = thePath.rfind('\\');
400     if(pos > 0) path = thePath.substr(0, pos+1); 
401   }
402   if(path.empty()) {
403     pos = thePath.rfind('|');
404     if(pos > 0) path = thePath.substr(0, pos+1); 
405   }
406   if(path.empty()) {
407     path = thePath+"/";
408   }
409   
410 #ifdef WNT  //Check if the only disk letter is given as path
411   if(path.size() == 2 && path[1] == ":") path +='\\';
412 #endif
413
414   for(int i = 0, len = path.size(); i<len; i++) 
415     if(path[i] == '|') path[i] = '/';
416   return path;
417 }
418
419 //=======================================================================
420 // name    : GetFlag
421 // Purpose : Retrieve specified flaf from "AttributeFlags" attribute
422 //=======================================================================
423 bool SALOMEDS_Tool::GetFlag( const int             theFlag,
424                              SALOMEDS::Study_var   theStudy,
425                              SALOMEDS::SObject_var theObj )
426 {
427   SALOMEDS::GenericAttribute_var anAttr;
428   if ( !theObj->_is_nil() && theObj->FindAttribute( anAttr, "AttributeFlags" ) )
429   {
430     SALOMEDS::AttributeFlags_var aFlags = SALOMEDS::AttributeFlags::_narrow( anAttr );
431     return aFlags->Get( theFlag );
432   }
433
434   return false;
435 }
436
437 //=======================================================================
438 // name    : SetFlag
439 // Purpose : Set/Unset specified flaf from "AttributeFlags" attribute
440 //=======================================================================
441 bool SALOMEDS_Tool::SetFlag( const int           theFlag,
442                              SALOMEDS::Study_var theStudy,
443                              const std::string&  theEntry,
444                              const bool          theValue )
445 {
446   SALOMEDS::SObject_var anObj = theStudy->FindObjectID(theEntry.c_str());
447
448   if ( !anObj->_is_nil() )
449   {
450     SALOMEDS::GenericAttribute_var aGAttr;
451     if ( anObj->FindAttribute( aGAttr, "AttributeFlags" ) )
452     {
453       SALOMEDS::AttributeFlags_var anAttr = SALOMEDS::AttributeFlags::_narrow( aGAttr );
454       anAttr->Set( theFlag, theValue );
455     }
456     else if ( theValue )
457     {
458       SALOMEDS::StudyBuilder_var aBuilder = theStudy->NewBuilder();
459       SALOMEDS::AttributeFlags_var anAttr = SALOMEDS::AttributeFlags::_narrow(
460         aBuilder->FindOrCreateAttribute( anObj, "AttributeFlags" ) );
461       anAttr->Set( theFlag, theValue );
462     }
463     return true;
464   }
465
466   return false;
467 }
468
469 //=======================================================================
470 // name    : getAllChildren
471 // Purpose : Get all children of object.
472 //           If theObj is null all objects of study are returned
473 //=======================================================================
474 void SALOMEDS_Tool::GetAllChildren( SALOMEDS::Study_var               theStudy,
475                                     SALOMEDS::SObject_var             theObj,
476                                     std::list<SALOMEDS::SObject_var>& theList )
477 {
478   if ( theObj->_is_nil() )
479   {
480     SALOMEDS::SComponentIterator_var anIter = theStudy->NewComponentIterator();
481     for ( ; anIter->More(); anIter->Next() )
482     {
483       SALOMEDS::SObject_var anObj = SALOMEDS::SObject::_narrow( anIter->Value() );
484       if ( !anObj->_is_nil() )
485       {
486         theList.push_back( anObj );
487         GetAllChildren( theStudy, anObj, theList );
488       }
489     }
490   }
491   else
492   {
493     SALOMEDS::ChildIterator_var anIter = theStudy->NewChildIterator( theObj );
494     for ( ; anIter->More(); anIter->Next() )
495     {
496       SALOMEDS::SObject_var anObj = anIter->Value();
497       SALOMEDS::SObject_var aRef;
498       if ( !anObj->ReferencedObject( aRef ) )
499       {
500         theList.push_back( anObj );
501         GetAllChildren( theStudy, anObj, theList );
502       }
503     }
504   }
505 }
506
507
508