Salome HOME
f8d0870ea3bedc587fe3dd22394747bce3a12e6b
[modules/kernel.git] / src / TOOLSDS / SALOMEDS_Tool.cxx
1 // Copyright (C) 2007-2014  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 SALOMEDS::ListOfFileNames& theFiles,
136                                          const bool IsDirDeleted)
137 {
138   std::string aDirName = theDirectory;
139
140   int i, aLength = theFiles.length();
141   for(i=1; i<=aLength; i++) {
142     std::string aFile(aDirName);
143     aFile += theFiles[i-1];
144     if(!Exists(aFile)) continue;
145
146 #ifdef WIN32
147     DeleteFile(aFile.c_str());
148 #else 
149     unlink(aFile.c_str());
150 #endif
151   }
152
153   if(IsDirDeleted) {
154     if(Exists(aDirName)) {
155 #ifdef WIN32
156       RemoveDirectory(aDirName.c_str());
157 #else
158       rmdir(aDirName.c_str());
159 #endif
160     }
161   }
162
163 }
164
165 //============================================================================
166 // function : PutFilesToStream
167 // purpose  : converts the files from a list 'theFiles' to the stream
168 //============================================================================
169 namespace
170 {
171   SALOMEDS::TMPFile* 
172   PutFilesToStream(const std::string& theFromDirectory,
173                    const SALOMEDS::ListOfFileNames& theFiles,
174                    const SALOMEDS::ListOfFileNames& theFileNames,
175                    const int theNamesOnly)
176   {
177     int i, aLength = theFiles.length();
178     if(aLength == 0)
179       return (new SALOMEDS::TMPFile);
180     
181     //Get a temporary directory for saved a file
182     std::string aTmpDir = theFromDirectory;
183     
184     long aBufferSize = 0;
185     long aCurrentPos;
186     
187     int aNbFiles = 0;
188     int* aFileNameSize= new int[aLength];
189     long* aFileSize= new long[aLength];
190     
191     //Determine the required size of the buffer
192     
193     for(i=0; i<aLength; i++) {
194       
195       //Check if the file exists
196       
197       if (!theNamesOnly) { // mpv 15.01.2003: if only file names must be stroed, then size of files is zero
198         std::string aFullPath = aTmpDir + const_cast<char*>(theFiles[i].in());   
199         if(!Exists(aFullPath)) continue;
200 #ifdef WIN32
201         std::ifstream aFile(aFullPath.c_str(), std::ios::binary);
202 #else
203         std::ifstream aFile(aFullPath.c_str());
204 #endif
205         aFile.seekg(0, std::ios::end);
206         aFileSize[i] = aFile.tellg();
207         aBufferSize += aFileSize[i];              //Add a space to store the file
208       }
209       aFileNameSize[i] = strlen(theFileNames[i])+1;
210       aBufferSize += aFileNameSize[i];          //Add a space to store the file name
211       aBufferSize += (theNamesOnly)?4:12;       //Add 4 bytes: a length of the file name,
212       //    8 bytes: length of the file itself
213       aNbFiles++;
214     } 
215     
216     if ( aNbFiles == 0 ) return (new SALOMEDS::TMPFile);
217     aBufferSize += 4;      //4 bytes for a number of the files that will be written to the stream;
218     unsigned char* aBuffer = new unsigned char[aBufferSize];  
219     if(aBuffer == NULL)
220       return (new SALOMEDS::TMPFile);
221     
222     //Initialize 4 bytes of the buffer by 0
223     memset(aBuffer, 0, 4); 
224     //Copy the number of files that will be written to the stream
225     memcpy(aBuffer, &aNbFiles, ((sizeof(int) > 4) ? 4 : sizeof(int))); 
226     
227     
228     aCurrentPos = 4;
229     
230     for(i=0; i<aLength; i++) {
231       std::ifstream *aFile;
232       if (!theNamesOnly) { // mpv 15.01.2003: we don't open any file if theNamesOnly = true
233         std::string aFullPath = aTmpDir + const_cast<char*>(theFiles[i].in());
234         if(!Exists(aFullPath)) continue;
235 #ifdef WIN32
236         aFile = new std::ifstream(aFullPath.c_str(), std::ios::binary);
237 #else
238         aFile = new std::ifstream(aFullPath.c_str());
239 #endif  
240       }
241       //Initialize 4 bytes of the buffer by 0
242       memset((aBuffer + aCurrentPos), 0, 4); 
243       //Copy the length of the file name to the buffer
244       memcpy((aBuffer + aCurrentPos), (aFileNameSize + i), ((sizeof(int) > 4) ? 4 : sizeof(int))); 
245       aCurrentPos += 4;
246       
247       //Copy the file name to the buffer
248       memcpy((aBuffer + aCurrentPos), theFileNames[i], aFileNameSize[i]);
249       aCurrentPos += aFileNameSize[i];
250       
251       if (!theNamesOnly) { // mpv 15.01.2003: we don't copy file content to the buffer if !theNamesOnly
252         //Initialize 8 bytes of the buffer by 0
253         memset((aBuffer + aCurrentPos), 0, 8); 
254         //Copy the length of the file to the buffer
255         memcpy((aBuffer + aCurrentPos), (aFileSize + i), ((sizeof(long) > 8) ? 8 : sizeof(long)));
256         aCurrentPos += 8;
257         
258         aFile->seekg(0, std::ios::beg);
259         aFile->read((char *)(aBuffer + aCurrentPos), aFileSize[i]);
260         aFile->close();
261         delete(aFile);
262         aCurrentPos += aFileSize[i];
263       }
264     }
265     
266     delete[] aFileNameSize;
267     delete[] aFileSize;
268     
269     
270     CORBA::Octet* anOctetBuf =  (CORBA::Octet*)aBuffer;
271     
272     return (new SALOMEDS::TMPFile(aBufferSize, aBufferSize, anOctetBuf, 1));
273   }
274   
275 }
276
277
278 SALOMEDS::TMPFile* 
279 SALOMEDS_Tool::PutFilesToStream(const std::string& theFromDirectory,
280                                 const SALOMEDS::ListOfFileNames& theFiles,
281                                 const int theNamesOnly)
282 {
283   SALOMEDS::ListOfFileNames aFileNames(theFiles);
284   return ::PutFilesToStream(theFromDirectory,theFiles,aFileNames,theNamesOnly);
285 }
286
287
288 SALOMEDS::TMPFile* 
289 SALOMEDS_Tool::PutFilesToStream(const SALOMEDS::ListOfFileNames& theFiles,
290                                 const SALOMEDS::ListOfFileNames& theFileNames)
291 {
292   return ::PutFilesToStream("",theFiles,theFileNames,0);
293 }
294
295 //============================================================================
296 // function : PutStreamToFile
297 // purpose  : converts the stream "theStream" to the files
298 //============================================================================
299 SALOMEDS::ListOfFileNames_var 
300 SALOMEDS_Tool::PutStreamToFiles(const SALOMEDS::TMPFile& theStream,
301                                 const std::string& theToDirectory,
302                                 const int theNamesOnly)
303 {
304   SALOMEDS::ListOfFileNames_var aFiles = new SALOMEDS::ListOfFileNames;
305
306   if(theStream.length() == 0)
307     return aFiles;
308
309   //Get a temporary directory for saving a file
310   std::string aTmpDir = theToDirectory;
311
312   unsigned char *aBuffer = (unsigned char*)theStream.NP_data();
313
314   if(aBuffer == NULL)
315     return aFiles;
316
317   long aFileSize, aCurrentPos = 4;
318   int i, aFileNameSize, aNbFiles = 0;
319
320   //Copy the number of files in the stream
321   memcpy(&aNbFiles, aBuffer, sizeof(int)); 
322
323   aFiles->length(aNbFiles);
324
325   for(i=0; i<aNbFiles; i++) {
326
327     //Put a length of the file name to aFileNameSize
328     memcpy(&aFileNameSize, (aBuffer + aCurrentPos), ((sizeof(int) > 4) ? 4 : sizeof(int))); 
329     aCurrentPos += 4;
330
331     char *aFileName = new char[aFileNameSize];
332     //Put a file name to aFileName
333     memcpy(aFileName, (aBuffer + aCurrentPos), aFileNameSize); 
334 #ifdef WIN32
335     for (int i = 0; i < strlen(aFileName); i++)
336     {
337       if (aFileName[i] == ':')
338         aFileName[i] = '_';
339     }
340 #endif
341     aCurrentPos += aFileNameSize;
342  
343     //Put a length of the file to aFileSize
344     if (!theNamesOnly) {
345       memcpy(&aFileSize, (aBuffer + aCurrentPos), ((sizeof(long) > 8) ? 8 : sizeof(long)));
346       aCurrentPos += 8;    
347       
348       std::string aFullPath = aTmpDir + aFileName;
349 #ifdef WIN32
350       std::ofstream aFile(aFullPath.c_str(), std::ios::binary);
351 #else
352       std::ofstream aFile(aFullPath.c_str());
353 #endif
354       aFile.write((char *)(aBuffer+aCurrentPos), aFileSize); 
355       aFile.close();  
356       aCurrentPos += aFileSize;
357     }
358     aFiles[i] = CORBA::string_dup(aFileName);
359     delete[] aFileName;
360   }
361
362   return aFiles;
363 }
364
365 //============================================================================
366 // function : GetNameFromPath
367 // purpose  : Returns the name by the path
368 //============================================================================
369 std::string SALOMEDS_Tool::GetNameFromPath(const std::string& thePath) {
370   if (thePath.empty()) return "";
371   std::string aPath = thePath;
372   bool isFound = false;
373   int pos = aPath.rfind('/');
374   if(pos > 0) {
375     aPath = aPath.substr(pos+1, aPath.size());
376     isFound = true;
377   }    
378   if(!isFound) {
379     pos = aPath.rfind('\\'); 
380     if(pos > 0) {
381       aPath = aPath.substr(pos+1, aPath.size()); 
382       isFound = true;
383     }  
384   }  
385   if(!isFound) {  
386     pos = aPath.rfind('|');
387     if(pos > 0) aPath =  aPath.substr(pos+1, aPath.size()); 
388   }
389
390   pos = aPath.rfind('.'); 
391   if(pos > 0)  aPath = aPath.substr(0, pos); //Remove extension
392     
393   return aPath;
394 }
395
396 //============================================================================
397 // function : GetDirFromPath
398 // purpose  : Returns the dir by the path
399 //============================================================================
400 std::string SALOMEDS_Tool::GetDirFromPath(const std::string& thePath) {
401   if (thePath.empty()) return "";
402
403   int pos = thePath.rfind('/');
404   std::string path;
405   if(pos > 0) {
406     path = thePath.substr(0, pos+1);
407   }
408   if(path.empty()) {
409     pos = thePath.rfind('\\');
410     if(pos > 0) path = thePath.substr(0, pos+1); 
411   }
412   if(path.empty()) {
413     pos = thePath.rfind('|');
414     if(pos > 0) path = thePath.substr(0, pos+1); 
415   }
416   if(path.empty()) {
417     path = thePath+"/";
418   }
419   
420 #ifdef WIN32  //Check if the only disk letter is given as path
421   if(path.size() == 2 && path[1] == ':') path +='\\';
422 #endif
423
424   for(int i = 0, len = path.size(); i<len; i++) 
425     if(path[i] == '|') path[i] = '/';
426   return path;
427 }
428
429 //=======================================================================
430 // name    : GetFlag
431 // Purpose : Retrieve specified flaf from "AttributeFlags" attribute
432 //=======================================================================
433 bool SALOMEDS_Tool::GetFlag( const int             theFlag,
434                              SALOMEDS::Study_var   theStudy,
435                              SALOMEDS::SObject_var theObj )
436 {
437   SALOMEDS::GenericAttribute_var anAttr;
438   if ( !theObj->_is_nil() && theObj->FindAttribute( anAttr, "AttributeFlags" ) )
439   {
440     SALOMEDS::AttributeFlags_var aFlags = SALOMEDS::AttributeFlags::_narrow( anAttr );
441     return aFlags->Get( theFlag );
442   }
443
444   return false;
445 }
446
447 //=======================================================================
448 // name    : SetFlag
449 // Purpose : Set/Unset specified flaf from "AttributeFlags" attribute
450 //=======================================================================
451 bool SALOMEDS_Tool::SetFlag( const int           theFlag,
452                              SALOMEDS::Study_var theStudy,
453                              const std::string&  theEntry,
454                              const bool          theValue )
455 {
456   SALOMEDS::SObject_var anObj = theStudy->FindObjectID(theEntry.c_str());
457
458   if ( !anObj->_is_nil() )
459   {
460     SALOMEDS::GenericAttribute_var aGAttr;
461     if ( anObj->FindAttribute( aGAttr, "AttributeFlags" ) )
462     {
463       SALOMEDS::AttributeFlags_var anAttr = SALOMEDS::AttributeFlags::_narrow( aGAttr );
464       anAttr->Set( theFlag, theValue );
465     }
466     else if ( theValue )
467     {
468       SALOMEDS::StudyBuilder_var aBuilder = theStudy->NewBuilder();
469       SALOMEDS::AttributeFlags_var anAttr = SALOMEDS::AttributeFlags::_narrow(
470         aBuilder->FindOrCreateAttribute( anObj, "AttributeFlags" ) );
471       anAttr->Set( theFlag, theValue );
472     }
473     return true;
474   }
475
476   return false;
477 }
478
479 //=======================================================================
480 // name    : getAllChildren
481 // Purpose : Get all children of object.
482 //           If theObj is null all objects of study are returned
483 //=======================================================================
484 void SALOMEDS_Tool::GetAllChildren( SALOMEDS::Study_var               theStudy,
485                                     SALOMEDS::SObject_var             theObj,
486                                     std::list<SALOMEDS::SObject_var>& theList )
487 {
488   if ( theObj->_is_nil() )
489   {
490     SALOMEDS::SComponentIterator_var anIter = theStudy->NewComponentIterator();
491     for ( ; anIter->More(); anIter->Next() )
492     {
493       SALOMEDS::SObject_var anObj = SALOMEDS::SObject::_narrow( anIter->Value() );
494       if ( !anObj->_is_nil() )
495       {
496         theList.push_back( anObj );
497         GetAllChildren( theStudy, anObj, theList );
498       }
499     }
500   }
501   else
502   {
503     SALOMEDS::ChildIterator_var anIter = theStudy->NewChildIterator( theObj );
504     for ( ; anIter->More(); anIter->Next() )
505     {
506       SALOMEDS::SObject_var anObj = anIter->Value();
507       SALOMEDS::SObject_var aRef;
508       if ( !anObj->ReferencedObject( aRef ) )
509       {
510         theList.push_back( anObj );
511         GetAllChildren( theStudy, anObj, theList );
512       }
513     }
514   }
515 }
516
517
518