diff --git a/src/Kernel/IJK/Framework/LecFicDistribue_sansnum.cpp b/src/Kernel/IJK/Framework/LecFicDistribue_sansnum.cpp index 9879b03de9..18d173fff8 100644 --- a/src/Kernel/IJK/Framework/LecFicDistribue_sansnum.cpp +++ b/src/Kernel/IJK/Framework/LecFicDistribue_sansnum.cpp @@ -1,5 +1,5 @@ /**************************************************************************** -* Copyright (c) 2025, CEA +* Copyright (c) 2026, CEA * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -19,7 +19,7 @@ LecFicDistribue_sansnum::LecFicDistribue_sansnum(int) { - bin_=0; + set_bin(false); } LecFicDistribue_sansnum::LecFicDistribue_sansnum():EFichier() {} diff --git a/src/Kernel/Utilitaires/EChaine.cpp b/src/Kernel/Utilitaires/EChaine.cpp index 6797f287cb..274733b3f1 100644 --- a/src/Kernel/Utilitaires/EChaine.cpp +++ b/src/Kernel/Utilitaires/EChaine.cpp @@ -1,5 +1,5 @@ /**************************************************************************** -* Copyright (c) 2022, CEA +* Copyright (c) 2026, CEA * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -35,6 +35,6 @@ void EChaine::init(const char *str) if (istrstream_) delete istrstream_; istrstream_ = new istringstream(str); // a copy of str is taken - set_istream(istrstream_); + attach(*istrstream_); } diff --git a/src/Kernel/Utilitaires/EChaine.h b/src/Kernel/Utilitaires/EChaine.h index 4524bae409..eba7ca3488 100644 --- a/src/Kernel/Utilitaires/EChaine.h +++ b/src/Kernel/Utilitaires/EChaine.h @@ -1,5 +1,5 @@ /**************************************************************************** -* Copyright (c) 2022, CEA +* Copyright (c) 2026, CEA * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -19,11 +19,11 @@ #include #include using std::istringstream; -/*! @brief An input stream whose source is a character string. +/*! @brief Une entree dont la source est une chaine de caracteres. * - * The constructor creates its own copy of the string, so that - * the original string can be modified afterwards without modifying - * the EChaine. + * Le constructeur cree sa propre copie de la chaine, de sorte + * que la chaine d'origine peut etre modifiee ensuite sans modifier + * la EChaine. * */ diff --git a/src/Kernel/Utilitaires/EChaineJDD.cpp b/src/Kernel/Utilitaires/EChaineJDD.cpp index 759be37688..4125e3730b 100644 --- a/src/Kernel/Utilitaires/EChaineJDD.cpp +++ b/src/Kernel/Utilitaires/EChaineJDD.cpp @@ -30,17 +30,21 @@ EChaineJDD::EChaineJDD(const char* str) : init(str); } -EChaineJDD::~EChaineJDD() { } +EChaineJDD::~EChaineJDD() { + if (istrstream_) + delete istrstream_; +} void EChaineJDD::init(const char *str) { if (istrstream_) delete istrstream_; istrstream_ = new istringstream(str); // a copy of str is taken - set_istream(istrstream_); + attach(*istrstream_); } -Entree& EChaineJDD::operator>>(int& ob) { return operator_template(ob); } +/* +Entree& EChaineJDD::operator>>(True_int& ob) { return operator_template(ob); } Entree& EChaineJDD::operator>>(double& ob) { return operator_template(ob); } int EChaineJDD::get(char *ob, std::streamsize bufsize) @@ -54,3 +58,4 @@ int EChaineJDD::get(char *ob, std::streamsize bufsize) int ret = Entree::get(ob,bufsize); return ret; } +*/ diff --git a/src/Kernel/Utilitaires/EChaineJDD.h b/src/Kernel/Utilitaires/EChaineJDD.h index ed92fc2843..7f23496450 100644 --- a/src/Kernel/Utilitaires/EChaineJDD.h +++ b/src/Kernel/Utilitaires/EChaineJDD.h @@ -16,6 +16,9 @@ #ifndef EChaineJDD_included #define EChaineJDD_included +#include + +#include #include #include using std::istringstream; @@ -34,11 +37,18 @@ class EChaineJDD : public Entree ~EChaineJDD() override; void init(const char *str); + + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wextra" + EChaineJDD(const EChaineJDD& other): Input(dynamic_cast(other)) {} + EChaineJDD(EChaineJDD& other): Input(dynamic_cast(other)) {} + #pragma GCC diagnostic pop + using Entree::operator>>; using Entree::get; - Entree& operator>>(int& ob) override; - Entree& operator>>(double& ob) override; - int get(char *ob, std::streamsize bufsize) override; + //Entree& operator>>(True_int& ob) override; + //Entree& operator>>(double& ob) override; + //int get(char *ob, std::streamsize bufsize) override; void set_track_lines(bool b) { track_lines_ = b ;} diff --git a/src/Kernel/Utilitaires/EFichier.cpp b/src/Kernel/Utilitaires/EFichier.cpp index 08a5f40f1b..b034bd04a0 100644 --- a/src/Kernel/Utilitaires/EFichier.cpp +++ b/src/Kernel/Utilitaires/EFichier.cpp @@ -1,5 +1,5 @@ /**************************************************************************** -* Copyright (c) 2023, CEA +* Copyright (c) 2026, CEA * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -13,11 +13,12 @@ * *****************************************************************************/ +#include #include Implemente_instanciable(EFichier,"EFichier",Entree_Fichier_base); -EFichier::EFichier(const char* name,IOS_OPEN_MODE mode) :Entree_Fichier_base(name,mode) +EFichier::EFichier(const char* name,IOS_OPEN_MODE mode_) :Entree_Fichier_base(name,mode_) { if (Process::me()>1) { diff --git a/src/Kernel/Utilitaires/EFichier.h b/src/Kernel/Utilitaires/EFichier.h index f215081b31..afaea701bd 100644 --- a/src/Kernel/Utilitaires/EFichier.h +++ b/src/Kernel/Utilitaires/EFichier.h @@ -1,5 +1,5 @@ /**************************************************************************** -* Copyright (c) 2022, CEA +* Copyright (c) 2026, CEA * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -17,19 +17,34 @@ #define EFichier_included +#include #include +#include -/*! @brief File for reading. This class is to the C++ ifstream class what the Entree class is to the +/*! @brief Fichier en lecture Cette classe est a la classe C++ ifstream ce que la classe Entree est a la * - * C++ istream class. It virtually redefines the read operators for a file. + * classe C++ istream. Elle redefinit de facon virtuelle les operateurs de lecture dans un fichier. * */ class EFichier : public Entree_Fichier_base { + Declare_instanciable(EFichier); + public: - EFichier(const char* name,IOS_OPEN_MODE mode=ios::in); + + using Entree_Fichier_base::Entree_Fichier_base; + using Input::operator>>; + + EFichier(const char* name,IOS_OPEN_MODE mode=std::ios::in); + + + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wextra" + EFichier(const EFichier& other): Entree_Fichier_base(dynamic_cast(other)) {} + EFichier(EFichier& other): Entree_Fichier_base(dynamic_cast(other)) {} + #pragma GCC diagnostic pop }; #endif diff --git a/src/Kernel/Utilitaires/EFichierBin.h b/src/Kernel/Utilitaires/EFichierBin.h index 4b20427f7f..a14b913c59 100644 --- a/src/Kernel/Utilitaires/EFichierBin.h +++ b/src/Kernel/Utilitaires/EFichierBin.h @@ -1,5 +1,5 @@ /**************************************************************************** -* Copyright (c) 2022, CEA +* Copyright (c) 2026, CEA * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -21,7 +21,7 @@ #include #include -/*! @brief Reading from a file of objects written in binary format. +/*! @brief Lecture dans un fichier d'objets ecrits au format binaire * * @sa SFichierBin EFichier */ @@ -34,17 +34,23 @@ class EFichierBin : public EFichier { set_bin(1); }; - EFichierBin(const char* name,IOS_OPEN_MODE mode=ios::in) - { - ifstream_=0; + EFichierBin(const char* name,IOS_OPEN_MODE mode_=ios::in) { + // do not use the EFichier opener because it is limited to serial cases set_bin(1); - ouvrir(name,mode); - if(ifstream_->fail()) + ouvrir(name,mode_); + if(fail()) { Cerr << "Error while opening the file " << name << finl; Process::exit(); } - }; + } + + + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wextra" + EFichierBin(const EFichierBin& other): EFichier(dynamic_cast(other)) {} + EFichierBin(EFichierBin& other): EFichier(dynamic_cast(other)) {} + #pragma GCC diagnostic pop }; diff --git a/src/Kernel/Utilitaires/Entree.cpp b/src/Kernel/Utilitaires/Entree.cpp index 3130c04644..f75cfd1bcf 100644 --- a/src/Kernel/Utilitaires/Entree.cpp +++ b/src/Kernel/Utilitaires/Entree.cpp @@ -13,142 +13,46 @@ * *****************************************************************************/ +#include + #include #include #include -#include -#include - -using std::ifstream; - -Entree::Entree() : AbstractIO(), - error_action_(ERROR_CONTINUE), - diffuse_(true), - istream_(nullptr) -{ -} - -Entree::Entree(istream& is) : Entree() -{ - istream_ = new istream(is.rdbuf()); -} - -Entree::Entree(const Entree& is) : Entree() -{ - istream_ = new istream(is.get_istream().rdbuf()); -} - -istream& Entree::get_istream() -{ - return *istream_; -} - -const istream& Entree::get_istream() const -{ - return *istream_; -} -void Entree::set_istream(istream* is) -{ - istream_ = is; -} -Entree& Entree::operator >>(Entree& (*f)(Entree&)) -{ - (*f)(*this); - return *this; -} -Entree& Entree::operator >>(istream& (*f)(istream&)) -{ - (*f)(*istream_); - return *this; -} -Entree& Entree::operator >>(ios& (*f)(ios&)) -{ - (*f)(*istream_); - return *this; -} - -// Assignment operators -Entree& Entree::operator=(istream& is) -{ - if(istream_) - delete istream_; - istream_ = new istream(is.rdbuf()); - return *this; -} - -Entree& Entree::operator=(Entree& is) -{ - if(istream_) - delete istream_; - istream_ = new istream(is.get_istream().rdbuf()); - return *this; -} - -/*! @brief Reads a string from ostream_. bufsize is the size of the buffer allocated for ob (including - * - * the final null character). - * The string always contains a null character even on failure. - * The method returns 1 if reading is successful, 0 otherwise. - * If the buffer is too small, we currently call exit(), but - * in the future we could test: if strlen(ob)==bufsize-1, then - * call lire() again until the end is reached. If the next lire() - * returns a string of length zero, it means the string length was - * exactly bufsize-1. - * Warning: the behaviour differs between binary and ASCII mode. - * In binary mode, the string is read until the next '\0'. - * In ASCII mode, the string is read until the next separator (space, tab, newline). - * - */ -int Entree::get(char* ob, std::streamsize bufsize) +int Entree::jumpOfLines() { - assert(istream_!=0); - assert(bufsize > 0); - ob[bufsize-1] = 1; - if(bin_) - { - // In binary mode, read until the next null character - // (including spaces, newlines, etc.) - std::streamsize i; - for (i = 0; i < bufsize-1; i++) - { - (*istream_).read(ob+i, sizeof(char)); - if (!error_handle(istream_->fail())) - ob[i] = 0; - if (ob[i] == 0) - break; - } - ob[i] = 0; - } - else + if(rdbuf() != nullptr) { - // C++20 solution: use std::string then copy - std::string temp; - (*istream_) >> temp; - if (!error_handle(istream_->fail())) - { - ob[0] = 0; - } - else + int jol = 0; + char tmp=(char)this->peek(); + while(isspace(tmp)) //tmp=='\n') { - std::streamsize len = std::min(static_cast(temp.size()), bufsize - 1); - std::memcpy(ob, temp.c_str(), len); - ob[len] = '\0'; + if(tmp=='\n') + jol++; + std::istream::get(tmp); + tmp=(char)this->peek(); } + return jol; } - if (ob[bufsize-1] == 0) - { - // Note Benoit Mathieu: - // If the buffer was filled to the end, it is probably too small. - // Continuing to read is dangerous because in ASCII mode we cannot know - // whether the string was read exactly (which would be fine) or whether - // it was not fully read as an int. Thorough testing of the STL would be - // needed, and the result likely depends on the implementation. Therefore, - // if the buffer is full, we abort the code. - Cerr << "Error in Entree::lire(char* ob, int bufsize) : buffer too small" << finl; - Process::exit(); - } - return (!istream_->fail()); + return -1; +} + +int is_a_binary_file(Nom& filename) +{ + // On parcourt les 1000 premiers octets + // Detection tres imparfaite donc limite + // aux fichiers geom de TRUST + int n=0; + int c; + std::ifstream fic(filename.getChar()); + // Si on rencontre un caractere ASCII>127 + // alors le fichier est de type binaire + while((c = fic.get()) != EOF && n++<1000) + if ((c>127)||(c<9)) + return 1; + // GF sous windows les caracteres binaire sont surtout <9 + // else printf("ici %d %c \n",c,c); + return 0; } void error_convert(const char * s, const char * type) @@ -157,14 +61,14 @@ void error_convert(const char * s, const char * type) Process::exit(); } -/*! @brief Conversion method. +/*! @brief methode de conversion * */ void convert_to(const char *s, int& ob) { errno = 0; char * errorptr = 0; - ob = (int)strtol(s, &errorptr, 0 /* base 10 by default */); + ob = (int)strtol(s, &errorptr, 0 /* base 10 par defaut */); if (errno || *errorptr != 0) error_convert(s,"int"); } @@ -172,7 +76,7 @@ void convert_to(const char *s, long& ob) { errno = 0; char * errorptr = 0; - ob = strtol(s, &errorptr, 0 /* base 10 by default */); + ob = strtol(s, &errorptr, 0 /* base 10 par defaut */); if (errno || *errorptr != 0) error_convert(s,"long"); } @@ -181,12 +85,12 @@ void convert_to(const char *s, long long& ob) errno = 0; char * errorptr = 0; #ifdef HPPA_11 /* NO_PROCESS */ - ob = strtol(s, &errorptr, 0 /* base 10 by default */); + ob = strtol(s, &errorptr, 0 /* base 10 par defaut */); #else /* NO_PROCESS */ #ifdef MICROSOFT - ob = _strtoi64(s, &errorptr, 0 /* base 10 by default */); + ob = _strtoi64(s, &errorptr, 0 /* base 10 par defaut */); #else - ob = strtoll(s, &errorptr, 0 /* base 10 by default */); + ob = strtoll(s, &errorptr, 0 /* base 10 par defaut */); #endif #endif /* NO_PROCESS */ if (errno || *errorptr != 0) error_convert(s,"long long"); @@ -208,312 +112,49 @@ void convert_to(const char *s, double& ob) if (errno || *errorptr != 0) error_convert(s,"double"); } -// Virtual method to read an int or a real number. In this base class, reading is done from istream using read() (if is_bin() == 1) -// or using operator>>() (if is_bin() == 0). If the check_types flag is set, convert_to() is called to verify the types of the objects read. -// In that case, for ints, the formats 123 (decimal), 0xa345 (hexadecimal) and others are accepted. -// If an error occurs, error_handle_() is called. -// Note for developers of derived classes: the implementation of this method must always go through error_handle_(). -Entree& Entree::operator>>(double& ob) { return operator_template(ob); } - -// Virtual method to read an array of ints or reals (the array must have the correct size: no verification is possible) -int Entree::get(double * ob, std::streamsize n) { return get_template(ob,n); } - -Entree& Entree::operator>>(int& ob) { return operator_template(ob); } -int Entree::get(int * ob, std::streamsize n) { return get_template(ob,n); } - -Entree& Entree::operator>>(float& ob) { return operator_template(ob); } -int Entree::get(float * ob, std::streamsize n) { return get_template(ob,n); } - -Entree& Entree::operator>>(long& ob) { return operator_template(ob); } -int Entree::get(long * ob, std::streamsize n) { return get_template(ob,n); } - -Entree& Entree::operator>>(long long& ob) { return operator_template(ob); } -int Entree::get(long long * ob, std::streamsize n) { return get_template(ob,n); } - -// Yes this is awful. We will get rid of this along with Nom. -Entree& Entree::operator>>(std::string& ob) { Nom tmp; *this >> tmp; ob = tmp.getString(); return *this;} - -Entree& Entree::operator >>(Objet_U& ob) { return ob.readOn(*this); } - -int Entree::jumpOfLines() -{ - if(istream_) - { - int jol = 0; - char tmp=(char)istream_->peek(); - while(isspace(tmp)) //tmp=='\n') - { - if(tmp=='\n') - jol++; - istream_->get(tmp); - tmp=(char)istream_->peek(); - } - return jol; - } - return -1; -} - -int Entree::eof() -{ - if(istream_) - return (istream_->eof()); - else - return -1; -} -int Entree::fail() -{ - if(istream_) - return (istream_->fail()); - else - return -1; -} -int Entree::good() -{ - if(istream_) - return (istream_->good()); - else - return -1; -} -Entree::~Entree() -{ -#ifndef TRUST_USE_UVM // ToDo bug ? - if(istream_) - delete istream_; -#endif - istream_=nullptr; -} - -/*! @brief Changes the file write mode. - * - * This method can be called at any time. - * - */ -void Entree::set_bin(bool bin) -{ - bin_ = bin; - if (istream_) - { - Cerr<<"Error you cant change binary format after open "<> i; // i contains 123 - * check_types(1); - * is >> i; // Error: reads the string 123.456 and tries to convert it to int - * See operator>>(int &) - * - */ -void Entree::set_check_types(bool flag) -{ - check_types_ = flag; -} - - -/*! @brief This function is called by operator>>, get, get_nom, ouvrir, fermer, lire, etc. - * - * .. on failure (when fail() is set). - * It returns 0 if an error occurred (go through error_handle() which - * handles inline the case where there is no error), and 1 if there is no error. - * (for coding convenience, one writes "return error_handle(fail());" - * It can be configured to: - * - return "0" on error and continue code execution - * (case of legacy code that does not handle exceptions but periodically - * tests the fail() flag) - * In this case, operator>> methods continue execution even on failure, - * and the content of the read variables is undefined! - * - call Process::exit() (case of a code section where no error handling - * is desired and everything is assumed to succeed) - * - throw an exception (allows rigorous error handling and optimal - * user feedback depending on context) - * - * @sa set_error_action() - * - */ -int Entree::error_handle_(int fail_flag) -{ - if (!fail_flag) - return 1; - - switch(error_action_) - { - case ERROR_CONTINUE: - break; - case ERROR_EXIT: - Cerr << "Error while reading in Entree object. Exiting.\n"; - if (istream_) - { - // We do not use Entree::eof() because in the case of a Lec_Fic_Dif, - // eof() is parallel and could block. - if (get_istream().eof()) - Cerr << " End of file reached." << finl; - else - Cerr << " IO error (not an EOF error)." << finl; - } - Process::exit(); - break; - case ERROR_EXCEPTION: - Entree_Sortie_Error e; - throw (e); - } - return 0; -} - -/*! @brief Returns error_action_ for this input (allows modifying it and restoring the previous value afterwards). +/*! @brief renvoie error_action_ pour cette entree (permet de la modifier et de restaurer ensuite la valeur anterieure) * */ Entree::Error_Action Entree::get_error_action() { - return error_action_; + switch (error_mode) { + case ErrorMode::Continue: return ERROR_CONTINUE; + case ErrorMode::Exit: return ERROR_EXIT; + case ErrorMode::Throw: return ERROR_EXCEPTION; + default: + Cerr << "Invalid mode." << finl; + Process::exit(); + return ERROR_CONTINUE; + } } -/*! @brief Changes the error behaviour of the input; see error_handle_() and get_error_action(). +/*! @brief Change le comportement en cas d'erreur de l'entree, voir error_handle_() et get_error_action() * */ void Entree::set_error_action(Entree::Error_Action action) { - error_action_ = action; + switch (action) { + case ERROR_CONTINUE: set_error_mode(ErrorMode::Continue); break; + case ERROR_EXIT: set_error_mode(ErrorMode::Exit); break; + case ERROR_EXCEPTION: set_error_mode(ErrorMode::Throw); break; + } } -// Detects whether a file with name filename -// is of binary type -int is_a_binary_file(Nom& filename) -{ - // Scan the first 1000 bytes - // Very imperfect detection, therefore limited - // to TRUST geometry files - int n=0; - int c; - std::ifstream fic(filename.getChar()); - // If a character with ASCII value > 127 is encountered, - // the file is of binary type - while((c = fic.get()) != EOF && n++<1000) - if ((c>127)||(c<9)) - return 1; - // GF on windows, binary characters are mostly <9 - // else printf("ici %d %c \n",c,c); - return 0; +void Entree::set_istream(std::istream* stream_pointer) { + if (stream_pointer == nullptr) + detach(); + else + attach(*stream_pointer); } -/*! @brief Sets the diffuse flag for this input stream. - * - * This virtual method does nothing in the base class; see override in Lec_Diffuse_base. - * @param diffuse Whether to diffuse data to other processes. - */ -void Entree::set_diffuse(bool diffuse) -{ - // virtual method does nothing ; cf override in Lec_Diffuse_base - diffuse_ = true; +void Entree::set_istream(std::istream& stream) { + attach(stream); } - -template -int Entree::get_template(_TYPE_ *ob, std::streamsize n) -{ - assert(istream_!=0); - assert(n >= 0); - if (bin_) - { - if (this->must_convert<_TYPE_>()) - { - // Need to cast, use '>>' operator - see doc in operator_template<> - for (int i = 0; i < n; i++) (*this) >> ob[i]; - } - else - { - // In binary, optimized block reading: - char *ptr = (char*) ob; - std::streamsize sz = sizeof(_TYPE_); - sz *= n; - istream_->read(ptr, sz); - error_handle(istream_->fail()); - } - } - else - { - // In ASCII mode: use operator>> to verify conversions - // Warning: we call the one from this class, not from a derived class - for (int i = 0; i < n; i++) Entree::operator>>(ob[i]); - } - return (!istream_->fail()); +const std::istream& Entree::get_istream() const { + return *this; } -// Explicit instanciations: -template int Entree::get_template(int *ob, std::streamsize n); -template int Entree::get_template(long *ob, std::streamsize n); -template int Entree::get_template(long long *ob, std::streamsize n); -template int Entree::get_template(double *ob, std::streamsize n); -template int Entree::get_template(float *ob, std::streamsize n); - - -template -Entree& Entree::operator_template(_TYPE_& ob) -{ - assert(istream_!=0); - if (bin_) - { - // Do we need to worry about 32b / 64b conversion? - if (this->must_convert<_TYPE_>()) - { - // Yes, then two cases: - // Case 1: requested _TYPE_ is 32b and file is 64b -> only OK if read value is actually within the 32b range - if (is_64b_) - { - std::int64_t pr; - char *ptr = (char*) ≺ - istream_->read(ptr, sizeof(std::int64_t)); - if (pr > std::numeric_limits::max()) - { - Cerr << "Can't read this int64 binary file with an int32 binary: values too big, overflow!!" << finl; - throw; - } - // It's ok, we passed the check above, we can safely downcast: - ob = static_cast<_TYPE_>(pr); - } - // Case 2: requested _TYPE_ is 64b and file is 32b -> this is always OK, just need int to make sure we really read a 32b value - else - { - int pr; - char * ptr = (char*) ≺ - istream_->read(ptr, sizeof(int)); - ob=(_TYPE_)pr; - } - } - else // File has the same bit-ness as binary, or we are trying to read a non-problematic type - all OK. - { - char *ptr = (char*) &ob; - istream_->read(ptr, sizeof(_TYPE_)); - error_handle(istream_->fail()); - } - } - else // Not binary, ascii format - { - if (check_types_) - { - char buffer[100]; - int ok = Entree::get(buffer, 100); // Must call get() from this class, not a derived one - if (ok) - convert_to(buffer, ob); - } - else - { - (*istream_) >> ob; - error_handle(istream_->fail()); - } - } - return *this; +std::istream& Entree::get_istream() { + return *this; } - -// Explicit instanciations: -template Entree& Entree::operator_template(int& ob); -template Entree& Entree::operator_template(long& ob); -template Entree& Entree::operator_template(long long& ob); -template Entree& Entree::operator_template(double& ob); -template Entree& Entree::operator_template(float& ob); - diff --git a/src/Kernel/Utilitaires/Entree.h b/src/Kernel/Utilitaires/Entree.h index 5c2e9397d2..997756917b 100644 --- a/src/Kernel/Utilitaires/Entree.h +++ b/src/Kernel/Utilitaires/Entree.h @@ -16,113 +16,68 @@ #ifndef Entree_included #define Entree_included -#include -#include -#include -#include -#include -#include // For EOF on GNU >= 4.4 -#include // for LIBLATAFILTER int64 -#include // For INT32_MAX on GNU >= 13 - -using std::istream; -using std::ios; - -template class TRUST_Ref; -class TRUST_Ref_Objet_U; +#include + class Objet_U; -class Nom; -/*! @brief Class defining operators and methods for all reading operation in an input flow (file, keyboard - * communication buffer, etc.) - * - * @sa Sortie - */ -class Entree: public AbstractIO -{ -public: - // Constructors - Entree(); - Entree(istream& is); - Entree(const Entree& is); - virtual ~Entree(); - - void set_bin(bool bin) override; - - // Assignment operators - Entree& operator=(istream& is); - Entree& operator=(Entree& is); - - virtual istream& get_istream(); - virtual const istream& get_istream() const; - void set_istream(istream *is); - - Entree& operator >>(Entree& (*f)(Entree&)); - Entree& operator >>(istream& (*f)(istream&)); - Entree& operator >>(ios& (*f)(ios&)); - - template - Entree& operator>>(const TRUST_Ref& ) { std::cerr << __func__ << " :: SHOULD NOT BE CALLED ! Use -> !! " << std::endl ; throw; } - - Entree& operator>>(const TRUST_Ref_Objet_U& ) { std::cerr << __func__ << " :: SHOULD NOT BE CALLED ! Use -> !! " << std::endl ; throw; } - - virtual Entree& operator>>(int& ob); - virtual Entree& operator>>(long& ob); - virtual Entree& operator>>(long long& ob); - virtual Entree& operator>>(float& ob); - virtual Entree& operator>>(double& ob); - virtual Entree& operator>>(std::string& ob); - - // final - virtual Entree& operator>>(Objet_U& ob) final; - - virtual int get(int *ob, std::streamsize n); - virtual int get(long *ob, std::streamsize n); - virtual int get(long long *ob, std::streamsize n); - virtual int get(float *ob, std::streamsize n); - virtual int get(double *ob, std::streamsize n); - - virtual int get(char *buf, std::streamsize bufsize); - - virtual int eof(); - virtual int jumpOfLines(); - virtual int fail(); - virtual int good(); - virtual void set_check_types(bool flag); - bool check_types() const { return check_types_; } - enum Error_Action { ERROR_EXIT, ERROR_CONTINUE, ERROR_EXCEPTION }; - virtual void set_error_action(Error_Action); - Error_Action get_error_action(); - - inline operator istream& () { return get_istream(); } - inline istream& putback(char ch) { return get_istream().putback(ch); } - inline bool get_diffuse() { return diffuse_; } - - virtual void set_diffuse(bool diffuse); - -protected: - // Inline method to handle the trivial case quickly. Otherwise, calls the virtual method error_handle_(). - inline int error_handle(int fail_flag) - { - if (!fail_flag) return 1; - else return error_handle_(fail_flag); - } - - virtual int error_handle_(int fail_flag); - bool check_types_ = false; - Error_Action error_action_; - bool diffuse_; // By default true, but some child classes (e.g. LecFicDiffuse) can set it temporarily to false to not diffuse to other processes - -private: - istream *istream_; - - template - int get_template(_TYPE_ *ob, std::streamsize n); - - template - Entree& operator_template(_TYPE_& ob); +class Entree: virtual public Input { + public: + using Input::Input; + + Entree(const Input& other): Input(other) {} + Entree(Input& other): Input(other) {} + + + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wextra" + + Entree(const Entree& other) : Input(other.rdbuf()) {} + Entree(Entree& other) : Input(other.rdbuf()) {} + + #pragma GCC diagnostic pop + + // forward operator>> to Input implementation (need to do one explicitly for lvalues) + Entree& operator>>(Objet_U& ob) override { + Input::operator>>(ob); + return *this; + } + + template + Entree& operator>>(Type& value) & { + Input::operator>>(value); + return *this; + } + + template + Entree& operator>>(Type&) && = delete; + + void set_check_types(int) {} + + virtual void set_bin(int value) { set_bin(!!value); } + virtual void set_bin(bool value) { set_binary(value); } + virtual void set_64b(bool value) { set_64_bits(value); } + virtual void set_diffuse(bool value) { diffuse_ = true; } // true by default and cannot be change + virtual bool get_diffuse() const { return diffuse_; } + + void set_istream(std::istream* stream_pointer); + void set_istream(std::istream& stream); + virtual const std::istream& get_istream() const; + virtual std::istream& get_istream(); + virtual int jumpOfLines(); + + public: + + enum Error_Action { ERROR_EXIT, ERROR_CONTINUE, ERROR_EXCEPTION }; + virtual void set_error_action(Error_Action); + Error_Action get_error_action(); + + protected: + + bool diffuse_ = true; // this flag as no real meaning in TRUST, but some classe use it }; +// for storing opened binary files +class Nom; int is_a_binary_file(Nom&); void convert_to(const char *s, int& ob); @@ -131,9 +86,4 @@ void convert_to(const char *s, long long& ob); void convert_to(const char *s, float& ob); void convert_to(const char *s, double& ob); -// Class returned by Entree when an exception is raised on error -class Entree_Sortie_Error -{ -}; - #endif diff --git a/src/Kernel/Utilitaires/Entree_Brute.cpp b/src/Kernel/Utilitaires/Entree_Brute.cpp index 52146513e3..e6cb7306ac 100644 --- a/src/Kernel/Utilitaires/Entree_Brute.cpp +++ b/src/Kernel/Utilitaires/Entree_Brute.cpp @@ -1,5 +1,5 @@ /**************************************************************************** -* Copyright (c) 2024, CEA +* Copyright (c) 2026, CEA * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -45,22 +45,14 @@ void Entree_Brute::set_bin(bool bin) void Entree_Brute::set_data(const char * data, unsigned sz) { - if(data_) + if (istrstream_) { - // For now forbid multiple calls ... could try deleting data_ - //Cerr << "Entree_Brute::set_data(): Multiple calls forbidden! " << finl; - //Process::exit(-1); - delete[] data_; - if (istrstream_) - delete istrstream_; - istrstream_ = new istringstream(); - set_istream(istrstream_); + delete istrstream_; } - const std::istream& iss = get_istream(); - std::streambuf * sb = iss.rdbuf(); + istrstream_ = new std::istringstream( + std::string(data, sz) + ); - data_ = new char[sz]; - std::copy(data, data+sz, data_); - sb->pubsetbuf(data_, sz); + set_istream(istrstream_); } diff --git a/src/Kernel/Utilitaires/Entree_Brute.h b/src/Kernel/Utilitaires/Entree_Brute.h index 5d4a78d0c6..8337657b5d 100644 --- a/src/Kernel/Utilitaires/Entree_Brute.h +++ b/src/Kernel/Utilitaires/Entree_Brute.h @@ -1,5 +1,5 @@ /**************************************************************************** -* Copyright (c) 2024, CEA +* Copyright (c) 2026, CEA * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -32,6 +32,7 @@ class Entree_Brute : public Entree public: Entree_Brute(); ~Entree_Brute() override; + using Entree::set_bin; void set_bin(bool bin) override; void set_data(const char * data, unsigned sz); diff --git a/src/Kernel/Utilitaires/Entree_Fichier_base.cpp b/src/Kernel/Utilitaires/Entree_Fichier_base.cpp index abb0f135e4..da6154153b 100644 --- a/src/Kernel/Utilitaires/Entree_Fichier_base.cpp +++ b/src/Kernel/Utilitaires/Entree_Fichier_base.cpp @@ -16,7 +16,7 @@ #include #include #include -#include + #ifndef LATATOOLS #include #endif @@ -32,132 +32,57 @@ Sortie& Entree_Fichier_base::printOn(Sortie& s) const { throw; } -Entree_Fichier_base::Entree_Fichier_base() -{ - ifstream_=0; -} -bool fileExists(const char* name) -{ - struct stat buffer; - if (stat(name, &buffer) == 0 && S_ISREG(buffer.st_mode)) - return true; - else - return false; -} -Entree_Fichier_base::Entree_Fichier_base(const char* name,IOS_OPEN_MODE mode) -{ - ifstream_ = new ifstream(name, mode); - if(ifstream_->fail() || !fileExists(name)) - { - Cerr << "Error while opening the file " << name << finl; - Process::exit(); - } - set_istream(ifstream_); -} -ifstream& Entree_Fichier_base::get_ifstream() +std::ifstream& Entree_Fichier_base::get_ifstream() { - return *ifstream_; + return *this; } Entree_Fichier_base::~Entree_Fichier_base() { - Entree_Fichier_base::close(); + //Entree_Fichier_base::close(); } -int Entree_Fichier_base::ouvrir(const char* name, IOS_OPEN_MODE mode) +int Entree_Fichier_base::ouvrir(const char* name, IOS_OPEN_MODE mode_) { - if(ifstream_) - delete ifstream_; - IOS_OPEN_MODE ios_mod=mode; - if (bin_) - { - ios_mod=ios_mod|ios::binary; - } - ifstream_ = new ifstream(name,ios_mod); - int ok = ifstream_->good() && fileExists(name); - set_istream(ifstream_); + //if (is_open()) { + close(); + clear(); + //} - if (bin_) - { + IOS_OPEN_MODE ios_mod = mode_; + + if (is_bin) { + ios_mod=ios_mod|ios::binary; + } + + open(name, ios_mod); + + int ok = good(); + + if (is_bin) { Nom test; (*this) >> test; if (test == "INT64") { - is_64b_ = true; + set_64_bits(true); #ifndef INT_is_64_ Cerr<<"Opening " <good() && fileExists(name); - set_istream(ifstream_); + close(); + clear(); + open(name, ios_mod); + ok = good(); } } return ok; } - -void Entree_Fichier_base::close() -{ - if(ifstream_) - { - ifstream_->close(); - // do not destroy ifstream here, it will be done by Entree - // delete ifstream_; - } -} - -int Entree_Fichier_base::eof() -{ - if(ifstream_) - return ifstream_->eof(); - else - return -1; -} - -int Entree_Fichier_base::fail() -{ - if(ifstream_) - return ifstream_->fail(); - else - return -1; -} - -int Entree_Fichier_base::good() -{ - if(ifstream_) - return ifstream_->good(); - else - return -1; -} - -void Entree_Fichier_base::precision(int pre) -{ - if(ifstream_) - ifstream_->precision(pre); -} - -void Entree_Fichier_base::setf(IOS_FORMAT code) -{ - if(ifstream_) - ifstream_->setf(code); -} - -/*! @brief Return True if the file can be opened for reading, false otherwise. - * - */ -bool Entree_Fichier_base::Can_be_read(const char * name) -{ - std::ifstream ifs(name,ios::in); - return ifs.good(); -} - diff --git a/src/Kernel/Utilitaires/Entree_Fichier_base.h b/src/Kernel/Utilitaires/Entree_Fichier_base.h index 670951bd06..334b60c1ba 100644 --- a/src/Kernel/Utilitaires/Entree_Fichier_base.h +++ b/src/Kernel/Utilitaires/Entree_Fichier_base.h @@ -1,5 +1,5 @@ /**************************************************************************** -* Copyright (c) 2022, CEA +* Copyright (c) 2026, CEA * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -17,43 +17,33 @@ #define Entree_Fichier_base_included -#include -#include -#include -using std::ifstream; -using std::ofstream; -using std::streampos; +#include -/*! @brief File for reading. This class is to the C++ ifstream class what the Entree class is to the - * - * C++ istream class. It virtually redefines the read operators for a file. - * - */ +class Entree_Fichier_base: virtual public Entree, public InputFile { -class Entree_Fichier_base : public Entree, public Objet_U -{ Declare_base_sans_constructeur(Entree_Fichier_base); -public: - Entree_Fichier_base(); - Entree_Fichier_base(const Entree_Fichier_base&) = default; - Entree_Fichier_base(const char* name,IOS_OPEN_MODE mode=ios::in); - ifstream& get_ifstream(); - void close(); - int eof() override; - int fail() override; - int good() override; - void precision(int pre); - void setf(IOS_FORMAT code); + public: + using Entree::Entree; + using InputFile::InputFile; + using Input::operator>>; - virtual int ouvrir(const char* name, IOS_OPEN_MODE mode=ios::in); - static bool Can_be_read(const char * name); + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wextra" + + Entree_Fichier_base(Entree_Fichier_base& other) { + Input::attach(static_cast(other)); + } + + Entree_Fichier_base(const Entree_Fichier_base& other) { + Input::attach(static_cast(const_cast(other))); + } -protected: - ifstream* ifstream_; + #pragma GCC diagnostic pop + + virtual int ouvrir(const char* name, IOS_OPEN_MODE mode=ios::in); -private: - Entree_Fichier_base& operator=(const Entree_Fichier_base&); // copy is forbidden + std::ifstream& get_ifstream(); }; #endif diff --git a/src/Kernel/Utilitaires/Entree_Sortie_Error.h b/src/Kernel/Utilitaires/Entree_Sortie_Error.h new file mode 100644 index 0000000000..f025872170 --- /dev/null +++ b/src/Kernel/Utilitaires/Entree_Sortie_Error.h @@ -0,0 +1,23 @@ +/**************************************************************************** +* Copyright (c) 2026, CEA +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: +* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. +* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. +* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +*****************************************************************************/ +#ifndef Entree_Sortie_Error_included +#define Entree_Sortie_Error_included + +// Classe renvoyee par Entree si une exception est levee lors d'une erreur +class Entree_Sortie_Error +{ +}; + +#endif diff --git a/src/Kernel/Utilitaires/Entree_complete.cpp b/src/Kernel/Utilitaires/Entree_complete.cpp index bf8ce5453c..a43820e109 100644 --- a/src/Kernel/Utilitaires/Entree_complete.cpp +++ b/src/Kernel/Utilitaires/Entree_complete.cpp @@ -14,114 +14,3 @@ *****************************************************************************/ #include -#include -#include -#include -#include - -Entree_complete::Entree_complete(const char* str_entree1, Entree& entree2) -{ - num_entree_ = 0; - str_size_ = (int)strlen(str_entree1); - chaine_str_.init(str_entree1); - Process::Journal() << "Construction of a Entree_complete with : " << str_entree1 << finl; - entree2_ = &entree2; - num_entree_ = 0; - Error_Action action = entree2.get_error_action(); - Entree::set_error_action(action); - chaine_str_.set_error_action(action); - int check_types_sa = entree2.check_types(); - Entree::set_check_types(check_types_sa); - chaine_str_.set_check_types(check_types_sa); -} - -Entree_complete::~Entree_complete() { entree2_ = 0; } - -Entree& Entree_complete::get_input() -{ - if (num_entree_ == 0) - { - int pos = (int)chaine_str_.get_istream().tellg(); - if (pos < str_size_ && pos >= 0) - return chaine_str_; - num_entree_ = 1; - } - return *entree2_; -} - -int Entree_complete::get(char* ob, std::streamsize bufsize) -{ - Entree& is = get_input(); - return is.get(ob, bufsize); -} - -Entree& Entree_complete::operator>>(int& ob) { return operator_template(ob); } -int Entree_complete::get(int * ob, std::streamsize n) { return get_template(ob,n); } - -Entree& Entree_complete::operator>>(long& ob) { return operator_template(ob); } -int Entree_complete::get(long * ob, std::streamsize n) { return get_template(ob,n); } - -Entree& Entree_complete::operator>>(long long& ob) { return operator_template(ob); } -int Entree_complete::get(long long * ob, std::streamsize n) { return get_template(ob,n); } - -Entree& Entree_complete::operator>>(float& ob) { return operator_template(ob); } -int Entree_complete::get(float * ob, std::streamsize n) { return get_template(ob,n); } - -Entree& Entree_complete::operator>>(double& ob) { return operator_template(ob); } -int Entree_complete::get(double * ob, std::streamsize n) { return get_template(ob,n); } - -int Entree_complete::eof() -{ - Entree& is = get_input(); - return is.eof(); -} - -int Entree_complete::fail() -{ - Entree& is = get_input(); - return is.fail(); -} - -int Entree_complete::good() -{ - Entree& is = get_input(); - return is.good(); -} - -/*! @brief Changing the type of input is forbidden. - * - * exit() - * - */ -void Entree_complete::set_bin(bool bin) -{ - if (bin) - { - Cerr << "Error in Entree_complete::set_bin(bool bin) : not supported" << finl; - Process::exit(); - } -} - -/*! @brief Sets the flag on both source inputs. Warning, the flag of entree2 is modified! - * - * See Entree::set_check_types() - * - */ -void Entree_complete::set_check_types(bool flag) -{ - Entree::set_check_types(flag); - chaine_str_.set_check_types(flag); - entree2_->set_check_types(flag); -} - -/*! @brief Sets the value on both source inputs. Warning, the value of entree2 is modified! - * - * See Entree::set_error_action() - * - */ -void Entree_complete::set_error_action(Error_Action action) -{ - Entree::set_error_action(action); - chaine_str_.set_error_action(action); - entree2_->set_error_action(action); -} diff --git a/src/Kernel/Utilitaires/Entree_complete.h b/src/Kernel/Utilitaires/Entree_complete.h index 694cdcd106..e75f6734df 100644 --- a/src/Kernel/Utilitaires/Entree_complete.h +++ b/src/Kernel/Utilitaires/Entree_complete.h @@ -16,80 +16,12 @@ #ifndef Entree_complete_included #define Entree_complete_included -#include +//#include -/*! @brief This class behaves like EChaine until the end of the string is reached. - * - * The remainder is read from entree2 passed as parameter. - * check_types() and error_action() are identical to those of entree2. - * - */ +#include -class Entree_complete: public Entree -{ -public: - Entree_complete(const char *str, Entree& entree2); - ~Entree_complete() override; - - using Entree::operator>>; - - Entree& operator>>(int& ob) override; - Entree& operator>>(long& ob) override; - Entree& operator>>(long long& ob) override; - Entree& operator>>(float& ob) override; - Entree& operator>>(double& ob) override; - - int get(int *ob, std::streamsize n) override; - int get(long *ob, std::streamsize n) override; - int get(long long*ob, std::streamsize n) override; - int get(float *ob, std::streamsize n) override; - int get(double *ob, std::streamsize n) override; - int get(char *buf, std::streamsize bufsize) override; - - int eof() override; - int fail() override; - int good() override; - - void set_bin(bool bin) override; - void set_error_action(Error_Action) override; - void set_check_types(bool flag) override; - -protected: - Entree& get_input(); - // If num_entree_ == 0, we are reading from chaine_str, otherwise from entree2_ - int num_entree_; - int str_size_; - EChaine chaine_str_; - // Reference to the second input (we do not own the pointed object) - Entree *entree2_; - -private: - template - int get_template(_TYPE_ *ob, std::streamsize n); - - template - Entree& operator_template(_TYPE_&ob); +class Entree_complete: public InputConcat { + using InputConcat::InputConcat; }; -template -int Entree_complete::get_template(_TYPE_ *ob, std::streamsize n) -{ - // Loop to allow the value array to span across both inputs: - for (std::streamsize i = 0; i < n; i++) - { - Entree& is = get_input(); - if (! is.get(ob+i, 1)) - return 0; - } - return 1; -} - -template -Entree& Entree_complete::operator_template(_TYPE_& ob) -{ - Entree& is = get_input(); - is >> ob; - return *this; -} - #endif /* Entree_complete_included */ diff --git a/src/Kernel/Utilitaires/Input.cpp b/src/Kernel/Utilitaires/Input.cpp new file mode 100644 index 0000000000..3369543078 --- /dev/null +++ b/src/Kernel/Utilitaires/Input.cpp @@ -0,0 +1,222 @@ +/**************************************************************************** +* Copyright (c) 2026, CEA +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: +* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. +* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. +* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +*****************************************************************************/ + +#include + +#include +#include +#include +#include + +#ifndef LATATOOLS +#include +#endif + +Input& Input::operator>>(Objet_U& ob) { + return ob.readOn(*this); +} + +#ifndef LATATOOLS +void Input::share(int& ok, char* array, std::streamsize size) { + assert(get_diffusion()); // this method call only make sens in diffusion mode + + assert(size < std::numeric_limits::max()); + + envoyer_broadcast(ok, 0); + + if (ok) + envoyer_broadcast_array(array, static_cast(size), 0); // send from processor 0 to other processors + + // broadcast stream state + share_state(); +} + +void Input::share_state() { + // get the state for the process + std::ios::iostate state = std::ios::goodbit; + if (Process::me() == 0) { + state = this->rdstate(); + } + + // broadcast stream state of process 0 + int state_int = static_cast(state); + envoyer_broadcast(state_int, 0); + + // apply state locally + this->clear(); + state = static_cast(state_int); + this->setstate(state); +} +#endif + +void Input::update_mode() { + if (is_bin) { + if (is_64_bits) + read_mode = Input::ReadMode::Bin64; + else + read_mode = Input::ReadMode::Bin32; + } else { + read_mode = Input::ReadMode::ASCII; + } +} + +void Input::set_binary(bool value) { + is_bin = value; + update_mode(); +} + +void Input::set_64_bits(bool value) { + is_64_bits = value; + update_mode(); +} + +void Input::set_diffusion(bool value) { + if (Process::nproc() > 1) { + if (value) { + if (Process::me() == 0) + communication_mode = CommunicationMode::Send; + else + communication_mode = CommunicationMode::Receive; + } else { + communication_mode = CommunicationMode::Isolated; + } + } else { // no need for diffusion operations + communication_mode = CommunicationMode::Isolated; + } +} + +bool Input::get_diffusion() const { + return communication_mode != CommunicationMode::Isolated; +} + +void Input::set_avoid_conversion(bool value) { + avoid_conversion = value; +} + +int Input::read_text(char* ob, std::streamsize bufsize) { + + assert(rdbuf() != 0); + assert(bufsize > 0); + ob[bufsize-1] = 1; + + + //std::cout << "read text start (bin: " << is_bin << ", size: " << bufsize << ")" << std::endl; + //ssize_t position = tellg(); + + if (is_bin) { + // En binaire, on lit jusqu'au prochain caractere 0 + // (on lit les espaces, retours a la ligne etc) + std::streamsize i; + for (i = 0; i < bufsize-1; i++) + { + (*this).read(ob+i, sizeof(char)); + //std::cout << "read " << i << ": " << ob << std::endl; + if (fail()) { + ob[i] = 0; + //std::cout << "fail" << std::endl; + } + if (ob[i] == 0) { + //std::cout << "eos, peak: " << std::string(1, char(this->peek())) << std::endl; + /* + if (i == 0) + Process::exit("Empty"); + */ + break; + } + } + ob[i] = 0; + } else { + // L'appel suivant permet a l'operateur>> de limiter le nombre + // de caracteres lus. On lira au maximum bufsize-1 caracteres. + std::istream& is = dynamic_cast(*this); + + is >> std::ws; // skip leading spaces + + std::streamsize i = 0; + for (; i < bufsize - 1; ++i) { + int c = is.peek(); + if (c == EOF || std::isspace(static_cast(c))) + break; + + ob[i] = static_cast(is.get()); // advance in the stream + } + ob[i] = '\0'; + + //is >> std::ws; // skip remaining spaces + + if (fail()) + ob[0] = 0; + } + + if (ob[bufsize-1] == 0) { + // Note Benoit Mathieu: + // Si on a rempli le buffer jusqu'au bout, c'est qu'il est probablement + // trop petit. Lire la suite est dangereux car en ascii on ne sait pas + // si on a pu lire pile poil la chaine (donc c'est ok), ou si la chaine + // n'a pas ete lue en int. Il faut tester tres serieusement la stl et + // ca depend sans doute de l'implementation. Donc, si le buffer est plein, + // on plante le code et tant pis. + Cerr << "Error in Entree::lire(char* ob, int bufsize) : buffer too small" << finl; + Process::exit(); + } + + //std::cout << "read '" << ob << "' at " << position << std::endl; + + return error_handler(); +} + +void Input::set_error_mode(ErrorMode error_mode_) { + error_mode = error_mode_; +} + +int Input::error_handler() { + // if fail bit not set, its okay + if (!fail()) + return 1; + + switch (error_mode) { + case ErrorMode::Continue: break; // do nothing + case ErrorMode::Exit: + Cerr << "Error while reading in Entree object. Exiting.\n"; + if (eof()) + Cerr << " End of file reached." << finl; + else + Cerr << " IO error (not an EOF error)." << finl; + + Process::exit(); + break; + case ErrorMode::Throw: + if (eof()) { + InputOutputException e("End of file reached."); + throw(e); + } else { + InputOutputException e("Unknown error."); + throw(e); + } + break; + } + return 0; +} + + +void Input::copy_modes(const Input& other) { + read_mode = other.read_mode; + error_mode = other.error_mode; + communication_mode = other.communication_mode; + + is_bin = other.is_bin; + is_64_bits = other.is_64_bits; + avoid_conversion = other.avoid_conversion; +} diff --git a/src/Kernel/Utilitaires/Input.h b/src/Kernel/Utilitaires/Input.h new file mode 100644 index 0000000000..dd129fa1a8 --- /dev/null +++ b/src/Kernel/Utilitaires/Input.h @@ -0,0 +1,391 @@ +/**************************************************************************** +* Copyright (c) 2026, CEA +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: +* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. +* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. +* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +*****************************************************************************/ +#ifndef Input_included +#define Input_included + +#include +#include +#include +#include + +#include +#include + +class Objet_U; +template class TRUST_Ref; +class TRUST_Ref_Objet_U; +class Entree; + +#include + +class Input: public std::istream { + + /////////// + // enums // + /////////// + + public: + + enum class ReadMode { + ASCII, + Bin32, // FIXME should be remove at some point + Bin64 + }; + + enum class CommunicationMode { + Isolated, + Send, + Receive + }; + + enum class ErrorMode { + Continue, + Exit, + Throw + }; + + ////////////////// + // constructors // + ////////////////// + + using std::istream::istream; + + Input(): std::istream(nullptr) {} + + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wextra" + + Input(const Input& other): std::istream(other.rdbuf()) // attach same buffer + { + this->clear(other.rdstate()); // copy stream state flags + copy_modes(other); + } + + Input(const std::istream& stream): std::istream(stream.rdbuf()) {} + Input(const std::streambuf& buffer): Input(const_cast(buffer)) {} + + Input(Input& other): std::istream(other.rdbuf()) // attach same buffer + { + this->clear(other.rdstate()); // copy stream state flags + copy_modes(other); + } + + + Input(std::istream& stream): std::istream(stream.rdbuf()) {} + Input(std::streambuf& buffer): std::istream(&buffer) {} + + #pragma GCC diagnostic pop + + /////////////// + // operators // + /////////////// + + virtual Input& operator>>(Objet_U& ob); // could be set to final once Entree is remove + + template + Input& operator>>(TRUST_Ref&) { std::cerr << __func__ << " :: SHOULD NOT BE CALLED ! Use -> !! " << std::endl ; throw; } + + Input& operator>>(TRUST_Ref_Objet_U&) { std::cerr << __func__ << " :: SHOULD NOT BE CALLED ! Use -> !! " << std::endl ; throw; } + + template ::value>> + Input& operator>>(Type& value) { + get(value); + return *this; + } + + /////////////// + // operators // + /////////////// + + // idealy we would prevent dynamic allocation (it could mess the internal buffers) + // however it is use for TRUST_REF so I comment the deletes + //void* operator new(std::size_t) = delete; + //void* operator new[](std::size_t) = delete; + + ///////////// + // methods // + ///////////// + + void attach(std::istream& stream) { + this->rdbuf(stream.rdbuf()); + this->clear(stream.rdstate()); // copy state + } + + void detach() { + this->rdbuf(nullptr); + this->setstate(std::ios::eofbit | std::ios::badbit); + } + + //using std::istream::get; + + // get a single value + template + int get(Type& value) { + int ok = 0; + + //static_assert(std::is_trivially_copyable::value, "Can only read trivially copyable objects (for MPI support)."); + if (communication_mode != CommunicationMode::Isolated && !std::is_trivially_copyable::value) { // FIXME add a proper serializer, not just one working with Objets_U + std::cerr << "Can only read trivially copyable objects on MPI communications (for MPI support)." << std::endl; + Process::exit(1); + } + + if (communication_mode == CommunicationMode::Isolated || communication_mode == CommunicationMode::Send) { + switch (read_mode) { + case ReadMode::ASCII: + ok = read_ascii(value); + break; + case ReadMode::Bin32: + if (!std::is_integral::value && (sizeof(Type) == 8)) // allows to read 8 bits for double + ok = read_bin(value); + else + ok = read_bin(value); + break; + case ReadMode::Bin64: + ok = read_bin(value); + break; + default: + std::cerr << "Invalid reading mode encounter while reading stream." << std::endl; + Process::exit(1); + ok = 1; + } + } + +#ifndef LATATOOLS + if (communication_mode == CommunicationMode::Send || communication_mode == CommunicationMode::Receive) { + share(ok, reinterpret_cast(&value), sizeof(Type)); + } +#endif + + return ok; + } + + template + int read_ascii(Type& value) { + //std::istream::operator>>(value); + static_cast(*this) >> value; // use cast to avoid ambiguity + return error_handler(); + } + + template + int read_bin(Type& value) { + // the Type is non arithmetic (integer or float), we use the operator>> method to redirect to correct method +#if __cplusplus >= 201703L + if constexpr (!std::is_arithmetic::value) { // constexpr required here if non-integer types are used, otherwise it will try to compile read_bin(Type* array, std::streamsize size) with the type and will fail when trying to compile the underlying get method +#else + if (!std::is_arithmetic::value) { +#endif + operator>>(value); + return error_handler(); + } else { + // if it is an arithmetic type, we can use the method for arrays + return read_bin(&value, 1); + } + } + + // get an array + template + int get(Type* array, std::streamsize size) { + static_assert(std::is_trivially_copyable::value, "Can only read trivially copyable objects (for MPI support)."); + + int ok = 1; + +/* +#ifndef LATATOOLS + if (communication_mode == CommunicationMode::Send || communication_mode == CommunicationMode::Receive) { + if constexpr (std::is_same::value) { + // use strlen to get the array size (zero-terminated) // FIXME should probably remove this, it seems strange that only arrays of char have this behavior (occure in Nom::readOn for example), furthermore, it cannot work with lata tools + if (Process::je_suis_maitre()) + size = std::strlen(array); + + share(ok, reinterpret_cast(&size), sizeof(std::streamsize)); + } + } + + if (!ok) + return ok; +#endif +*/ + + if (communication_mode == CommunicationMode::Isolated || communication_mode == CommunicationMode::Send) { + // for text we use a special method + if constexpr (std::is_same::value) { + ok = read_text(reinterpret_cast(array), size); + } else { + switch (read_mode) { + case ReadMode::ASCII: + ok = read_ascii(array, size); + break; + case ReadMode::Bin32: + if (!std::is_integral::value && (sizeof(Type) == 8)) // allows to read 8 bits for double + ok = read_bin(array, size); + else + ok = read_bin(array, size); + break; + case ReadMode::Bin64: + ok = read_bin(array, size); + break; + default: + std::cerr << "Invalid reading mode encounter while reading stream." << std::endl; + Process::exit(1); + ok = 0; + } + } + } + +/* + if (!ok) + return ok; +*/ + +#ifndef LATATOOLS + if (communication_mode == CommunicationMode::Send || communication_mode == CommunicationMode::Receive) { + share(ok, reinterpret_cast(array), size * sizeof(Type)); + } +#endif + + return ok; + } + + int read_text(char* array, std::streamsize size); + + template + int read_ascii(Type* array, std::streamsize size) { + for (std::streamsize index = 0; index < size; index++) + read_ascii(array[index]); + return error_handler(); + } + + template + int read_bin(Type* array, std::streamsize size) { + // if the Buffer size is the same as type size and type is an integer, or if the Type is floating point, we simply read the array + if (avoid_conversion || (std::is_integral::value && (sizeof(Buffer) == sizeof(Type))) || !std::is_integral::value) { // could use constexpr but for some reason lata_tools compile in c++14 and constexpr is thus not available + this->read(reinterpret_cast(array), size * sizeof(Type)); + return error_handler(); + } + + // if Type is not an integer, we call the get on every element + if (!std::is_integral::value) { + for (std::streamsize index = 0; index < size; index++) + read_bin(array[index]); + + return error_handler(); + } + + // now we only deal with integer types + // there is two cases: Type can be signed or unsigned + if (std::is_signed::value) { + // read a buffer or signed version of Buffer + using SBuffer = typename std::make_signed::type; + return read_bin_integer(array, size); + } else { + using UBuffer = typename std::make_unsigned::type; + return read_bin_integer(array, size); + } + + return error_handler(); + } + + template + int read_bin_integer(Type* array, std::streamsize size) { + // we read a buffer of type Buffer then convert while checking boundaries + assert(std::is_integral::value && std::is_integral::value); // Type and Buffer should both be integers.; + assert((std::is_signed::value ^ std::is_signed::value) == 0); // Type and Buffer types should both be signed or both be unsigned.; + assert(sizeof(Buffer) != sizeof(Type)); // this method can be call in that case but it slower + + int ok = 1; + + // get + Buffer* buffer = new Buffer[size]; + this->read(reinterpret_cast(buffer), size * sizeof(Buffer)); + ok &= error_handler(); + + // convert + if (sizeof(Buffer) <= sizeof(Type)) { + // if the size of Buffer smaller than Type, than a Buffer value always fit in a Type + for (std::streamsize index = 0; index < size; index++) { + array[index] = static_cast(buffer[index]); + } + } else { + // if the size of Type is smaller than Buffer, there might be some overflow + for (std::streamsize index = 0; index < size; index++) { + // we check if the value fits (we can cast the min and max because we know that sizeof(Buffer) is greater than sizeof(Type) here) + if (buffer[index] >= static_cast(std::numeric_limits::min()) && buffer[index] <= static_cast(std::numeric_limits::max())) { + array[index] = static_cast(buffer[index]); + } else { + std::cerr << "Error while reading stream: the target variable will overflow." << std::endl; + Process::exit(1); + ok = 0; + } + } + } + + delete[] buffer; + + return ok; + } + + private: + + void update_mode(); + int error_handler(); + +#ifndef LATATOOLS + + protected: + + void share(int& ok, char* array, std::streamsize size); + void share_state(); +#endif + + protected: + + void copy_modes(const Input& other); + + public: + + void set_binary(bool value); + void set_64_bits(bool value); + void set_diffusion(bool value); + bool get_diffusion() const; + void set_avoid_conversion(bool value); + void set_error_mode(ErrorMode error_mode); + const ErrorMode& get_error_mode() const; + + //////////////// + // attributes // + //////////////// + + public: + + ErrorMode error_mode = ErrorMode::Continue; + + protected: + + ReadMode read_mode = ReadMode::ASCII; + CommunicationMode communication_mode = CommunicationMode::Isolated; + + bool is_bin = false; + +#ifdef INT_is_64_ + bool is_64_bits = true; +#else + bool is_64_bits = false; +#endif + + bool avoid_conversion = false; +}; + + +#endif diff --git a/src/Kernel/Utilitaires/InputCommBuffer.cpp b/src/Kernel/Utilitaires/InputCommBuffer.cpp index 8b159a5527..c81049d507 100644 --- a/src/Kernel/Utilitaires/InputCommBuffer.cpp +++ b/src/Kernel/Utilitaires/InputCommBuffer.cpp @@ -1,5 +1,5 @@ /**************************************************************************** -* Copyright (c) 2025, CEA +* Copyright (c) 2026, CEA * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -20,9 +20,9 @@ InputCommBuffer::InputCommBuffer() { set_error_action(ERROR_CONTINUE); - bin_ = 1; + set_bin(true); // Communication buffer should never try to convert int into long: - avoid_conversion_ = true; + set_avoid_conversion(true); memorysize_ = 16; size_ = 0; // Always allocate something (create_stream needs at least one byte diff --git a/src/Kernel/Utilitaires/InputConcat.cpp b/src/Kernel/Utilitaires/InputConcat.cpp new file mode 100644 index 0000000000..5b4d4b47ab --- /dev/null +++ b/src/Kernel/Utilitaires/InputConcat.cpp @@ -0,0 +1,33 @@ +/**************************************************************************** +* Copyright (c) 2026, CEA +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: +* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. +* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. +* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +*****************************************************************************/ +#include + + +InputConcat::InputConcat(std::streambuf* a, std::streambuf* b): + Input(nullptr), string(), buffer(a, b) { // first initialize the Input with a nullptr as buffer and initialize a ConcatBuffer + + // then set the internal buffer of the Input to this buffer + this->rdbuf(&buffer); +} + +InputConcat::InputConcat(const Nom& string_, Input& stream): + Input(nullptr), string(string_.getString()), buffer(&string, stream.rdbuf()) { + + // then set the internal buffer of the Input to this buffer + this->rdbuf(&buffer); + + // also copy the modes of the input + copy_modes(stream); +} diff --git a/src/Kernel/Utilitaires/InputConcat.h b/src/Kernel/Utilitaires/InputConcat.h new file mode 100644 index 0000000000..43a6e47a10 --- /dev/null +++ b/src/Kernel/Utilitaires/InputConcat.h @@ -0,0 +1,99 @@ +/**************************************************************************** +* Copyright (c) 2026, CEA +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: +* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. +* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. +* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +*****************************************************************************/ +#ifndef InputConcat_included +#define InputConcat_included + +#include + +#include +#include + +class InputConcat : virtual public Input { + + ///////////// + // classes // + ///////////// + + private: + + class ConcatBuffer : public std::streambuf { + + ////////////////// + // constructors // + ////////////////// + + public: + + ConcatBuffer(std::streambuf* a, std::streambuf* b): first(a), second(b), current(a) {} + + ///////////// + // methods // + ///////////// + + protected: + + int_type underflow() override { + if (!current) + return traits_type::eof(); + + int_type c = current->sgetc(); + if (traits_type::eq_int_type(c, traits_type::eof())) { + if (current == first) { + current = second; + return underflow(); + } + return traits_type::eof(); + } + return c; + } + + int_type uflow() override { + int_type c = underflow(); + if (!traits_type::eq_int_type(c, traits_type::eof())) + current->sbumpc(); + return c; + } + + //////////////// + // attributes // + //////////////// + + private: + + std::streambuf* first; + std::streambuf* second; + std::streambuf* current; + }; + + ////////////////// + // constructors // + ////////////////// + + public: + + InputConcat(std::streambuf* a, std::streambuf* b); + InputConcat(const Nom& string_, Input& stream); + + //////////////// + // attributes // + //////////////// + + protected: + + std::stringbuf string; // when used with an input string and a stream + ConcatBuffer buffer; +}; + +#endif diff --git a/src/Kernel/Utilitaires/InputFile.cpp b/src/Kernel/Utilitaires/InputFile.cpp new file mode 100644 index 0000000000..6eac91630e --- /dev/null +++ b/src/Kernel/Utilitaires/InputFile.cpp @@ -0,0 +1,64 @@ +/**************************************************************************** +* Copyright (c) 2026, CEA +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: +* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. +* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. +* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +*****************************************************************************/ +#include + +#ifndef LATATOOLS +#include +#endif + + +void InputFile::open(const char* file_name, std::ios_base::openmode mode) { + // open the file only on process 0 if shared + if (communication_mode == CommunicationMode::Isolated || communication_mode == CommunicationMode::Send) { + std::ifstream::open(file_name, mode); + } + + // shared the buffer accross process (not usefull but allow to check the buffer state on all process + if (communication_mode == CommunicationMode::Send || communication_mode == CommunicationMode::Receive) { + share_buffer(); + } +} + +void InputFile::close() { + // close on process 0 if shared + if (communication_mode == CommunicationMode::Isolated || communication_mode == CommunicationMode::Send) { + std::ifstream::close(); + } + + // share buffer (none now) (it also share state) + if (communication_mode == CommunicationMode::Send || communication_mode == CommunicationMode::Receive) { + share_buffer(); + } +} + +void InputFile::share_buffer() { +#ifndef LATATOOLS + /* + // get the buffer on process 0 + std::streambuf* buffer = nullptr; + if (Process::me() == 0) + buffer = this->rdbuf(); + + // share the pointer to buffer on all process + char address[sizeof(std::streambuf*)]; + std::memcpy(address, &buffer, sizeof(std::streambuf*)); + envoyer_broadcast_array(address, sizeof(std::streambuf*), 0); + std::memcpy(&buffer, address, sizeof(std::streambuf*)); + */ + + // share the state of the istream + share_state(); +#endif +} diff --git a/src/Kernel/Utilitaires/InputFile.h b/src/Kernel/Utilitaires/InputFile.h new file mode 100644 index 0000000000..86ee6d2770 --- /dev/null +++ b/src/Kernel/Utilitaires/InputFile.h @@ -0,0 +1,70 @@ +/**************************************************************************** +* Copyright (c) 2026, CEA +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: +* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. +* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. +* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +*****************************************************************************/ +#ifndef InputFile_included +#define InputFile_included + +#include +#include + +#if __cplusplus >= 201703L +#include +#endif + +#include +#include + +class InputFile: virtual public Input, public std::ifstream, public Objet_U { + + ////////////////// + // constructors // + ////////////////// + + public: + + // we hide the std::ifstream constructors and use our own open method + InputFile(): Input(), std::ifstream() {} + explicit InputFile(const char* file_name, std::ios_base::openmode mode = std::ios_base::in): Input(), std::ifstream() { + open(file_name, mode); + } + + explicit InputFile(const std::string& file_name, std::ios_base::openmode mode = std::ios_base::in): + InputFile(file_name.c_str(), mode) {} + + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wextra" + InputFile(const InputFile& other): Input(dynamic_cast(other)) {} + InputFile(InputFile& other): Input(dynamic_cast(other)) {} + #pragma GCC diagnostic pop + + ///////////// + // methods // + ///////////// + + public: + + void open(const char* file_name, std::ios_base::openmode mode = std::ios_base::in); + void open(const std::string& file_name, std::ios_base::openmode mode = std::ios_base::in) { open(file_name.c_str(), mode); } +#if __cplusplus >= 201703L + void open(const std::filesystem::path& file_name, std::ios_base::openmode mode = std::ios_base::in) { open(file_name.c_str(), mode); } +#endif + + void close(); + + private: + + void share_buffer(); +}; + +#endif diff --git a/src/Kernel/Utilitaires/InputOutputException.cpp b/src/Kernel/Utilitaires/InputOutputException.cpp new file mode 100644 index 0000000000..cf0a88dd96 --- /dev/null +++ b/src/Kernel/Utilitaires/InputOutputException.cpp @@ -0,0 +1,19 @@ +/**************************************************************************** +* Copyright (c) 2026, CEA +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: +* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. +* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. +* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +*****************************************************************************/ +#include + +const char* InputOutputException::what() const noexcept { + return ("InputOutputException: " + message).c_str(); +} diff --git a/src/Kernel/Utilitaires/InputOutputException.h b/src/Kernel/Utilitaires/InputOutputException.h new file mode 100644 index 0000000000..e87911e245 --- /dev/null +++ b/src/Kernel/Utilitaires/InputOutputException.h @@ -0,0 +1,51 @@ +/**************************************************************************** +* Copyright (c) 2026, CEA +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: +* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. +* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. +* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +*****************************************************************************/ +#ifndef InputOutputException_included +#define InputOutputException_included + +#include +#include + +#include + + +// make InputOutputException derived from Entree_Sortie_Error for backward compatibility +class InputOutputException : public std::exception, public Entree_Sortie_Error { + + ////////////////// + // constructors // + ////////////////// + + public: + + explicit InputOutputException(const std::string& message_) : message(message_) {} + + ///////////// + // methods // + ///////////// + + // override what() + const char* what() const noexcept override; + + //////////////// + // attributes // + //////////////// + + private: + + std::string message; +}; + +#endif diff --git a/src/Kernel/Utilitaires/InputString.h b/src/Kernel/Utilitaires/InputString.h new file mode 100644 index 0000000000..7061215fe5 --- /dev/null +++ b/src/Kernel/Utilitaires/InputString.h @@ -0,0 +1,34 @@ +/**************************************************************************** +* Copyright (c) 2026, CEA +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: +* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. +* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. +* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +*****************************************************************************/ +#ifndef InputString_included +#define InputString_included + +#include + +#include + +class InputString: virtual public Input, public std::istringstream { + + ////////////////// + // constructors // + ////////////////// + + public: + + using std::istringstream::istringstream; + +}; + +#endif diff --git a/src/Kernel/Utilitaires/LecFicDiffuse.cpp b/src/Kernel/Utilitaires/LecFicDiffuse.cpp index a71420a12a..66d0c2b6fc 100644 --- a/src/Kernel/Utilitaires/LecFicDiffuse.cpp +++ b/src/Kernel/Utilitaires/LecFicDiffuse.cpp @@ -1,5 +1,5 @@ /**************************************************************************** -* Copyright (c) 2024, CEA +* Copyright (c) 2026, CEA * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -29,21 +29,22 @@ Sortie& LecFicDiffuse::printOn(Sortie& s) const } // LecFicDiffuse::LecFicDiffuse():EFichier() -LecFicDiffuse::LecFicDiffuse() +LecFicDiffuse::LecFicDiffuse(): Lec_Diffuse_base() { - file_.set_error_action(ERROR_CONTINUE); + set_error_action(ERROR_CONTINUE); } -/*! @brief Opens file name. +/*! @brief ouverture du fichier name. * - * This method must be called on all processors. On failure: exit(). + * Cette methode doit etre appelee sur tous les processeurs. En cas + * d'echec : exit() * */ LecFicDiffuse::LecFicDiffuse(const char* name, - IOS_OPEN_MODE mode) + IOS_OPEN_MODE mode_): Lec_Diffuse_base() { - file_.set_error_action(ERROR_CONTINUE); - int ok = ouvrir(name, mode); + set_error_action(ERROR_CONTINUE); + int ok = ouvrir(name, mode_); if (!ok && Process::je_suis_maitre()) { Cerr << "File " << name << " does not exist (LecFicDiffuse)" << finl; @@ -51,44 +52,89 @@ LecFicDiffuse::LecFicDiffuse(const char* name, } } -/*! @brief Opens the file. +/*! @brief Ouverture du fichier. * - * This method must be called by all processors in the group. - * Return value: 1 if ok, 0 otherwise. + * Cette methode doit etre appelee par tous les processeurs du groupe. + * Valeur de retour: 1 si ok, 0 sinon * */ int LecFicDiffuse::ouvrir(const char* name, - IOS_OPEN_MODE mode) + IOS_OPEN_MODE mode_) { int ok = 0; - if(Process::je_suis_maitre()) - ok = file_.ouvrir(name, mode); + +{ + int x = 2* (Process::me() == 0); + envoyer_broadcast(x, 0); + assert(x == 2); + } + + Process::barrier(); + Process::barrier(); + Process::barrier(); + + //if(Process::je_suis_maitre()) { + Entree_Fichier_base::ouvrir(name, mode_); + +{ + int x = 3 * (Process::me() == 0); + envoyer_broadcast(x, 0); + assert(x == 3); + } + + + ok = is_open(); + //} + +{ + int x = 2 * (Process::me() == 0); + envoyer_broadcast(x, 0); + assert(x == 2); + } + + Process::barrier(); + Process::barrier(); + Process::barrier(); + +{ + int x = 1 * (Process::me() == 0); + envoyer_broadcast(x, 0); + assert(x == 1); + } + envoyer_broadcast(ok, 0); + +{ + int x = 3 * (Process::me() == 0); + envoyer_broadcast(x, 0); + assert(x == 3); + } + return ok; } /*! @brief * */ -istream& LecFicDiffuse::get_istream() +std::istream& LecFicDiffuse::get_istream() { if(!Process::je_suis_maitre()) { std::cerr << "Error get_istream (LecFicDiffuse)" << std::endl; Process::exit(); } - return file_.get_istream(); + return Entree::get_istream(); } /*! @brief * */ -const istream& LecFicDiffuse::get_istream() const +const std::istream& LecFicDiffuse::get_istream() const { if(!Process::je_suis_maitre()) { std::cerr << "Error get_istream (LecFicDiffuse)" << std::endl; Process::exit(); } - return file_.get_istream(); + return get_istream(); } diff --git a/src/Kernel/Utilitaires/LecFicDiffuse.h b/src/Kernel/Utilitaires/LecFicDiffuse.h index 995c3604af..fff298b100 100644 --- a/src/Kernel/Utilitaires/LecFicDiffuse.h +++ b/src/Kernel/Utilitaires/LecFicDiffuse.h @@ -1,5 +1,5 @@ /**************************************************************************** -* Copyright (c) 2022, CEA +* Copyright (c) 2026, CEA * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -21,29 +21,59 @@ class Objet_U; -/*! @brief This class implements the operators and virtual methods of the EFichier class as follows: The file to read is physically located on the disk of the machine hosting the master task of the Trio-U application (the process of rank 0 in the "tous" group), +/*! @brief Cette classe implemente les operateurs et les methodes virtuelles de la classe EFichier de la facon suivante : Le fichier a lire est physiquement localise sur le disque de la machine hebergeant la tache maitre de l'application Trio-U (le processus de rang 0 dans le groupe "tous") * - * and each item read from this file is broadcast to all other processes in the group. - * The same applies to the methods for inspecting the state of a file. + * et chaque item lu dans ce fichier est diffuse a tous les autres processus du groupe tous. + * Il en est de meme pour les methodes d'inspection de l'etat d'un fichier. * */ -class LecFicDiffuse : public Lec_Diffuse_base -{ - Declare_instanciable_sans_constructeur(LecFicDiffuse); - // the master reads the file and propagates the information -public: - LecFicDiffuse(); - LecFicDiffuse(const char* name, IOS_OPEN_MODE mode=ios::in); - int ouvrir(const char* name, IOS_OPEN_MODE mode=ios::in) override; - istream& get_istream() override; - const istream& get_istream() const override; - //Entree& get_entree_master(); -protected: - inline Entree& get_entree_master() override - { - return file_; - }; - EFichier file_; +class LecFicDiffuse : public Lec_Diffuse_base { + + ////////////////// + // constructors // + ////////////////// + + Declare_instanciable_sans_constructeur(LecFicDiffuse); + // le maitre lit le fichier et propage l'information + + public: + + LecFicDiffuse(); + LecFicDiffuse(const char* name, IOS_OPEN_MODE mode_=ios::in); + + /////////////// + // operators // + /////////////// + + public: + + using Input::operator>>; + + ///////////// + // methods // + ///////////// + + public: + + using Input::get; + + int ouvrir(const char* name, IOS_OPEN_MODE mode_=ios::in) override; + + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wextra" + LecFicDiffuse(const LecFicDiffuse& other): Lec_Diffuse_base(dynamic_cast(other)) {} + LecFicDiffuse(LecFicDiffuse& other): Lec_Diffuse_base(dynamic_cast(other)) {} + #pragma GCC diagnostic pop + + std::istream& get_istream() override; + const std::istream& get_istream() const override; + + protected: + + inline Entree& get_entree_master() override { + return *this; + }; }; + #endif diff --git a/src/Kernel/Utilitaires/LecFicDiffuseBin.h b/src/Kernel/Utilitaires/LecFicDiffuseBin.h index e136f09a27..d86e82fe43 100644 --- a/src/Kernel/Utilitaires/LecFicDiffuseBin.h +++ b/src/Kernel/Utilitaires/LecFicDiffuseBin.h @@ -1,5 +1,5 @@ /**************************************************************************** -* Copyright (c) 2022, CEA +* Copyright (c) 2026, CEA * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -39,11 +39,24 @@ class LecFicDiffuseBin : public LecFicDiffuse { set_bin(1); }; - LecFicDiffuseBin(const char* name,IOS_OPEN_MODE mode=ios::in) + LecFicDiffuseBin(const char* name,IOS_OPEN_MODE mode_=ios::in) { set_bin(1); - ouvrir(name,mode); + ouvrir(name,mode_); }; + + int ouvrir(const char* name, IOS_OPEN_MODE mode_=ios::in) override + { + set_bin(1); + return LecFicDiffuse::ouvrir(name,mode_); + }; + + + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wextra" + LecFicDiffuseBin(const LecFicDiffuseBin& other): LecFicDiffuse(dynamic_cast(other)) {} + LecFicDiffuseBin(LecFicDiffuseBin& other): LecFicDiffuse(dynamic_cast(other)) {} + #pragma GCC diagnostic pop }; #endif diff --git a/src/Kernel/Utilitaires/LecFicDiffuse_JDD.cpp b/src/Kernel/Utilitaires/LecFicDiffuse_JDD.cpp index 9eb28d686f..ed3feea9cc 100644 --- a/src/Kernel/Utilitaires/LecFicDiffuse_JDD.cpp +++ b/src/Kernel/Utilitaires/LecFicDiffuse_JDD.cpp @@ -22,6 +22,7 @@ Implemente_instanciable_sans_constructeur(LecFicDiffuse_JDD,"LecFicDiffuse_JDD",Lec_Diffuse_base); bool LecFicDiffuse_JDD::apply_verif = true; + Entree& LecFicDiffuse_JDD::readOn(Entree& s) { throw; @@ -32,19 +33,23 @@ Sortie& LecFicDiffuse_JDD::printOn(Sortie& s) const throw; } -LecFicDiffuse_JDD::LecFicDiffuse_JDD() +LecFicDiffuse_JDD::LecFicDiffuse_JDD() : Lec_Diffuse_base() { + set_error_action(ERROR_CONTINUE); } -/*! @brief Opens file name. +/*! @brief ouverture du fichier name. * - * This method must be called on all processors. On failure: exit(). + * Cette methode doit etre appelee sur tous les processeurs. En cas + * d'echec : exit() * */ LecFicDiffuse_JDD::LecFicDiffuse_JDD(const char* name, - IOS_OPEN_MODE mode) + IOS_OPEN_MODE mode_): Lec_Diffuse_base() { - int ok = ouvrir(name, mode); + + //file_.set_error_action(ERROR_CONTINUE); + int ok = ouvrir(name, mode_); if (!ok && Process::je_suis_maitre()) { Cerr << "File " << name << " does not exist (LecFicDiffuse_JDD)" << finl; @@ -53,14 +58,14 @@ LecFicDiffuse_JDD::LecFicDiffuse_JDD(const char* name, } -/*! @brief Opens the file. +/*! @brief Ouverture du fichier. * - * This method must be called by all processors in the group. - * Return value: 1 if ok, 0 otherwise. + * Cette methode doit etre appelee par tous les processeurs du groupe. + * Valeur de retour: 1 si ok, 0 sinon * */ int LecFicDiffuse_JDD::ouvrir(const char* name, - IOS_OPEN_MODE mode) + IOS_OPEN_MODE mode_) { int ok = 0; if(Process::je_suis_maitre()) @@ -69,7 +74,7 @@ int LecFicDiffuse_JDD::ouvrir(const char* name, bool fin_lu = false; Motcle fin("fin|end"); EFichier file_; - ok = file_.ouvrir(name, mode); + ok = file_.ouvrir(name, mode_); if (!ok ) { Cerr << "File " << name << " does not exist (LecFicDiffuse_JDD)" << finl; @@ -104,7 +109,7 @@ int LecFicDiffuse_JDD::ouvrir(const char* name, if (motlu=="#") { // Cerr<<" on passe les commentaires"<>motlu; - } } if (fin_lu) @@ -214,6 +218,8 @@ int LecFicDiffuse_JDD::ouvrir(const char* name, Process::Journal()<<"JDD interpreted: "<>; + + + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wextra" + LecFicDiffuse_JDD(const LecFicDiffuse_JDD& other): Lec_Diffuse_base(dynamic_cast(other)) {} + LecFicDiffuse_JDD(LecFicDiffuse_JDD& other): Lec_Diffuse_base(dynamic_cast(other)) {} + #pragma GCC diagnostic pop + static bool apply_verif; protected: EChaineJDD chaine_; + ///! whether obsolete keywords should be checked or not. True by default. + }; #endif diff --git a/src/Kernel/Utilitaires/LecFicDistribue.cpp b/src/Kernel/Utilitaires/LecFicDistribue.cpp index d77cd8301c..107b1bf289 100644 --- a/src/Kernel/Utilitaires/LecFicDistribue.cpp +++ b/src/Kernel/Utilitaires/LecFicDistribue.cpp @@ -1,5 +1,5 @@ /**************************************************************************** -* Copyright (c) 2024, CEA +* Copyright (c) 2026, CEA * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -31,7 +31,7 @@ Sortie& LecFicDistribue::printOn(Sortie& s) const LecFicDistribue::LecFicDistribue(int) { - bin_=0; + set_bin(false); } LecFicDistribue::LecFicDistribue():EFichier() {} @@ -40,28 +40,28 @@ LecFicDistribue::~LecFicDistribue() EFichier::close(); } -/*! @brief Constructor. Opens the file with the given mode and prot parameters. +/*! @brief Constructeur Ouvre le fichier avec les parametres mode_ et prot donnes * - * These parameters are the parameters of the standard open method. + * Ces parametres sont les parametres de la methode open standard * - * @param (const char* name) file name - * @param (int mode) parameter passed to open - * @param (int prot) parameter passed to open + * @param (const char* name) nom du fichier + * @param (int mode_) parametre passe a open + * @param (int prot) parametre passe a open */ -LecFicDistribue::LecFicDistribue(const char* name, IOS_OPEN_MODE mode) +LecFicDistribue::LecFicDistribue(const char* name, IOS_OPEN_MODE mode_) { - LecFicDistribue::ouvrir(name, mode); + LecFicDistribue::ouvrir(name, mode_); } -/*! @brief Opens the file with the given mode and prot parameters. These parameters are the parameters of the standard open method. +/*! @brief Ouvre le fichier avec les parametres mode_ et prot donnes Ces parametres sont les parametres de la methode open standard * - * @param (const char* name) file name - * @param (int mode) parameter passed to open - * @param (int prot) parameter passed to open + * @param (const char* name) nom du fichier + * @param (int mode_) parametre passe a open + * @param (int prot) parametre passe a open * @return (Entree&) *this */ -int LecFicDistribue::ouvrir(const char* name, IOS_OPEN_MODE mode) +int LecFicDistribue::ouvrir(const char* name, IOS_OPEN_MODE mode_) { Nom nom_fic(name); if(Process::is_parallel()) @@ -75,8 +75,8 @@ int LecFicDistribue::ouvrir(const char* name, IOS_OPEN_MODE mode) nom_fic = localisation + "/" + nom_fic; #endif - - if (!EFichier::ouvrir((const char*)nom_fic,mode)) + + if (!EFichier::ouvrir((const char*)nom_fic,mode_)) { Cerr << "File " << nom_fic << " not found or could not be opened." << finl; return 0; diff --git a/src/Kernel/Utilitaires/LecFicDistribue.h b/src/Kernel/Utilitaires/LecFicDistribue.h index 8579703d47..808419adfa 100644 --- a/src/Kernel/Utilitaires/LecFicDistribue.h +++ b/src/Kernel/Utilitaires/LecFicDistribue.h @@ -1,5 +1,5 @@ /**************************************************************************** -* Copyright (c) 2022, CEA +* Copyright (c) 2026, CEA * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -22,23 +22,30 @@ class Objet_U; -/*! @brief This class implements the operators and virtual methods of the EFichier class as follows: there are as many files as there are processes, physically located on the disk of the machine hosting the master task of the Trio-U application (the process of rank 0 in the "all" group). +/*! @brief Cette classe implemente les operateurs et les methodes virtuelles de la classe EFichier de la facon suivante : Il y a autant de fichiers que de processus, physiquement localises sur le disque de la machine hebergeant la tache maitre de l'applicatin Trio-U (le processus de rang 0 dans le groupe "tous"). * - * The master process reads one item at a time from each file and sends it to the corresponding process. - * The same applies to the methods for inspecting the state of a file. + * Le processus maitre lit tour a tour un item dans chacun des fichiers et l'envoie au processus correspondant. + * Il en est de meme pour les methodes d'inspection de l'etat d'un fichier. * */ class LecFicDistribue : public EFichier { Declare_instanciable(LecFicDistribue); - // the master reads the file and propagates the information + // le maitre lit le fichier et propage l'information private : LecFicDistribue(int); public: - LecFicDistribue(const char* name, IOS_OPEN_MODE mode=ios::in); + LecFicDistribue(const char* name, IOS_OPEN_MODE mode_=ios::in); - int ouvrir(const char* name, IOS_OPEN_MODE mode=ios::in) override; + int ouvrir(const char* name, IOS_OPEN_MODE mode_=ios::in) override; + + + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wextra" + LecFicDistribue(const LecFicDistribue& other): EFichier(dynamic_cast(other)) {} + LecFicDistribue(LecFicDistribue& other): EFichier(dynamic_cast(other)) {} + #pragma GCC diagnostic pop protected: diff --git a/src/Kernel/Utilitaires/LecFicDistribueBin.h b/src/Kernel/Utilitaires/LecFicDistribueBin.h index 0b75d734ec..677749ff22 100644 --- a/src/Kernel/Utilitaires/LecFicDistribueBin.h +++ b/src/Kernel/Utilitaires/LecFicDistribueBin.h @@ -1,5 +1,5 @@ /**************************************************************************** -* Copyright (c) 2022, CEA +* Copyright (c) 2026, CEA * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -21,29 +21,36 @@ class Objet_U; -/*! @brief Reading from a file in binary format. +/*! @brief Lecture dans un fichier au format binaire. * - * This class implements the operators and virtual methods of the EFichier class as follows: - * There are as many files as there are processes, physically located on the disk of the machine hosting the master task of the Trio-U application (the process of rank 0 in the "tous" group). - * The master process reads one item at a time from each file and sends it to the corresponding process. - * The same applies to the methods for inspecting the state of a file. + * Cette classe implemente les operateurs et les methodes virtuelles de la classe EFichier de la facon suivante : + * Il y a autant de fichiers que de processus, physiquement localises sur le disque de la machine hebergeant la tache maitre de l'applicatin Trio-U (le processus de rang 0 dans le groupe "tous"). + * Le processus maitre lit tour a tour un item dans chacun des fichiers et l'envoie au processus correspondant. + * Il en est de meme pour les methodes d'inspection de l'etat d'un fichier. * */ class LecFicDistribueBin : public LecFicDistribue { Declare_instanciable_sans_constructeur(LecFicDistribueBin); - // the master reads the file and propagates the information + // le maitre lit le fichier et propage l'information public: LecFicDistribueBin() { set_bin(1); }; - LecFicDistribueBin(const char* name,IOS_OPEN_MODE mode=ios::in) + LecFicDistribueBin(const char* name,IOS_OPEN_MODE mode_=ios::in) { set_bin(1); - ouvrir(name,mode); + ouvrir(name,mode_); }; + + + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wextra" + LecFicDistribueBin(const LecFicDistribueBin& other): LecFicDistribue(dynamic_cast(other)) {} + LecFicDistribueBin(LecFicDistribueBin& other): LecFicDistribue(dynamic_cast(other)) {} + #pragma GCC diagnostic pop }; #endif diff --git a/src/Kernel/Utilitaires/Lec_Diffuse_base.cpp b/src/Kernel/Utilitaires/Lec_Diffuse_base.cpp index 43a7851e03..6489d1fa9a 100644 --- a/src/Kernel/Utilitaires/Lec_Diffuse_base.cpp +++ b/src/Kernel/Utilitaires/Lec_Diffuse_base.cpp @@ -30,126 +30,9 @@ Sortie& Lec_Diffuse_base::printOn(Sortie& s) const throw; } -/*! @brief Does nothing (protected constructor since this is a base class). +/*! @brief ne fait rien (constructeur protege car c'est une classe de base) * */ -Lec_Diffuse_base::Lec_Diffuse_base() { } - -/*! @brief Error. - * - */ -Lec_Diffuse_base& Lec_Diffuse_base::operator=(const Lec_Diffuse_base& ) -{ - Cerr << "Error in Lec_Diffuse_base & operator=(const Lec_Diffuse_base & is)" << finl; - Process::exit(); - return *this; -} - -Entree& Lec_Diffuse_base::operator>>(int& ob) { return operator_template(ob); } -int Lec_Diffuse_base::get(int* ob, std::streamsize n) { return get_template(ob, n); } - -Entree& Lec_Diffuse_base::operator>>(long& ob) { return operator_template(ob); } -int Lec_Diffuse_base::get(long* ob, std::streamsize n) { return get_template(ob, n); } - -Entree& Lec_Diffuse_base::operator>>(long long& ob) { return operator_template(ob); } -int Lec_Diffuse_base::get(long long* ob, std::streamsize n) { return get_template(ob, n); } - -Entree& Lec_Diffuse_base::operator>>(float& ob) { return operator_template(ob); } -int Lec_Diffuse_base::get(float* ob, std::streamsize n) { return get_template(ob, n); } - -Entree& Lec_Diffuse_base::operator>>(double& ob) { return operator_template(ob); } -int Lec_Diffuse_base::get(double *ob, std::streamsize n) { return get_template(ob, n); } - -int Lec_Diffuse_base::get(char *buf, std::streamsize bufsize) -{ - int l = -1; - if (Process::je_suis_maitre()) - { - Entree& is = get_entree_master(); - assert(is.get_error_action() == ERROR_CONTINUE); - int ok = is.get(buf, bufsize); - if (ok) - l = (int)strlen(buf) + 1; - } - else if (!diffuse_) - { - Cerr << "Lec_Diffuse_base::get(...) can't be used with diffuse_=0 on non master process." << finl; - Process::exit(); - } - if (diffuse_) - { - envoyer_broadcast(l, 0); - if (l > 0) - envoyer_broadcast_array(buf, l, 0); - } - return error_handle(l < 0); -} - -int Lec_Diffuse_base::eof() -{ - int flag = 0; - if (Process::je_suis_maitre()) - { - Entree& is = get_entree_master(); - flag = is.eof(); - } - if (diffuse_) envoyer_broadcast(flag, 0); - return flag; -} - -int Lec_Diffuse_base::good() -{ - int flag = 0; - if (Process::je_suis_maitre()) - { - Entree& is = get_entree_master(); - flag = is.good(); - } - if (diffuse_) envoyer_broadcast(flag, 0); - return flag; -} - -int Lec_Diffuse_base::fail() -{ - int flag = 0; - if (Process::je_suis_maitre()) - { - Entree& is = get_entree_master(); - flag = is.fail(); - } - if (diffuse_) envoyer_broadcast(flag, 0); - return flag; -} - -/*! @brief Calls get_entree_master(). - * - * set_bin(bin) - * - */ -void Lec_Diffuse_base::set_bin(bool bin) -{ - if (Process::je_suis_maitre()) - { - Entree& is = get_entree_master(); - is.set_bin(bin); - } - if (diffuse_) envoyer_broadcast(bin, 0); - Entree::set_bin(bin); -} - -/*! @brief Calls get_entree_master(). - * - * set_check_types(flag) - * - */ -void Lec_Diffuse_base::set_check_types(bool flag) -{ - Entree::set_check_types(flag); - Entree& is = get_entree_master(); - is.set_check_types(flag); -} - -void Lec_Diffuse_base::set_diffuse(bool diffuse) -{ - diffuse_ = diffuse; +Lec_Diffuse_base::Lec_Diffuse_base() { + set_diffusion(true); } diff --git a/src/Kernel/Utilitaires/Lec_Diffuse_base.h b/src/Kernel/Utilitaires/Lec_Diffuse_base.h index 3b60425a59..ef74bb8c72 100644 --- a/src/Kernel/Utilitaires/Lec_Diffuse_base.h +++ b/src/Kernel/Utilitaires/Lec_Diffuse_base.h @@ -20,16 +20,16 @@ #include #include -/*! @brief Base class for diffused inputs: the master processor reads data from get_entree_master() and broadcasts it +/*! @brief Classe de base des entrees diffusees: le processeur maitre lit les donnees dans la classe get_entree_master() et les diffuse * - * to all processors. - * Warning: the methods operator>>(), get(), eof(), good() and bad() - * must be called simultaneously on all processors. - * Derived classes must reimplement get_entree_master(). - * The get_entree_master() method must return a reference to the input - * that serves as source on the master processor; it is never called - * on other processors. - * Warning: the source input must have set_error_action(ERROR_CONTINUE). + * sur tous les processeurs. + * Attention, les methodes operator>>(), get(), eof(), good() et bad() + * doivent etre appelees simultanement sur tous les processeurs. + * Les classes derivees doivent reimplementer get_entree_master(). + * La methode get_entree_master() doit renvoyer une reference a l'entree + * qui sert de source sur le processeur maitre, elle n'est jamais appellee + * sur les autres processeurs. + * Attention: l'entree source doit avoir set_error_action(ERROR_CONTINUE) * */ @@ -38,93 +38,30 @@ class Lec_Diffuse_base: public EFichier { Declare_base_sans_constructeur(Lec_Diffuse_base); public: - using Entree::operator>>; - - Entree& operator>>(int& ob) override; - Entree& operator>>(long& ob) override; - Entree& operator>>(long long& ob) override; - Entree& operator>>(float& ob) override; - Entree& operator>>(double& ob) override; - - int get(int *ob, std::streamsize n) override; - int get(long *ob, std::streamsize n) override; - int get(long long *ob, std::streamsize n) override; - int get(float *ob, std::streamsize n) override; - int get(double *ob, std::streamsize n) override; - int get(char *buf, std::streamsize bufsize) override; - - int eof() override; - int good() override; - int fail() override; - - void set_bin(bool bin) override; - void set_check_types(bool flag) override; - - void set_diffuse(bool diffuse) override; + using EFichier::operator>>; protected: Lec_Diffuse_base(); - Lec_Diffuse_base(const Lec_Diffuse_base&) = default; + //Lec_Diffuse_base(const Lec_Diffuse_base&) = default; Lec_Diffuse_base& operator=(const Lec_Diffuse_base&); virtual Entree& get_entree_master() = 0; -private: - template - int get_template(_TYPE_ *ob, std::streamsize n); - template - Entree& operator_template(_TYPE_&ob); -}; + virtual void set_diffuse(bool value) override { + this->diffuse_ = value; -template -int Lec_Diffuse_base::get_template(_TYPE_ *ob, std::streamsize n) -{ - int ok = 0; - if (Process::je_suis_maitre()) - { - Entree& is = get_entree_master(); - assert(is.get_error_action() == ERROR_CONTINUE); - ok = is.get(ob, n); - } - else if (!diffuse_) - { - Cerr << "Lec_Diffuse_base::get(...) can't be used with diffuse_=0 on non master process." << finl; - Process::exit(); - } - if (diffuse_) - { - envoyer_broadcast(ok, 0); - assert(n < std::numeric_limits::max()); - if (ok) - envoyer_broadcast_array(ob, (int)n, 0); - } - return error_handle(!ok); -} + if (Process::je_suis_maitre()) + set_diffusion(value); + } // to temporary disable it -template -Entree& Lec_Diffuse_base::operator_template(_TYPE_& ob) -{ - int ok = 0; - if (Process::je_suis_maitre()) - { - Entree& is = get_entree_master(); - assert(is.get_error_action() == ERROR_CONTINUE); - is >> ob; - ok = is.good(); - } - else if (!diffuse_) - { - Cerr << "Lec_Diffuse_base::operator>> can't be used with diffuse_=0 on non master process." << finl; - Process::exit(); - } - if (diffuse_) - { - envoyer_broadcast(ok, 0); - if (ok) - envoyer_broadcast(ob, 0); - } - error_handle(!ok); - return *this; -} + + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wextra" + Lec_Diffuse_base(const Lec_Diffuse_base& other): EFichier(dynamic_cast(other)) {} + Lec_Diffuse_base(Lec_Diffuse_base& other): EFichier(dynamic_cast(other)) {} + #pragma GCC diagnostic pop + +private: +}; #endif diff --git a/src/Kernel/Utilitaires/Objet_U.cpp b/src/Kernel/Utilitaires/Objet_U.cpp index c2a1992133..27ed15727a 100644 --- a/src/Kernel/Utilitaires/Objet_U.cpp +++ b/src/Kernel/Utilitaires/Objet_U.cpp @@ -1,5 +1,5 @@ /**************************************************************************** -* Copyright (c) 2025, CEA +* Copyright (c) 2026, CEA * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -291,6 +291,17 @@ Entree& Objet_U::readOn(Entree& s) return s; } +Input& Objet_U::readOn(Input& s) +{ + Entree e(s); + readOn(e); + + // we must transfer the state of e in s (the EOF flag, Good flag...) + s.clear(); + s.setstate(e.rdstate()); + return s; +} + /*! @brief Returns 1 if x and *this are the same instance (same memory address). * * @param x The object to compare with. diff --git a/src/Kernel/Utilitaires/Objet_U.h b/src/Kernel/Utilitaires/Objet_U.h index 9b2a703bcd..3c376aae70 100644 --- a/src/Kernel/Utilitaires/Objet_U.h +++ b/src/Kernel/Utilitaires/Objet_U.h @@ -75,6 +75,7 @@ class Objet_U : public Process virtual int duplique() const =0; virtual Sortie& printOn(Sortie& ) const; virtual Entree& readOn(Entree& ) ; + Input& readOn(Input& ); virtual unsigned taille_memoire() const =0; virtual int est_egal_a(const Objet_U&) const; virtual const Nom& le_nom() const;