// This file is part of the Herezh++ application. // // The finite element software Herezh++ is dedicated to the field // of mechanics for large transformations of solid structures. // It is developed by Gérard Rio (APP: IDDN.FR.010.0106078.000.R.P.2006.035.20600) // INSTITUT DE RECHERCHE DUPUY DE LÔME (IRDL) . // // Herezh++ is distributed under GPL 3 license ou ultérieure. // // Copyright (C) 1997-2021 Université Bretagne Sud (France) // AUTHOR : Gérard Rio // E-MAIL : gerardrio56@free.fr // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, // or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. // See the GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see . // // For more information, please consult: . /************************************************************************ * * * DATE: 23/01/97 * * $ * * AUTEUR: G RIO (mailto:gerardrio56@free.fr) * * $ * * PROJET: Herezh++ * * $ * ************************************************************************ * BUT: definir l'ensemble des outils relatifs aux * * operations basiques de lecture dans le fichier * * d'entree * * $ * * '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' * * * VERIFICATION: * * * * ! date ! auteur ! but ! * * ------------------------------------------------------------ * * ! ! ! ! * * * * $ * * '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' * * MODIFICATIONS: * * * ! date ! auteur ! but ! * * ------------------------------------------------------------ * * * * $ * * * ************************************************************************/ #ifndef UtiLecture_H #define UtiLecture_H #include //#include "Debug.h" #ifndef ENLINUX_STREAM #include // pour le flot en memoire centrale #else #include // pour le flot en memoire centrale #endif #include #include #include #include "Sortie.h" #include using namespace std; /** @defgroup Goupe_relatif_aux_entrees_sorties * * BUT: groupe relatif aux méthodes de lectures et d'écritures sur fichiers, écrans * * * \author Gérard Rio * \version 1.0 * \date 23/01/97 * \brief groupe relatif aux méthodes de lectures et d'écritures sur fichiers, écrans * */ /// @addtogroup Goupe_relatif_aux_entrees_sorties /// @{ /// class UtilLecture { public : // VARIABLES PUBLIQUES : // --------------- cas du fichier principal .info et dérivés ------------------ char* tablcar ; // buffer contenant les infos utiles courantes const int longueur; // longueur maxi du tableau de travail class ErrNouvelleDonnee // gestion d'exception pour nouvel_Enreg // =1 lecture OK on est arrive a la fin de tous les fichiers, < 0 probleme de lecture { public : int lecture; ErrNouvelleDonnee (int entrees) {lecture = entrees;} ; // CONSTRUCTEURS ~ErrNouvelleDonnee () {};// DESTRUCTEUR : }; // Flot d'entree // pour la lecture en memoire centrale, permet la conversion de type // dans le cas de lecture de tableau de character il faut tout // d'abord preciser le nombre de carractere a lire avec la fonction // membre width(nb de crarac) // a utiliser pour la lecture d'entier, de reelle etc #ifndef ENLINUX_STREAM istringstream * entree; ostringstream * sortie; #else istrstream * entree; ostrstream * sortie; #endif // retour du fichier dans lequel on écrit les commandes .info ofstream * Commande_pointInfo() {return ptrcommandefich;}; // retour du fichier dans lequel on écrit le schema XML ofstream * ShemaXML() {return ptrschemaXMLfich;}; // fichier de recopie des informations lue par le programme ofstream * copie; // --------------- fin du cas du fichier principal .info et dérivés ------------------ // --------------- cas du fichier de commandes de visualisation ------------------ char* tablcarCVisu ; // buffer contenant les infos utiles courantes class ErrNouvelleDonneeCVisu // gestion d'exception pour nouvel_EnregCVisu // =1 lecture OK on est arrive a la fin de tous les fichiers, < 0 probleme de lecture // = 0 probleme d'ouverture de fichier en lecture // = 10 probleme en ouverture pour l'écriture { public : int lecture; ErrNouvelleDonneeCVisu (int entrees) {lecture = entrees;} ; // CONSTRUCTEURS ~ErrNouvelleDonneeCVisu () {};// DESTRUCTEUR : }; // Flot d'entree // pour la lecture en memoire centrale, permet la conversion de type // dans le cas de lecture de tableau de character il faut tout // d'abord preciser le nombre de carractere a lire avec la fonction // membre width(nb de crarac) // a utiliser pour la lecture d'entier, de reelle etc #ifndef ENLINUX_STREAM istringstream * entCVisu; #else istrstream * entCVisu; #endif // --------------- fin du cas du fichier de commandes de visualisation ------------------ // CONSTRUCTEURS : // ++ le constructeur officiel ++ // il y a passage éventuelle d'argument : argc=le nombre d'argument // argv : donne un tableau correspondant de mots clés // ---> lecture de la racine du nom du fichier princial UtilLecture (int argc=0, const char * argv[] = NULL) ; // DESTRUCTEUR : ~UtilLecture () ; // METHODES PUBLIQUES : // ouverture du fichier de lecture. Les infos interressantes se trouvent // dans la chaine pointee par tablcar : // // ou cela peut-être l'ouverture d'un nouveau fichier d'écriture de commande // ceci en fonction des réponses de l'utilisateur lors de la création de l'instance // UtilLecture. Dans ce cas le fichier .info n'est disponible qu'en écriture !!! // aucune des fonctions de lecture sont activable : // // en retour idem = Lec_ent_info() int OuvrirFichier (); // raffraichir le dernier fichier de lecture .info en cours // il y a fermeture puis ouverture au même endroit du fichier .info void Raffraichir_pointInfo(); // fermeture du fichier .info qui est en création donc en écriture //(ce n'est pas celui qui serait en lecture !!), void fermeture_pointInfo(); // fermeture du fichier SchemaXML void fermetureSchemaXML(); // ouverture d'un fichier de copie des infos lue par le programme // utilise pour verifier la bonne lecture void OuvrirCopie(); // fermeture du fichier void FermerCopie(); // redirection du flot d'entré vers un nouveau fichier // nevezFich pointe sur le nom du nouveau fichier void NouveauFichier( char* nevezFich) ; // fermeture du flot actuel, et retour sur le flot précédent // indic est un indicateur de retour // = 0 il reste encore des fichiers intermédiaires ouverts // =1 on se situe sur le flot primaire void FermetureFichier(int& indic); // lecture d'une nouvelle ligne de donnee utilisable pour les donnees // lorsqu'apparait le signe < dans le fichier d'entree il y a automatiquement // ouverture d'un nouveau fichier void NouvelleDonnee(); // idem mais sans ouverture de fichier automatique // le signe < est conservé dans la ligne void NouvelleDonneeSansInf(); // Retour du flot au debut de l'enregistrement // a utiliser s'il y a eu une erreur de lecture sur le flot // mais que l'on connait l'erreur et l'on veut relire // par exemple : on essaie un string -> erreur, alors c'est un reel // on veut relire un reel, on utilise FlotDebutDonnee() avant void FlotDebutDonnee(); // gestion d'erreur d'entree // ecriture d'un message d'erreur du a une mauvaise lecture // le programme ecrit la chaine transmise puis le contenu des buffers void ErreurLecture(UtilLecture::ErrNouvelleDonnee,char*); // ecriture d'un message et du contenu des buffers courant void MessageBuffer(string); // affichage sur la sortie standard de l'enregistrement courant void AfficheEnreg () const ; // retourne la racine du nom du fichier principal char* RacineNom() { return (char*)nomRacine.c_str() ;}; // indique de type d'entrée des données ou de sortie // dans le cas ou c'est une création de fichier de commande // = -11 indique que l'on cré un fichier de commande .info // = -12 création du fichier schema XML // = 0 indique que ce sera via le fichier info // = 1 ce sera via un fichier base-info // = 2 ce sera via un serveur base-info int Lec_ent_info () {return lec_ent_info;}; // -------------- cas de la base d'info ---------------- //fichier base_info dans lequel sont lus les enregistrements // dans le cas ou celui-ci n'est pas ouvert il y a ouverture ifstream * Ent_BI() ; // et pour l'écriture // dans le cas ou celui-ci n'est pas ouvert il y a ouverture ofstream * Sort_BI() ; // ouverture du fichier base_info après le .info dans le cas d'un restart par exemple // dans le cas ou le fichier est déjà ouvert en lecture ou écriture dans le type demandé // il n'y a aucune action // a priori le fichier est ouvert en lecture : lecture // mais il peut également être en écriture : ecriture void Ouverture_base_info(string type_entree="lecture"); // fermeture du fichier base_info void Fermeture_base_info(); // positionnement dans le fichier d'entrès au niveau d'un numéro d'incrément // si l'on ne trouve pas le numéro on renvoi un indicateur à false bool Positionnement_base_info(int inc_voulu); // positionnement dans le fichier d'entrès au niveau du numéro d'incrément suivant // si l'on ne trouve pas de numéro on renvoi un indicateur à false // la méthode renvoie également la position du début de l'incrément // et le numéro trouvé d'incrément bool Increment_suivant_base_info(streampos& debut_increment,int& inc_lu); // enregistrement de la position // normalement correspond à un début d'incrément void Enregistrement_position_increment_base_info(int incr); // renvoi tous les incréments actuellements enregistré list Liste_increment(); // -------------- cas des temps de calcul ---------------- // ouverture du fichier spécifique des temps cpu void Ouverture_fichier_temps_cpu(); // fermeture du fichier des temps cpu void Fermeture_fichier_temps_cpu(); // récupération du fichier des temps cpu ofstream & Sort_temps_cpu() { return *sort__temps_cpu;}; // -------------- cas de la visualisation ---------------- // +++ vrml ++++ // ouverture du fichier principal vrml void Ouverture_fichier_principal_vrml(); // fermeture du fichier principal vrml void Fermeture_fichier_principal_vrml(); // récupération du fichier principal vrml ofstream & Sort_princ_vrml() { return *sort_princ_vrml;}; // ouverture du fichier de légendes vrml void Ouverture_fichier_legende_vrml(); // fermeture du fichier légendes vrml void Fermeture_fichier_legende_vrml(); // récupération du fichier légendes vrml ofstream & Sort_legende_vrml() { return *sort_legende_vrml;}; // existance bool Existe_princ_vrml() const {return (sort_princ_vrml==NULL ? false : true); }; // +++ maple ++++ // ouverture du fichier maple void Ouverture_fichier_principal_maple(); // fermeture du fichier principal maple void Fermeture_fichier_principal_maple(); // récupération du fichier principal maple ofstream & Sort_princ_maple() { return *sort_princ_maple;}; // existance bool Existe_princ_maple() const {return (sort_princ_maple==NULL ? false : true); }; // +++ geomview ++++ // ouverture du fichier principal geomview void Ouverture_fichier_principal_geomview(); // fermeture du fichier principal geomview void Fermeture_fichier_principal_geomview(); // récupération du fichier principal geomview ofstream & Sort_princ_geomview() { return *sort_princ_geomview;}; // ouverture du fichier de légendes geomview void Ouverture_fichier_legende_geomview(); // fermeture du fichier légendes geomview void Fermeture_fichier_legende_geomview(); // récupération du fichier légendes geomview ofstream & Sort_legende_geomview() { return *sort_legende_geomview;}; // existance bool Existe_princ_geomview() const {return (sort_princ_geomview==NULL ? false : true); }; bool Existe_legende_geomview() const {return (sort_legende_geomview==NULL ? false : true); }; // +++ Gid ++++ // ouverture du fichier pour le maillage initial Gid void Ouverture_fichier_initial_Gid(); // fermeture du fichier maillage initial Gid void Fermeture_fichier_initial_Gid(); // récupération du fichier maillage initial Gid ofstream & Sort_initial_Gid() { return *sort_initial_Gid;}; // ouverture du fichier résultat Gid void Ouverture_fichier_resultat_Gid(); // fermeture du fichier résultat Gid void Fermeture_fichier_resultat_Gid(); // récupération du fichier résultats Gid ofstream & Sort_resultat_Gid() { return *sort_resultat_Gid;}; // existance bool Existe_initial_Gid() const {return (sort_initial_Gid==NULL ? false : true); }; bool Existe_resultat_Gid() const {return (sort_resultat_Gid==NULL ? false : true); }; // +++ Gmsh ++++ // ouverture du fichier pour le maillage initial Gmsh void Ouverture_fichier_initial_Gmsh(); // fermeture du fichier maillage initial Gmsh void Fermeture_fichier_initial_Gmsh(); // récupération du fichier maillage initial Gmsh ofstream & Sort_initial_Gmsh() { return *sort_initial_Gmsh;}; // création du répertoire contenant tous les fichiers résultats void CreationRepertoireResultat(); // ouverture d'un fichier résultat Gmsh, comprenant un nom particulier // si le fichier n'existe pas -> création void Ouverture_fichier_resultat_Gmsh(const string& nom); // ouverture d'un ensemble de fichiers: ces fichiers seront ensuite accessibles // si un des fichiers n'existe pas -> création void Ouverture_fichier_resultat_Gmsh(const list & list_nom); // récupération de la liste de noms de base qui servent pour la création des // fichiers de base: cette liste = la somme des noms passés en paramètre via les // méthode Ouverture_fichier_resultat_Gmsh et Ouverture_fichier_resultat_Gmsh // chaque nom peut ensuite être utilisé dans les méthodes d'accès, ouverture, fermeture const list & Noms_base_fichiers_gmsh() const { return noms_base_fichiers_gmsh;}; // fermeture d'un fichier résultat Gmsh void Fermeture_fichier_resultat_Gmsh(const string& nom); // fermeture de tous les fichiers résultat void Fermeture_TousLesFichiersResultats_Gmsh(); // récupération d'un fichier résultats Gmsh ofstream & Sort_resultat_Gmsh(const string& nom); // existance bool Existe_initial_Gmsh() const {return (sort_initial_Gmsh==NULL ? false : true); }; // pour tester l'existance d'un fichier resultat on utilise la liste Noms_base_fichiers_gmsh() // ------------ automatisation de la visualisation ------ // ouverture du fichier CommandeVisu s'il est déjà ouvert on ne fait rien // a priori le fichier est ouvert en lecture : type_entree = "lecture" // mais il peut également être en écriture : type_entree = "ecriture" void Ouverture_CommandeVisu(string type_entree); // fermeture du fichier CommandeVisu void Fermeture_CommandeVisu(); // changement du nom de fichier .CVisu // entraîne la fermeture du fichier en cours, en lecture et en écriture // il n'y a pas de vérification à ce niveau d'existence éventuelle // car on ne sait pas ce que l'on veut en faire // si la chaine de caractère passée en paramètre est non nulle on l'utilise // sinon on passe en interactif et on demande le nom de la chaine void Changement_NomCVisu(string nouveauNomCvisu); //fichier CommandeVisu dans lequel sont lus les enregistrements // uniquement l'écriture est à accés directe ofstream * Sort_CommandeVisu(); // lecture d'une nouvelle ligne de donnee utilisable pour l'entree de donnee // dans le fichier de commande de visualisation (idem NouvelleDonnee mais en plus simple // car il n'y a pas de fichier inclus) void NouvelleDonneeCVisu(); // recherche dans le fichier de commande la chaine de caractère passée en paramètre // retour false: si on ne trouve pas la chaine // retour true: si on la trouve, et dans ce cas le pointeur courant du fichier est // positionné sur la ligne de la chaine bool PositionEtExisteCVisu(const string chaine); //------------ utilitaire de lecture d'un parametre précédé d'un mot clé, avec une restriction // sur les valeurs // val_defaut: si la grandeur n'est pas lue, elle est mise par défaut = val_defaut // nom_class_methode: le nom de la methode qui appel l'utilitaire -> sortie dans le message si pb // min max : les bornes entre lesquelles doit se trouver le parametre lue sinon -> génération d'une erreur et arrêt // si max < min alors la condition n'est pas prise en compte // mot_cle : mot_cle devant précéder le parametre // parametre: le parametre à lire // retourne un boolean: indique si oui ou non il y a eu lecture bool Lecture_un_parametre_int(int val_defaut,const string& nom_class_methode ,int min, int max, string& mot_cle, int& parametre ) const; // idem pour un double bool Lecture_un_parametre_double(double val_defaut,const string& nom_class_methode ,double min, double max,const string& mot_cle, double& parametre ) const; // lecture et passage d'un mot clé: il y a simplement vérification que c'est le bon mot clé qui est lue // ramène si oui ou non le mot clé à été lue bool Lecture_et_verif_mot_cle(const string& nom_class_methode,const string& mot_cle) const; // idem pour un mot clé et un string: nom bool Lecture_mot_cle_et_string(const string& nom_class_methode,const string& mot_cle,string& nom) const; //------------- utilitaires de lecture d'une grandeurs qui peut-être une constante utilisateur --- // int Lect_avec_const_int_utilisateur()const; double lect_avec_const_double_utilisateur(string erreur) const; // modification interactive d'une constante utilisateur // la constante doit déjà exister static void Modif_interactive_constante_utilisateur(); // ----------- définition de conteneurs à usage interne ----------- // cependant elles ne peuvent pas être déclaré en protégé ?? // protected : //private : // définition de type particulier // def d'un maillon de liste chainee pour memoriser les differentes ouverture // de fichier class PointFich { public : PointFich* t1; // adresse du maillon precedent string nom; // nom du fichier ifstream * sauvePtr; // sauvegarde de pointeur de fichier int numLigne; // numero de la ligne actuellement lue PointFich ( ) : nom(0),numLigne(0),t1(NULL),sauvePtr(NULL) {}; // défaut, ne doit pas être utilisé // constructeur utile: PointFich ( PointFich* x1,ifstream * x2,string n) : nom(n),numLigne(0),t1(x1),sauvePtr(x2) {}; // constructeur de copie PointFich (const PointFich& a) : nom(a.nom),numLigne(a.numLigne),t1(a.t1),sauvePtr(a.sauvePtr) {}; ~PointFich () {}; // operateur = PointFich& operator= (const PointFich & a) {nom=a.nom;numLigne=a.numLigne;t1=a.t1;sauvePtr=a.sauvePtr;return *this;}; }; // gestion d'exception pour nouvel_Enreg class ErrNouvelEnreg // =0 lecture OK, sinon =1 -> fin de fichier, < 0 probleme de lecture { public : int lecture; ErrNouvelEnreg (int entrees) {lecture = entrees;} ; // CONSTRUCTEURS ~ErrNouvelEnreg () {};// DESTRUCTEUR : }; // def d'une position d'incrément dans le fichier base_info class Position_BI { // surcharge de l'operator de lecture friend istream & operator >> (istream & entree, Position_BI& a); // surcharge de l'operator d'ecriture friend ostream & operator << (ostream & sort, const Position_BI& a); public : Position_BI(streampos posi=(ios::beg), int num = 0) : // constructeur position (posi), num_incr(num) {}; ~Position_BI() {}; // destructeur Position_BI(const Position_BI& a) : // constructeur de copie position (a.position),num_incr(a.num_incr) {}; // surcharge des operateurs bool operator == ( const Position_BI& a) const {if (a.num_incr == this->num_incr) return true; else return false;}; bool operator > ( const Position_BI& a) const { return (this->num_incr > a.num_incr);}; bool operator < ( const Position_BI& a) const { return (this->num_incr < a.num_incr);}; Position_BI& operator = (const Position_BI& a) {position = a.position; num_incr = a.num_incr;return *this;}; bool operator != (const Position_BI& a) { return !(*this == a);}; // données streampos position; // position dans le fichier int num_incr; // numéro de l'incrément }; // gestion d'exception pour nouvel_EnregCVisu class ErrNouvelEnregCVisu // =0 lecture OK, sinon =1 -> fin de fichier, < 0 probleme de lecture { public : int lecture; ErrNouvelEnregCVisu (int entrees) {lecture = entrees;} ; // CONSTRUCTEURS ~ErrNouvelEnregCVisu () {};// DESTRUCTEUR : }; // VARIABLES PROTEGEES : private : char* pteurnom; // pointeur sur la racine du nom du fichier principal string nomRacine; // racine du nom du fichier principal ifstream * ptrfich ; //fichier dans lequel sont lus les enregistrements ofstream * ptrcommandefich;// fichier dans lequel on écrit les commandes .info ofstream * ptrschemaXMLfich;// fichier dans lequel on écrit le schema XML char* tableau ; // le tableau de travail intermediaire char* tabMultiLignes; // stockage intermédiaire de plusieurs lignes string nomCourant; // nom du fichier courant ouvert en lecture int lec_ent_info; // type d'entrée des données // = 0 indique que ce sera via le fichier info // = 1 ce sera via un fichier base-info // = 2 ce sera via un serveur base-info // = -11 création d'un fichier de commande // = -12 création du schema XML fstream * ent_BI ; //fichier base_info dans lequel sont lus les enregistrements fstream * sort_BI ; //fichier base_info de sauvegarde fstream * ent_PI ; //fichier de la liste des pointeurs d'incréments de base info fstream * sort_PI ; //fichier base_info de sauvegarde // -------cas des temps de calcul ---------------- ofstream * sort__temps_cpu; // ------ pour la visualisation ----- ofstream * sort_princ_vrml; // fichier principal vrml ofstream * sort_legende_vrml; // fichier de legendes vrml ofstream * sort_princ_maple; // fichier principal maple ofstream * sort_princ_geomview; // fichier principal geomview ofstream * sort_legende_geomview; // fichier de legendes geomview ofstream * sort_initial_Gid; // fichier maillage initial pour Gid ofstream * sort_resultat_Gid; // fichier des résultats pour Gid ofstream * sort_initial_Gmsh; // fichier maillage initial pour Gmsh map < string, ofstream * , std::less > sort_resultat_Gmsh; list noms_base_fichiers_gmsh; // la liste des clés dans la map // on double l'info, mais cela permet de récupérer la liste indépendamment de la map // ------ pour l'automatisation de l'interactif --------- fstream * sort_CommandeVisu; // écriture des parametres de visualisation fstream * ent_CommandeVisu; // lecture des parametres de visualisation char* tableauCVisu ; // le tableau de travail intermediaire char* ptnomCVisu; // le pointeur de nom pour le CVisu string nomRacineCVisu; // racine du nom pour le CVisu int dernier_increment_lu; // variable de travail pour Increment_suivant_base_info // liste des posistions déjà investiguées dans le fichier .base_info list liste_posi_BI; // maillon courant des fichiers ouverts via .info PointFich* maille1; // METHODES PROTEGEES : void Nouvel_enreg () ; // lecture d'un nouvelle enregistrement // dans le fichier courant void Nouvel_enregCvisu () ; // lecture d'un nouvelle enregistrement // dans le fichier de commande de visualisation // ouverture du fichier CommandeVisu dans lequel sont lus les enregistrements ifstream * Ent_CommandeVisu(); // cherche l'apparition d'une chaine de caractere -> pas bon a priori void Cherche(const char *); // entrée par argument au niveau de la construction de l'objet UtilLecture // dans le cas où il y a eu un pb lec_ent_info=-100, et rien n'est initialisé bool EntreeParArgument(int argc, const char * argv[]); // entrée interactive au niveau de la construction de l'objet UtilLecture // dans le cas où il y a eu un pb lec_ent_info=-100, et rien n'est initialisé void EntreeInteractive(string& ancien,bool& ouverture_ancien); }; /// @} // end of group #endif