]> SALOME platform Git repositories - modules/kernel.git/blob - src/TOOLSDS/SALOMEDS_Tool.cxx
Salome HOME
Merging from V4_1_0_maintainance for porting on Win32 Platform
[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 #include "Basics_DirUtils.hxx"
31
32 #ifndef WIN32
33 #include <sys/time.h>
34 #include <sys/stat.h>
35 #include <sys/types.h>
36 #include <pwd.h> 
37 #include <unistd.h>
38 #else
39 #include <time.h>
40 #include <lmcons.h>
41 #endif
42
43 #include <iostream> 
44 #include <fstream>
45 #include <stdlib.h>
46
47 #include <SALOMEconfig.h>
48 #include CORBA_SERVER_HEADER(SALOMEDS_Attributes)
49
50 using namespace std;
51
52 bool Exists(const 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   string aDirName = theDirectory;
139
140   int i, aLength = theFiles.length();
141   for(i=1; i<=aLength; i++) {
142     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     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         string aFullPath = aTmpDir + const_cast<char*>(theFiles[i].in());   
199         if(!Exists(aFullPath)) continue;
200 #ifdef WIN32
201         ifstream aFile(aFullPath.c_str(), ios::binary);
202 #else
203         ifstream aFile(aFullPath.c_str());
204 #endif
205         aFile.seekg(0, 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     aBufferSize += 4;      //4 bytes for a number of the files that will be written to the stream;
217     unsigned char* aBuffer = new unsigned char[aBufferSize];  
218     if(aBuffer == NULL)
219       return (new SALOMEDS::TMPFile);
220     
221     //Initialize 4 bytes of the buffer by 0
222     memset(aBuffer, 0, 4); 
223     //Copy the number of files that will be written to the stream
224     memcpy(aBuffer, &aNbFiles, ((sizeof(int) > 4) ? 4 : sizeof(int))); 
225     
226     
227     aCurrentPos = 4;
228     
229     for(i=0; i<aLength; i++) {
230       ifstream *aFile;
231       if (!theNamesOnly) { // mpv 15.01.2003: we don't open any file if theNamesOnly = true
232         string aFullPath = aTmpDir + const_cast<char*>(theFiles[i].in());
233         if(!Exists(aFullPath)) continue;
234 #ifdef WIN32
235         aFile = new ifstream(aFullPath.c_str(), ios::binary);
236 #else
237         aFile = new ifstream(aFullPath.c_str());
238 #endif  
239       }
240       //Initialize 4 bytes of the buffer by 0
241       memset((aBuffer + aCurrentPos), 0, 4); 
242       //Copy the length of the file name to the buffer
243       memcpy((aBuffer + aCurrentPos), (aFileNameSize + i), ((sizeof(int) > 4) ? 4 : sizeof(int))); 
244       aCurrentPos += 4;
245       
246       //Copy the file name to the buffer
247       memcpy((aBuffer + aCurrentPos), theFileNames[i], aFileNameSize[i]);
248       aCurrentPos += aFileNameSize[i];
249       
250       if (!theNamesOnly) { // mpv 15.01.2003: we don't copy file content to the buffer if !theNamesOnly
251         //Initialize 8 bytes of the buffer by 0
252         memset((aBuffer + aCurrentPos), 0, 8); 
253         //Copy the length of the file to the buffer
254         memcpy((aBuffer + aCurrentPos), (aFileSize + i), ((sizeof(long) > 8) ? 8 : sizeof(long)));
255         aCurrentPos += 8;
256         
257         aFile->seekg(0, ios::beg);
258         aFile->read((char *)(aBuffer + aCurrentPos), aFileSize[i]);
259         aFile->close();
260         delete(aFile);
261         aCurrentPos += aFileSize[i];
262       }
263     }
264     
265     delete[] aFileNameSize;
266     delete[] aFileSize;
267     
268     
269     CORBA::Octet* anOctetBuf =  (CORBA::Octet*)aBuffer;
270     
271     return (new SALOMEDS::TMPFile(aBufferSize, aBufferSize, anOctetBuf, 1));
272   }
273   
274 }
275
276
277 SALOMEDS::TMPFile* 
278 SALOMEDS_Tool::PutFilesToStream(const std::string& theFromDirectory,
279                                 const SALOMEDS::ListOfFileNames& theFiles,
280                                 const int theNamesOnly)
281 {
282   SALOMEDS::ListOfFileNames aFileNames(theFiles);
283   return ::PutFilesToStream(theFromDirectory,theFiles,aFileNames,theNamesOnly);
284 }
285
286
287 SALOMEDS::TMPFile* 
288 SALOMEDS_Tool::PutFilesToStream(const SALOMEDS::ListOfFileNames& theFiles,
289                                 const SALOMEDS::ListOfFileNames& theFileNames)
290 {
291   return ::PutFilesToStream("",theFiles,theFileNames,0);
292 }
293
294 //============================================================================
295 // function : PutStreamToFile
296 // purpose  : converts the stream "theStream" to the files
297 //============================================================================
298 SALOMEDS::ListOfFileNames_var 
299 SALOMEDS_Tool::PutStreamToFiles(const SALOMEDS::TMPFile& theStream,
300                                 const std::string& theToDirectory,
301                                 const int theNamesOnly)
302 {
303   SALOMEDS::ListOfFileNames_var aFiles = new SALOMEDS::ListOfFileNames;
304
305   if(theStream.length() == 0)
306     return aFiles;
307
308   //Get a temporary directory for saving a file
309   string aTmpDir = theToDirectory;
310
311   unsigned char *aBuffer = (unsigned char*)theStream.NP_data();
312
313   if(aBuffer == NULL)
314     return aFiles;
315
316   long aFileSize, aCurrentPos = 4;
317   int i, aFileNameSize, aNbFiles = 0;
318
319   //Copy the number of files in the stream
320   memcpy(&aNbFiles, aBuffer, sizeof(int)); 
321
322   aFiles->length(aNbFiles);
323
324   for(i=0; i<aNbFiles; i++) {
325
326     //Put a length of the file name to aFileNameSize
327     memcpy(&aFileNameSize, (aBuffer + aCurrentPos), ((sizeof(int) > 4) ? 4 : sizeof(int))); 
328     aCurrentPos += 4;
329
330     char *aFileName = new char[aFileNameSize];
331     //Put a file name to aFileName
332     memcpy(aFileName, (aBuffer + aCurrentPos), aFileNameSize); 
333     aCurrentPos += aFileNameSize;
334  
335     //Put a length of the file to aFileSize
336     if (!theNamesOnly) {
337       memcpy(&aFileSize, (aBuffer + aCurrentPos), ((sizeof(long) > 8) ? 8 : sizeof(long)));
338       aCurrentPos += 8;    
339       
340       string aFullPath = aTmpDir + aFileName;
341 #ifdef WIN32
342       ofstream aFile(aFullPath.c_str(), ios::binary);
343 #else
344       ofstream aFile(aFullPath.c_str());
345 #endif
346       aFile.write((char *)(aBuffer+aCurrentPos), aFileSize); 
347       aFile.close();  
348       aCurrentPos += aFileSize;
349     }
350     aFiles[i] = CORBA::string_dup(aFileName);
351     delete[] aFileName;
352   }
353
354   return aFiles;
355 }
356
357 //============================================================================
358 // function : GetNameFromPath
359 // purpose  : Returns the name by the path
360 //============================================================================
361 std::string SALOMEDS_Tool::GetNameFromPath(const std::string& thePath) {
362   if (thePath.empty()) return "";
363   string aPath = thePath;
364   bool isFound = false;
365   int pos = aPath.rfind('/');
366   if(pos > 0) {
367     aPath = aPath.substr(pos+1, aPath.size());
368     isFound = true;
369   }    
370   if(!isFound) {
371     pos = aPath.rfind('\\'); 
372     if(pos > 0) {
373       aPath = aPath.substr(pos+1, aPath.size()); 
374       isFound = true;
375     }  
376   }  
377   if(!isFound) {  
378     pos = aPath.rfind('|');
379     if(pos > 0) aPath =  aPath.substr(pos+1, aPath.size()); 
380   }
381
382   pos = aPath.rfind('.'); 
383   if(pos > 0)  aPath = aPath.substr(0, pos); //Remove extension
384     
385   return aPath;
386 }
387
388 //============================================================================
389 // function : GetDirFromPath
390 // purpose  : Returns the dir by the path
391 //============================================================================
392 std::string SALOMEDS_Tool::GetDirFromPath(const std::string& thePath) {
393   if (thePath.empty()) return "";
394
395   int pos = thePath.rfind('/');
396   string path;
397   if(pos > 0) {
398     path = thePath.substr(0, pos+1);
399   }
400   if(path.empty()) {
401     pos = thePath.rfind('\\');
402     if(pos > 0) path = thePath.substr(0, pos+1); 
403   }
404   if(path.empty()) {
405     pos = thePath.rfind('|');
406     if(pos > 0) path = thePath.substr(0, pos+1); 
407   }
408   if(path.empty()) {
409     path = thePath+"/";
410   }
411   
412 #ifdef WIN32  //Check if the only disk letter is given as path
413   if(path.size() == 2 && path[1] == ':') path +='\\';
414 #endif
415
416   for(int i = 0, len = path.size(); i<len; i++) 
417     if(path[i] == '|') path[i] = '/';
418   return path;
419 }
420
421 //=======================================================================
422 // name    : GetFlag
423 // Purpose : Retrieve specified flaf from "AttributeFlags" attribute
424 //=======================================================================
425 bool SALOMEDS_Tool::GetFlag( const int             theFlag,
426                              SALOMEDS::Study_var   theStudy,
427                              SALOMEDS::SObject_var theObj )
428 {
429   SALOMEDS::GenericAttribute_var anAttr;
430   if ( !theObj->_is_nil() && theObj->FindAttribute( anAttr, "AttributeFlags" ) )
431   {
432     SALOMEDS::AttributeFlags_var aFlags = SALOMEDS::AttributeFlags::_narrow( anAttr );
433     return aFlags->Get( theFlag );
434   }
435
436   return false;
437 }
438
439 //=======================================================================
440 // name    : SetFlag
441 // Purpose : Set/Unset specified flaf from "AttributeFlags" attribute
442 //=======================================================================
443 bool SALOMEDS_Tool::SetFlag( const int           theFlag,
444                              SALOMEDS::Study_var theStudy,
445                              const std::string&  theEntry,
446                              const bool          theValue )
447 {
448   SALOMEDS::SObject_var anObj = theStudy->FindObjectID(theEntry.c_str());
449
450   if ( !anObj->_is_nil() )
451   {
452     SALOMEDS::GenericAttribute_var aGAttr;
453     if ( anObj->FindAttribute( aGAttr, "AttributeFlags" ) )
454     {
455       SALOMEDS::AttributeFlags_var anAttr = SALOMEDS::AttributeFlags::_narrow( aGAttr );
456       anAttr->Set( theFlag, theValue );
457     }
458     else if ( theValue )
459     {
460       SALOMEDS::StudyBuilder_var aBuilder = theStudy->NewBuilder();
461       SALOMEDS::AttributeFlags_var anAttr = SALOMEDS::AttributeFlags::_narrow(
462         aBuilder->FindOrCreateAttribute( anObj, "AttributeFlags" ) );
463       anAttr->Set( theFlag, theValue );
464     }
465     return true;
466   }
467
468   return false;
469 }
470
471 //=======================================================================
472 // name    : getAllChildren
473 // Purpose : Get all children of object.
474 //           If theObj is null all objects of study are returned
475 //=======================================================================
476 void SALOMEDS_Tool::GetAllChildren( SALOMEDS::Study_var               theStudy,
477                                     SALOMEDS::SObject_var             theObj,
478                                     std::list<SALOMEDS::SObject_var>& theList )
479 {
480   if ( theObj->_is_nil() )
481   {
482     SALOMEDS::SComponentIterator_var anIter = theStudy->NewComponentIterator();
483     for ( ; anIter->More(); anIter->Next() )
484     {
485       SALOMEDS::SObject_var anObj = SALOMEDS::SObject::_narrow( anIter->Value() );
486       if ( !anObj->_is_nil() )
487       {
488         theList.push_back( anObj );
489         GetAllChildren( theStudy, anObj, theList );
490       }
491     }
492   }
493   else
494   {
495     SALOMEDS::ChildIterator_var anIter = theStudy->NewChildIterator( theObj );
496     for ( ; anIter->More(); anIter->Next() )
497     {
498       SALOMEDS::SObject_var anObj = anIter->Value();
499       SALOMEDS::SObject_var aRef;
500       if ( !anObj->ReferencedObject( aRef ) )
501       {
502         theList.push_back( anObj );
503         GetAllChildren( theStudy, anObj, theList );
504       }
505     }
506   }
507 }
508
509
510