1 #include "LightApp_Driver.h"
\r
3 #include <TCollection_AsciiString.hxx>
\r
5 #include <OSD_Path.hxx>
\r
6 #include <OSD_File.hxx>
\r
7 #include <OSD_Directory.hxx>
\r
8 #include <OSD_Process.hxx>
\r
9 #include <OSD_Directory.hxx>
\r
10 #include <OSD_Protection.hxx>
\r
11 #include <OSD_SingleProtection.hxx>
\r
12 #include <OSD_FileIterator.hxx>
\r
19 LightApp_Driver::LightApp_Driver()
\r
24 LightApp_Driver::~LightApp_Driver()
\r
28 using namespace std;
\r
30 //================================================================
\r
31 // Function : SaveDatasInFile
\r
32 /*! Purpose : save in file 'theFileName' datas from this driver*/
\r
33 //================================================================
\r
34 bool LightApp_Driver::SaveDatasInFile( const char* theFileName, bool isMultiFile )
\r
37 std::map<std::string, ListOfFiles>::const_iterator it;
\r
38 for (it = myMap.begin(); it != myMap.end(); ++it)
\r
41 unsigned char** aBuffer = new unsigned char*[aNbModules];
\r
42 long* aBufferSize = new long[aNbModules];
\r
43 char** aModuleName = new char*[aNbModules];
\r
45 if(aBuffer == NULL || aBufferSize == NULL || aModuleName == NULL)
\r
48 int aFileBufferSize = 4; //4 bytes for a number of the modules that will be written to the stream;
\r
50 for (it = myMap.begin(); it != myMap.end(); ++it) {
\r
51 aModuleName[i] = const_cast<char*>(it->first.c_str());//(it->first);
\r
52 aFileBufferSize += 4; //Add 4 bytes: a length of the module name
\r
53 aFileBufferSize += strlen(aModuleName[i])+1;
\r
54 std::string aName(aModuleName[i]);
\r
55 PutFilesToStream(aName, aBuffer[i], aBufferSize[i], isMultiFile);
\r
56 aFileBufferSize += 8; //Add 8 bytes: a length of the buffer
\r
57 aFileBufferSize += aBufferSize[i];
\r
58 // Remove the files and tmp directory, created by the component storage procedure
\r
60 RemoveTemporaryFiles(aModuleName[i], true);
\r
65 unsigned char* aFileBuffer = new unsigned char[aFileBufferSize];
\r
66 if(aFileBuffer == NULL)
\r
69 int aCurrentPos = 0;
\r
71 //Initialize 4 bytes of the buffer by 0
\r
72 memset(aFileBuffer, 0, 4);
\r
73 //Copy the number of modules that will be written to the stream
\r
74 memcpy(aFileBuffer, &aNbModules, ((sizeof(int) > 4) ? 4 : sizeof(int)));
\r
77 int aBufferNameSize = 0;
\r
78 for (i = 0; i < n; i++) {
\r
79 aBufferNameSize = strlen(aModuleName[i])+1;
\r
80 //Initialize 4 bytes of the buffer by 0
\r
81 memset((aFileBuffer + aCurrentPos), 0, 4);
\r
82 //Copy the length of the module name to the buffer
\r
83 memcpy((aFileBuffer + aCurrentPos), &aBufferNameSize, ((sizeof(int) > 4) ? 4 : sizeof(int)));
\r
85 //Copy the module name to the buffer
\r
86 memcpy((aFileBuffer + aCurrentPos), aModuleName[i], aBufferNameSize);
\r
87 aCurrentPos += aBufferNameSize;
\r
89 //Initialize 8 bytes of the buffer by 0
\r
90 memset((aFileBuffer + aCurrentPos), 0, 8);
\r
91 //Copy the length of the module buffer to the buffer
\r
92 memcpy((aFileBuffer + aCurrentPos), (aBufferSize + i), ((sizeof(long) > 8) ? 8 : sizeof(long)));
\r
94 //Copy the module buffer to the buffer
\r
95 memcpy((aFileBuffer + aCurrentPos), aBuffer[i], aBufferSize[i]);
\r
96 aCurrentPos += aBufferSize[i];
\r
99 ofstream aFile(theFileName);
\r
100 aFile.write((char*)aFileBuffer, aFileBufferSize);
\r
104 delete[] aBufferSize;
\r
105 delete[] aModuleName;
\r
106 delete[] aFileBuffer;
\r
110 //=======================================================================
\r
111 // name : ReaDatasFromFile
\r
112 /*! Purpose : filling current driver from file 'theFileName'*/
\r
113 //=======================================================================
\r
114 bool LightApp_Driver::ReadDatasFromFile( const char* theFileName, bool isMultiFile )
\r
117 ifstream aFile(theFileName, ios::binary);
\r
119 ifstream aFile(theFileName);
\r
122 aFile.seekg(0, ios::end);
\r
123 int aFileBufferSize = aFile.tellg();
\r
124 unsigned char* aFileBuffer = new unsigned char[aFileBufferSize];
\r
125 aFile.seekg(0, ios::beg);
\r
126 aFile.read((char*)aFileBuffer, aFileBufferSize);
\r
129 int aNbModules = 0;
\r
130 //Copy the number of files in the stream
\r
131 memcpy(&aNbModules, aFileBuffer, sizeof(int));
\r
132 long aCurrentPos = 4;
\r
133 int aModuleNameSize;
\r
135 for (int i = 0; i < aNbModules; i++) {
\r
136 //Put a length of the module name to aModuleNameSize
\r
137 memcpy(&aModuleNameSize, (aFileBuffer + aCurrentPos), ((sizeof(int) > 4) ? 4 : sizeof(int)));
\r
140 char *aModuleName = new char[aModuleNameSize];
\r
141 //Put a module name to aModuleName
\r
142 memcpy(aModuleName, (aFileBuffer + aCurrentPos), aModuleNameSize);
\r
143 aCurrentPos += aModuleNameSize;
\r
145 //Put a length of the file buffer to aBufferSize
\r
147 memcpy(&aBufferSize, (aFileBuffer + aCurrentPos), ((sizeof(long) > 8) ? 8 : sizeof(long)));
\r
149 unsigned char *aBuffer = new unsigned char[aBufferSize];
\r
151 //Put a buffer for current module to aBuffer
\r
152 memcpy(aBuffer, (aFileBuffer + aCurrentPos), aBufferSize);
\r
153 aCurrentPos += aBufferSize;
\r
155 // Put buffer to aListOfFiles and set to myMap
\r
156 ListOfFiles aListOfFiles = PutStreamToFiles(aBuffer, aBufferSize, isMultiFile);
\r
157 SetListOfFiles(aModuleName, aListOfFiles);
\r
159 delete[] aModuleName;
\r
162 delete[] aFileBuffer;
\r
166 //================================================================
\r
167 // Function : GetTmpDir
\r
168 /*! Purpose : returns temp directory for path 'theURL'*/
\r
169 //================================================================
\r
170 std::string LightApp_Driver::GetTmpDir (const char* theURL, const bool isMultiFile)
\r
172 std::string anURLDir = GetDirFromPath(theURL);
\r
173 std::string aTmpDir = isMultiFile ? anURLDir : GetTmpDir();
\r
178 //================================================================
\r
179 // Function : GetListOfFiles
\r
180 /*! Purpose : returns list of files for module with name 'theModuleName'*/
\r
181 //================================================================
\r
182 LightApp_Driver::ListOfFiles LightApp_Driver::GetListOfFiles( const char* theModuleName )
\r
184 ListOfFiles aListOfFiles;
\r
186 std::string aName(theModuleName);
\r
187 if (myMap.count(aName))
\r
188 aListOfFiles = myMap[aName];
\r
190 return aListOfFiles;
\r
193 //================================================================
\r
194 // Function : SetListOfFiles
\r
195 /*! Purpose : sets list of files for module with name 'theModuleName'*/
\r
196 //================================================================
\r
197 void LightApp_Driver::SetListOfFiles( const char* theModuleName, const ListOfFiles theListOfFiles )
\r
199 std::string aName (theModuleName);
\r
200 myMap[aName] = theListOfFiles;
\r
203 //============================================================================
\r
204 // function : PutFilesToStream
\r
205 /*! Purpose : converts files which was created from module <theModuleName> into a byte sequence unsigned char*/
\r
206 //============================================================================
\r
207 void LightApp_Driver::PutFilesToStream( const std::string& theModuleName, unsigned char*& theBuffer,
\r
208 long& theBufferSize, bool theNamesOnly )
\r
210 ListOfFiles aFiles = myMap[theModuleName];
\r
211 // aFiles must contain temporary directory name in its first item
\r
212 // and names of files (relatively the temporary directory) in the others
\r
214 int i, aLength = aFiles.size() - 1;
\r
217 theBuffer = new unsigned char[theBufferSize];
\r
220 //Get a temporary directory for saved a file
\r
221 TCollection_AsciiString aTmpDir(const_cast<char*>(aFiles[0].c_str()));
\r
223 long aBufferSize = 0;
\r
226 int* aFileNameSize= new int[aLength];
\r
227 long* aFileSize= new long[aLength];
\r
229 //Determine the required size of the buffer
\r
230 TCollection_AsciiString aFileName;
\r
231 for (i = 0; i < aLength; i++) {
\r
232 char* aFName = const_cast<char*>(aFiles[i+1].c_str());
\r
233 aFileName = aFName;
\r
234 //Check if the file exists
\r
235 if (!theNamesOnly) { // mpv 15.01.2003: if only file names must be stroed, then size of files is zero
\r
236 TCollection_AsciiString aFullPath = aTmpDir + aFileName;
\r
237 OSD_Path anOSDPath(aFullPath);
\r
238 OSD_File anOSDFile(anOSDPath);
\r
239 if(!anOSDFile.Exists()) continue;
\r
241 ifstream aFile(aFullPath.ToCString(), ios::binary);
\r
243 ifstream aFile(aFullPath.ToCString());
\r
245 aFile.seekg(0, ios::end);
\r
246 aFileSize[i] = aFile.tellg();
\r
247 aBufferSize += aFileSize[i]; //Add a space to store the file
\r
249 aFileNameSize[i] = strlen(aFName) + 1;
\r
250 aBufferSize += aFileNameSize[i]; //Add a space to store the file name
\r
251 aBufferSize += (theNamesOnly)?4:12; //Add 4 bytes: a length of the file name,
\r
252 // 8 bytes: length of the file itself
\r
257 aBufferSize += 4; //4 bytes for a number of the files that will be written to the stream;
\r
258 theBuffer = new unsigned char[aBufferSize];
\r
259 if(theBuffer == NULL) {
\r
264 //Initialize 4 bytes of the buffer by 0
\r
265 memset(theBuffer, 0, 4);
\r
266 //Copy the number of files that will be written to the stream
\r
267 memcpy(theBuffer, &aNbFiles, ((sizeof(int) > 4) ? 4 : sizeof(int)));
\r
271 for(i = 0; i < aLength; i++) {
\r
273 if (!theNamesOnly) { // mpv 15.01.2003: we don't open any file if theNamesOnly = true
\r
274 TCollection_AsciiString aName(const_cast<char*>(aFiles[i+1].c_str()));
\r
275 TCollection_AsciiString aFullPath = aTmpDir + aName;
\r
276 OSD_Path anOSDPath(aFullPath);
\r
277 OSD_File anOSDFile(anOSDPath);
\r
278 if(!anOSDFile.Exists()) continue;
\r
280 aFile = new ifstream(aFullPath.ToCString(), ios::binary);
\r
282 aFile = new ifstream(aFullPath.ToCString());
\r
285 //Initialize 4 bytes of the buffer by 0
\r
286 memset((theBuffer + aCurrentPos), 0, 4);
\r
287 //Copy the length of the file name to the buffer
\r
288 memcpy((theBuffer + aCurrentPos), (aFileNameSize + i), ((sizeof(int) > 4) ? 4 : sizeof(int)));
\r
291 //Copy the file name to the buffer
\r
292 char* aFName = const_cast<char*>(aFiles[i+1].c_str());
\r
293 memcpy((theBuffer + aCurrentPos), aFName, aFileNameSize[i]);
\r
294 aCurrentPos += aFileNameSize[i];
\r
296 if (!theNamesOnly) { // mpv 15.01.2003: we don't copy file content to the buffer if !theNamesOnly
\r
297 //Initialize 8 bytes of the buffer by 0
\r
298 memset((theBuffer + aCurrentPos), 0, 8);
\r
299 //Copy the length of the file to the buffer
\r
300 memcpy((theBuffer + aCurrentPos), (aFileSize + i), ((sizeof(long) > 8) ? 8 : sizeof(long)));
\r
303 aFile->seekg(0, ios::beg);
\r
304 aFile->read((char *)(theBuffer + aCurrentPos), aFileSize[i]);
\r
307 aCurrentPos += aFileSize[i];
\r
310 delete[] aFileNameSize;
\r
311 delete[] aFileSize;
\r
313 theBufferSize = aBufferSize;
\r
316 //============================================================================
\r
317 // function : PutStreamToFile
\r
318 /*! Purpose : converts a byte sequence <theBuffer> to files and return list of them*/
\r
319 //============================================================================
\r
320 LightApp_Driver::ListOfFiles LightApp_Driver::PutStreamToFiles( const unsigned char* theBuffer,
\r
321 const long theBufferSize, bool theNamesOnly )
\r
323 if(theBufferSize == 0 || theBuffer == 0)
\r
324 return ListOfFiles();
\r
326 // Create a temporary directory for the component's data files
\r
327 std::string aDir = GetTmpDir();
\r
329 //Get a temporary directory for saving a file
\r
330 TCollection_AsciiString aTmpDir(const_cast<char*>(aDir.c_str()));
\r
332 long aFileSize, aCurrentPos = 4;
\r
333 int i, aFileNameSize, aNbFiles = 0;
\r
335 //Copy the number of files in the stream
\r
336 memcpy(&aNbFiles, theBuffer, sizeof(int));
\r
338 const int n = aNbFiles + 1;
\r
339 ListOfFiles aFiles(n);
\r
342 for(i = 0; i < aNbFiles; i++) {
\r
343 //Put a length of the file name to aFileNameSize
\r
344 memcpy(&aFileNameSize, (theBuffer + aCurrentPos), ((sizeof(int) > 4) ? 4 : sizeof(int)));
\r
347 char *aFileName = new char[aFileNameSize];
\r
348 //Put a file name to aFileName
\r
349 memcpy(aFileName, (theBuffer + aCurrentPos), aFileNameSize);
\r
350 aCurrentPos += aFileNameSize;
\r
352 //Put a length of the file to aFileSize
\r
353 if (!theNamesOnly) {
\r
354 memcpy(&aFileSize, (theBuffer + aCurrentPos), ((sizeof(long) > 8) ? 8 : sizeof(long)));
\r
357 TCollection_AsciiString aFullPath = aTmpDir + aFileName;
\r
358 ofstream aFile(aFullPath.ToCString());
\r
359 aFile.write((char *)(theBuffer+aCurrentPos), aFileSize);
\r
361 aCurrentPos += aFileSize;
\r
363 std::string aStrFileName(aFileName);
\r
364 aFiles[i+1] = aStrFileName;
\r
365 delete[] aFileName;
\r
370 //============================================================================
\r
371 // function : RemoveTemporaryFiles
\r
372 /*! Purpose : removes files which was created from module theModuleName if <IsDirDeleted> is true tmp directory is also deleted if it is empty*/
\r
373 //============================================================================
\r
374 void LightApp_Driver::RemoveTemporaryFiles( const char* theModuleName, const bool IsDirDeleted )
\r
376 std::string aModuleName(theModuleName);
\r
377 ListOfFiles aFiles = myMap[aModuleName];
\r
378 // aFiles must contain temporary directory name in its first item
\r
379 // and names of files (relatively the temporary directory) in the others
\r
381 int i, aLength = aFiles.size() - 1;
\r
385 //Get a temporary directory for saved a file
\r
386 TCollection_AsciiString aDirName(const_cast<char*>(aFiles[0].c_str()));
\r
388 for(i = 0; i < aLength; i++) {
\r
389 TCollection_AsciiString aFile(aDirName);
\r
390 aFile += const_cast<char*>(aFiles[i+1].c_str());
\r
391 OSD_Path anOSDPath(aFile);
\r
392 OSD_File anOSDFile(anOSDPath);
\r
393 if(!anOSDFile.Exists()) continue;
\r
395 OSD_Protection aProtection = anOSDFile.Protection();
\r
396 aProtection.SetUser(OSD_RW);
\r
397 anOSDFile.SetProtection(aProtection);
\r
399 anOSDFile.Remove();
\r
403 OSD_Path aPath(aDirName);
\r
404 OSD_Directory aDir(aPath);
\r
405 OSD_FileIterator anIterator(aPath, '*');
\r
407 if(aDir.Exists() && !anIterator.More()) aDir.Remove();
\r
411 //============================================================================
\r
412 // function : ClearDriverContents
\r
413 /*! Purpose : clear map of list files*/
\r
414 //============================================================================
\r
415 void LightApp_Driver::ClearDriverContents()
\r
420 //============================================================================
\r
421 // function : GetTempDir
\r
422 /*! Purpose : return a temp directory to store created files like "/tmp/sub_dir/" */
\r
423 //============================================================================
\r
424 std::string LightApp_Driver::GetTmpDir()
\r
426 //Find a temporary directory to store a file
\r
427 TCollection_AsciiString aTmpDir;
\r
429 char *Tmp_dir = getenv("SALOME_TMP_DIR");
\r
430 if(Tmp_dir != NULL) {
\r
431 aTmpDir = TCollection_AsciiString(Tmp_dir);
\r
433 if(aTmpDir.Value(aTmpDir.Length()) != '\\') aTmpDir+='\\';
\r
435 if(aTmpDir.Value(aTmpDir.Length()) != '/') aTmpDir+='/';
\r
440 aTmpDir = TCollection_AsciiString("C:\\");
\r
442 aTmpDir = TCollection_AsciiString("/tmp/");
\r
446 srand((unsigned int)time(NULL));
\r
447 int aRND = 999 + (int)(100000.0*rand()/(RAND_MAX+1.0)); //Get a random number to present a name of a sub directory
\r
448 TCollection_AsciiString aSubDir(aRND);
\r
449 if(aSubDir.Length() <= 1) aSubDir = TCollection_AsciiString("123409876");
\r
451 aTmpDir += aSubDir; //Get RND sub directory
\r
454 if(aTmpDir.Value(aTmpDir.Length()) != '\\') aTmpDir+='\\';
\r
456 if(aTmpDir.Value(aTmpDir.Length()) != '/') aTmpDir+='/';
\r
459 OSD_Path aPath(aTmpDir);
\r
460 OSD_Directory aDir(aPath);
\r
462 for(aRND = 0; aDir.Exists(); aRND++) {
\r
463 aTmpDir.Insert((aTmpDir.Length() - 1), TCollection_AsciiString(aRND)); //Build a unique directory name
\r
464 aPath = OSD_Path(aTmpDir);
\r
465 aDir = OSD_Directory(aPath);
\r
468 OSD_Protection aProtection(OSD_RW, OSD_RWX, OSD_RX, OSD_RX);
\r
469 aDir.Build(aProtection);
\r
471 return aTmpDir.ToCString();
\r
474 //============================================================================
\r
475 // function : GetDirFromPath
\r
476 /*! Purpose : returns the dir by the path*/
\r
477 //============================================================================
\r
478 std::string LightApp_Driver::GetDirFromPath( const std::string& thePath ) {
\r
481 OSD_Path aPath = OSD_Path(TCollection_AsciiString(const_cast<char*>(thePath.c_str())));
\r
482 TCollection_AsciiString aDirString(aPath.Trek());
\r
483 aDirString.ChangeAll('|','/');
\r
484 return aDirString.ToCString();
\r