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