1 #include "LightApp_Driver.h"
3 #include <TCollection_AsciiString.hxx>
5 #include <OSD_Path.hxx>
6 #include <OSD_File.hxx>
7 #include <OSD_Directory.hxx>
8 #include <OSD_Process.hxx>
9 #include <OSD_Directory.hxx>
10 #include <OSD_Protection.hxx>
11 #include <OSD_SingleProtection.hxx>
12 #include <OSD_FileIterator.hxx>
14 #include <qfileinfo.h>
22 LightApp_Driver::LightApp_Driver()
27 LightApp_Driver::~LightApp_Driver()
33 //================================================================
34 // Function : SaveDatasInFile
35 /*! Purpose : save in file 'theFileName' datas from this driver*/
36 //================================================================
37 bool LightApp_Driver::SaveDatasInFile( const char* theFileName, bool isMultiFile )
40 std::map<std::string, ListOfFiles>::const_iterator it;
41 for (it = myMap.begin(); it != myMap.end(); ++it)
44 unsigned char** aBuffer = new unsigned char*[aNbModules];
45 long* aBufferSize = new long[aNbModules];
46 char** aModuleName = new char*[aNbModules];
48 if(aBuffer == NULL || aBufferSize == NULL || aModuleName == NULL)
51 int aFileBufferSize = 4; //4 bytes for a number of the modules that will be written to the stream;
53 for (it = myMap.begin(); it != myMap.end(); ++it) {
54 aModuleName[i] = const_cast<char*>(it->first.c_str());//(it->first);
55 aFileBufferSize += 4; //Add 4 bytes: a length of the module name
56 aFileBufferSize += strlen(aModuleName[i])+1;
57 std::string aName(aModuleName[i]);
58 PutFilesToStream(aName, aBuffer[i], aBufferSize[i], isMultiFile);
59 aFileBufferSize += 8; //Add 8 bytes: a length of the buffer
60 aFileBufferSize += aBufferSize[i];
65 unsigned char* aFileBuffer = new unsigned char[aFileBufferSize];
66 if(aFileBuffer == NULL)
69 myTmpDir = QDir::convertSeparators( QFileInfo( theFileName ).dirPath( true ) + "/" ).latin1() ;
73 //Initialize 4 bytes of the buffer by 0
74 memset(aFileBuffer, 0, 4);
75 //Copy the number of modules that will be written to the stream
76 memcpy(aFileBuffer, &aNbModules, ((sizeof(int) > 4) ? 4 : sizeof(int)));
79 int aBufferNameSize = 0;
80 for (i = 0; i < n; i++) {
81 aBufferNameSize = strlen(aModuleName[i])+1;
82 //Initialize 4 bytes of the buffer by 0
83 memset((aFileBuffer + aCurrentPos), 0, 4);
84 //Copy the length of the module name to the buffer
85 memcpy((aFileBuffer + aCurrentPos), &aBufferNameSize, ((sizeof(int) > 4) ? 4 : sizeof(int)));
87 //Copy the module name to the buffer
88 memcpy((aFileBuffer + aCurrentPos), aModuleName[i], aBufferNameSize);
89 aCurrentPos += aBufferNameSize;
91 //Initialize 8 bytes of the buffer by 0
92 memset((aFileBuffer + aCurrentPos), 0, 8);
93 //Copy the length of the module buffer to the buffer
94 memcpy((aFileBuffer + aCurrentPos), (aBufferSize + i), ((sizeof(long) > 8) ? 8 : sizeof(long)));
96 //Copy the module buffer to the buffer
97 memcpy((aFileBuffer + aCurrentPos), aBuffer[i], aBufferSize[i]);
98 aCurrentPos += aBufferSize[i];
102 ofstream aFile(theFileName, ios::out | ios::binary);
104 ofstream aFile(theFileName);
106 aFile.write((char*)aFileBuffer, aFileBufferSize);
110 delete[] aBufferSize;
111 delete[] aModuleName;
112 delete[] aFileBuffer;
117 //=======================================================================
118 // name : ReaDatasFromFile
119 /*! Purpose : filling current driver from file 'theFileName'*/
120 //=======================================================================
121 bool LightApp_Driver::ReadDatasFromFile( const char* theFileName, bool isMultiFile )
124 ifstream aFile(theFileName, ios::binary);
126 ifstream aFile(theFileName);
129 myTmpDir = QDir::convertSeparators( QFileInfo( theFileName ).dirPath( true ) + "/" ).latin1() ;
131 aFile.seekg(0, ios::end);
132 int aFileBufferSize = aFile.tellg();
133 unsigned char* aFileBuffer = new unsigned char[aFileBufferSize];
134 aFile.seekg(0, ios::beg);
135 aFile.read((char*)aFileBuffer, aFileBufferSize);
139 //Copy the number of files in the stream
140 memcpy(&aNbModules, aFileBuffer, sizeof(int));
141 long aCurrentPos = 4;
144 for (int i = 0; i < aNbModules; i++) {
145 //Put a length of the module name to aModuleNameSize
146 memcpy(&aModuleNameSize, (aFileBuffer + aCurrentPos), ((sizeof(int) > 4) ? 4 : sizeof(int)));
149 char *aModuleName = new char[aModuleNameSize];
150 //Put a module name to aModuleName
151 memcpy(aModuleName, (aFileBuffer + aCurrentPos), aModuleNameSize);
152 aCurrentPos += aModuleNameSize;
154 //Put a length of the file buffer to aBufferSize
156 memcpy(&aBufferSize, (aFileBuffer + aCurrentPos), ((sizeof(long) > 8) ? 8 : sizeof(long)));
158 unsigned char *aBuffer = new unsigned char[aBufferSize];
160 //Put a buffer for current module to aBuffer
161 memcpy(aBuffer, (aFileBuffer + aCurrentPos), aBufferSize);
162 aCurrentPos += aBufferSize;
164 // Put buffer to aListOfFiles and set to myMap
165 ListOfFiles aListOfFiles = PutStreamToFiles(aBuffer, aBufferSize, isMultiFile);
166 SetListOfFiles(aModuleName, aListOfFiles);
168 delete[] aModuleName;
172 delete[] aFileBuffer;
177 //================================================================
178 // Function : GetTmpDir
179 /*! Purpose : returns temp directory for path 'theURL'*/
180 //================================================================
181 std::string LightApp_Driver::GetTmpDir (const char* theURL, const bool isMultiFile)
183 std::string anURLDir = GetDirFromPath(theURL);
184 std::string aTmpDir = isMultiFile ? anURLDir : GetTmpDir();
189 //================================================================
190 // Function : GetListOfFiles
191 /*! Purpose : returns list of files for module with name 'theModuleName'*/
192 //================================================================
193 LightApp_Driver::ListOfFiles LightApp_Driver::GetListOfFiles( const char* theModuleName )
195 ListOfFiles aListOfFiles;
197 std::string aName(theModuleName);
198 if (myMap.count(aName))
199 aListOfFiles = myMap[aName];
204 //================================================================
205 // Function : SetListOfFiles
206 /*! Purpose : sets list of files for module with name 'theModuleName'*/
207 //================================================================
208 void LightApp_Driver::SetListOfFiles( const char* theModuleName, const ListOfFiles theListOfFiles )
210 std::string aName (theModuleName);
211 myMap[aName] = theListOfFiles;
214 //============================================================================
215 // function : PutFilesToStream
216 /*! Purpose : converts files which was created from module <theModuleName> into a byte sequence unsigned char*/
217 //============================================================================
218 void LightApp_Driver::PutFilesToStream( const std::string& theModuleName, unsigned char*& theBuffer,
219 long& theBufferSize, bool theNamesOnly )
221 ListOfFiles aFiles = myMap[theModuleName];
222 // aFiles must contain temporary directory name in its first item
223 // and names of files (relatively the temporary directory) in the others
225 int i, aLength = aFiles.size() - 1;
228 theBuffer = new unsigned char[theBufferSize];
231 //Get a temporary directory for saved a file
232 TCollection_AsciiString aTmpDir(const_cast<char*>(aFiles[0].c_str()));
234 long aBufferSize = 0;
237 int* aFileNameSize= new int[aLength];
238 long* aFileSize= new long[aLength];
240 //Determine the required size of the buffer
241 TCollection_AsciiString aFileName;
242 for (i = 0; i < aLength; i++) {
243 char* aFName = const_cast<char*>(aFiles[i+1].c_str());
245 //Check if the file exists
246 if (!theNamesOnly) { // mpv 15.01.2003: if only file names must be stroed, then size of files is zero
247 TCollection_AsciiString aFullPath = aTmpDir + aFileName;
248 OSD_Path anOSDPath(aFullPath);
249 OSD_File anOSDFile(anOSDPath);
250 if(!anOSDFile.Exists()) continue;
252 ifstream aFile(aFullPath.ToCString(), ios::binary);
254 ifstream aFile(aFullPath.ToCString());
256 aFile.seekg(0, ios::end);
257 aFileSize[i] = aFile.tellg();
258 aBufferSize += aFileSize[i]; //Add a space to store the file
260 aFileNameSize[i] = strlen(aFName) + 1;
261 aBufferSize += aFileNameSize[i]; //Add a space to store the file name
262 aBufferSize += (theNamesOnly)?4:12; //Add 4 bytes: a length of the file name,
263 // 8 bytes: length of the file itself
267 aBufferSize += 4; //4 bytes for a number of the files that will be written to the stream;
268 theBuffer = new unsigned char[aBufferSize];
269 if(theBuffer == NULL) {
274 //Initialize 4 bytes of the buffer by 0
275 memset(theBuffer, 0, 4);
276 //Copy the number of files that will be written to the stream
277 memcpy(theBuffer, &aNbFiles, ((sizeof(int) > 4) ? 4 : sizeof(int)));
281 for(i = 0; i < aLength; i++) {
283 if (!theNamesOnly) { // mpv 15.01.2003: we don't open any file if theNamesOnly = true
284 TCollection_AsciiString aName(const_cast<char*>(aFiles[i+1].c_str()));
285 TCollection_AsciiString aFullPath = aTmpDir + aName;
286 OSD_Path anOSDPath(aFullPath);
287 OSD_File anOSDFile(anOSDPath);
288 if(!anOSDFile.Exists()) continue;
290 aFile = new ifstream(aFullPath.ToCString(), ios::binary);
292 aFile = new ifstream(aFullPath.ToCString());
295 //Initialize 4 bytes of the buffer by 0
296 memset((theBuffer + aCurrentPos), 0, 4);
297 //Copy the length of the file name to the buffer
298 memcpy((theBuffer + aCurrentPos), (aFileNameSize + i), ((sizeof(int) > 4) ? 4 : sizeof(int)));
301 //Copy the file name to the buffer
302 char* aFName = const_cast<char*>(aFiles[i+1].c_str());
303 memcpy((theBuffer + aCurrentPos), aFName, aFileNameSize[i]);
304 aCurrentPos += aFileNameSize[i];
306 if (!theNamesOnly) { // mpv 15.01.2003: we don't copy file content to the buffer if !theNamesOnly
307 //Initialize 8 bytes of the buffer by 0
308 memset((theBuffer + aCurrentPos), 0, 8);
309 //Copy the length of the file to the buffer
310 memcpy((theBuffer + aCurrentPos), (aFileSize + i), ((sizeof(long) > 8) ? 8 : sizeof(long)));
313 aFile->seekg(0, ios::beg);
314 aFile->read((char *)(theBuffer + aCurrentPos), aFileSize[i]);
317 aCurrentPos += aFileSize[i];
320 delete[] aFileNameSize;
323 theBufferSize = aBufferSize;
326 //============================================================================
327 // function : PutStreamToFile
328 /*! Purpose : converts a byte sequence <theBuffer> to files and return list of them*/
329 //============================================================================
330 LightApp_Driver::ListOfFiles LightApp_Driver::PutStreamToFiles( const unsigned char* theBuffer,
331 const long theBufferSize, bool theNamesOnly )
333 if(theBufferSize == 0 || theBuffer == 0)
334 return ListOfFiles();
336 // Create a temporary directory for the component's data files
337 std::string aDir = GetTmpDir();
339 //Get a temporary directory for saving a file
340 TCollection_AsciiString aTmpDir(const_cast<char*>(aDir.c_str()));
342 long aFileSize, aCurrentPos = 4;
343 int i, aFileNameSize, aNbFiles = 0;
345 //Copy the number of files in the stream
346 memcpy(&aNbFiles, theBuffer, sizeof(int));
348 const int n = aNbFiles + 1;
349 ListOfFiles aFiles(n);
352 for(i = 0; i < aNbFiles; i++) {
353 //Put a length of the file name to aFileNameSize
354 memcpy(&aFileNameSize, (theBuffer + aCurrentPos), ((sizeof(int) > 4) ? 4 : sizeof(int)));
357 char *aFileName = new char[aFileNameSize];
358 //Put a file name to aFileName
359 memcpy(aFileName, (theBuffer + aCurrentPos), aFileNameSize);
360 aCurrentPos += aFileNameSize;
362 //Put a length of the file to aFileSize
364 memcpy(&aFileSize, (theBuffer + aCurrentPos), ((sizeof(long) > 8) ? 8 : sizeof(long)));
367 TCollection_AsciiString aFullPath = aTmpDir + aFileName;
370 ofstream aFile(aFullPath.ToCString(), ios::out | ios::binary);
372 ofstream aFile(aFullPath.ToCString());
375 aFile.write((char *)(theBuffer+aCurrentPos), aFileSize);
377 aCurrentPos += aFileSize;
379 std::string aStrFileName(aFileName);
380 aFiles[i+1] = aStrFileName;
386 //============================================================================
387 // function : RemoveFiles
388 /*! Purpose : Remove files. First item in <theFiles> is a directory with slash at the end.
389 Other items are names of files. If <IsDirDeleted> is true,
390 then the directory is also deleted.
392 //============================================================================
393 void LightApp_Driver::RemoveFiles( const ListOfFiles& theFiles, const bool IsDirDeleted)
395 int i, aLength = theFiles.size() - 1;
399 //Get a temporary directory for saved a file
400 TCollection_AsciiString aDirName(const_cast<char*>(theFiles[0].c_str()));
402 for(i = 0; i < aLength; i++) {
403 TCollection_AsciiString aFile(aDirName);
404 aFile += const_cast<char*>(theFiles[i+1].c_str());
405 OSD_Path anOSDPath(aFile);
406 OSD_File anOSDFile(anOSDPath);
407 if(!anOSDFile.Exists()) continue;
413 OSD_Path aPath(aDirName);
414 OSD_Directory aDir(aPath);
415 OSD_FileIterator anIterator(aPath, '*');
417 if(aDir.Exists() && !anIterator.More()) aDir.Remove();
421 //============================================================================
422 // function : RemoveTemporaryFiles
423 /*! Purpose : removes files which was created from module theModuleName if
424 <IsDirDeleted> is true tmp directory is also deleted if it is empty*/
425 //============================================================================
426 void LightApp_Driver::RemoveTemporaryFiles( const char* theModuleName, const bool IsDirDeleted )
428 std::string aModuleName(theModuleName);
429 ListOfFiles aFiles = myMap[aModuleName];
430 // aFiles must contain temporary directory name in its first item
431 // and names of files (relatively the temporary directory) in the others
432 RemoveFiles( aFiles, IsDirDeleted );
436 //============================================================================
437 // function : ClearDriverContents
438 /*! Purpose : clear map of list files*/
439 //============================================================================
440 void LightApp_Driver::ClearDriverContents()
442 std::map<std::string, ListOfFiles>::iterator it;
443 for ( it = myMap.begin(); it != myMap.end(); ++it )
445 const char* aModuleName = const_cast<char*>(it->first.c_str());
446 RemoveTemporaryFiles( aModuleName, false );
451 //============================================================================
452 // function : GetTempDir
453 /*! Purpose : return a temp directory to store created files like "/tmp/sub_dir/" */
454 //============================================================================
455 std::string LightApp_Driver::GetTmpDir()
457 if ( myTmpDir.length() != 0 )
460 //Find a temporary directory to store a file
461 TCollection_AsciiString aTmpDir;
463 char *Tmp_dir = getenv("SALOME_TMP_DIR");
465 Tmp_dir = getenv ( "TEMP" );
467 Tmp_dir = getenv ( "TMP" );
470 aTmpDir = TCollection_AsciiString(Tmp_dir);
472 if(aTmpDir.Value(aTmpDir.Length()) != '\\') aTmpDir+='\\';
474 if(aTmpDir.Value(aTmpDir.Length()) != '/') aTmpDir+='/';
480 aTmpDir = TCollection_AsciiString("C:\\");
482 aTmpDir = TCollection_AsciiString("/tmp/");
486 srand((unsigned int)time(NULL));
487 int aRND = 999 + (int)(100000.0*rand()/(RAND_MAX+1.0)); //Get a random number to present a name of a sub directory
488 TCollection_AsciiString aSubDir(aRND);
489 if(aSubDir.Length() <= 1) aSubDir = TCollection_AsciiString("123409876");
491 aTmpDir += aSubDir; //Get RND sub directory
494 if(aTmpDir.Value(aTmpDir.Length()) != '\\') aTmpDir+='\\';
496 if(aTmpDir.Value(aTmpDir.Length()) != '/') aTmpDir+='/';
499 OSD_Path aPath(aTmpDir);
500 OSD_Directory aDir(aPath);
502 for(aRND = 0; aDir.Exists(); aRND++) {
503 aTmpDir.Insert((aTmpDir.Length() - 1), TCollection_AsciiString(aRND)); //Build a unique directory name
504 aPath = OSD_Path(aTmpDir);
505 aDir = OSD_Directory(aPath);
508 myTmpDir = aTmpDir.ToCString();
510 return aTmpDir.ToCString();
513 //============================================================================
514 // function : GetDirFromPath
515 /*! Purpose : returns the dir by the path*/
516 //============================================================================
517 std::string LightApp_Driver::GetDirFromPath( const std::string& thePath ) {
520 OSD_Path aPath = OSD_Path(TCollection_AsciiString(const_cast<char*>(thePath.c_str())));
521 TCollection_AsciiString aDirString(aPath.Trek());
522 aDirString.ChangeAll('|','/');
523 return aDirString.ToCString();