Back to index

salome-kernel  6.5.0
Salome_file_i.cxx
Go to the documentation of this file.
00001 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
00002 //
00003 // This library is free software; you can redistribute it and/or
00004 // modify it under the terms of the GNU Lesser General Public
00005 // License as published by the Free Software Foundation; either
00006 // version 2.1 of the License.
00007 //
00008 // This library is distributed in the hope that it will be useful,
00009 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00010 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00011 // Lesser General Public License for more details.
00012 //
00013 // You should have received a copy of the GNU Lesser General Public
00014 // License along with this library; if not, write to the Free Software
00015 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00016 //
00017 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00018 //
00019 
00020 //  File   : Salome_file_i.cxx
00021 //  Author : André RIBES, EDF
00022 //  Module : SALOME
00023 //  $Header: 
00024 //
00025 #include "Salome_file_i.hxx"
00026 #include "utilities.h"
00027 #include <stdlib.h>
00028 #include "HDFOI.hxx"
00029 #ifndef WIN32
00030 # include <unistd.h>
00031 # define _getcwd getcwd
00032 # define _open   open
00033 #else
00034 # include <direct.h>
00035 # include <io.h>
00036 # include <windows.h>
00037 #endif
00038 
00045 //=============================================================================
00049 //=============================================================================
00050 
00051 Salome_file_i::Salome_file_i()
00052 {
00053   _fileId = 0;
00054 #ifndef WIN32
00055   _path_max = 1 + pathconf("/", _PC_PATH_MAX);
00056 #else
00057   _path_max = 32768;
00058   //from MSDN:
00059   //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.
00060   //currently #define _MAX_PATH   260
00061 #endif
00062   _state.name = CORBA::string_dup("");
00063   _state.hdf5_file_name = CORBA::string_dup("");
00064   _state.number_of_files = 0;
00065   _state.files_ok = true;
00066   _container = Engines::Container::_nil();
00067   _default_source_Salome_file = Engines::Salome_file::_nil();
00068 }
00069 
00070 //=============================================================================
00074 //=============================================================================
00075 
00076 Salome_file_i::~Salome_file_i()
00077 {
00078 }
00079 
00080 //=============================================================================
00085 //=============================================================================
00086 void 
00087 Salome_file_i::load(const char* hdf5_file) {
00088   _state.hdf5_file_name = CORBA::string_dup(hdf5_file);
00089   try
00090   {
00091     HDFfile *hdf_file;
00092     HDFgroup *hdf_group;
00093     HDFdataset *hdf_dataset;
00094     int size;
00095     int fd;
00096     char * value;
00097     char * buffer;
00098 
00099     hdf_file = new HDFfile((char*) hdf5_file);
00100     hdf_file->OpenOnDisk(HDF_RDONLY);
00101 
00102     hdf_group = new HDFgroup("CONFIG",hdf_file); 
00103     hdf_group->OpenOnDisk();
00104     hdf_dataset = new HDFdataset("MODE",hdf_group);
00105     hdf_dataset->OpenOnDisk();
00106     size = hdf_dataset->GetSize();
00107     value = new char[size];
00108     hdf_dataset->ReadFromDisk(value);
00109     hdf_dataset->CloseOnDisk();
00110     std::string mode(value);
00111     delete value;
00112     
00113     hdf_group = new HDFgroup("GROUP_FILES",hdf_file); 
00114     hdf_group->OpenOnDisk();
00115     hdf_dataset = new HDFdataset("LIST_OF_FILES",hdf_group);
00116     hdf_dataset->OpenOnDisk();
00117     size = hdf_dataset->GetSize();
00118     value = new char[size];
00119     hdf_dataset->ReadFromDisk(value);
00120     hdf_dataset->CloseOnDisk();
00121     std::string list_of_files(value);
00122     delete value;
00123 
00124     std::istringstream iss(list_of_files);
00125     std::string file_name;
00126     while (std::getline(iss, file_name, ' '))
00127     {
00128       std::string dataset_group_name("DATASET");
00129       dataset_group_name += file_name;
00130 
00131       hdf_group = new HDFgroup(dataset_group_name.c_str(), hdf_file); 
00132       hdf_group->OpenOnDisk();
00133 
00134       hdf_dataset = new HDFdataset("NAME",hdf_group);
00135       hdf_dataset->OpenOnDisk();
00136       size = hdf_dataset->GetSize();
00137       value = new char[size];
00138       hdf_dataset->ReadFromDisk(value);
00139       hdf_dataset->CloseOnDisk();
00140       std::string name(value);
00141 
00142       hdf_dataset = new HDFdataset("PATH",hdf_group);
00143       hdf_dataset->OpenOnDisk();
00144       size = hdf_dataset->GetSize();
00145       value = new char[size];
00146       hdf_dataset->ReadFromDisk(value);
00147       hdf_dataset->CloseOnDisk();
00148       std::string path(value);
00149 
00150       hdf_dataset = new HDFdataset("TYPE",hdf_group);
00151       hdf_dataset->OpenOnDisk();
00152       size = hdf_dataset->GetSize();
00153       value = new char[size];
00154       hdf_dataset->ReadFromDisk(value);
00155       hdf_dataset->CloseOnDisk();
00156       std::string type(value);
00157 
00158       hdf_dataset = new HDFdataset("SOURCE_FILE_NAME",hdf_group);
00159       hdf_dataset->OpenOnDisk();
00160       size = hdf_dataset->GetSize();
00161       value = new char[size];
00162       hdf_dataset->ReadFromDisk(value);
00163       hdf_dataset->CloseOnDisk();
00164       std::string source_file_name(value);
00165 
00166       hdf_dataset = new HDFdataset("STATUS",hdf_group);
00167       hdf_dataset->OpenOnDisk();
00168       size = hdf_dataset->GetSize();
00169       value = new char[size];
00170       hdf_dataset->ReadFromDisk(value);
00171       hdf_dataset->CloseOnDisk();
00172       std::string status(value);
00173 
00174       if (mode == "all") {
00175 
00176         // Changing path, is now current directory
00177         path = getcwd(NULL, _path_max);
00178   
00179         std::string group_name("GROUP");
00180         group_name += file_name;
00181         hdf_group = new HDFgroup(group_name.c_str(),hdf_file); 
00182         hdf_group->OpenOnDisk();
00183         hdf_dataset = new HDFdataset("FILE DATASET",hdf_group);
00184         hdf_dataset->OpenOnDisk();
00185         size = hdf_dataset->GetSize();
00186         buffer = new char[size];
00187       
00188         if ( (fd = ::open(file_name.c_str(),O_RDWR|O_CREAT,00666)) <0) { 
00189           SALOME::ExceptionStruct es;
00190           es.type = SALOME::INTERNAL_ERROR;
00191           std::string text = "open failed";
00192           es.text = CORBA::string_dup(text.c_str());
00193           throw SALOME::SALOME_Exception(es);
00194         };
00195         hdf_dataset->ReadFromDisk(buffer);
00196         if ( write(fd,buffer,size) <0) { 
00197           SALOME::ExceptionStruct es;
00198           es.type = SALOME::INTERNAL_ERROR;
00199           std::string text = "write failed";
00200           es.text = CORBA::string_dup(text.c_str());
00201           throw SALOME::SALOME_Exception(es);
00202         };
00203         // Close the target file
00204         ::close(fd);
00205 
00206         Engines::file infos;
00207         infos.file_name = CORBA::string_dup(file_name.c_str());
00208         infos.path = CORBA::string_dup(path.c_str());
00209         infos.type = CORBA::string_dup(type.c_str());
00210         infos.source_file_name = CORBA::string_dup(source_file_name.c_str());
00211         infos.status = CORBA::string_dup(status.c_str());
00212 
00213         _fileManaged[file_name] = infos;
00214 
00215         // Update Salome_file state
00216         _state.number_of_files++;
00217         _state.files_ok = true;
00218       }
00219       else {
00220         Engines::file infos;
00221         infos.file_name = CORBA::string_dup(file_name.c_str());
00222         infos.path = CORBA::string_dup(path.c_str());
00223         infos.type = CORBA::string_dup(type.c_str());
00224         infos.source_file_name = CORBA::string_dup(source_file_name.c_str());
00225         infos.status = CORBA::string_dup(status.c_str());
00226         // Infos for parallel extensions...
00227         infos.node = 0;
00228         infos.container = Engines::Container::_duplicate(_container);
00229 
00230         _fileManaged[file_name] = infos;
00231 
00232         // Update Salome_file state
00233         _state.number_of_files++;
00234         if (status != "ok")
00235           _state.files_ok = false;
00236       }
00237     }
00238   }
00239   catch (HDFexception)
00240   {
00241     SALOME::ExceptionStruct es;
00242     es.type = SALOME::INTERNAL_ERROR;
00243     std::string text = "!!!! HDFexception";
00244     es.text = CORBA::string_dup(text.c_str());
00245     throw SALOME::SALOME_Exception(es);
00246   }
00247 }
00248 
00249 //=============================================================================
00254 //=============================================================================
00255 void 
00256 Salome_file_i::save(const char* hdf5_file) {
00257   _state.hdf5_file_name = CORBA::string_dup(hdf5_file);
00258   try
00259   {
00260     HDFfile *hdf_file;
00261     HDFgroup *hdf_group;
00262     HDFdataset *hdf_dataset;
00263     hdf_size size[1];
00264     _t_fileManaged::iterator begin = _fileManaged.begin();
00265     _t_fileManaged::iterator end = _fileManaged.end();
00266 
00267     hdf_file = new HDFfile((char*) _state.hdf5_file_name.in());
00268     hdf_file->CreateOnDisk();
00269 
00270     // Save mode information
00271     hdf_group = new HDFgroup("CONFIG", hdf_file);
00272     hdf_group->CreateOnDisk();
00273     std::string mode("infos");
00274     size[0] = strlen(mode.c_str()) + 1;
00275     hdf_dataset = new HDFdataset("MODE", hdf_group, HDF_STRING, size, 1);
00276     hdf_dataset->CreateOnDisk();
00277     hdf_dataset->WriteOnDisk((void *) mode.c_str());
00278     hdf_dataset->CloseOnDisk();
00279     hdf_group->CloseOnDisk();
00280 
00281     // List of files that are managed
00282     std::string list_of_files;
00283     for(;begin!=end;begin++) 
00284     {
00285       Engines::file file_infos = begin->second;
00286       std::string file_name(file_infos.file_name.in());
00287 
00288       list_of_files = list_of_files + file_name + std::string(" ");
00289     }
00290     hdf_group = new HDFgroup("GROUP_FILES", hdf_file);
00291     hdf_group->CreateOnDisk();
00292     size[0] = strlen(list_of_files.c_str()) + 1;
00293     hdf_dataset = new HDFdataset("LIST_OF_FILES", hdf_group, HDF_STRING, size, 1);
00294     hdf_dataset->CreateOnDisk();
00295     hdf_dataset->WriteOnDisk((void *) list_of_files.c_str());
00296     hdf_dataset->CloseOnDisk();
00297     hdf_group->CloseOnDisk();
00298 
00299     // Insert Files into the hdf5_file
00300     begin = _fileManaged.begin();
00301     for(;begin!=end;begin++) 
00302     {
00303       Engines::file file_infos = begin->second;
00304       std::string file_name(file_infos.file_name.in());
00305       std::string comp_file_name(_fileManaged[file_name].path.in());
00306       comp_file_name.append(_fileManaged[file_name].file_name.in());
00307       std::string dataset_group_name("DATASET");
00308       dataset_group_name += std::string(_fileManaged[file_name].file_name.in());
00309 
00310       hdf_group = new HDFgroup((char *) dataset_group_name.c_str(), hdf_file);
00311       hdf_group->CreateOnDisk();
00312       size[0] = strlen(file_infos.file_name.in()) + 1;
00313       hdf_dataset = new HDFdataset("NAME", hdf_group, HDF_STRING, size, 1);
00314       hdf_dataset->CreateOnDisk();
00315       hdf_dataset->WriteOnDisk((void *) file_infos.file_name.in());
00316       hdf_dataset->CloseOnDisk();
00317       size[0] = strlen(file_infos.path.in()) + 1;
00318       hdf_dataset = new HDFdataset("PATH", hdf_group, HDF_STRING, size, 1);
00319       hdf_dataset->CreateOnDisk();
00320       hdf_dataset->WriteOnDisk((void *) file_infos.path.in());
00321       hdf_dataset->CloseOnDisk();
00322       size[0] = strlen(file_infos.type.in()) + 1;
00323       hdf_dataset = new HDFdataset("TYPE", hdf_group, HDF_STRING, size, 1);
00324       hdf_dataset->CreateOnDisk();
00325       hdf_dataset->WriteOnDisk((void *) file_infos.type.in());
00326       hdf_dataset->CloseOnDisk();
00327       size[0] = strlen(file_infos.source_file_name.in()) + 1;
00328       hdf_dataset = new HDFdataset("SOURCE_FILE_NAME", hdf_group, HDF_STRING, size, 1);
00329       hdf_dataset->CreateOnDisk();
00330       hdf_dataset->WriteOnDisk((void *) file_infos.source_file_name.in());
00331       hdf_dataset->CloseOnDisk();
00332       size[0] = strlen(file_infos.status.in()) + 1;
00333       hdf_dataset = new HDFdataset("STATUS", hdf_group, HDF_STRING, size, 1);
00334       hdf_dataset->CreateOnDisk();
00335       hdf_dataset->WriteOnDisk((void *) file_infos.status.in());
00336       hdf_dataset->CloseOnDisk();
00337       hdf_group->CloseOnDisk();
00338     }
00339 
00340     hdf_file->CloseOnDisk();
00341 
00342     //      delete hdf_dataset;
00343     //      delete hdf_group; ----> SEGFAULT !!!
00344     //      delete hdf_file; ----> SEGFAULT !!!
00345   }
00346   catch (HDFexception)
00347   {
00348     SALOME::ExceptionStruct es;
00349     es.type = SALOME::INTERNAL_ERROR;
00350     std::string text = "!!!! HDFexception";
00351     es.text = CORBA::string_dup(text.c_str());
00352     throw SALOME::SALOME_Exception(es);
00353   }
00354 }
00355 
00356 //=============================================================================
00361 //=============================================================================
00362 void 
00363 Salome_file_i::save_all(const char* hdf5_file) {
00364 
00365   _state.hdf5_file_name = CORBA::string_dup(hdf5_file);
00366   // Test Salome_file status
00367   if (_state.files_ok == false) {
00368     SALOME::ExceptionStruct es;
00369     es.type = SALOME::INTERNAL_ERROR;
00370     std::string text = "File Not Ok !";
00371     es.text = CORBA::string_dup(text.c_str());
00372     throw SALOME::SALOME_Exception(es);
00373   }
00374 
00375   // For each file we create two groups
00376   // First group contains file's informations
00377   // Second group contains the file
00378   // At the end we create a group and a dataset containing the names
00379   // of all the files.
00380   try
00381   {
00382     HDFfile *hdf_file;
00383     HDFgroup *hdf_group;
00384     HDFdataset *hdf_dataset;
00385     hdf_size size[1];
00386     _t_fileManaged::iterator begin = _fileManaged.begin();
00387     _t_fileManaged::iterator end = _fileManaged.end();
00388 
00389     hdf_file = new HDFfile((char*) _state.hdf5_file_name.in());
00390     hdf_file->CreateOnDisk();
00391 
00392     // Save mode information
00393     hdf_group = new HDFgroup("CONFIG", hdf_file);
00394     hdf_group->CreateOnDisk();
00395     std::string mode("all");
00396     size[0] = strlen(mode.c_str()) + 1;
00397     hdf_dataset = new HDFdataset("MODE", hdf_group, HDF_STRING, size, 1);
00398     hdf_dataset->CreateOnDisk();
00399     hdf_dataset->WriteOnDisk((void *) mode.c_str());
00400     hdf_dataset->CloseOnDisk();
00401     hdf_group->CloseOnDisk();
00402 
00403 
00404     // List of files that will be inserted
00405     std::string list_of_files;
00406     for(;begin!=end;begin++) 
00407     {
00408       Engines::file file_infos = begin->second;
00409       std::string file_name(file_infos.file_name.in());
00410 
00411       list_of_files = list_of_files + file_name + std::string(" ");
00412     }
00413     hdf_group = new HDFgroup("GROUP_FILES", hdf_file);
00414     hdf_group->CreateOnDisk();
00415     size[0] = strlen(list_of_files.c_str()) + 1;
00416     hdf_dataset = new HDFdataset("LIST_OF_FILES", hdf_group, HDF_STRING, size, 1);
00417     hdf_dataset->CreateOnDisk();
00418     hdf_dataset->WriteOnDisk((void *) list_of_files.c_str());
00419     hdf_dataset->CloseOnDisk();
00420     hdf_group->CloseOnDisk();
00421 
00422     // Insert Files into the hdf5_file
00423     begin = _fileManaged.begin();
00424     for(;begin!=end;begin++) 
00425     {
00426       Engines::file file_infos = begin->second;
00427       std::string file_name(file_infos.file_name.in());
00428       std::string comp_file_name(_fileManaged[file_name].path.in());
00429       comp_file_name.append(_fileManaged[file_name].file_name.in());
00430       std::string group_name("GROUP");
00431       group_name += std::string(_fileManaged[file_name].file_name.in());
00432       std::string dataset_group_name("DATASET");
00433       dataset_group_name += std::string(_fileManaged[file_name].file_name.in());
00434 
00435       hdf_group = new HDFgroup((char *) group_name.c_str(), hdf_file);
00436       hdf_group->CreateOnDisk();
00437       HDFConvert::FromAscii(comp_file_name.c_str(), *hdf_group, "FILE DATASET");
00438       hdf_group->CloseOnDisk();
00439 
00440       hdf_group = new HDFgroup((char *) dataset_group_name.c_str(), hdf_file);
00441       hdf_group->CreateOnDisk();
00442       size[0] = strlen(file_infos.file_name.in()) + 1;
00443       hdf_dataset = new HDFdataset("NAME", hdf_group, HDF_STRING, size, 1);
00444       hdf_dataset->CreateOnDisk();
00445       hdf_dataset->WriteOnDisk((void *) file_infos.file_name.in());
00446       hdf_dataset->CloseOnDisk();
00447       size[0] = strlen(file_infos.path.in()) + 1;
00448       hdf_dataset = new HDFdataset("PATH", hdf_group, HDF_STRING, size, 1);
00449       hdf_dataset->CreateOnDisk();
00450       hdf_dataset->WriteOnDisk((void *) file_infos.path.in());
00451       hdf_dataset->CloseOnDisk();
00452       size[0] = strlen(file_infos.type.in()) + 1;
00453       hdf_dataset = new HDFdataset("TYPE", hdf_group, HDF_STRING, size, 1);
00454       hdf_dataset->CreateOnDisk();
00455       hdf_dataset->WriteOnDisk((void *) file_infos.type.in());
00456       hdf_dataset->CloseOnDisk();
00457       size[0] = strlen(file_infos.source_file_name.in()) + 1;
00458       hdf_dataset = new HDFdataset("SOURCE_FILE_NAME", hdf_group, HDF_STRING, size, 1);
00459       hdf_dataset->CreateOnDisk();
00460       hdf_dataset->WriteOnDisk((void *) file_infos.source_file_name.in());
00461       hdf_dataset->CloseOnDisk();
00462       size[0] = strlen(file_infos.status.in()) + 1;
00463       hdf_dataset = new HDFdataset("STATUS", hdf_group, HDF_STRING, size, 1);
00464       hdf_dataset->CreateOnDisk();
00465       hdf_dataset->WriteOnDisk((void *) file_infos.status.in());
00466       hdf_dataset->CloseOnDisk();
00467       hdf_group->CloseOnDisk();
00468 
00469     }
00470 
00471     hdf_file->CloseOnDisk();
00472 
00473     //      delete hdf_dataset;
00474     //      delete hdf_group; ----> SEGFAULT !!!
00475     //      delete hdf_file; ----> SEGFAULT !!!
00476   }
00477   catch (HDFexception)
00478   {
00479     SALOME::ExceptionStruct es;
00480     es.type = SALOME::INTERNAL_ERROR;
00481     std::string text = "!!!! HDFexception";
00482     es.text = CORBA::string_dup(text.c_str());
00483     throw SALOME::SALOME_Exception(es);
00484   }
00485 }
00486 
00487 //=============================================================================
00492 //=============================================================================
00493 void 
00494 Salome_file_i::setLocalFile(const char* comp_file_name)
00495 {
00496   std::string file_name("");
00497   std::string path("");
00498   std::string type("local");
00499   std::string source_file_name("");
00500   std::string status("not_ok");
00501 
00502   std::string cp_file_name(comp_file_name);
00503   std::size_t index = cp_file_name.rfind("/");
00504   if (index != -1)
00505   {
00506     file_name = cp_file_name.substr(index+1);
00507     path =  cp_file_name.substr(0,index+1);
00508   }
00509   else
00510   {
00511     file_name = comp_file_name;    
00512     path = getcwd(NULL, _path_max);;
00513   }
00514 
00515   // Test if this file is already added
00516   _t_fileManaged::iterator it = _fileManaged.find(file_name);
00517   if (it != _fileManaged.end()) 
00518   {
00519     SALOME::ExceptionStruct es;
00520     es.type = SALOME::INTERNAL_ERROR;
00521     std::string text = "file already added";
00522     es.text = CORBA::string_dup(text.c_str());
00523     throw SALOME::SALOME_Exception(es);
00524   }
00525 
00526   // Test if the file is ok
00527   if(fopen(comp_file_name,"rb") != NULL)
00528     status = "ok";
00529 
00530   // Adding file with is informations
00531   Engines::file infos;
00532   infos.file_name = CORBA::string_dup(file_name.c_str());
00533   infos.path = CORBA::string_dup(path.c_str());
00534   infos.type = CORBA::string_dup(type.c_str());
00535   infos.source_file_name = CORBA::string_dup(source_file_name.c_str());
00536   infos.status = CORBA::string_dup(status.c_str());
00537   // Infos for parallel extensions...
00538   infos.node = 0;
00539   infos.container = Engines::Container::_duplicate(_container);
00540 
00541   _fileManaged[file_name] = infos;
00542 
00543   // Update Salome_file state
00544   _state.number_of_files++;
00545   if (status != "ok")
00546     _state.files_ok = false;
00547 }
00548 
00549 //=============================================================================
00554 //=============================================================================
00555 void 
00556 Salome_file_i::setDistributedFile(const char* comp_file_name)
00557 {
00558   std::string file_name("");
00559   std::string path("");
00560   std::string type("distributed");
00561   std::string source_file_name("");
00562   std::string status("not_ok");
00563 
00564   std::string cp_file_name(comp_file_name);
00565   std::size_t index = cp_file_name.rfind("/");
00566   if (index != -1)
00567   {
00568     file_name = cp_file_name.substr(index+1);
00569     path =  cp_file_name.substr(0,index+1);
00570   }
00571   else
00572   {
00573     file_name = comp_file_name;
00574     path = getcwd(NULL, _path_max);;
00575   }
00576 
00577   // Test if this file is already added
00578   _t_fileManaged::iterator it = _fileManaged.find(file_name);
00579   if (it != _fileManaged.end()) 
00580   {
00581     SALOME::ExceptionStruct es;
00582     es.type = SALOME::INTERNAL_ERROR;
00583     std::string text = "file already added";
00584     es.text = CORBA::string_dup(text.c_str());
00585     throw SALOME::SALOME_Exception(es);
00586   }
00587 
00588   // Adding file with his informations
00589   Engines::file infos;
00590   infos.file_name = CORBA::string_dup(file_name.c_str());
00591   infos.path = CORBA::string_dup(path.c_str());
00592   infos.type = CORBA::string_dup(type.c_str());
00593   infos.source_file_name = CORBA::string_dup(source_file_name.c_str());
00594   infos.status = CORBA::string_dup(status.c_str());
00595   // Infos for parallel extensions...
00596   infos.node = 0;
00597   infos.container = Engines::Container::_duplicate(_container);
00598 
00599   _fileManaged[file_name] = infos;
00600 
00601   if(!CORBA::is_nil(_default_source_Salome_file)) 
00602   {
00603     _fileDistributedSource[file_name] = 
00604       Engines::Salome_file::_duplicate(_default_source_Salome_file);
00605   }
00606 
00607   // Update Salome_file state
00608   _state.number_of_files++;
00609   _state.files_ok = false;
00610 }
00611 
00612 //=============================================================================
00617 //=============================================================================
00618 void
00619 Salome_file_i::connect(Engines::Salome_file_ptr source_Salome_file) 
00620 {
00621   if(CORBA::is_nil(_default_source_Salome_file)) 
00622   {
00623     _default_source_Salome_file = Engines::Salome_file::_duplicate(source_Salome_file);
00624     _t_fileManaged::iterator begin = _fileManaged.begin();
00625     _t_fileManaged::iterator end = _fileManaged.end();
00626     for(;begin!=end;begin++) {
00627       // Get the name of the file
00628       std::string file_name = begin->first;
00629       _t_fileDistributedSource::iterator it = _fileDistributedSource.find(file_name);
00630       if (it == _fileDistributedSource.end()) 
00631       {
00632         _fileDistributedSource[file_name] = Engines::Salome_file::_duplicate(source_Salome_file);
00633       }
00634     }
00635   }
00636   else
00637   {
00638     SALOME::ExceptionStruct es;
00639     es.type = SALOME::INTERNAL_ERROR;
00640     std::string text = "already connected to a default Salome_file";
00641     es.text = CORBA::string_dup(text.c_str());
00642     throw SALOME::SALOME_Exception(es);
00643   }
00644   // We can connect this Salome_file if there is only one file managed
00645   // by the Salome_file
00646   //std::string fname;
00647   //if (_fileManaged.size() == 1) 
00648   //{
00649     // only one file managed 
00650   //  _t_fileManaged::iterator it = _fileManaged.begin();
00651   //  fname = it->first;
00652   //  _fileDistributedSource[fname] = Engines::Salome_file::_duplicate(source_Salome_file);
00653   //}
00654   //else 
00655   //{
00656   //  SALOME::ExceptionStruct es;
00657   //  es.type = SALOME::INTERNAL_ERROR;
00658   //  std::string text = "cannot connect";
00659    // es.text = CORBA::string_dup(text.c_str());
00660    // throw SALOME::SALOME_Exception(es);
00661   //}
00662 }
00663 
00664 //=============================================================================
00669 //=============================================================================
00670 void
00671 Salome_file_i::connectDistributedFile(const char * file_name,
00672                                       Engines::Salome_file_ptr source_Salome_file) 
00673 {
00674   // Test if this file is added
00675   _t_fileManaged::iterator it = _fileManaged.find(file_name);
00676   if (it == _fileManaged.end()) 
00677   {
00678     SALOME::ExceptionStruct es;
00679     es.type = SALOME::INTERNAL_ERROR;
00680     std::string text = "file is not added";
00681     es.text = CORBA::string_dup(text.c_str());
00682     throw SALOME::SALOME_Exception(es);
00683   }
00684   else 
00685   {
00686     _fileDistributedSource[file_name] = Engines::Salome_file::_duplicate(source_Salome_file);
00687   }
00688 }
00689 
00690 //=============================================================================
00695 //=============================================================================
00696 void 
00697 Salome_file_i::setDistributedSourceFile(const char* file_name,
00698                                         const char * source_file_name)
00699 {
00700   std::string fname(file_name);
00701 
00702   // Test if this file is added
00703   _t_fileManaged::iterator it = _fileManaged.find(fname);
00704   if (it == _fileManaged.end()) 
00705   {
00706     SALOME::ExceptionStruct es;
00707     es.type = SALOME::INTERNAL_ERROR;
00708     std::string text = "file is not added";
00709     es.text = CORBA::string_dup(text.c_str());
00710     throw SALOME::SALOME_Exception(es);
00711   }
00712   else 
00713   {
00714     _fileManaged[fname].source_file_name = CORBA::string_dup(source_file_name);
00715   }
00716 }
00717 
00718 //=============================================================================
00723 //=============================================================================
00724 void 
00725 Salome_file_i::recvFiles() {
00726   
00727   std::string files_not_ok("");
00728 
00729   _t_fileManaged::iterator begin = _fileManaged.begin();
00730   _t_fileManaged::iterator end = _fileManaged.end();
00731   for(;begin!=end;begin++) 
00732   {
00733     bool result = true;
00734     Engines::file file_infos = begin->second;
00735     // Test if the file is local or distributed
00736     if (std::string(file_infos.type.in()) == "local")
00737     {
00738       if (std::string(file_infos.status.in()) == "not_ok")
00739         result = checkLocalFile(file_infos.file_name.in());
00740     }
00741     else
00742     {
00743       if (std::string(file_infos.status.in()) == "not_ok")
00744         result = getDistributedFile(file_infos.file_name.in());
00745     }
00746     // if the result is false
00747     // we add this file to files_not_ok
00748     if (!result) 
00749     {
00750       files_not_ok.append(" ");
00751       files_not_ok.append(file_infos.file_name.in());
00752     }
00753   }
00754 
00755   if (files_not_ok != "")
00756   {
00757     SALOME::ExceptionStruct es;
00758     es.type = SALOME::INTERNAL_ERROR;
00759     std::string text = "files not ready : " + files_not_ok;
00760     es.text = CORBA::string_dup(text.c_str());
00761     throw SALOME::SALOME_Exception(es);
00762   }
00763   else
00764   {
00765     // We change the state of the Salome_file
00766     _state.files_ok = true;
00767   }
00768 }
00769 
00770 //=============================================================================
00776 //=============================================================================
00777 bool
00778 Salome_file_i::checkLocalFile(std::string file_name)
00779 {
00780   bool result = true;
00781 
00782   std::string comp_file_name(_fileManaged[file_name].path.in());
00783   comp_file_name.append("/");
00784   comp_file_name.append(_fileManaged[file_name].file_name.in());
00785   if(fopen(comp_file_name.c_str(),"rb") == NULL)
00786   {
00787     INFOS("file " << comp_file_name << " cannot be open for reading");
00788     _fileManaged[file_name].status = CORBA::string_dup("not_ok");
00789     result = false;
00790   }
00791 
00792   if (result)
00793   {
00794     _fileManaged[file_name].status = CORBA::string_dup("ok");
00795   }
00796   return result;
00797 }
00798 
00799 //=============================================================================
00809 //=============================================================================
00810 bool
00811 Salome_file_i::getDistributedFile(std::string file_name)
00812 {
00813   bool result = true;
00814   const char * source_file_name = _fileManaged[file_name].source_file_name.in();
00815   int fileId;
00816   FILE* fp;
00817   std::string comp_file_name(_fileManaged[file_name].path.in());
00818   comp_file_name.append("/");
00819   comp_file_name.append(_fileManaged[file_name].file_name.in());
00820 
00821   // Test if the process can write on disk
00822   if ((fp = fopen(comp_file_name.c_str(),"wb")) == NULL)
00823   {
00824     INFOS("file " << comp_file_name << " cannot be open for writing");
00825     _fileManaged[file_name].status = CORBA::string_dup("not_ok");
00826     result = false;
00827     return result;
00828   }
00829 
00830   try 
00831   {
00832     fileId = _fileDistributedSource[file_name]->open(source_file_name);
00833   }
00834   catch (...) 
00835   {
00836     _fileManaged[file_name].status = CORBA::string_dup("not_ok");
00837     fclose(fp);
00838     result = false;
00839     return result;
00840   }
00841 
00842   if (fileId > 0)
00843   {
00844     Engines::fileBlock* aBlock;
00845     int toFollow = 1;
00846     int ctr=0;
00847     MESSAGE("begin of transfer of " << comp_file_name);
00848     while (toFollow)
00849     {
00850       ctr++;
00851       aBlock = _fileDistributedSource[file_name]->getBlock(fileId);
00852       toFollow = aBlock->length();
00853       CORBA::Octet *buf = aBlock->get_buffer();
00854 #if defined(_DEBUG_) || defined(_DEBUG)
00855       int nbWri = fwrite(buf, sizeof(CORBA::Octet), toFollow, fp);
00856       ASSERT(nbWri == toFollow);
00857 #else
00858       fwrite(buf, sizeof(CORBA::Octet), toFollow, fp);
00859 #endif
00860       delete aBlock;
00861     }
00862     fclose(fp);
00863     MESSAGE("end of transfer of " << comp_file_name);
00864     _fileDistributedSource[file_name]->close(fileId);
00865   }
00866   else
00867   {
00868     INFOS("open reference file for copy impossible");
00869     result = false;
00870     fclose(fp);
00871     _fileManaged[file_name].status = CORBA::string_dup("not_ok");
00872     return result;
00873   }
00874 
00875   _fileManaged[file_name].status = CORBA::string_dup("ok");
00876   return result;
00877 }
00878 
00879 //=============================================================================
00884 //=============================================================================
00885 void 
00886 Salome_file_i::removeFile(const char* file_name) 
00887 {
00888   MESSAGE("Salome_file_i::removeFile : NOT YET IMPLEMENTED");
00889 }
00890     
00891 //=============================================================================
00896 //=============================================================================
00897 void 
00898 Salome_file_i::removeFiles() {
00899   MESSAGE("Salome_file_i::removeFiles : NOT YET IMPLEMENTED");
00900 }
00901 
00902 //=============================================================================
00907 //=============================================================================
00908 Engines::files* 
00909 Salome_file_i::getFilesInfos() {
00910 
00911   Engines::files * infos = new Engines::files();
00912   infos->length(_fileManaged.size());
00913 
00914   _t_fileManaged::iterator begin = _fileManaged.begin();
00915   _t_fileManaged::iterator end = _fileManaged.end();
00916   int i = 0;
00917   for(;begin!=end;begin++) {
00918     (*infos)[i] = *(new Engines::file(begin->second));
00919     i++;
00920   }
00921   return infos;
00922 }
00923 
00924 //=============================================================================
00929 //=============================================================================
00930 Engines::file* 
00931 Salome_file_i::getFileInfos(const char* file_name) {
00932 
00933   std::string fname(file_name);
00934 
00935   // Test if this file is managed
00936   _t_fileManaged::iterator it = _fileManaged.find(fname);
00937   if (it == _fileManaged.end()) 
00938   {
00939     SALOME::ExceptionStruct es;
00940     es.type = SALOME::INTERNAL_ERROR;
00941     es.text = "file is not managed";
00942     throw SALOME::SALOME_Exception(es);
00943   }
00944 
00945   Engines::file * infos = new Engines::file(_fileManaged[fname]);
00946   return infos;
00947 }
00948 
00949 //=============================================================================
00954 //=============================================================================
00955 Engines::SfState* 
00956 Salome_file_i::getSalome_fileState() 
00957 {
00958   return new Engines::SfState(_state);
00959 }
00960 
00961 //=============================================================================
00968 //=============================================================================
00969 
00970 CORBA::Long 
00971 Salome_file_i::open(const char* file_name)
00972 {
00973   int aKey = 0;
00974 
00975   std::string fname(file_name);
00976   if (fname == "") {
00977     // We enter in the simple case where the user
00978     // has not used setDistributedSourceFile.
00979     // In this case we try to see if the Salome_file
00980     if (_fileManaged.size() == 1) 
00981     {
00982       // only one file managed 
00983       _t_fileManaged::iterator it = _fileManaged.begin();
00984       fname = it->first;
00985     }
00986     else
00987     {
00988       // we can't choose the file so :
00989       return aKey;
00990     }
00991   }
00992 
00993   _t_fileManaged::iterator it = _fileManaged.find(fname);
00994   if (it == _fileManaged.end())
00995   {
00996     return aKey;
00997   }
00998   
00999   std::string comp_file_name(_fileManaged[fname].path.in());
01000   comp_file_name.append("/");
01001   comp_file_name.append(fname);
01002   MESSAGE("Salome_file_i::open " << comp_file_name);
01003   FILE* fp;
01004   if ((fp = fopen(comp_file_name.c_str(),"rb")) == NULL)
01005     {
01006       INFOS("file " << comp_file_name << " is not readable");
01007       return aKey;
01008     }
01009 
01010   aKey = ++_fileId;
01011   _fileAccess[aKey] = fp;
01012   return aKey;
01013 }
01014 
01015 //=============================================================================
01020 //=============================================================================
01021 
01022 void 
01023 Salome_file_i::close(CORBA::Long fileId)
01024 {
01025   MESSAGE("Salome_file_i::close");
01026   FILE* fp;
01027   if (!(fp = _fileAccess[fileId]) )
01028     {
01029       INFOS(" no FILE structure associated to fileId " << fileId);
01030     }
01031   else fclose(fp);
01032 }
01033 
01034 //=============================================================================
01041 //=============================================================================
01042 
01043 #define FILEBLOCK_SIZE 256*1024
01044 
01045 Engines::fileBlock* 
01046 Salome_file_i::getBlock(CORBA::Long fileId)
01047 {
01048   Engines::fileBlock* aBlock = new Engines::fileBlock;
01049 
01050   FILE* fp;
01051   if (! (fp = _fileAccess[fileId]) )
01052   {
01053     INFOS(" no FILE structure associated to fileId " <<fileId);
01054     return aBlock;
01055   }
01056 
01057   // use replace member function for sequence to avoid copy
01058   // see Advanced CORBA Programming with C++ pp 187-194
01059   CORBA::Octet *buf;
01060   buf = Engines::fileBlock::allocbuf(FILEBLOCK_SIZE);
01061   int nbRed = fread(buf, sizeof(CORBA::Octet), FILEBLOCK_SIZE, fp);
01062   aBlock->replace(nbRed, nbRed, buf, 1); // 1 means give ownership
01063   return aBlock;
01064 }
01065 
01066 void 
01067 Salome_file_i::setContainer(Engines::Container_ptr container)
01068 {
01069   _container = Engines::Container::_duplicate(container);
01070 
01071   // Update All the files
01072   _t_fileManaged::iterator begin = _fileManaged.begin();
01073   _t_fileManaged::iterator end = _fileManaged.end();
01074   for(;begin!=end;begin++) {
01075     begin->second.container = Engines::Container::_duplicate(container);
01076   }
01077 }
01078