Salome HOME
Base implementation of Notebook
[modules/kernel.git] / src / TOOLSDS / SALOMEDS_Tool.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      : SALOMEDS_Tool.cxx
23 //  Created   : Mon Oct 21 16:24:34 2002
24 //  Author    : Sergey RUIN
25 //  Project   : SALOME
26 //  Module    : SALOMEDS
27 //
28 #include "SALOMEDS_Tool.hxx"
29
30 #include "utilities.h"
31 #include "Basics_DirUtils.hxx"
32
33 #ifndef WIN32
34 #include <sys/time.h>
35 #include <sys/stat.h>
36 #include <sys/types.h>
37 #include <pwd.h> 
38 #include <unistd.h>
39 #else
40 #include <time.h>
41 #include <lmcons.h>
42 #endif
43
44 #include <iostream> 
45 #include <fstream>
46 #include <stdlib.h>
47
48 #include <SALOMEconfig.h>
49 #include CORBA_SERVER_HEADER(SALOMEDS_Attributes)
50
51 using namespace std;
52
53 bool Exists(const string thePath) 
54 {
55 #ifdef WIN32 
56   if (  GetFileAttributes (  thePath.c_str()  ) == 0xFFFFFFFF  ) { 
57     if (  GetLastError () == ERROR_FILE_NOT_FOUND  ) {
58       return false;
59     }
60   }
61 #else 
62   int status = access ( thePath.c_str() , F_OK ); 
63   if (status != 0) return false;
64 #endif
65   return true;
66 }
67
68
69 //============================================================================
70 // function : GetTempDir
71 // purpose  : Return a temp directory to store created files like "/tmp/sub_dir/" 
72 //============================================================================ 
73 std::string SALOMEDS_Tool::GetTmpDir()
74 {
75   return Kernel_Utils::GetTmpDirByEnv("SALOME_TMP_DIR");
76   //Find a temporary directory to store a file
77
78   /*string aTmpDir = "";
79
80   char *Tmp_dir = getenv("SALOME_TMP_DIR");
81   if(Tmp_dir != NULL) {
82     aTmpDir = string(Tmp_dir);
83 #ifdef WIN32
84     if(aTmpDir[aTmpDir.size()-1] != '\\') aTmpDir+='\\';
85 #else
86     if(aTmpDir[aTmpDir.size()-1] != '/') aTmpDir+='/';
87 #endif      
88   }
89   else {
90 #ifdef WIN32
91     aTmpDir = string("C:\\");
92 #else
93     aTmpDir = string("/tmp/");
94 #endif
95   }
96
97   srand((unsigned int)time(NULL));
98   int aRND = 999 + (int)(100000.0*rand()/(RAND_MAX+1.0)); //Get a random number to present a name of a sub directory
99   char buffer[127];
100   sprintf(buffer, "%d", aRND);
101   string aSubDir(buffer);
102   if(aSubDir.size() <= 1) aSubDir = string("123409876");
103
104   aTmpDir += aSubDir; //Get RND sub directory
105
106   string aDir = aTmpDir;
107
108   if(Exists(aDir)) {
109     for(aRND = 0; Exists(aDir); aRND++) {
110       sprintf(buffer, "%d", aRND);
111       aDir = aTmpDir+buffer;  //Build a unique directory name
112     }
113   }
114
115 #ifdef WIN32
116   if(aDir[aDir.size()-1] != '\\') aDir+='\\';
117 #else
118   if(aDir[aTmpDir.size()-1] != '/') aDir+='/';
119 #endif
120
121
122 #ifdef WIN32
123   CreateDirectory(aDir.c_str(), NULL);
124 #else
125   mkdir(aDir.c_str(), 0x1ff); 
126 #endif
127
128   return aDir;*/
129 }
130
131 //============================================================================
132 // function : RemoveTemporaryFiles
133 // purpose  : Removes files listed in theFileList
134 //============================================================================
135 void SALOMEDS_Tool::RemoveTemporaryFiles(const std::string& theDirectory, 
136                                          const SALOMEDS::ListOfFileNames& theFiles,
137                                          const bool IsDirDeleted)
138 {
139   string aDirName = theDirectory;
140
141   int i, aLength = theFiles.length();
142   for(i=1; i<=aLength; i++) {
143     string aFile(aDirName);
144     aFile += theFiles[i-1];
145     if(!Exists(aFile)) continue;
146
147 #ifdef WIN32
148     DeleteFile(aFile.c_str());
149 #else 
150     unlink(aFile.c_str());
151 #endif
152   }
153
154   if(IsDirDeleted) {
155     if(Exists(aDirName)) {
156 #ifdef WIN32
157       RemoveDirectory(aDirName.c_str());
158 #else
159       rmdir(aDirName.c_str());
160 #endif
161     }
162   }
163
164 }
165
166 //============================================================================
167 // function : PutFilesToStream
168 // purpose  : converts the files from a list 'theFiles' to the stream
169 //============================================================================
170 namespace
171 {
172   SALOMEDS::TMPFile* 
173   PutFilesToStream(const std::string& theFromDirectory,
174                    const SALOMEDS::ListOfFileNames& theFiles,
175                    const SALOMEDS::ListOfFileNames& theFileNames,
176                    const int theNamesOnly)
177   {
178     int i, aLength = theFiles.length();
179     if(aLength == 0)
180       return (new SALOMEDS::TMPFile);
181     
182     //Get a temporary directory for saved a file
183     string aTmpDir = theFromDirectory;
184     
185     long aBufferSize = 0;
186     long aCurrentPos;
187     
188     int aNbFiles = 0;
189     int* aFileNameSize= new int[aLength];
190     long* aFileSize= new long[aLength];
191     
192     //Determine the required size of the buffer
193     
194     for(i=0; i<aLength; 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         string aFullPath = aTmpDir + const_cast<char*>(theFiles[i].in());   
200         if(!Exists(aFullPath)) continue;
201 #ifdef WIN32
202         ifstream aFile(aFullPath.c_str(), ios::binary);
203 #else
204         ifstream aFile(aFullPath.c_str());
205 #endif
206         aFile.seekg(0, ios::end);
207         aFileSize[i] = aFile.tellg();
208         aBufferSize += aFileSize[i];              //Add a space to store the file
209       }
210       aFileNameSize[i] = strlen(theFileNames[i])+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     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       ifstream *aFile;
232       if (!theNamesOnly) { // mpv 15.01.2003: we don't open any file if theNamesOnly = true
233         string aFullPath = aTmpDir + const_cast<char*>(theFiles[i].in());
234         if(!Exists(aFullPath)) continue;
235 #ifdef WIN32
236         aFile = new ifstream(aFullPath.c_str(), ios::binary);
237 #else
238         aFile = new 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, 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   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     aCurrentPos += aFileNameSize;
335  
336     //Put a length of the file to aFileSize
337     if (!theNamesOnly) {
338       memcpy(&aFileSize, (aBuffer + aCurrentPos), ((sizeof(long) > 8) ? 8 : sizeof(long)));
339       aCurrentPos += 8;    
340       
341       string aFullPath = aTmpDir + aFileName;
342 #ifdef WIN32
343       ofstream aFile(aFullPath.c_str(), ios::binary);
344 #else
345       ofstream aFile(aFullPath.c_str());
346 #endif
347       aFile.write((char *)(aBuffer+aCurrentPos), aFileSize); 
348       aFile.close();  
349       aCurrentPos += aFileSize;
350     }
351     aFiles[i] = CORBA::string_dup(aFileName);
352     delete[] aFileName;
353   }
354
355   return aFiles;
356 }
357
358 //============================================================================
359 // function : GetNameFromPath
360 // purpose  : Returns the name by the path
361 //============================================================================
362 std::string SALOMEDS_Tool::GetNameFromPath(const std::string& thePath) {
363   if (thePath.empty()) return "";
364   string aPath = thePath;
365   bool isFound = false;
366   int pos = aPath.rfind('/');
367   if(pos > 0) {
368     aPath = aPath.substr(pos+1, aPath.size());
369     isFound = true;
370   }    
371   if(!isFound) {
372     pos = aPath.rfind('\\'); 
373     if(pos > 0) {
374       aPath = aPath.substr(pos+1, aPath.size()); 
375       isFound = true;
376     }  
377   }  
378   if(!isFound) {  
379     pos = aPath.rfind('|');
380     if(pos > 0) aPath =  aPath.substr(pos+1, aPath.size()); 
381   }
382
383   pos = aPath.rfind('.'); 
384   if(pos > 0)  aPath = aPath.substr(0, pos); //Remove extension
385     
386   return aPath;
387 }
388
389 //============================================================================
390 // function : GetDirFromPath
391 // purpose  : Returns the dir by the path
392 //============================================================================
393 std::string SALOMEDS_Tool::GetDirFromPath(const std::string& thePath) {
394   if (thePath.empty()) return "";
395
396   int pos = thePath.rfind('/');
397   string path;
398   if(pos > 0) {
399     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     pos = thePath.rfind('|');
407     if(pos > 0) path = thePath.substr(0, pos+1); 
408   }
409   if(path.empty()) {
410     path = thePath+"/";
411   }
412   
413 #ifdef WIN32  //Check if the only disk letter is given as path
414   if(path.size() == 2 && path[1] == ':') path +='\\';
415 #endif
416
417   for(int i = 0, len = path.size(); i<len; i++) 
418     if(path[i] == '|') path[i] = '/';
419   return path;
420 }
421
422 //=======================================================================
423 // name    : GetFlag
424 // Purpose : Retrieve specified flaf from "AttributeFlags" attribute
425 //=======================================================================
426 bool SALOMEDS_Tool::GetFlag( const int             theFlag,
427                              SALOMEDS::Study_var   theStudy,
428                              SALOMEDS::SObject_var theObj )
429 {
430   SALOMEDS::GenericAttribute_var anAttr;
431   if ( !theObj->_is_nil() && theObj->FindAttribute( anAttr, "AttributeFlags" ) )
432   {
433     SALOMEDS::AttributeFlags_var aFlags = SALOMEDS::AttributeFlags::_narrow( anAttr );
434     return aFlags->Get( theFlag );
435   }
436
437   return false;
438 }
439
440 //=======================================================================
441 // name    : SetFlag
442 // Purpose : Set/Unset specified flaf from "AttributeFlags" attribute
443 //=======================================================================
444 bool SALOMEDS_Tool::SetFlag( const int           theFlag,
445                              SALOMEDS::Study_var theStudy,
446                              const std::string&  theEntry,
447                              const bool          theValue )
448 {
449   SALOMEDS::SObject_var anObj = theStudy->FindObjectID(theEntry.c_str());
450
451   if ( !anObj->_is_nil() )
452   {
453     SALOMEDS::GenericAttribute_var aGAttr;
454     if ( anObj->FindAttribute( aGAttr, "AttributeFlags" ) )
455     {
456       SALOMEDS::AttributeFlags_var anAttr = SALOMEDS::AttributeFlags::_narrow( aGAttr );
457       anAttr->Set( theFlag, theValue );
458     }
459     else if ( theValue )
460     {
461       SALOMEDS::StudyBuilder_var aBuilder = theStudy->NewBuilder();
462       SALOMEDS::AttributeFlags_var anAttr = SALOMEDS::AttributeFlags::_narrow(
463         aBuilder->FindOrCreateAttribute( anObj, "AttributeFlags" ) );
464       anAttr->Set( theFlag, theValue );
465     }
466     return true;
467   }
468
469   return false;
470 }
471
472 //=======================================================================
473 // name    : getAllChildren
474 // Purpose : Get all children of object.
475 //           If theObj is null all objects of study are returned
476 //=======================================================================
477 void SALOMEDS_Tool::GetAllChildren( SALOMEDS::Study_var               theStudy,
478                                     SALOMEDS::SObject_var             theObj,
479                                     std::list<SALOMEDS::SObject_var>& theList )
480 {
481   if ( theObj->_is_nil() )
482   {
483     SALOMEDS::SComponentIterator_var anIter = theStudy->NewComponentIterator();
484     for ( ; anIter->More(); anIter->Next() )
485     {
486       SALOMEDS::SObject_var anObj = SALOMEDS::SObject::_narrow( anIter->Value() );
487       if ( !anObj->_is_nil() )
488       {
489         theList.push_back( anObj );
490         GetAllChildren( theStudy, anObj, theList );
491       }
492     }
493   }
494   else
495   {
496     SALOMEDS::ChildIterator_var anIter = theStudy->NewChildIterator( theObj );
497     for ( ; anIter->More(); anIter->Next() )
498     {
499       SALOMEDS::SObject_var anObj = anIter->Value();
500       SALOMEDS::SObject_var aRef;
501       if ( !anObj->ReferencedObject( aRef ) )
502       {
503         theList.push_back( anObj );
504         GetAllChildren( theStudy, anObj, theList );
505       }
506     }
507   }
508 }
509
510
511