1 /******
2 * fileio.h
3 * Tom Prince and John Bowman 2004/05/10
4 *
5 * Handle input/output
6 ******/
7
8 #ifndef FILEIO_H
9 #define FILEIO_H
10
11 #include <fstream>
12 #include <iostream>
13 #include <sstream>
14
15 #include "common.h"
16
17 #ifdef HAVE_RPC_RPC_H
18 #include "xstream.h"
19 #endif
20
21 #include "pair.h"
22 #include "triple.h"
23 #include "guide.h"
24 #include "pen.h"
25
26 #include "camperror.h"
27 #include "interact.h"
28 #include "errormsg.h"
29 #include "util.h"
30 #include "process.h"
31 #include "locate.h"
32 #include "parser.h"
33
34 namespace vm {
35 extern bool indebugger;
36 }
37
38 namespace camp {
39
40 extern string tab;
41 extern string newline;
42
43 enum Mode {NOMODE,INPUT,OUTPUT,UPDATE,BINPUT,BOUTPUT,BUPDATE,XINPUT,XOUTPUT,
44 XUPDATE,OPIPE};
45
46 static const string FileModes[]=
47 {"none","input","output","output(update)",
48 "input(binary)","output(binary)","output(binary,update)",
49 "input(xdr)","output(xdr)","output(xdr,update)","output(pipe)"};
50
51 extern FILE *pipeout;
52
openpipeout()53 inline void openpipeout()
54 {
55 int fd=intcast(settings::getSetting<Int>("outpipe"));
56 if(!pipeout && fd >= 0) pipeout=fdopen(fd,"w");
57 if(!pipeout) {
58 ostringstream buf;
59 buf << "Cannot open outpipe " << fd;
60 reportError(buf);
61 }
62 }
63
locatefile(string name)64 inline string locatefile(string name) {
65 string s=settings::locateFile(name);
66 return s.empty() ? name : s;
67 }
68
69 class file : public gc {
70 protected:
71 string name;
72 bool check; // Check whether input file exists.
73 Mode type;
74
75 Int nx,ny,nz; // Array dimensions
76 bool linemode; // Array reads will stop at eol instead of eof.
77 bool csvmode; // Read comma-separated values.
78 bool wordmode; // Delimit strings by white space instead of eol.
79 bool singlereal; // Read/write single-precision XDR/binary reals.
80 bool singleint; // Read/write single-precision XDR/binary ints.
81 bool signedint; // Read/write signed XDR/binary ints.
82
83 bool closed; // File has been closed.
84 bool standard; // Standard input/output
85 bool binary; // Read in binary mode.
86
87 bool nullfield; // Used to detect a final null field in csv+line mode.
88 string whitespace;
89 size_t index; // Terminator index.
90
91 public:
92
Standard()93 bool Standard() {return standard;}
94
standardEOF()95 void standardEOF() {
96 #if defined(HAVE_LIBREADLINE) && defined(HAVE_LIBCURSES)
97 cout << endl;
98 #endif
99 }
100
101 template<class T>
purgeStandard(T &)102 void purgeStandard(T&) {
103 if(standard) {
104 int c;
105 if(cin.eof())
106 standardEOF();
107 else {
108 cin.clear();
109 while((c=cin.peek()) != EOF) {
110 cin.ignore();
111 if(c == '\n') break;
112 }
113 }
114 }
115 }
116
purgeStandard(string &)117 void purgeStandard(string&) {
118 if(cin.eof())
119 standardEOF();
120 }
121
122 void dimension(Int Nx=-1, Int Ny=-1, Int Nz=-1) {
123 if(Nx < -2 || Ny < -2 || Nz < -2) {
124 ostringstream buf;
125 buf << "Invalid array dimensions: " << Nx << ", " << Ny << ", " << Nz;
126 reportError(buf);
127 }
128
129 nx=Nx; ny=Ny; nz=Nz;
130 }
131
132 file(const string& name, bool check=true, Mode type=NOMODE,
133 bool binary=false, bool closed=false) :
name(name)134 name(name), check(check), type(type), linemode(false), csvmode(false),
135 wordmode(false), singlereal(false), singleint(true), signedint(true),
136 closed(closed), standard(name.empty()), binary(binary), nullfield(false),
137 whitespace("") {dimension();}
138
open()139 virtual void open() {}
140
Check()141 void Check() {
142 if(error()) {
143 ostringstream buf;
144 buf << "Cannot open file \"" << name << "\"";
145 reportError(buf);
146 }
147 }
148
~file()149 virtual ~file() {}
150
isOpen()151 bool isOpen() {
152 if(closed) {
153 ostringstream buf;
154 buf << "I/O operation attempted on ";
155 if(name != "") buf << "closed file \'" << name << "\'";
156 else buf << "null file";
157 reportError(buf);
158 }
159 return true;
160 }
161
filename()162 string filename() {return name;}
eol()163 virtual bool eol() {return false;}
nexteol()164 virtual bool nexteol() {return false;}
text()165 virtual bool text() {return false;}
eof()166 virtual bool eof() {return true;}
error()167 virtual bool error() {return true;}
close()168 virtual void close() {}
clear()169 virtual void clear() {}
precision(Int)170 virtual Int precision(Int) {return 0;}
flush()171 virtual void flush() {}
tell()172 virtual size_t tell() {return 0;}
173 virtual void seek(Int, bool=true) {}
174
FileMode()175 string FileMode() {return FileModes[type];}
176
unsupported(const char * rw,const char * type)177 void unsupported(const char *rw, const char *type) {
178 ostringstream buf;
179 buf << rw << " of type " << type << " not supported in " << FileMode()
180 << " mode";
181 reportError(buf);
182 }
183
noread(const char * type)184 void noread(const char *type) {unsupported("Read",type);}
nowrite(const char * type)185 void nowrite(const char *type) {unsupported("Write",type);}
186
Read(bool &)187 virtual void Read(bool&) {noread("bool");}
Read(Int &)188 virtual void Read(Int&) {noread("int");}
Read(double &)189 virtual void Read(double&) {noread("real");}
Read(float &)190 virtual void Read(float&) {noread("real");}
Read(pair &)191 virtual void Read(pair&) {noread("pair");}
Read(triple &)192 virtual void Read(triple&) {noread("triple");}
Read(char &)193 virtual void Read(char&) {noread("char");}
Read(string &)194 virtual void Read(string&) {noread("string");}
readwhite(string &)195 virtual void readwhite(string&) {noread("string");}
196
write(bool)197 virtual void write(bool) {nowrite("bool");}
write(Int)198 virtual void write(Int) {nowrite("int");}
write(double)199 virtual void write(double) {nowrite("real");}
write(const pair &)200 virtual void write(const pair&) {nowrite("pair");}
write(const triple &)201 virtual void write(const triple&) {nowrite("triple");}
write(const string &)202 virtual void write(const string&) {nowrite("string");}
write(const pen &)203 virtual void write(const pen&) {nowrite("pen");}
write(guide *)204 virtual void write(guide *) {nowrite("guide");}
write(const transform &)205 virtual void write(const transform&) {nowrite("transform");}
writeline()206 virtual void writeline() {nowrite("string");}
207
ignoreComment()208 virtual void ignoreComment() {};
csv()209 virtual void csv() {};
210
211 template<class T>
ignoreComment(T &)212 void ignoreComment(T&) {
213 ignoreComment();
214 }
215
ignoreComment(string &)216 void ignoreComment(string&) {}
ignoreComment(char &)217 void ignoreComment(char&) {}
218
219 template<class T>
read(T & val)220 void read(T& val) {
221 if(binary) Read(val);
222 else {
223 if(standard) clear();
224 if(errorstream::interrupt) throw interrupted();
225 else {
226 ignoreComment(val);
227 val=T();
228 if(!nullfield)
229 Read(val);
230 csv();
231 whitespace="";
232 }
233 }
234 }
235
Nx()236 Int Nx() {return nx;}
Ny()237 Int Ny() {return ny;}
Nz()238 Int Nz() {return nz;}
239
Nx(Int n)240 void Nx(Int n) {nx=n;}
Ny(Int n)241 void Ny(Int n) {ny=n;}
Nz(Int n)242 void Nz(Int n) {nz=n;}
243
LineMode(bool b)244 void LineMode(bool b) {linemode=b;}
LineMode()245 bool LineMode() {return linemode;}
246
CSVMode(bool b)247 void CSVMode(bool b) {csvmode=b; if(b) wordmode=false;}
CSVMode()248 bool CSVMode() {return csvmode;}
249
WordMode(bool b)250 void WordMode(bool b) {wordmode=b; if(b) csvmode=false;}
WordMode()251 bool WordMode() {return wordmode;}
252
SingleReal(bool b)253 void SingleReal(bool b) {singlereal=b;}
SingleReal()254 bool SingleReal() {return singlereal;}
255
SingleInt(bool b)256 void SingleInt(bool b) {singleint=b;}
SingleInt()257 bool SingleInt() {return singleint;}
258
SignedInt(bool b)259 void SignedInt(bool b) {signedint=b;}
SignedInt()260 bool SignedInt() {return signedint;}
261 };
262
263 class opipe : public file {
264 public:
opipe(const string & name)265 opipe(const string& name) : file(name,false,OPIPE) {standard=false;}
266
open()267 void open() {
268 openpipeout();
269 }
270
text()271 bool text() {return true;}
eof()272 bool eof() {return pipeout ? feof(pipeout) : true;}
error()273 bool error() {return pipeout ? ferror(pipeout) : true;}
clear()274 void clear() {if(pipeout) clearerr(pipeout);}
flush()275 void flush() {if(pipeout) fflush(pipeout);}
276
277 void seek(Int pos, bool begin=true) {
278 if(!standard && pipeout) {
279 clear();
280 fseek(pipeout,pos,begin ? SEEK_SET : SEEK_END);
281 }
282 }
283
tell()284 size_t tell() {
285 return pipeout ? ftell(pipeout) : 0;
286 }
287
write(const string & val)288 void write(const string& val) {
289 fprintf(pipeout,"%s",val.c_str());
290 }
291
write(bool val)292 void write(bool val) {
293 ostringstream s;
294 s << val;
295 write(s.str());
296 }
297
write(Int val)298 void write(Int val) {
299 ostringstream s;
300 s << val;
301 write(s.str());
302 }
write(double val)303 void write(double val) {
304 ostringstream s;
305 s << val;
306 write(s.str());
307 }
write(const pair & val)308 void write(const pair& val) {
309 ostringstream s;
310 s << val;
311 write(s.str());
312 }
write(const triple & val)313 void write(const triple& val) {
314 ostringstream s;
315 s << val;
316 write(s.str());
317 }
318
write(const pen & val)319 void write(const pen &val) {
320 ostringstream s;
321 s << val;
322 write(s.str());
323 }
324
write(guide * val)325 void write(guide *val) {
326 ostringstream s;
327 s << *val;
328 write(s.str());
329 }
330
write(const transform & val)331 void write(const transform& val) {
332 ostringstream s;
333 s << val;
334 write(s.str());
335 }
336
writeline()337 void writeline() {
338 fprintf(pipeout,"\n");
339 if(errorstream::interrupt) throw interrupted();
340 }
341 };
342
343 class ifile : public file {
344 protected:
345 istream *stream;
346 std::fstream *fstream;
347 stringstream buf;
348 char comment;
349 std::ios::openmode mode;
350 bool comma;
351
352 public:
353 ifile(const string& name, char comment, bool check=true, Mode type=INPUT,
354 std::ios::openmode mode=std::ios::in) :
file(name,check,type)355 file(name,check,type), stream(&cin), fstream(NULL),
356 comment(comment), mode(mode), comma(false) {}
357
358 // Binary file
359 ifile(const string& name, bool check=true, Mode type=BINPUT,
360 std::ios::openmode mode=std::ios::in) :
file(name,check,type,true)361 file(name,check,type,true), mode(mode) {}
362
~ifile()363 ~ifile() {close();}
364
365 void open();
366 bool eol();
367 bool nexteol();
368
text()369 bool text() {return true;}
eof()370 bool eof() {return stream->eof();}
error()371 bool error() {return stream->fail();}
372
close()373 void close() {
374 if(!standard && fstream) {
375 fstream->close();
376 closed=true;
377 delete fstream;
378 fstream=NULL;
379 processData().ifile.remove(index);
380 }
381 }
382
clear()383 void clear() {stream->clear();}
384
385 void seek(Int pos, bool begin=true) {
386 if(!standard && fstream) {
387 clear();
388 fstream->seekg(pos,begin ? std::ios::beg : std::ios::end);
389 }
390 }
391
tell()392 size_t tell() {
393 if(fstream)
394 return fstream->tellg();
395 else
396 return 0;
397 }
398
399 void csv();
400
401 virtual void ignoreComment();
402
403 // Skip over white space
readwhite(string & val)404 void readwhite(string& val) {val=string(); *stream >> val;}
405
Read(bool & val)406 void Read(bool &val) {string t; readwhite(t); val=(t == "true");}
Read(Int & val)407 void Read(Int& val) {*stream >> val;}
Read(double & val)408 void Read(double& val) {*stream >> val;}
Read(pair & val)409 void Read(pair& val) {*stream >> val;}
Read(triple & val)410 void Read(triple& val) {*stream >> val;}
Read(char & val)411 void Read(char& val) {stream->get(val);}
412 void Read(string& val);
413 };
414
415 class iofile : public ifile {
416 public:
417 iofile(const string& name, char comment=0) :
418 ifile(name,comment,true,UPDATE,std::ios::in | std::ios::out) {}
419
precision(Int p)420 Int precision(Int p) {
421 return p == 0 ? stream->precision(settings::getSetting<Int>("digits")) :
422 stream->precision(p);
423 }
flush()424 void flush() {if(fstream) fstream->flush();}
425
write(bool val)426 void write(bool val) {*fstream << (val ? "true " : "false ");}
write(Int val)427 void write(Int val) {*fstream << val;}
write(double val)428 void write(double val) {*fstream << val;}
write(const pair & val)429 void write(const pair& val) {*fstream << val;}
write(const triple & val)430 void write(const triple& val) {*fstream << val;}
write(const string & val)431 void write(const string& val) {*fstream << val;}
write(const pen & val)432 void write(const pen& val) {*fstream << val;}
write(guide * val)433 void write(guide *val) {*fstream << *val;}
write(const transform & val)434 void write(const transform& val) {*fstream << val;}
435
writeline()436 void writeline() {
437 *fstream << newline;
438 if(errorstream::interrupt) throw interrupted();
439 }
440 };
441
442 class ofile : public file {
443 protected:
444 ostream *stream;
445 std::ofstream *fstream;
446 std::ios::openmode mode;
447 public:
448 ofile(const string& name, Mode type=OUTPUT,
449 std::ios::openmode mode=std::ios::trunc) :
file(name,true,type)450 file(name,true,type), stream(&cout), fstream(NULL), mode(mode) {}
451
~ofile()452 ~ofile() {close();}
453
open()454 void open() {
455 if(standard) {
456 if(mode & std::ios::binary)
457 reportError("Cannot open standard output in binary mode");
458 stream=&cout;
459 } else {
460 name=outpath(name);
461 stream=fstream=new std::ofstream(name.c_str(),mode | std::ios::trunc);
462 stream->precision(settings::getSetting<Int>("digits"));
463 index=processData().ofile.add(fstream);
464 Check();
465 }
466 }
467
text()468 bool text() {return true;}
eof()469 bool eof() {return stream->eof();}
error()470 bool error() {return stream->fail();}
471
close()472 void close() {
473 if(!standard && fstream) {
474 fstream->close();
475 closed=true;
476 delete fstream;
477 fstream=NULL;
478 processData().ofile.remove(index);
479 }
480 }
clear()481 void clear() {stream->clear();}
precision(Int p)482 Int precision(Int p) {
483 return p == 0 ? stream->precision(settings::getSetting<Int>("digits")) :
484 stream->precision(p);
485 }
flush()486 void flush() {stream->flush();}
487
488 void seek(Int pos, bool begin=true) {
489 if(!standard && fstream) {
490 clear();
491 fstream->seekp(pos,begin ? std::ios::beg : std::ios::end);
492 }
493 }
494
tell()495 size_t tell() {
496 if(fstream)
497 return fstream->tellp();
498 else
499 return 0;
500 }
501
enabled()502 bool enabled() {return !standard || settings::verbose > 1 ||
503 interact::interactive || !settings::getSetting<bool>("quiet");}
504
write(bool val)505 void write(bool val) {*stream << (val ? "true " : "false ");}
write(Int val)506 void write(Int val) {*stream << val;}
write(double val)507 void write(double val) {*stream << val;}
write(const pair & val)508 void write(const pair& val) {*stream << val;}
write(const triple & val)509 void write(const triple& val) {*stream << val;}
write(const string & val)510 void write(const string& val) {*stream << val;}
write(const pen & val)511 void write(const pen& val) {*stream << val;}
write(guide * val)512 void write(guide *val) {*stream << *val;}
write(const transform & val)513 void write(const transform& val) {*stream << val;}
514
515 void writeline();
516 };
517
518 class ibfile : public ifile {
519 public:
520 ibfile(const string& name, bool check=true, Mode type=BINPUT,
521 std::ios::openmode mode=std::ios::in) :
522 ifile(name,check,type,mode | std::ios::binary) {}
523 template<class T>
iread(T & val)524 void iread(T& val) {
525 val=T();
526 if(fstream) fstream->read((char *) &val,sizeof(T));
527 }
528
Read(bool & val)529 void Read(bool& val) {iread(val);}
Read(Int & val)530 void Read(Int& val) {
531 if(signedint) {
532 if(singleint) {int ival; iread(ival); val=ival;}
533 else iread(val);
534 } else {
535 if(singleint) {unsigned ival; iread(ival); val=Intcast(ival);}
536 else {unsignedInt ival; iread(ival); val=Intcast(ival);}
537 }
538 }
Read(char & val)539 void Read(char& val) {iread(val);}
Read(string & val)540 void Read(string& val) {char c; iread(c); val=c;}
541
Read(double & val)542 void Read(double& val) {
543 if(singlereal) {float fval; iread(fval); val=fval;}
544 else iread(val);
545 }
546 };
547
548 class iobfile : public ibfile {
549 public:
iobfile(const string & name)550 iobfile(const string& name) :
551 ibfile(name,true,BUPDATE,std::ios::in | std::ios::out) {}
552
flush()553 void flush() {if(fstream) fstream->flush();}
554
555 template<class T>
iwrite(T val)556 void iwrite(T val) {
557 if(fstream) fstream->write((char *) &val,sizeof(T));
558 }
559
write(bool val)560 void write(bool val) {iwrite(val);}
write(Int val)561 void write(Int val) {
562 if(signedint) {
563 if(singleint) iwrite(intcast(val));
564 else iwrite(val);
565 } else {
566 if(singleint) iwrite(unsignedcast(val));
567 else iwrite(unsignedIntcast(val));
568 }
569 }
write(const string & val)570 void write(const string& val) {iwrite(val);}
write(const pen & val)571 void write(const pen& val) {iwrite(val);}
write(guide * val)572 void write(guide *val) {iwrite(val);}
write(const transform & val)573 void write(const transform& val) {iwrite(val);}
write(double val)574 void write(double val) {
575 if(singlereal) iwrite((float) val);
576 else iwrite(val);
577 }
write(const pair & val)578 void write(const pair& val) {
579 write(val.getx());
580 write(val.gety());
581 }
write(const triple & val)582 void write(const triple& val) {
583 write(val.getx());
584 write(val.gety());
585 write(val.getz());
586 }
writeline()587 void writeline() {}
588 };
589
590 class obfile : public ofile {
591 public:
obfile(const string & name)592 obfile(const string& name) : ofile(name,BOUTPUT,std::ios::binary) {}
593
594 template<class T>
iwrite(T val)595 void iwrite(T val) {
596 if(fstream) fstream->write((char *) &val,sizeof(T));
597 }
598
write(bool val)599 void write(bool val) {iwrite(val);}
write(Int val)600 void write(Int val) {
601 if(signedint) {
602 if(singleint) iwrite(intcast(val));
603 else iwrite(val);
604 } else {
605 if(singleint) iwrite(unsignedcast(val));
606 else iwrite(unsignedIntcast(val));
607 }
608 }
write(const string & val)609 void write(const string& val) {iwrite(val);}
write(const pen & val)610 void write(const pen& val) {iwrite(val);}
write(guide * val)611 void write(guide *val) {iwrite(val);}
write(const transform & val)612 void write(const transform& val) {iwrite(val);}
write(double val)613 void write(double val) {
614 if(singlereal) iwrite((float) val);
615 else iwrite(val);
616 }
write(const pair & val)617 void write(const pair& val) {
618 write(val.getx());
619 write(val.gety());
620 }
write(const triple & val)621 void write(const triple& val) {
622 write(val.getx());
623 write(val.gety());
624 write(val.getz());
625 }
626
writeline()627 void writeline() {}
628 };
629
630 #ifdef HAVE_RPC_RPC_H
631
632 class ixfile : public file {
633 protected:
634 xdr::ioxstream *fstream;
635 xdr::xios::open_mode mode;
636 public:
637 ixfile(const string& name, bool check=true, Mode type=XINPUT,
638 xdr::xios::open_mode mode=xdr::xios::in) :
file(name,check,type,true)639 file(name,check,type,true), fstream(NULL), mode(mode) {}
640
open()641 void open() {
642 name=locatefile(inpath(name));
643 fstream=new xdr::ioxstream(name.c_str(),mode);
644 index=processData().ixfile.add(fstream);
645 if(check) Check();
646 }
647
close()648 void close() {
649 if(fstream) {
650 fstream->close();
651 closed=true;
652 delete fstream;
653 fstream=NULL;
654 processData().ixfile.remove(index);
655 }
656 }
657
~ixfile()658 ~ixfile() {close();}
659
eof()660 bool eof() {return fstream ? fstream->eof() : true;}
error()661 bool error() {return fstream ? fstream->fail() : true;}
662
clear()663 void clear() {if(fstream) fstream->clear();}
664
665 void seek(Int pos, bool begin=true) {
666 if(!standard && fstream) {
667 clear();
668 fstream->seek(pos,begin ? xdr::xios::beg : xdr::xios::end);
669 }
670 }
671
tell()672 size_t tell() {
673 if(fstream)
674 return fstream->tell();
675 else
676 return 0;
677 }
678
Read(Int & val)679 void Read(Int& val) {
680 if(signedint) {
681 if(singleint) {int ival=0; *fstream >> ival; val=ival;}
682 else {val=0; *fstream >> val;}
683 } else {
684 if(singleint) {unsigned ival=0; *fstream >> ival; val=Intcast(ival);}
685 else {unsignedInt ival=0; *fstream >> ival; val=Intcast(ival);}
686 }
687 }
Read(double & val)688 void Read(double& val) {
689 if(singlereal) {float fval=0.0; *fstream >> fval; val=fval;}
690 else {
691 val=0.0;
692 *fstream >> val;
693 }
694 }
Read(pair & val)695 void Read(pair& val) {
696 double x,y;
697 Read(x);
698 Read(y);
699 val=pair(x,y);
700 }
Read(triple & val)701 void Read(triple& val) {
702 double x,y,z;
703 Read(x);
704 Read(y);
705 Read(z);
706 val=triple(x,y,z);
707 }
708 };
709
710 class ioxfile : public ixfile {
711 public:
ioxfile(const string & name)712 ioxfile(const string& name) : ixfile(outpath(name),true,XUPDATE,
713 xdr::xios::out) {}
714
flush()715 void flush() {if(fstream) fstream->flush();}
716
write(Int val)717 void write(Int val) {
718 if(signedint) {
719 if(singleint) *fstream << intcast(val);
720 else *fstream << val;
721 } else {
722 if(singleint) *fstream << unsignedcast(val);
723 else *fstream << unsignedIntcast(val);
724 }
725 }
write(double val)726 void write(double val) {
727 if(singlereal) *fstream << (float) val;
728 else *fstream << val;
729 }
write(const pair & val)730 void write(const pair& val) {
731 write(val.getx());
732 write(val.gety());
733 }
write(const triple & val)734 void write(const triple& val) {
735 write(val.getx());
736 write(val.gety());
737 write(val.getz());
738 }
739 };
740
741 class oxfile : public file {
742 xdr::oxstream *fstream;
743 public:
oxfile(const string & name)744 oxfile(const string& name) : file(name,true,XOUTPUT), fstream(NULL) {}
745
open()746 void open() {
747 fstream=new xdr::oxstream(outpath(name).c_str(),xdr::xios::trunc);
748 index=processData().oxfile.add(fstream);
749 Check();
750 }
751
close()752 void close() {
753 if(fstream) {
754 fstream->close();
755 closed=true;
756 delete fstream;
757 fstream=NULL;
758 processData().oxfile.remove(index);
759 }
760 }
761
~oxfile()762 ~oxfile() {close();}
763
eof()764 bool eof() {return fstream ? fstream->eof() : true;}
error()765 bool error() {return fstream ? fstream->fail() : true;}
clear()766 void clear() {if(fstream) fstream->clear();}
flush()767 void flush() {if(fstream) fstream->flush();}
768
769 void seek(Int pos, bool begin=true) {
770 if(!standard && fstream) {
771 clear();
772 fstream->seek(pos,begin ? xdr::xios::beg : xdr::xios::end);
773 }
774 }
775
tell()776 size_t tell() {
777 if(fstream)
778 return fstream->tell();
779 else
780 return 0;
781 }
782
write(Int val)783 void write(Int val) {
784 if(signedint) {
785 if(singleint) *fstream << intcast(val);
786 else *fstream << val;
787 } else {
788 if(singleint) *fstream << unsignedcast(val);
789 else *fstream << unsignedIntcast(val);
790 }
791 }
write(double val)792 void write(double val) {
793 if(singlereal) *fstream << (float) val;
794 else *fstream << val;
795 }
write(const pair & val)796 void write(const pair& val) {
797 write(val.getx());
798 write(val.gety());
799 }
write(const triple & val)800 void write(const triple& val) {
801 write(val.getx());
802 write(val.gety());
803 write(val.getz());
804 }
805 };
806
807 #endif
808
809 extern ofile Stdout;
810 extern file nullfile;
811
812 } // namespace camp
813
814 #endif // FILEIO_H
815