// IOSTREAM // 'fake' or 'pocket' iostreams... // UnderC Development Project, 2001. #ifndef _IOSTREAM_H #define _IOSTREAM_H #ifdef _CONSOLE const bool USES_WCON = false; #else const bool USES_WCON = true; #endif #ifdef __UNDERC__ typedef void *FHandle; // this is the exported type of FILE *... #else #include #include typedef FILE *FHandle; #define wcon_fscanf fscanf #endif const int MAX_LINE = 512; namespace std { namespace ios { enum { in=1,out=2,binary=4,app=8,ate=16,trunc=32, beg=0,end=2,cur=1 }; } typedef unsigned long streampos; class base_stream { public: // these fields need to be public until friendship is sorted out! FHandle hand; bool m_redirect; bool open_file(const char *file, int access=ios::in) { if (file) { char mode[5],ch; int i = 0; if (access & ios::in) ch = 'r'; if (access & ios::out) ch = 'w'; if (access & ios::app) ch = 'a'; mode[i++] = ch; // *fix 1.2.3 ios::in | ios::out case not handled properly! // *fix 1.2.3b it's && not || ! if (ch == 'r' && access & ios::out) { mode[i++] = 'w'; mode[i++] = '+'; } if (access & ios::binary) mode[i++] = 'b'; mode[i] = '\0'; hand = fopen(file,mode); m_redirect = false; } else hand = 0; return hand ? true : false; } void close() { if (hand) fclose(hand); } virtual void flush() { fflush(hand); } }; class ostream: public base_stream { public: ostream(FHandle h=0) { hand = h; } ostream& write(char *buff, int sz) { fwrite(buff,1,sz,hand); return *this; } bool good() { return hand ? true : false; } bool bad() { return ! good(); } ostream& seekp(streampos pos, int which=ios::beg) { fseek(hand,pos,which); return *this; } streampos tellp() { return ftell(hand); } }; class ofstream: public ostream { public: bool open(const char *file, int access=0) { return open_file(file,access | ios::out); } ofstream(const char *file=0, int access=0) { open(file,access); } ~ofstream() { close(); } }; class istream: public base_stream { private: int m_no_read; public: istream(FHandle h=0) { hand = h; m_redirect = USES_WCON; } istream& getline(char *buff,int sz) { char *s = fgets(buff,sz,hand); if (! m_redirect && s) s[strlen(s)-1] = '\0'; // remove \n! return *this; } istream& read(char *buff, int sz) { m_no_read = fread(buff,1,sz,hand); return *this; } istream& putback(char ch) { ungetc(ch, hand); return *this; } int gcount() { return m_no_read; } istream& write(char *buff, int sz) { // have to say ios::out as well! fwrite(buff,1,sz,hand); return *this; } istream& seekg(streampos pos, int which=ios::beg) { fseek(hand,pos,which); return *this; } streampos tellg() { return ftell(hand); } virtual bool eof() { return feof(hand); } bool good() { return hand ? (! eof()) : false; } bool bad() { return ! good(); } bool operator! () { return ! good(); } operator int () { return good(); } }; class ifstream: public istream { public: bool open(const char *str, int access=0) { return open_file(str,access | ios::in); } ifstream(const char *file=0, int access=0) { open(file,access); } ~ifstream() { close(); } }; struct _Endl_ { int t; }; #ifdef __UNDERC__ ostream cout(_get_std_stream(2)); ostream cerr(_get_std_stream(3)); istream cin(_get_std_stream(1)); #else ostream cout(stdout); ostream cerr(stderr); istream cin(stdin); #endif _Endl_ endl; } // namespace std // *fiddle 0.9.4 All operator overloading must be kept in global // until we've sorted out cross-namespace overloading. std::ostream& operator<< (std::ostream& os, int val) { fprintf(os.hand,"%d",val); return os; } std::ostream& operator<< (std::ostream& os, long val) { fprintf(os.hand,"%d",val); return os; } std::ostream& operator<< (std::ostream& os, unsigned int val) { fprintf(os.hand,"%u",val); return os; } std::ostream& operator<< (std::ostream& os, unsigned long val) { fprintf(os.hand,"%u",val); return os; } std::ostream& operator<< (std::ostream& os, bool val) { fprintf(os.hand,"%s",val ? "true" : "false"); return os; } std::ostream& operator<< (std::ostream& os, double val) { fprintf(os.hand,"%lf",val); return os; } //*SJD* Curious that printf() is expecting a float as a double... std::ostream& operator<< (std::ostream& os, float val) { fprintf(os.hand,"%lf",(double)val); return os; } std::ostream& operator<< (std::ostream& os, const char *val) { fprintf(os.hand,"%s",val); return os; } std::ostream& operator << (std::ostream& os, std::_Endl_& e) { fprintf(os.hand,"\n"); os.flush(); return os; } std::ostream& operator<< (std::ostream& os, void *val) { fprintf(os.hand,"%x",val); return os; } std::ostream& operator<< (std::ostream& os, char ch) { fprintf(os.hand,"%c",ch); return os; } std::istream& operator>> (std::istream& is, int& val) { if (is.m_redirect) wcon_fscanf(is.hand,"%d",&val); else fscanf(is.hand,"%d",&val); return is; } std::istream& operator>> (std::istream& is, double& val) { if (is.m_redirect) wcon_fscanf(is.hand,"%lf",&val); else fscanf(is.hand,"%lf",&val); return is; } std::istream& operator>> (std::istream& is, float& val) { if (is.m_redirect) wcon_fscanf(is.hand,"%f",&val); else fscanf(is.hand,"%f",&val); return is; } std::istream& operator>> (std::istream& is, const char *val) { if (is.m_redirect) wcon_fscanf(is.hand,"%s",val); else fscanf(is.hand,"%s",val); return is; } std::istream& operator>> (std::istream& is, char& ch) { if (is.m_redirect) wcon_fscanf(is.hand,"%c",&ch); else fscanf(is.hand,"%c",&ch); return is; } std::istream& operator>> (std::istream& is, void*& ptr) { if (is.m_redirect) wcon_fscanf(is.hand,"%x",&ptr); else fscanf(is.hand,"%x",&ptr); return is; } #endif