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