1 // -*- Mode : c++ -*-
2 //
3 // SUMMARY  :
4 // USAGE    :
5 // ORG      :
6 // AUTHOR   : Frederic Hecht
7 // E-MAIL   : hecht@ann.jussieu.fr
8 //
9 
10 /*
11 
12  This file is part of Freefem++
13 
14  Freefem++ is free software; you can redistribute it and/or modify
15  it under the terms of the GNU Lesser General Public License as published by
16  the Free Software Foundation; either version 2.1 of the License, or
17  (at your option) any later version.
18 
19  Freefem++  is distributed in the hope that it will be useful,
20  but WITHOUT ANY WARRANTY; without even the implied warranty of
21  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  GNU Lesser General Public License for more details.
23 
24  You should have received a copy of the GNU Lesser General Public License
25  along with Freefem++; if not, write to the Free Software
26  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
27  */
28 
29 #include <cstdio>
30 #include <iostream>
31 #include <fstream>
32 #include "error.hpp"
33 #include <cstring>
34 #include <cstdlib>
35 #include <cctype>
36 
37 #ifndef MESHIO_H_
38 #define MESHIO_H_
39 
40 using namespace std;
41 //  PB compilo HP aCC
42 #if defined(__hpux) || defined(__SUNPRO_CC)
43 #define IOS_OPENMODE int
44 #else
45 #define IOS_OPENMODE ios::openmode
46 #endif
47 extern long verbosity;
48 
49 namespace bamg {
50 
51   extern void (*MeshIstreamErrorHandler)(ios &);
52 
53   void WriteStr(ostream &out, char *str);
54 
55   double *ReadbbFile(const char *file, long &nbsol, long &lsol, const int dim = 2,
56                      const int typesol = 2);
57   double *ReadBBFile(const char *file, long &nbsol, long &lsol, int *&typesols, const int dim = 2,
58                      const int typesol = 2);
59   // solution at vertex (P1)
60 
61   union Char4orLong {
62     char c[4];
63     long l;
64   };
65 
66   class MeshIstream {
67    public:
68     istream &in;
69     const char *CurrentFile;
70     //  ifstream  fin;
71     int LineNumber, LineError, opened;
72 
cm()73     istream &cm( )    //  mange les blancs et les commentaire
74     {
75       char c;
76       int cmm = 0;
77       while (in.get(c) &&
78              (isspace(c)
79                 ? (((c == '\n' || c == char(12) || c == char(15)) && (LineNumber++, cmm = 0)), 1)
80                 : (cmm || (c == '#' && (cmm = 1)))))
81         ((void)0);
82       if (in.good( )) in.putback(c);
83       return in;
84     }
85 
86     // void rewind(){ fin.clear();fin.seekg(0);}
87 
eol()88     void eol( )    // go to end of line
89     {
90       char c;
91       while (in.get(c) && (c != '\n') && (c != '\r')) (void)0;
92     }
93     void ShowIoErr(int);
err()94     MeshIstream &err( ) {
95       if (!in.good( )) ShowIoErr(in.rdstate( ));
96       return *this;
97     }
98     //  MeshIstream(istream & i): in(i),CurrentFile(0),LineNumber(1),LineError(0) {}
99 
MeshIstream(const char * file_name)100     MeshIstream(const char *file_name)
101       : in(*new ifstream(file_name)), CurrentFile(file_name), LineNumber(1), LineError(0) {
102       if (!in) {
103         cerr << " Error Opening file " << file_name, CurrentFile = 0;
104         ShowIoErr(1);
105       }
106       if (verbosity > 4) cout << "    Openfile : " << file_name << endl;
107       err( );
108     }
109 
110     /*  //  void close()
111     {
112         if (CurrentFile) {
113           if(verbosity>5) cout << "    Closefile: " <<  CurrentFile << endl;
114           CurrentFile=0;in.close();}
115     } */
eof()116     int eof( ) { return in.eof( ); }
~MeshIstream()117     ~MeshIstream( ) { delete &in; }
118     int IsString(const char *s);
119     char *ReadStr( );
120     MeshIstream &operator>>(short &i) {
121       cm( ) >> i;
122       return err( );
123     }
124     MeshIstream &operator>>(long &i) {
125       cm( ) >> i;
126       return err( );
127     }
128     MeshIstream &operator>>(int &i) {
129       cm( ) >> i;
130       return err( );
131     }
132     MeshIstream &operator>>(float &i) {
133       cm( ) >> i;
134       return err( );
135     }
136     MeshIstream &operator>>(double &i) {
137       cm( ) >> i;
138       return err( );
139     }
140     MeshIstream &operator>>(char *&i) {
141       i = ReadStr( );
142       return err( );
143     }
144   };
145   // Fortran unformatted file  interface ----------
146 
147   class IFortranUnFormattedFile {
148     //  template<class T> friend IFortranUnFormattedFile & operator>>(IFortranUnFormattedFile &f,T &
149     //  l);
150     istream *f;
151     long i, l, n, j, nb_rec;
152     const char *file_name;
153     int to_close;
154 
155    public:
IFortranUnFormattedFile(char * name)156     IFortranUnFormattedFile(char *name)
157       : f(new ifstream(name)), i(0), l(0), n((long)-sizeof(long)), nb_rec(0), file_name(name),
158         to_close(1) {
159       if (!*f) Error(0);
160     }
161 
IFortranUnFormattedFile(MeshIstream & ff)162     IFortranUnFormattedFile(MeshIstream &ff)
163       : f(&ff.in), i(0), l(0), n((long)-sizeof(long)), nb_rec(0), file_name(ff.CurrentFile),
164         to_close(0) {
165       if (!*f) Error(0);
166     }
167 
168     ~IFortranUnFormattedFile( );
169     long Record( );
where()170     long where( ) { return j - i; }
171     void read4(char *c, int);    // for the fortran 77 char4
172     void read(char *p, const size_t lg);
173     void Error(int);
174   };
175 
176   class OFortranUnFormattedFile {
177     //  template<class T> friend OFortranUnFormattedFile & operator<<(OFortranUnFormattedFile
178     //  &f,const T & l);
179     ostream *f;
180     long i, l, n, j, nb_rec;
181     const static char *unkown;
182     const char *file_name;
183     int to_close;
184 
185    public:
186     OFortranUnFormattedFile(const char *name, IOS_OPENMODE mm = ios::trunc)
f(new ofstream (name,mm))187       : f(new ofstream(name, mm)), i(0), l(0), n((long)-sizeof(long)), nb_rec(0), file_name(name),
188         to_close(1) {
189       if (!*f) Error(0);
190     }
OFortranUnFormattedFile(ostream & ff)191     OFortranUnFormattedFile(ostream &ff)
192       : f(&ff), i(0), l(0), n((long)-sizeof(long)), nb_rec(0), file_name(unkown), to_close(0) {
193       if (!*f) Error(0);
194     }
195 
196     ~OFortranUnFormattedFile( );
197 
198     long Record(long ll = 0);
where()199     long where( ) { return j - i; }
200     void write4(const char *c, int);    // for the fortran 77 char4
201     void write(const char *p, const size_t lg);
202     void Error(int);
203   };
204 
205   /// ---------- inline -------------------------
206 
read(char * p,const size_t lg)207   inline void IFortranUnFormattedFile::read(char *p, const size_t lg) {
208     f->read(p, lg);
209     j += lg;
210     if (j > n)
211       Error(1);
212     else if (!f->good( ))
213       Error(2);
214   }
215 
write(const char * p,const size_t lg)216   inline void OFortranUnFormattedFile::write(const char *p, const size_t lg) {
217     f->write(p, lg);
218     j += lg;
219     if (l && j > n)
220       Error(1);
221     else if (!f->good( ))
222       Error(2);
223   }
224 
225   template< class T >
226   inline IFortranUnFormattedFile &operator>>(IFortranUnFormattedFile &f, T &l) {
227     f.read((char *)&l, sizeof(l));
228     return f;
229   }
230   /*  bug sur sun
231   template inline
232    OFortranUnFormattedFile & operator<<(OFortranUnFormattedFile &f,const T & l)
233    {
234      f.write((char *) &l,sizeof(l));return f;
235    }
236   on ex les template  */
237 
238   inline OFortranUnFormattedFile &operator<<(OFortranUnFormattedFile &f, const int &l) {
239     f.write((char *)&l, sizeof(l));
240     return f;
241   }
242   inline OFortranUnFormattedFile &operator<<(OFortranUnFormattedFile &f, const long &l) {
243     f.write((char *)&l, sizeof(l));
244     return f;
245   }
246   inline OFortranUnFormattedFile &operator<<(OFortranUnFormattedFile &f, const double &l) {
247     f.write((char *)&l, sizeof(l));
248     return f;
249   }
250   inline OFortranUnFormattedFile &operator<<(OFortranUnFormattedFile &f, const float &l) {
251     f.write((char *)&l, sizeof(l));
252     return f;
253   }
254 
write4(const char * c,int ll)255   inline void OFortranUnFormattedFile::write4(const char *c, int ll) {
256     int i, j;
257     Char4orLong ch4;
258     for (i = 0; i < ll; i++) {
259       ch4.l = 0;
260       for (j = 0; j < 4; j++) ch4.c[j] = *c ? *c++ : ' ';
261       *this << ch4.l;
262     }
263   }
read4(char * c,int ll)264   inline void IFortranUnFormattedFile::read4(char *c, int ll) {
265     int i, j;
266     Char4orLong ch4;
267 
268     for (i = 0; i < ll; i++) {
269       *this >> ch4.l;
270       for (j = 0; j < 4; j++) *c++ = ch4.c[j];
271     }
272     *c = 0;    // end of string
273   }
274 
275 }    // namespace bamg
276 
277 #endif    // MESHIO_H_
278