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