Salome HOME
PR: mergefrom_BR_CCRT_11Nov04
[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 using namespace std;
29
30 //============================================================================
31 // function : GetTempDir
32 // purpose  : Return a temp directory to store created files like "/tmp/sub_dir/" 
33 //============================================================================ 
34 std::string SALOMEDS_Tool::GetTmpDir()
35 {
36   //Find a temporary directory to store a file
37
38   TCollection_AsciiString aTmpDir;
39
40   char *Tmp_dir = getenv("SALOME_TMP_DIR");
41   if(Tmp_dir != NULL) {
42     aTmpDir = TCollection_AsciiString(Tmp_dir);
43 #ifdef WIN32
44     if(aTmpDir.Value(aTmpDir.Length()) != '\\') aTmpDir+='\\';
45 #else
46     if(aTmpDir.Value(aTmpDir.Length()) != '/') aTmpDir+='/';
47 #endif      
48   }
49   else {
50 #ifdef WIN32
51     aTmpDir = TCollection_AsciiString("C:\\");
52 #else
53     aTmpDir = TCollection_AsciiString("/tmp/");
54 #endif
55   }
56
57   srand((unsigned int)time(NULL));
58   int aRND = 999 + (int)(100000.0*rand()/(RAND_MAX+1.0)); //Get a random number to present a name of a sub directory
59   TCollection_AsciiString aSubDir(aRND);
60   if(aSubDir.Length() <= 1) aSubDir = TCollection_AsciiString("123409876");
61
62   MESSAGE("#### RND "  << aRND);
63
64   aTmpDir += aSubDir; //Get RND sub directory
65
66 #ifdef WIN32
67   if(aTmpDir.Value(aTmpDir.Length()) != '\\') aTmpDir+='\\';
68 #else
69   if(aTmpDir.Value(aTmpDir.Length()) != '/') aTmpDir+='/';
70 #endif
71
72   OSD_Path aPath(aTmpDir);
73   OSD_Directory aDir(aPath);
74
75   for(aRND = 0; aDir.Exists(); aRND++) {
76     aTmpDir.Insert((aTmpDir.Length() - 1), TCollection_AsciiString(aRND));  //Build a unique directory name
77     aPath = OSD_Path(aTmpDir);
78     aDir = OSD_Directory(aPath);
79   }
80
81   MESSAGE("#### TMP" << aTmpDir.ToCString());
82
83   OSD_Protection aProtection(OSD_RW, OSD_RWX, OSD_RX, OSD_RX);
84   aDir.Build(aProtection);
85
86   return aTmpDir.ToCString();
87 }
88
89 //============================================================================
90 // function : RemoveTemporaryFiles
91 // purpose  : Removes files listed in theFileList
92 //============================================================================
93 void SALOMEDS_Tool::RemoveTemporaryFiles(const char* theDirectory, 
94                                          const SALOMEDS::ListOfFileNames& theFiles,
95                                          const bool IsDirDeleted)
96 {
97   TCollection_AsciiString aDirName(const_cast<char*>(theDirectory));
98
99   int i, aLength = theFiles.length();
100   for(i=0; i<aLength; i++) {
101     TCollection_AsciiString aFile(aDirName);
102 //     aFile += (char*)theFiles[i];
103     aFile += (char*)theFiles[i].in();
104     OSD_Path anOSDPath(aFile);
105     OSD_File anOSDFile(anOSDPath);
106     if(!anOSDFile.Exists()) continue;
107
108     OSD_Protection aProtection = anOSDFile.Protection();
109     aProtection.SetUser(OSD_RW);
110     anOSDFile.SetProtection(aProtection);
111
112     anOSDFile.Remove();
113   }
114
115   if(IsDirDeleted) {
116     OSD_Path aPath(aDirName);
117     OSD_Directory aDir(aPath);
118     OSD_FileIterator anIterator(aPath, '*');
119
120     if(aDir.Exists() && !anIterator.More()) aDir.Remove();
121   }
122
123 }
124
125 //============================================================================
126 // function : PutFilesToStream
127 // purpose  : converts the files from a list 'theFiles' to the stream
128 //============================================================================
129 SALOMEDS::TMPFile* 
130 SALOMEDS_Tool::PutFilesToStream(const char* theFromDirectory,
131                                 const SALOMEDS::ListOfFileNames& theFiles,
132                                 const int theNamesOnly)
133 {
134   int i, aLength = theFiles.length();
135   if(aLength == 0)
136 //    return NULL;
137     return (new SALOMEDS::TMPFile);
138
139   TCollection_AsciiString aTmpDir(const_cast<char*>(theFromDirectory)); //Get a temporary directory for saved a file
140
141   long aBufferSize = 0;
142   long aCurrentPos;
143
144   int aNbFiles = 0;
145   int* aFileNameSize= new int[aLength];
146   long* aFileSize= new long[aLength];
147
148   //Determine the required size of the buffer
149
150   for(i=0; i<aLength; i++) {
151
152     //Check if the file exists
153     
154     if (!theNamesOnly) { // mpv 15.01.2003: if only file names must be stroed, then size of files is zero
155       TCollection_AsciiString aFullPath = aTmpDir + CORBA::string_dup(theFiles[i]);   
156       OSD_Path anOSDPath(aFullPath);
157       OSD_File anOSDFile(anOSDPath);
158       if(!anOSDFile.Exists()) continue;
159 #ifdef WNT
160       ifstream aFile(aFullPath.ToCString(), ios::binary);
161 #else
162       ifstream aFile(aFullPath.ToCString());
163 #endif
164       aFile.seekg(0, ios::end);
165       aFileSize[i] = aFile.tellg();
166       aBufferSize += aFileSize[i];              //Add a space to store the file
167     }
168     aFileNameSize[i] = strlen(theFiles[i])+1;
169     aBufferSize += aFileNameSize[i];          //Add a space to store the file name
170     aBufferSize += (theNamesOnly)?4:12;       //Add 4 bytes: a length of the file name,
171                                               //    8 bytes: length of the file itself
172     aNbFiles++;
173   } 
174
175   aBufferSize += 4;      //4 bytes for a number of the files that will be written to the stream;
176   unsigned char* aBuffer = new unsigned char[aBufferSize];  
177   if(aBuffer == NULL)
178 //    return NULL; 
179     return (new SALOMEDS::TMPFile);
180
181   //Initialize 4 bytes of the buffer by 0
182   memset(aBuffer, 0, 4); 
183   //Copy the number of files that will be written to the stream
184   memcpy(aBuffer, &aNbFiles, ((sizeof(int) > 4) ? 4 : sizeof(int))); 
185
186
187   aCurrentPos = 4;
188
189   for(i=0; i<aLength; i++) {
190     ifstream *aFile;
191     if (!theNamesOnly) { // mpv 15.01.2003: we don't open any file if theNamesOnly = true
192       TCollection_AsciiString aFullPath = aTmpDir + CORBA::string_dup(theFiles[i]);
193       OSD_Path anOSDPath(aFullPath);
194       OSD_File anOSDFile(anOSDPath);
195       if(!anOSDFile.Exists()) continue;
196 #ifdef WNT
197       aFile = new ifstream(aFullPath.ToCString(), ios::binary);
198 #else
199       aFile = new ifstream(aFullPath.ToCString());
200 #endif  
201     }
202     //Initialize 4 bytes of the buffer by 0
203     memset((aBuffer + aCurrentPos), 0, 4); 
204     //Copy the length of the file name to the buffer
205     memcpy((aBuffer + aCurrentPos), (aFileNameSize + i), ((sizeof(int) > 4) ? 4 : sizeof(int))); 
206     aCurrentPos += 4;
207
208     //Copy the file name to the buffer
209     memcpy((aBuffer + aCurrentPos), theFiles[i], aFileNameSize[i]);
210     aCurrentPos += aFileNameSize[i];
211     
212     if (!theNamesOnly) { // mpv 15.01.2003: we don't copy file content to the buffer if !theNamesOnly
213       //Initialize 8 bytes of the buffer by 0
214       memset((aBuffer + aCurrentPos), 0, 8); 
215       //Copy the length of the file to the buffer
216       memcpy((aBuffer + aCurrentPos), (aFileSize + i), ((sizeof(long) > 8) ? 8 : sizeof(long)));
217       aCurrentPos += 8;
218       
219       aFile->seekg(0, ios::beg);
220       aFile->read((char *)(aBuffer + aCurrentPos), aFileSize[i]);
221       aFile->close();
222       delete(aFile);
223       aCurrentPos += aFileSize[i];
224     }
225   }
226
227   delete[] aFileNameSize;
228   delete[] aFileSize;
229   
230   
231   CORBA::Octet* anOctetBuf =  (CORBA::Octet*)aBuffer;
232   
233   return (new SALOMEDS::TMPFile(aBufferSize, aBufferSize, anOctetBuf, 1));
234 }
235
236 //============================================================================
237 // function : PutStreamToFile
238 // purpose  : converts the stream "theStream" to the files
239 //============================================================================
240 SALOMEDS::ListOfFileNames_var 
241 SALOMEDS_Tool::PutStreamToFiles(const SALOMEDS::TMPFile& theStream,
242                                 const char* theToDirectory,
243                                 const int theNamesOnly)
244 {
245   if(theStream.length() == 0) return NULL;
246   TCollection_AsciiString aTmpDir(const_cast<char*>(theToDirectory)); //Get a temporary directory for saving a file
247
248   unsigned char *aBuffer = (unsigned char*)theStream.NP_data();
249
250   if(aBuffer == NULL) return NULL;
251
252   long aBufferSize = theStream.length();
253   long aFileSize, aCurrentPos = 4;
254   int i, aFileNameSize, aNbFiles = 0;
255
256   //Copy the number of files in the stream
257   memcpy(&aNbFiles, aBuffer, sizeof(int)); 
258
259   SALOMEDS::ListOfFileNames_var aFiles = new SALOMEDS::ListOfFileNames;
260   aFiles->length(aNbFiles);
261
262   for(i=0; i<aNbFiles; i++) {
263
264     //Put a length of the file name to aFileNameSize
265     memcpy(&aFileNameSize, (aBuffer + aCurrentPos), ((sizeof(int) > 4) ? 4 : sizeof(int))); 
266     aCurrentPos += 4;
267
268     char *aFileName = new char[aFileNameSize];
269     //Put a file name to aFileName
270     memcpy(aFileName, (aBuffer + aCurrentPos), aFileNameSize); 
271     aCurrentPos += aFileNameSize;
272  
273     //Put a length of the file to aFileSize
274     if (!theNamesOnly) {
275       memcpy(&aFileSize, (aBuffer + aCurrentPos), ((sizeof(long) > 8) ? 8 : sizeof(long)));
276       aCurrentPos += 8;    
277       
278       TCollection_AsciiString aFullPath = aTmpDir + aFileName;
279       ofstream aFile(aFullPath.ToCString());
280       aFile.write((char *)(aBuffer+aCurrentPos), aFileSize); 
281       aFile.close();  
282       aCurrentPos += aFileSize;
283     }
284     aFiles[i] = CORBA::string_dup(aFileName);
285     delete[] aFileName;
286   }
287
288   return aFiles;
289 }
290
291 //============================================================================
292 // function : GetNameFromPath
293 // purpose  : Returns the name by the path
294 //============================================================================
295 std::string SALOMEDS_Tool::GetNameFromPath(const char* thePath) {
296   if (thePath == NULL) return string("");
297   OSD_Path aPath = OSD_Path(TCollection_AsciiString((char*)thePath));
298   TCollection_AsciiString aNameString(aPath.Name());
299   return aNameString.ToCString();
300 }
301
302 //============================================================================
303 // function : GetDirFromPath
304 // purpose  : Returns the dir by the path
305 //============================================================================
306 std::string SALOMEDS_Tool::GetDirFromPath(const char* thePath) {
307   if (thePath == NULL) return string("");
308   OSD_Path aPath = OSD_Path(TCollection_AsciiString((char*)thePath));
309   TCollection_AsciiString aDirString(aPath.Trek());
310   aDirString.ChangeAll('|','/');
311   return aDirString.ToCString();
312 }