From e0c6872cf40896c7be36b11dcc744620f10adf1d Mon Sep 17 00:00:00 2001 From: Norbert Preining Date: Mon, 2 Sep 2019 13:46:59 +0900 Subject: Initial commit --- graphics/asymptote/fileio.h | 814 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 814 insertions(+) create mode 100644 graphics/asymptote/fileio.h (limited to 'graphics/asymptote/fileio.h') diff --git a/graphics/asymptote/fileio.h b/graphics/asymptote/fileio.h new file mode 100644 index 0000000000..d5e78cec29 --- /dev/null +++ b/graphics/asymptote/fileio.h @@ -0,0 +1,814 @@ +/****** + * fileio.h + * Tom Prince and John Bowman 2004/05/10 + * + * Handle input/output + ******/ + +#ifndef FILEIO_H +#define FILEIO_H + +#include +#include +#include + +#include "common.h" + +#ifdef HAVE_RPC_RPC_H +#include "xstream.h" +#endif + +#include "pair.h" +#include "triple.h" +#include "guide.h" +#include "pen.h" + +#include "camperror.h" +#include "interact.h" +#include "errormsg.h" +#include "util.h" +#include "process.h" + +namespace vm { +extern bool indebugger; +} + +namespace camp { + +extern string tab; +extern string newline; + +enum Mode {NOMODE,INPUT,OUTPUT,UPDATE,BINPUT,BOUTPUT,BUPDATE,XINPUT,XOUTPUT, + XUPDATE,OPIPE}; + +static const string FileModes[]= +{"none","input","output","output(update)", + "input(binary)","output(binary)","output(binary,update)", + "input(xdr)","output(xdr)","output(xdr,update)","output(pipe)"}; + +extern FILE *pipeout; + +inline void openpipeout() +{ + int fd=intcast(settings::getSetting("outpipe")); + if(!pipeout && fd >= 0) pipeout=fdopen(fd,"w"); + if(!pipeout) { + ostringstream buf; + buf << "Cannot open outpipe " << fd; + reportError(buf); + } +} + +class file : public gc { +protected: + string name; + bool check; // Check whether input file exists. + Mode type; + + Int nx,ny,nz; // Array dimensions + bool linemode; // Array reads will stop at eol instead of eof. + bool csvmode; // Read comma-separated values. + bool wordmode; // Delimit strings by white space instead of eol. + bool singlereal; // Read/write single-precision XDR/binary reals. + bool singleint; // Read/write single-precision XDR/binary ints. + bool signedint; // Read/write signed XDR/binary ints. + + bool closed; // File has been closed. + bool standard; // Standard input/output + bool binary; // Read in binary mode. + + bool nullfield; // Used to detect a final null field in csv+line mode. + string whitespace; + size_t index; // Terminator index. + +public: + + bool Standard() {return standard;} + + void standardEOF() { +#if defined(HAVE_LIBREADLINE) && defined(HAVE_LIBCURSES) + cout << endl; +#endif + } + + template + void purgeStandard(T&) { + if(standard) { + int c; + if(cin.eof()) + standardEOF(); + else { + cin.clear(); + while((c=cin.peek()) != EOF) { + cin.ignore(); + if(c == '\n') break; + } + } + } + } + + void purgeStandard(string&) { + if(cin.eof()) + standardEOF(); + } + + void dimension(Int Nx=-1, Int Ny=-1, Int Nz=-1) {nx=Nx; ny=Ny; nz=Nz;} + + file(const string& name, bool check=true, Mode type=NOMODE, bool binary=false, + bool closed=false) : + name(name), check(check), type(type), linemode(false), csvmode(false), + singlereal(false), singleint(true), signedint(true), + closed(closed), standard(name.empty()), + binary(binary), nullfield(false), whitespace("") {dimension();} + + virtual void open() {} + + void Check() { + if(error()) { + ostringstream buf; + buf << "Cannot open file \"" << name << "\""; + reportError(buf); + } + } + + virtual ~file() {} + + bool isOpen() { + if(closed) { + ostringstream buf; + buf << "I/O operation attempted on "; + if(name != "") buf << "closed file \'" << name << "\'"; + else buf << "null file"; + reportError(buf); + } + return true; + } + + string filename() {return name;} + virtual bool eol() {return false;} + virtual bool nexteol() {return false;} + virtual bool text() {return false;} + virtual bool eof() {return true;} + virtual bool error() {return true;} + virtual void close() {} + virtual void clear() {} + virtual Int precision(Int) {return 0;} + virtual void flush() {} + virtual size_t tell() {return 0;} + virtual void seek(Int, bool=true) {} + + string FileMode() {return FileModes[type];} + + void unsupported(const char *rw, const char *type) { + ostringstream buf; + buf << rw << " of type " << type << " not supported in " << FileMode() + << " mode"; + reportError(buf); + } + + void noread(const char *type) {unsupported("Read",type);} + void nowrite(const char *type) {unsupported("Write",type);} + + virtual void Read(bool&) {noread("bool");} + virtual void Read(Int&) {noread("int");} + virtual void Read(double&) {noread("real");} + virtual void Read(float&) {noread("real");} + virtual void Read(pair&) {noread("pair");} + virtual void Read(triple&) {noread("triple");} + virtual void Read(char&) {noread("char");} + virtual void Read(string&) {noread("string");} + virtual void readwhite(string&) {noread("string");} + + virtual void write(bool) {nowrite("bool");} + virtual void write(Int) {nowrite("int");} + virtual void write(double) {nowrite("real");} + virtual void write(const pair&) {nowrite("pair");} + virtual void write(const triple&) {nowrite("triple");} + virtual void write(const string&) {nowrite("string");} + virtual void write(const pen&) {nowrite("pen");} + virtual void write(guide *) {nowrite("guide");} + virtual void write(const transform&) {nowrite("transform");} + virtual void writeline() {nowrite("string");} + + virtual void ignoreComment() {}; + virtual void csv() {}; + + template + void ignoreComment(T&) { + ignoreComment(); + } + + void ignoreComment(string&) {} + void ignoreComment(char&) {} + + template + void read(T& val) { + if(binary) Read(val); + else { + if(standard) clear(); + if(errorstream::interrupt) throw interrupted(); + else { + ignoreComment(val); + val=T(); + if(!nullfield) + Read(val); + csv(); + whitespace=""; + } + } + } + + Int Nx() {return nx;} + Int Ny() {return ny;} + Int Nz() {return nz;} + + void Nx(Int n) {nx=n;} + void Ny(Int n) {ny=n;} + void Nz(Int n) {nz=n;} + + void LineMode(bool b) {linemode=b;} + bool LineMode() {return linemode;} + + void CSVMode(bool b) {csvmode=b; if(b) wordmode=false;} + bool CSVMode() {return csvmode;} + + void WordMode(bool b) {wordmode=b; if(b) csvmode=false;} + bool WordMode() {return wordmode;} + + void SingleReal(bool b) {singlereal=b;} + bool SingleReal() {return singlereal;} + + void SingleInt(bool b) {singleint=b;} + bool SingleInt() {return singleint;} + + void SignedInt(bool b) {signedint=b;} + bool SignedInt() {return signedint;} +}; + +class opipe : public file { +public: + opipe(const string& name) : file(name,false,OPIPE) {standard=false;} + + void open() { + openpipeout(); + } + + bool text() {return true;} + bool eof() {return pipeout ? feof(pipeout) : true;} + bool error() {return pipeout ? ferror(pipeout) : true;} + void clear() {if(pipeout) clearerr(pipeout);} + void flush() {if(pipeout) fflush(pipeout);} + + void seek(Int pos, bool begin=true) { + if(!standard && pipeout) { + clear(); + fseek(pipeout,pos,begin ? SEEK_SET : SEEK_END); + } + } + + size_t tell() { + return pipeout ? ftell(pipeout) : 0; + } + + void write(const string& val) { + fprintf(pipeout,"%s",val.c_str()); + } + + void write(bool val) { + ostringstream s; + s << val; + write(s.str()); + } + + void write(Int val) { + ostringstream s; + s << val; + write(s.str()); + } + void write(double val) { + ostringstream s; + s << val; + write(s.str()); + } + void write(const pair& val) { + ostringstream s; + s << val; + write(s.str()); + } + void write(const triple& val) { + ostringstream s; + s << val; + write(s.str()); + } + + void write(const pen &val) { + ostringstream s; + s << val; + write(s.str()); + } + + void write(guide *val) { + ostringstream s; + s << *val; + write(s.str()); + } + + void write(const transform& val) { + ostringstream s; + s << val; + write(s.str()); + } + + void writeline() { + fprintf(pipeout,"\n"); + if(errorstream::interrupt) throw interrupted(); + } +}; + +class ifile : public file { +protected: + istream *stream; + std::fstream *fstream; + char comment; + std::ios::openmode mode; + bool comma; + +public: + ifile(const string& name, char comment, bool check=true, Mode type=INPUT, + std::ios::openmode mode=std::ios::in) : + file(name,check,type), stream(&cin), fstream(NULL), comment(comment), + mode(mode), comma(false) {} + + // Binary file + ifile(const string& name, bool check=true, Mode type=BINPUT, + std::ios::openmode mode=std::ios::in) : + file(name,check,type,true), mode(mode) {} + + ~ifile() {close();} + + void open() { + if(standard) { + if(mode & std::ios::binary) + reportError("Cannot open standard input in binary mode"); + stream=&cin; + } else { + if(mode & std::ios::out) + name=outpath(name); + stream=fstream=new std::fstream(name.c_str(),mode); + if(mode & std::ios::out) { + if(error()) { + delete fstream; + std::ofstream f(name.c_str()); + f.close(); + stream=fstream=new std::fstream(name.c_str(),mode); + } + } + index=processData().ifile.add(fstream); + if(check) Check(); + } + } + + bool eol(); + bool nexteol(); + + bool text() {return true;} + bool eof() {return stream->eof();} + bool error() {return stream->fail();} + + void close() { + if(!standard && fstream) { + fstream->close(); + closed=true; + delete fstream; + fstream=NULL; + processData().ifile.remove(index); + } + } + + void clear() {stream->clear();} + + void seek(Int pos, bool begin=true) { + if(!standard && fstream) { + clear(); + fstream->seekg(pos,begin ? std::ios::beg : std::ios::end); + } + } + + size_t tell() { + if(fstream) + return fstream->tellg(); + else + return 0; + } + + void csv(); + + virtual void ignoreComment(); + + // Skip over white space + void readwhite(string& val) {val=string(); *stream >> val;} + + void Read(bool &val) {string t; readwhite(t); val=(t == "true");} + void Read(Int& val) {*stream >> val;} + void Read(double& val) {*stream >> val;} + void Read(pair& val) {*stream >> val;} + void Read(triple& val) {*stream >> val;} + void Read(char& val) {stream->get(val);} + void Read(string& val); +}; + +class iofile : public ifile { +public: + iofile(const string& name, char comment=0) : + ifile(name,comment,true,UPDATE,std::ios::in | std::ios::out) {} + + Int precision(Int p) { + return p == 0 ? stream->precision() : stream->precision(p); + } + void flush() {if(fstream) fstream->flush();} + + void write(bool val) {*fstream << (val ? "true " : "false ");} + void write(Int val) {*fstream << val;} + void write(double val) {*fstream << val;} + void write(const pair& val) {*fstream << val;} + void write(const triple& val) {*fstream << val;} + void write(const string& val) {*fstream << val;} + void write(const pen& val) {*fstream << val;} + void write(guide *val) {*fstream << *val;} + void write(const transform& val) {*fstream << val;} + + void writeline() { + *fstream << newline; + if(errorstream::interrupt) throw interrupted(); + } +}; + +class ofile : public file { +protected: + ostream *stream; + std::ofstream *fstream; + std::ios::openmode mode; +public: + ofile(const string& name, Mode type=OUTPUT, + std::ios::openmode mode=std::ios::trunc) : + file(name,true,type), stream(&cout), fstream(NULL), mode(mode) {} + + ~ofile() {close();} + + void open() { + if(standard) { + if(mode & std::ios::binary) + reportError("Cannot open standard output in binary mode"); + stream=&cout; + } else { + name=outpath(name); + stream=fstream=new std::ofstream(name.c_str(),mode | std::ios::trunc); + index=processData().ofile.add(fstream); + Check(); + } + } + + bool text() {return true;} + bool eof() {return stream->eof();} + bool error() {return stream->fail();} + + void close() { + if(!standard && fstream) { + fstream->close(); + closed=true; + delete fstream; + fstream=NULL; + processData().ofile.remove(index); + } + } + void clear() {stream->clear();} + Int precision(Int p) { + return p == 0 ? stream->precision() : stream->precision(p); + } + void flush() {stream->flush();} + + void seek(Int pos, bool begin=true) { + if(!standard && fstream) { + clear(); + fstream->seekp(pos,begin ? std::ios::beg : std::ios::end); + } + } + + size_t tell() { + if(fstream) + return fstream->tellp(); + else + return 0; + } + + bool enabled() {return !standard || settings::verbose > 1 || + interact::interactive || !settings::getSetting("quiet");} + + void write(bool val) {*stream << (val ? "true " : "false ");} + void write(Int val) {*stream << val;} + void write(double val) {*stream << val;} + void write(const pair& val) {*stream << val;} + void write(const triple& val) {*stream << val;} + void write(const string& val) {*stream << val;} + void write(const pen& val) {*stream << val;} + void write(guide *val) {*stream << *val;} + void write(const transform& val) {*stream << val;} + + void writeline(); +}; + +class ibfile : public ifile { +public: + ibfile(const string& name, bool check=true, Mode type=BINPUT, + std::ios::openmode mode=std::ios::in) : + ifile(name,check,type,mode | std::ios::binary) {} + template + void iread(T& val) { + val=T(); + if(fstream) fstream->read((char *) &val,sizeof(T)); + } + + void Read(bool& val) {iread(val);} + void Read(Int& val) { + if(signedint) { + if(singleint) {int ival; iread(ival); val=ival;} + else iread(val); + } else { + if(singleint) {unsigned ival; iread(ival); val=Intcast(ival);} + else {unsignedInt ival; iread(ival); val=Intcast(ival);} + } + } + void Read(char& val) {iread(val);} + void Read(string& val) {char c; iread(c); val=c;} + + void Read(double& val) { + if(singlereal) {float fval; iread(fval); val=fval;} + else iread(val); + } +}; + +class iobfile : public ibfile { +public: + iobfile(const string& name) : + ibfile(name,true,BUPDATE,std::ios::in | std::ios::out) {} + + void flush() {if(fstream) fstream->flush();} + + template + void iwrite(T val) { + if(fstream) fstream->write((char *) &val,sizeof(T)); + } + + void write(bool val) {iwrite(val);} + void write(Int val) { + if(signedint) { + if(singleint) iwrite(intcast(val)); + else iwrite(val); + } else { + if(singleint) iwrite(unsignedcast(val)); + else iwrite(unsignedIntcast(val)); + } + } + void write(const string& val) {iwrite(val);} + void write(const pen& val) {iwrite(val);} + void write(guide *val) {iwrite(val);} + void write(const transform& val) {iwrite(val);} + void write(double val) { + if(singlereal) iwrite((float) val); + else iwrite(val); + } + void write(const pair& val) { + write(val.getx()); + write(val.gety()); + } + void write(const triple& val) { + write(val.getx()); + write(val.gety()); + write(val.getz()); + } + void writeline() {} +}; + +class obfile : public ofile { +public: + obfile(const string& name) : ofile(name,BOUTPUT,std::ios::binary) {} + + template + void iwrite(T val) { + if(fstream) fstream->write((char *) &val,sizeof(T)); + } + + void write(bool val) {iwrite(val);} + void write(Int val) { + if(signedint) { + if(singleint) iwrite(intcast(val)); + else iwrite(val); + } else { + if(singleint) iwrite(unsignedcast(val)); + else iwrite(unsignedIntcast(val)); + } + } + void write(const string& val) {iwrite(val);} + void write(const pen& val) {iwrite(val);} + void write(guide *val) {iwrite(val);} + void write(const transform& val) {iwrite(val);} + void write(double val) { + if(singlereal) iwrite((float) val); + else iwrite(val); + } + void write(const pair& val) { + write(val.getx()); + write(val.gety()); + } + void write(const triple& val) { + write(val.getx()); + write(val.gety()); + write(val.getz()); + } + + void writeline() {} +}; + +#ifdef HAVE_RPC_RPC_H + +class ixfile : public file { +protected: + xdr::ioxstream *fstream; + xdr::xios::open_mode mode; +public: + ixfile(const string& name, bool check=true, Mode type=XINPUT, + xdr::xios::open_mode mode=xdr::xios::in) : + file(name,check,type,true), fstream(NULL), mode(mode) {} + + void open() { + fstream=new xdr::ioxstream(name.c_str(),mode); + index=processData().ixfile.add(fstream); + if(check) Check(); + } + + void close() { + if(fstream) { + fstream->close(); + closed=true; + delete fstream; + fstream=NULL; + processData().ixfile.remove(index); + } + } + + ~ixfile() {close();} + + bool eof() {return fstream ? fstream->eof() : true;} + bool error() {return fstream ? fstream->fail() : true;} + + void clear() {if(fstream) fstream->clear();} + + void seek(Int pos, bool begin=true) { + if(!standard && fstream) { + clear(); + fstream->seek(pos,begin ? xdr::xios::beg : xdr::xios::end); + } + } + + size_t tell() { + if(fstream) + return fstream->tell(); + else + return 0; + } + + void Read(Int& val) { + if(signedint) { + if(singleint) {int ival=0; *fstream >> ival; val=ival;} + else {val=0; *fstream >> val;} + } else { + if(singleint) {unsigned ival=0; *fstream >> ival; val=Intcast(ival);} + else {unsignedInt ival=0; *fstream >> ival; val=Intcast(ival);} + } + } + void Read(double& val) { + if(singlereal) {float fval=0.0; *fstream >> fval; val=fval;} + else { + val=0.0; + *fstream >> val; + } + } + void Read(pair& val) { + double x,y; + Read(x); + Read(y); + val=pair(x,y); + } + void Read(triple& val) { + double x,y,z; + Read(x); + Read(y); + Read(z); + val=triple(x,y,z); + } +}; + +class ioxfile : public ixfile { +public: + ioxfile(const string& name) : ixfile(name,true,XUPDATE,xdr::xios::out) {} + + void flush() {if(fstream) fstream->flush();} + + void write(Int val) { + if(signedint) { + if(singleint) *fstream << intcast(val); + else *fstream << val; + } else { + if(singleint) *fstream << unsignedcast(val); + else *fstream << unsignedIntcast(val); + } + } + void write(double val) { + if(singlereal) *fstream << (float) val; + else *fstream << val; + } + void write(const pair& val) { + write(val.getx()); + write(val.gety()); + } + void write(const triple& val) { + write(val.getx()); + write(val.gety()); + write(val.getz()); + } +}; + +class oxfile : public file { + xdr::oxstream *fstream; +public: + oxfile(const string& name) : file(name,true,XOUTPUT), fstream(NULL) {} + + void open() { + fstream=new xdr::oxstream(outpath(name).c_str(),xdr::xios::trunc); + index=processData().oxfile.add(fstream); + Check(); + } + + void close() { + if(fstream) { + fstream->close(); + closed=true; + delete fstream; + fstream=NULL; + processData().oxfile.remove(index); + } + } + + ~oxfile() {close();} + + bool eof() {return fstream ? fstream->eof() : true;} + bool error() {return fstream ? fstream->fail() : true;} + void clear() {if(fstream) fstream->clear();} + void flush() {if(fstream) fstream->flush();} + + void seek(Int pos, bool begin=true) { + if(!standard && fstream) { + clear(); + fstream->seek(pos,begin ? xdr::xios::beg : xdr::xios::end); + } + } + + size_t tell() { + if(fstream) + return fstream->tell(); + else + return 0; + } + + void write(Int val) { + if(signedint) { + if(singleint) *fstream << intcast(val); + else *fstream << val; + } else { + if(singleint) *fstream << unsignedcast(val); + else *fstream << unsignedIntcast(val); + } + } + void write(double val) { + if(singlereal) *fstream << (float) val; + else *fstream << val; + } + void write(const pair& val) { + write(val.getx()); + write(val.gety()); + } + void write(const triple& val) { + write(val.getx()); + write(val.gety()); + write(val.getz()); + } +}; + +#endif + +extern ofile Stdout; +extern file nullfile; + +} // namespace camp + +#endif // FILEIO_H -- cgit v1.2.3