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