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