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