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