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