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