]> SALOME platform Git repositories - modules/kernel.git/blob - src/Container/Salome_file_i.cxx
Salome HOME
Merging from V4_1_0_maintainance for porting on Win32 Platform
[modules/kernel.git] / src / Container / Salome_file_i.cxx
1 // Copyright (C) 2007  OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
2 // 
3 //  This library is free software; you can redistribute it and/or 
4 //  modify it under the terms of the GNU Lesser General Public 
5 //  License as published by the Free Software Foundation; either 
6 //  version 2.1 of the License. 
7 // 
8 //  This library is distributed in the hope that it will be useful, 
9 //  but WITHOUT ANY WARRANTY; without even the implied warranty of 
10 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
11 //  Lesser General Public License for more details. 
12 // 
13 //  You should have received a copy of the GNU Lesser General Public 
14 //  License along with this library; if not, write to the Free Software 
15 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
16 // 
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19 //
20 //
21 //  File   : Salome_file_i.cxx
22 //  Author : André RIBES, EDF
23 //  Module : SALOME
24 //  $Header: 
25
26 #include "Salome_file_i.hxx"
27 #include "utilities.h"
28 #include <stdlib.h>
29 #include "HDFOI.hxx"
30 #ifndef WIN32
31 # include <unistd.h>
32 # define _getcwd getcwd
33 # define _open   open
34 #else
35 # include <direct.h>
36 # include <io.h>
37 # include <windows.h>
38 #endif
39
40
41 //=============================================================================
42 /*! 
43  *  Default constructor,
44  */
45 //=============================================================================
46
47 Salome_file_i::Salome_file_i()
48 {
49   _fileId = 0;
50 #ifndef WIN32
51   _path_max = 1 + pathconf("/", _PC_PATH_MAX);
52 #else
53   _path_max = 32768;
54   //from MSDN:
55   //Note The C Runtime supports path lengths up to 32768 characters in length, but it is up to the operating system, specifically the file system, to support these longer paths. The sum of the fields should not exceed _MAX_PATH for full backwards compatibility with Windows 98 FAT32 file systems. Windows NT 4.0, Windows 2000, Windows XP Home Edition, Windows XP Professional, Windows Server 2003, and Windows Server 2003 NTFS file system supports paths up to 32768 characters in length, but only when using the Unicode APIs. When using long path names, prefix the path with the characters \\?\ and use the Unicode versions of the C Runtime functions.
56   //currently #define _MAX_PATH   260
57 #endif
58   _state.name = CORBA::string_dup("");
59   _state.hdf5_file_name = CORBA::string_dup("");
60   _state.number_of_files = 0;
61   _state.files_ok = true;
62   _container = Engines::Container::_nil();
63   _default_source_Salome_file = Engines::Salome_file::_nil();
64 }
65
66 //=============================================================================
67 /*! 
68  *  Destructor
69  */
70 //=============================================================================
71
72 Salome_file_i::~Salome_file_i()
73 {
74 }
75
76 //=============================================================================
77 /*! 
78  *  CORBA method
79  * \see Engines::Salome_file::load
80  */
81 //=============================================================================
82 void 
83 Salome_file_i::load(const char* hdf5_file) {
84   _state.hdf5_file_name = CORBA::string_dup(hdf5_file);
85   try
86   {
87     HDFfile *hdf_file;
88     HDFgroup *hdf_group;
89     HDFdataset *hdf_dataset;
90     int size;
91     int fd;
92     char * value;
93     char * buffer;
94
95     hdf_file = new HDFfile((char*) hdf5_file);
96     hdf_file->OpenOnDisk(HDF_RDONLY);
97
98     hdf_group = new HDFgroup("CONFIG",hdf_file); 
99     hdf_group->OpenOnDisk();
100     hdf_dataset = new HDFdataset("MODE",hdf_group);
101     hdf_dataset->OpenOnDisk();
102     size = hdf_dataset->GetSize();
103     value = new char[size];
104     hdf_dataset->ReadFromDisk(value);
105     hdf_dataset->CloseOnDisk();
106     std::string mode(value);
107     delete value;
108     
109     hdf_group = new HDFgroup("GROUP_FILES",hdf_file); 
110     hdf_group->OpenOnDisk();
111     hdf_dataset = new HDFdataset("LIST_OF_FILES",hdf_group);
112     hdf_dataset->OpenOnDisk();
113     size = hdf_dataset->GetSize();
114     value = new char[size];
115     hdf_dataset->ReadFromDisk(value);
116     hdf_dataset->CloseOnDisk();
117     std::string list_of_files(value);
118     delete value;
119
120     std::istringstream iss(list_of_files);
121     std::string file_name;
122     while (std::getline(iss, file_name, ' '))
123     {
124       std::string dataset_group_name("DATASET");
125       dataset_group_name += file_name;
126
127       hdf_group = new HDFgroup(dataset_group_name.c_str(), hdf_file); 
128       hdf_group->OpenOnDisk();
129
130       hdf_dataset = new HDFdataset("NAME",hdf_group);
131       hdf_dataset->OpenOnDisk();
132       size = hdf_dataset->GetSize();
133       value = new char[size];
134       hdf_dataset->ReadFromDisk(value);
135       hdf_dataset->CloseOnDisk();
136       std::string name(value);
137
138       hdf_dataset = new HDFdataset("PATH",hdf_group);
139       hdf_dataset->OpenOnDisk();
140       size = hdf_dataset->GetSize();
141       value = new char[size];
142       hdf_dataset->ReadFromDisk(value);
143       hdf_dataset->CloseOnDisk();
144       std::string path(value);
145
146       hdf_dataset = new HDFdataset("TYPE",hdf_group);
147       hdf_dataset->OpenOnDisk();
148       size = hdf_dataset->GetSize();
149       value = new char[size];
150       hdf_dataset->ReadFromDisk(value);
151       hdf_dataset->CloseOnDisk();
152       std::string type(value);
153
154       hdf_dataset = new HDFdataset("SOURCE_FILE_NAME",hdf_group);
155       hdf_dataset->OpenOnDisk();
156       size = hdf_dataset->GetSize();
157       value = new char[size];
158       hdf_dataset->ReadFromDisk(value);
159       hdf_dataset->CloseOnDisk();
160       std::string source_file_name(value);
161
162       hdf_dataset = new HDFdataset("STATUS",hdf_group);
163       hdf_dataset->OpenOnDisk();
164       size = hdf_dataset->GetSize();
165       value = new char[size];
166       hdf_dataset->ReadFromDisk(value);
167       hdf_dataset->CloseOnDisk();
168       std::string status(value);
169
170       if (mode == "all") {
171
172         // Changing path, is now current directory
173         path = getcwd(NULL, _path_max);
174   
175         std::string group_name("GROUP");
176         group_name += file_name;
177         hdf_group = new HDFgroup(group_name.c_str(),hdf_file); 
178         hdf_group->OpenOnDisk();
179         hdf_dataset = new HDFdataset("FILE DATASET",hdf_group);
180         hdf_dataset->OpenOnDisk();
181         size = hdf_dataset->GetSize();
182         buffer = new char[size];
183       
184         if ( (fd = ::open(file_name.c_str(),O_RDWR|O_CREAT,00666)) <0) { 
185           SALOME::ExceptionStruct es;
186           es.type = SALOME::INTERNAL_ERROR;
187           std::string text = "open failed";
188           es.text = CORBA::string_dup(text.c_str());
189           throw SALOME::SALOME_Exception(es);
190         };
191         hdf_dataset->ReadFromDisk(buffer);
192         if ( write(fd,buffer,size) <0) { 
193           SALOME::ExceptionStruct es;
194           es.type = SALOME::INTERNAL_ERROR;
195           std::string text = "write failed";
196           es.text = CORBA::string_dup(text.c_str());
197           throw SALOME::SALOME_Exception(es);
198         };
199         // Close the target file
200         ::close(fd);
201
202         Engines::file infos;
203         infos.file_name = CORBA::string_dup(file_name.c_str());
204         infos.path = CORBA::string_dup(path.c_str());
205         infos.type = CORBA::string_dup(type.c_str());
206         infos.source_file_name = CORBA::string_dup(source_file_name.c_str());
207         infos.status = CORBA::string_dup(status.c_str());
208
209         _fileManaged[file_name] = infos;
210
211         // Update Salome_file state
212         _state.number_of_files++;
213         _state.files_ok = true;
214       }
215       else {
216         Engines::file infos;
217         infos.file_name = CORBA::string_dup(file_name.c_str());
218         infos.path = CORBA::string_dup(path.c_str());
219         infos.type = CORBA::string_dup(type.c_str());
220         infos.source_file_name = CORBA::string_dup(source_file_name.c_str());
221         infos.status = CORBA::string_dup(status.c_str());
222         // Infos for parallel extensions...
223         infos.node = 0;
224         infos.container = Engines::Container::_duplicate(_container);
225
226         _fileManaged[file_name] = infos;
227
228         // Update Salome_file state
229         _state.number_of_files++;
230         if (status != "ok")
231           _state.files_ok = false;
232       }
233     }
234   }
235   catch (HDFexception)
236   {
237     SALOME::ExceptionStruct es;
238     es.type = SALOME::INTERNAL_ERROR;
239     std::string text = "!!!! HDFexception";
240     es.text = CORBA::string_dup(text.c_str());
241     throw SALOME::SALOME_Exception(es);
242   }
243 }
244
245 //=============================================================================
246 /*! 
247  *  CORBA method
248  * \see Engines::Salome_file::save
249  */
250 //=============================================================================
251 void 
252 Salome_file_i::save(const char* hdf5_file) {
253   _state.hdf5_file_name = CORBA::string_dup(hdf5_file);
254   try
255   {
256     HDFfile *hdf_file;
257     HDFgroup *hdf_group;
258     HDFdataset *hdf_dataset;
259     hdf_size size[1];
260     _t_fileManaged::iterator begin = _fileManaged.begin();
261     _t_fileManaged::iterator end = _fileManaged.end();
262
263     hdf_file = new HDFfile((char*) _state.hdf5_file_name.in());
264     hdf_file->CreateOnDisk();
265
266     // Save mode information
267     hdf_group = new HDFgroup("CONFIG", hdf_file);
268     hdf_group->CreateOnDisk();
269     std::string mode("infos");
270     size[0] = strlen(mode.c_str()) + 1;
271     hdf_dataset = new HDFdataset("MODE", hdf_group, HDF_STRING, size, 1);
272     hdf_dataset->CreateOnDisk();
273     hdf_dataset->WriteOnDisk((void *) mode.c_str());
274     hdf_dataset->CloseOnDisk();
275     hdf_group->CloseOnDisk();
276
277     // List of files that are managed
278     std::string list_of_files;
279     for(;begin!=end;begin++) 
280     {
281       Engines::file file_infos = begin->second;
282       std::string file_name(file_infos.file_name.in());
283
284       list_of_files = list_of_files + file_name + std::string(" ");
285     }
286     hdf_group = new HDFgroup("GROUP_FILES", hdf_file);
287     hdf_group->CreateOnDisk();
288     size[0] = strlen(list_of_files.c_str()) + 1;
289     hdf_dataset = new HDFdataset("LIST_OF_FILES", hdf_group, HDF_STRING, size, 1);
290     hdf_dataset->CreateOnDisk();
291     hdf_dataset->WriteOnDisk((void *) list_of_files.c_str());
292     hdf_dataset->CloseOnDisk();
293     hdf_group->CloseOnDisk();
294
295     // Insert Files into the hdf5_file
296     begin = _fileManaged.begin();
297     for(;begin!=end;begin++) 
298     {
299       Engines::file file_infos = begin->second;
300       std::string file_name(file_infos.file_name.in());
301       std::string comp_file_name(_fileManaged[file_name].path.in());
302       comp_file_name.append(_fileManaged[file_name].file_name.in());
303       std::string dataset_group_name("DATASET");
304       dataset_group_name += std::string(_fileManaged[file_name].file_name.in());
305
306       hdf_group = new HDFgroup((char *) dataset_group_name.c_str(), hdf_file);
307       hdf_group->CreateOnDisk();
308       size[0] = strlen(file_infos.file_name.in()) + 1;
309       hdf_dataset = new HDFdataset("NAME", hdf_group, HDF_STRING, size, 1);
310       hdf_dataset->CreateOnDisk();
311       hdf_dataset->WriteOnDisk((void *) file_infos.file_name.in());
312       hdf_dataset->CloseOnDisk();
313       size[0] = strlen(file_infos.path.in()) + 1;
314       hdf_dataset = new HDFdataset("PATH", hdf_group, HDF_STRING, size, 1);
315       hdf_dataset->CreateOnDisk();
316       hdf_dataset->WriteOnDisk((void *) file_infos.path.in());
317       hdf_dataset->CloseOnDisk();
318       size[0] = strlen(file_infos.type.in()) + 1;
319       hdf_dataset = new HDFdataset("TYPE", hdf_group, HDF_STRING, size, 1);
320       hdf_dataset->CreateOnDisk();
321       hdf_dataset->WriteOnDisk((void *) file_infos.type.in());
322       hdf_dataset->CloseOnDisk();
323       size[0] = strlen(file_infos.source_file_name.in()) + 1;
324       hdf_dataset = new HDFdataset("SOURCE_FILE_NAME", hdf_group, HDF_STRING, size, 1);
325       hdf_dataset->CreateOnDisk();
326       hdf_dataset->WriteOnDisk((void *) file_infos.source_file_name.in());
327       hdf_dataset->CloseOnDisk();
328       size[0] = strlen(file_infos.status.in()) + 1;
329       hdf_dataset = new HDFdataset("STATUS", hdf_group, HDF_STRING, size, 1);
330       hdf_dataset->CreateOnDisk();
331       hdf_dataset->WriteOnDisk((void *) file_infos.status.in());
332       hdf_dataset->CloseOnDisk();
333       hdf_group->CloseOnDisk();
334     }
335
336     hdf_file->CloseOnDisk();
337
338     //      delete hdf_dataset;
339     //      delete hdf_group; ----> SEGFAULT !!!
340     //      delete hdf_file; ----> SEGFAULT !!!
341   }
342   catch (HDFexception)
343   {
344     SALOME::ExceptionStruct es;
345     es.type = SALOME::INTERNAL_ERROR;
346     std::string text = "!!!! HDFexception";
347     es.text = CORBA::string_dup(text.c_str());
348     throw SALOME::SALOME_Exception(es);
349   }
350 }
351
352 //=============================================================================
353 /*! 
354  *  CORBA method
355  * \see Engines::Salome_file::save_all
356  */
357 //=============================================================================
358 void 
359 Salome_file_i::save_all(const char* hdf5_file) {
360
361   _state.hdf5_file_name = CORBA::string_dup(hdf5_file);
362   // Test Salome_file status
363   if (_state.files_ok == false) {
364     SALOME::ExceptionStruct es;
365     es.type = SALOME::INTERNAL_ERROR;
366     std::string text = "File Not Ok !";
367     es.text = CORBA::string_dup(text.c_str());
368     throw SALOME::SALOME_Exception(es);
369   }
370
371   // For each file we create two groups
372   // First group contains file's informations
373   // Second group contains the file
374   // At the end we create a group and a dataset containing the names
375   // of all the files.
376   try
377   {
378     HDFfile *hdf_file;
379     HDFgroup *hdf_group;
380     HDFdataset *hdf_dataset;
381     hdf_size size[1];
382     _t_fileManaged::iterator begin = _fileManaged.begin();
383     _t_fileManaged::iterator end = _fileManaged.end();
384
385     hdf_file = new HDFfile((char*) _state.hdf5_file_name.in());
386     hdf_file->CreateOnDisk();
387
388     // Save mode information
389     hdf_group = new HDFgroup("CONFIG", hdf_file);
390     hdf_group->CreateOnDisk();
391     std::string mode("all");
392     size[0] = strlen(mode.c_str()) + 1;
393     hdf_dataset = new HDFdataset("MODE", hdf_group, HDF_STRING, size, 1);
394     hdf_dataset->CreateOnDisk();
395     hdf_dataset->WriteOnDisk((void *) mode.c_str());
396     hdf_dataset->CloseOnDisk();
397     hdf_group->CloseOnDisk();
398
399
400     // List of files that will be inserted
401     std::string list_of_files;
402     for(;begin!=end;begin++) 
403     {
404       Engines::file file_infos = begin->second;
405       std::string file_name(file_infos.file_name.in());
406
407       list_of_files = list_of_files + file_name + std::string(" ");
408     }
409     hdf_group = new HDFgroup("GROUP_FILES", hdf_file);
410     hdf_group->CreateOnDisk();
411     size[0] = strlen(list_of_files.c_str()) + 1;
412     hdf_dataset = new HDFdataset("LIST_OF_FILES", hdf_group, HDF_STRING, size, 1);
413     hdf_dataset->CreateOnDisk();
414     hdf_dataset->WriteOnDisk((void *) list_of_files.c_str());
415     hdf_dataset->CloseOnDisk();
416     hdf_group->CloseOnDisk();
417
418     // Insert Files into the hdf5_file
419     begin = _fileManaged.begin();
420     for(;begin!=end;begin++) 
421     {
422       Engines::file file_infos = begin->second;
423       std::string file_name(file_infos.file_name.in());
424       std::string comp_file_name(_fileManaged[file_name].path.in());
425       comp_file_name.append(_fileManaged[file_name].file_name.in());
426       std::string group_name("GROUP");
427       group_name += std::string(_fileManaged[file_name].file_name.in());
428       std::string dataset_group_name("DATASET");
429       dataset_group_name += std::string(_fileManaged[file_name].file_name.in());
430
431       hdf_group = new HDFgroup((char *) group_name.c_str(), hdf_file);
432       hdf_group->CreateOnDisk();
433       HDFConvert::FromAscii(comp_file_name.c_str(), *hdf_group, "FILE DATASET");
434       hdf_group->CloseOnDisk();
435
436       hdf_group = new HDFgroup((char *) dataset_group_name.c_str(), hdf_file);
437       hdf_group->CreateOnDisk();
438       size[0] = strlen(file_infos.file_name.in()) + 1;
439       hdf_dataset = new HDFdataset("NAME", hdf_group, HDF_STRING, size, 1);
440       hdf_dataset->CreateOnDisk();
441       hdf_dataset->WriteOnDisk((void *) file_infos.file_name.in());
442       hdf_dataset->CloseOnDisk();
443       size[0] = strlen(file_infos.path.in()) + 1;
444       hdf_dataset = new HDFdataset("PATH", hdf_group, HDF_STRING, size, 1);
445       hdf_dataset->CreateOnDisk();
446       hdf_dataset->WriteOnDisk((void *) file_infos.path.in());
447       hdf_dataset->CloseOnDisk();
448       size[0] = strlen(file_infos.type.in()) + 1;
449       hdf_dataset = new HDFdataset("TYPE", hdf_group, HDF_STRING, size, 1);
450       hdf_dataset->CreateOnDisk();
451       hdf_dataset->WriteOnDisk((void *) file_infos.type.in());
452       hdf_dataset->CloseOnDisk();
453       size[0] = strlen(file_infos.source_file_name.in()) + 1;
454       hdf_dataset = new HDFdataset("SOURCE_FILE_NAME", hdf_group, HDF_STRING, size, 1);
455       hdf_dataset->CreateOnDisk();
456       hdf_dataset->WriteOnDisk((void *) file_infos.source_file_name.in());
457       hdf_dataset->CloseOnDisk();
458       size[0] = strlen(file_infos.status.in()) + 1;
459       hdf_dataset = new HDFdataset("STATUS", hdf_group, HDF_STRING, size, 1);
460       hdf_dataset->CreateOnDisk();
461       hdf_dataset->WriteOnDisk((void *) file_infos.status.in());
462       hdf_dataset->CloseOnDisk();
463       hdf_group->CloseOnDisk();
464
465     }
466
467     hdf_file->CloseOnDisk();
468
469     //      delete hdf_dataset;
470     //      delete hdf_group; ----> SEGFAULT !!!
471     //      delete hdf_file; ----> SEGFAULT !!!
472   }
473   catch (HDFexception)
474   {
475     SALOME::ExceptionStruct es;
476     es.type = SALOME::INTERNAL_ERROR;
477     std::string text = "!!!! HDFexception";
478     es.text = CORBA::string_dup(text.c_str());
479     throw SALOME::SALOME_Exception(es);
480   }
481 }
482
483 //=============================================================================
484 /*! 
485  *  CORBA method
486  * \see Engines::Salome_file::setLocalFile
487  */
488 //=============================================================================
489 void 
490 Salome_file_i::setLocalFile(const char* comp_file_name)
491 {
492   std::string file_name("");
493   std::string path("");
494   std::string type("local");
495   std::string source_file_name("");
496   std::string status("not_ok");
497
498   std::string cp_file_name(comp_file_name);
499   std::size_t index = cp_file_name.rfind("/");
500   if (index != -1)
501   {
502     file_name = cp_file_name.substr(index+1);
503     path =  cp_file_name.substr(0,index+1);
504   }
505   else
506   {
507     file_name = comp_file_name;    
508     path = getcwd(NULL, _path_max);;
509   }
510
511   // Test if this file is already added
512   _t_fileManaged::iterator it = _fileManaged.find(file_name);
513   if (it != _fileManaged.end()) 
514   {
515     SALOME::ExceptionStruct es;
516     es.type = SALOME::INTERNAL_ERROR;
517     std::string text = "file already added";
518     es.text = CORBA::string_dup(text.c_str());
519     throw SALOME::SALOME_Exception(es);
520   }
521
522   // Test if the file is ok
523   if(fopen(comp_file_name,"rb") != NULL)
524     status = "ok";
525
526   // Adding file with is informations
527   Engines::file infos;
528   infos.file_name = CORBA::string_dup(file_name.c_str());
529   infos.path = CORBA::string_dup(path.c_str());
530   infos.type = CORBA::string_dup(type.c_str());
531   infos.source_file_name = CORBA::string_dup(source_file_name.c_str());
532   infos.status = CORBA::string_dup(status.c_str());
533   // Infos for parallel extensions...
534   infos.node = 0;
535   infos.container = Engines::Container::_duplicate(_container);
536
537   _fileManaged[file_name] = infos;
538
539   // Update Salome_file state
540   _state.number_of_files++;
541   if (status != "ok")
542     _state.files_ok = false;
543 }
544
545 //=============================================================================
546 /*! 
547  *  CORBA method
548  * \see Engines::Salome_file::setDistributedFile
549  */
550 //=============================================================================
551 void 
552 Salome_file_i::setDistributedFile(const char* comp_file_name)
553 {
554   std::string file_name("");
555   std::string path("");
556   std::string type("distributed");
557   std::string source_file_name("");
558   std::string status("not_ok");
559
560   std::string cp_file_name(comp_file_name);
561   std::size_t index = cp_file_name.rfind("/");
562   if (index != -1)
563   {
564     file_name = cp_file_name.substr(index+1);
565     path =  cp_file_name.substr(0,index+1);
566   }
567   else
568   {
569     file_name = comp_file_name;
570     path = getcwd(NULL, _path_max);;
571   }
572
573   // Test if this file is already added
574   _t_fileManaged::iterator it = _fileManaged.find(file_name);
575   if (it != _fileManaged.end()) 
576   {
577     SALOME::ExceptionStruct es;
578     es.type = SALOME::INTERNAL_ERROR;
579     std::string text = "file already added";
580     es.text = CORBA::string_dup(text.c_str());
581     throw SALOME::SALOME_Exception(es);
582   }
583
584   // Adding file with his informations
585   Engines::file infos;
586   infos.file_name = CORBA::string_dup(file_name.c_str());
587   infos.path = CORBA::string_dup(path.c_str());
588   infos.type = CORBA::string_dup(type.c_str());
589   infos.source_file_name = CORBA::string_dup(source_file_name.c_str());
590   infos.status = CORBA::string_dup(status.c_str());
591   // Infos for parallel extensions...
592   infos.node = 0;
593   infos.container = Engines::Container::_duplicate(_container);
594
595   _fileManaged[file_name] = infos;
596
597   if(!CORBA::is_nil(_default_source_Salome_file)) 
598   {
599     _fileDistributedSource[file_name] = 
600       Engines::Salome_file::_duplicate(_default_source_Salome_file);
601   }
602
603   // Update Salome_file state
604   _state.number_of_files++;
605   _state.files_ok = false;
606 }
607
608 //=============================================================================
609 /*! 
610  *  CORBA method
611  * \see Engines::Salome_file::connect
612  */
613 //=============================================================================
614 void
615 Salome_file_i::connect(Engines::Salome_file_ptr source_Salome_file) 
616 {
617   if(CORBA::is_nil(_default_source_Salome_file)) 
618   {
619     _default_source_Salome_file = Engines::Salome_file::_duplicate(source_Salome_file);
620     _t_fileManaged::iterator begin = _fileManaged.begin();
621     _t_fileManaged::iterator end = _fileManaged.end();
622     for(;begin!=end;begin++) {
623       // Get the name of the file
624       std::string file_name = begin->first;
625       _t_fileDistributedSource::iterator it = _fileDistributedSource.find(file_name);
626       if (it == _fileDistributedSource.end()) 
627       {
628         _fileDistributedSource[file_name] = Engines::Salome_file::_duplicate(source_Salome_file);
629       }
630     }
631   }
632   else
633   {
634     SALOME::ExceptionStruct es;
635     es.type = SALOME::INTERNAL_ERROR;
636     std::string text = "already connected to a default Salome_file";
637     es.text = CORBA::string_dup(text.c_str());
638     throw SALOME::SALOME_Exception(es);
639   }
640   // We can connect this Salome_file if there is only one file managed
641   // by the Salome_file
642   //std::string fname;
643   //if (_fileManaged.size() == 1) 
644   //{
645     // only one file managed 
646   //  _t_fileManaged::iterator it = _fileManaged.begin();
647   //  fname = it->first;
648   //  _fileDistributedSource[fname] = Engines::Salome_file::_duplicate(source_Salome_file);
649   //}
650   //else 
651   //{
652   //  SALOME::ExceptionStruct es;
653   //  es.type = SALOME::INTERNAL_ERROR;
654   //  std::string text = "cannot connect";
655    // es.text = CORBA::string_dup(text.c_str());
656    // throw SALOME::SALOME_Exception(es);
657   //}
658 }
659
660 //=============================================================================
661 /*! 
662  *  CORBA method
663  * \see Engines::Salome_file::connectDistributedFile
664  */
665 //=============================================================================
666 void
667 Salome_file_i::connectDistributedFile(const char * file_name,
668                                       Engines::Salome_file_ptr source_Salome_file) 
669 {
670   // Test if this file is added
671   _t_fileManaged::iterator it = _fileManaged.find(file_name);
672   if (it == _fileManaged.end()) 
673   {
674     SALOME::ExceptionStruct es;
675     es.type = SALOME::INTERNAL_ERROR;
676     std::string text = "file is not added";
677     es.text = CORBA::string_dup(text.c_str());
678     throw SALOME::SALOME_Exception(es);
679   }
680   else 
681   {
682     _fileDistributedSource[file_name] = Engines::Salome_file::_duplicate(source_Salome_file);
683   }
684 }
685
686 //=============================================================================
687 /*! 
688  *  CORBA method
689  * \see Engines::Salome_file::setDistributedSourceFile
690  */
691 //=============================================================================
692 void 
693 Salome_file_i::setDistributedSourceFile(const char* file_name,
694                                         const char * source_file_name)
695 {
696   std::string fname(file_name);
697
698   // Test if this file is added
699   _t_fileManaged::iterator it = _fileManaged.find(fname);
700   if (it == _fileManaged.end()) 
701   {
702     SALOME::ExceptionStruct es;
703     es.type = SALOME::INTERNAL_ERROR;
704     std::string text = "file is not added";
705     es.text = CORBA::string_dup(text.c_str());
706     throw SALOME::SALOME_Exception(es);
707   }
708   else 
709   {
710     _fileManaged[fname].source_file_name = CORBA::string_dup(source_file_name);
711   }
712 }
713
714 //=============================================================================
715 /*! 
716  *  CORBA method
717  * \see Engines::Salome_file::recvFiles
718  */
719 //=============================================================================
720 void 
721 Salome_file_i::recvFiles() {
722   
723   std::string files_not_ok("");
724
725   _t_fileManaged::iterator begin = _fileManaged.begin();
726   _t_fileManaged::iterator end = _fileManaged.end();
727   for(;begin!=end;begin++) 
728   {
729     bool result = true;
730     Engines::file file_infos = begin->second;
731     // Test if the file is local or distributed
732     if (std::string(file_infos.type.in()) == "local")
733     {
734       if (std::string(file_infos.status.in()) == "not_ok")
735         result = checkLocalFile(file_infos.file_name.in());
736     }
737     else
738     {
739       if (std::string(file_infos.status.in()) == "not_ok")
740         result = getDistributedFile(file_infos.file_name.in());
741     }
742     // if the result is false
743     // we add this file to files_not_ok
744     if (!result) 
745     {
746       files_not_ok.append(" ");
747       files_not_ok.append(file_infos.file_name.in());
748     }
749   }
750
751   if (files_not_ok != "")
752   {
753     SALOME::ExceptionStruct es;
754     es.type = SALOME::INTERNAL_ERROR;
755     std::string text = "files not ready : " + files_not_ok;
756     es.text = CORBA::string_dup(text.c_str());
757     throw SALOME::SALOME_Exception(es);
758   }
759   else
760   {
761     // We change the state of the Salome_file
762     _state.files_ok = true;
763   }
764 }
765
766 //=============================================================================
767 /*! 
768  *  local C++ method : This method is used by revFiles to check if a local 
769  *  managed file is ok.
770  *  \param  fileName name of the file
771  */
772 //=============================================================================
773 bool
774 Salome_file_i::checkLocalFile(std::string file_name)
775 {
776   bool result = true;
777
778   std::string comp_file_name(_fileManaged[file_name].path.in());
779   comp_file_name.append("/");
780   comp_file_name.append(_fileManaged[file_name].file_name.in());
781   if(fopen(comp_file_name.c_str(),"rb") == NULL)
782   {
783     INFOS("file " << comp_file_name << " cannot be open for reading");
784     _fileManaged[file_name].status = CORBA::string_dup("not_ok");
785     result = false;
786   }
787
788   if (result)
789   {
790     _fileManaged[file_name].status = CORBA::string_dup("ok");
791   }
792   return result;
793 }
794
795 //=============================================================================
796 /*! 
797  *  local C++ method : this method is used by recvFiles to get a 
798  *  distributed file from is distributed source.
799  *  If there is no source_file_name for the file, it tries to get
800  *  the file from the source. In this case, the source distributed file has to managed
801  *  only one file to be able to the send the file.
802  *
803  *  \param  fileName name of the file
804  */
805 //=============================================================================
806 bool
807 Salome_file_i::getDistributedFile(std::string file_name)
808 {
809   bool result = true;
810   const char * source_file_name = _fileManaged[file_name].source_file_name.in();
811   int fileId;
812   FILE* fp;
813   std::string comp_file_name(_fileManaged[file_name].path.in());
814   comp_file_name.append("/");
815   comp_file_name.append(_fileManaged[file_name].file_name.in());
816
817   // Test if the process can write on disk
818   if ((fp = fopen(comp_file_name.c_str(),"wb")) == NULL)
819   {
820     INFOS("file " << comp_file_name << " cannot be open for writing");
821     _fileManaged[file_name].status = CORBA::string_dup("not_ok");
822     result = false;
823     return result;
824   }
825
826   try 
827   {
828     fileId = _fileDistributedSource[file_name]->open(source_file_name);
829   }
830   catch (...) 
831   {
832     _fileManaged[file_name].status = CORBA::string_dup("not_ok");
833     fclose(fp);
834     result = false;
835     return result;
836   }
837
838   if (fileId > 0)
839   {
840     Engines::fileBlock* aBlock;
841     int toFollow = 1;
842     int ctr=0;
843     MESSAGE("begin of transfer of " << comp_file_name);
844     while (toFollow)
845     {
846       ctr++;
847       aBlock = _fileDistributedSource[file_name]->getBlock(fileId);
848       toFollow = aBlock->length();
849       CORBA::Octet *buf = aBlock->get_buffer();
850 #if defined(_DEBUG_) || defined(_DEBUG)
851       int nbWri = fwrite(buf, sizeof(CORBA::Octet), toFollow, fp);
852       ASSERT(nbWri == toFollow);
853 #else
854       fwrite(buf, sizeof(CORBA::Octet), toFollow, fp);
855 #endif
856       delete aBlock;
857     }
858     fclose(fp);
859     MESSAGE("end of transfer of " << comp_file_name);
860     _fileDistributedSource[file_name]->close(fileId);
861   }
862   else
863   {
864     INFOS("open reference file for copy impossible");
865     result = false;
866     fclose(fp);
867     _fileManaged[file_name].status = CORBA::string_dup("not_ok");
868     return result;
869   }
870
871   _fileManaged[file_name].status = CORBA::string_dup("ok");
872   return result;
873 }
874
875 //=============================================================================
876 /*! 
877  *  CORBA method
878  * \see Engines::Salome_file::removeFile
879  */
880 //=============================================================================
881 void 
882 Salome_file_i::removeFile(const char* file_name) 
883 {
884   MESSAGE("Salome_file_i::removeFile : NOT YET IMPLEMENTED");
885 }
886     
887 //=============================================================================
888 /*! 
889  *  CORBA method
890  * \see Engines::Salome_file::removeFiles
891  */
892 //=============================================================================
893 void 
894 Salome_file_i::removeFiles() {
895   MESSAGE("Salome_file_i::removeFiles : NOT YET IMPLEMENTED");
896 }
897
898 //=============================================================================
899 /*! 
900  *  CORBA method
901  * \see Engines::Salome_file::getFilesInfos
902  */
903 //=============================================================================
904 Engines::files* 
905 Salome_file_i::getFilesInfos() {
906
907   Engines::files * infos = new Engines::files();
908   infos->length(_fileManaged.size());
909
910   _t_fileManaged::iterator begin = _fileManaged.begin();
911   _t_fileManaged::iterator end = _fileManaged.end();
912   int i = 0;
913   for(;begin!=end;begin++) {
914     (*infos)[i] = *(new Engines::file(begin->second));
915     i++;
916   }
917   return infos;
918 }
919
920 //=============================================================================
921 /*! 
922  *  CORBA method
923  * \see Engines::Salome_file::getFileInfos
924  */
925 //=============================================================================
926 Engines::file* 
927 Salome_file_i::getFileInfos(const char* file_name) {
928
929   std::string fname(file_name);
930
931   // Test if this file is managed
932   _t_fileManaged::iterator it = _fileManaged.find(fname);
933   if (it == _fileManaged.end()) 
934   {
935     SALOME::ExceptionStruct es;
936     es.type = SALOME::INTERNAL_ERROR;
937     es.text = "file is not managed";
938     throw SALOME::SALOME_Exception(es);
939   }
940
941   Engines::file * infos = new Engines::file(_fileManaged[fname]);
942   return infos;
943 }
944
945 //=============================================================================
946 /*! 
947  *  CORBA method
948  * \see Engines::Salome_file::getSalome_fileState
949  */
950 //=============================================================================
951 Engines::SfState* 
952 Salome_file_i::getSalome_fileState() 
953 {
954   return new Engines::SfState(_state);
955 }
956
957 //=============================================================================
958 /*! 
959  *  CORBA method: try to open the file given. If the file is readable, return
960  *  a positive integer else return 0;
961  *  \param  fileName file name to be transfered
962  *  \return fileId = positive integer > 0 if open OK.
963  */
964 //=============================================================================
965
966 CORBA::Long 
967 Salome_file_i::open(const char* file_name)
968 {
969   int aKey = 0;
970
971   std::string fname(file_name);
972   if (fname == "") {
973     // We enter in the simple case where the user
974     // has not used setDistributedSourceFile.
975     // In this case we try to see if the Salome_file
976     if (_fileManaged.size() == 1) 
977     {
978       // only one file managed 
979       _t_fileManaged::iterator it = _fileManaged.begin();
980       fname = it->first;
981     }
982     else
983     {
984       // we can't choose the file so :
985       return aKey;
986     }
987   }
988
989   _t_fileManaged::iterator it = _fileManaged.find(fname);
990   if (it == _fileManaged.end())
991   {
992     return aKey;
993   }
994   
995   std::string comp_file_name(_fileManaged[fname].path.in());
996   comp_file_name.append("/");
997   comp_file_name.append(fname);
998   MESSAGE("Salome_file_i::open " << comp_file_name);
999   FILE* fp;
1000   if ((fp = fopen(comp_file_name.c_str(),"rb")) == NULL)
1001     {
1002       INFOS("file " << comp_file_name << " is not readable");
1003       return aKey;
1004     }
1005
1006   aKey = ++_fileId;
1007   _fileAccess[aKey] = fp;
1008   return aKey;
1009 }
1010
1011 //=============================================================================
1012 /*! 
1013  *  CORBA method: close the file associated to the fileId given at open.
1014  *  \param fileId got in return from open method
1015  */
1016 //=============================================================================
1017
1018 void 
1019 Salome_file_i::close(CORBA::Long fileId)
1020 {
1021   MESSAGE("Salome_file_i::close");
1022   FILE* fp;
1023   if (!(fp = _fileAccess[fileId]) )
1024     {
1025       INFOS(" no FILE structure associated to fileId " << fileId);
1026     }
1027   else fclose(fp);
1028 }
1029
1030 //=============================================================================
1031 /*! 
1032  *  CORBA method: get a block of data from the file associated to the fileId
1033  *  given at open.
1034  *  \param fileId got in return from open method
1035  *  \return an octet sequence. Last one is empty.
1036  */
1037 //=============================================================================
1038
1039 #define FILEBLOCK_SIZE 256*1024
1040
1041 Engines::fileBlock* 
1042 Salome_file_i::getBlock(CORBA::Long fileId)
1043 {
1044   Engines::fileBlock* aBlock = new Engines::fileBlock;
1045
1046   FILE* fp;
1047   if (! (fp = _fileAccess[fileId]) )
1048   {
1049     INFOS(" no FILE structure associated to fileId " <<fileId);
1050     return aBlock;
1051   }
1052
1053   // use replace member function for sequence to avoid copy
1054   // see Advanced CORBA Programming with C++ pp 187-194
1055   CORBA::Octet *buf;
1056   buf = Engines::fileBlock::allocbuf(FILEBLOCK_SIZE);
1057   int nbRed = fread(buf, sizeof(CORBA::Octet), FILEBLOCK_SIZE, fp);
1058   aBlock->replace(nbRed, nbRed, buf, 1); // 1 means give ownership
1059   return aBlock;
1060 }
1061
1062 void 
1063 Salome_file_i::setContainer(Engines::Container_ptr container)
1064 {
1065   _container = Engines::Container::_duplicate(container);
1066
1067   // Update All the files
1068   _t_fileManaged::iterator begin = _fileManaged.begin();
1069   _t_fileManaged::iterator end = _fileManaged.end();
1070   for(;begin!=end;begin++) {
1071     begin->second.container = Engines::Container::_duplicate(container);
1072   }
1073 }
1074