FileDescriptor.h Source File (original) (raw)

00001 00002 #ifndef MPS_FileDescriptor_H 00003 #define MPS_FileDescriptor_H 00004 00005 #include <sys/time.h> 00006 #include <sys/types.h> 00007 #include <unistd.h> 00008 00009 #ifdef WIN32 00010 #include <winsock.h> 00011 #endif 00012 00013 #include <ref.h> 00014 #include 00015 #include 00016 #include 00017 #include 00018 #include 00019 00020 class FileDescriptor; 00021 class FileDescriptorManager; 00022 00023 00024 00025 00026 00027 class FileDescriptor: public Referenceable { 00028 public: 00029
00030 00031 00032 00033 class Exception: public std::exception { 00034 private: 00035 string message;
00036 int savedErrno;
00037 00038 public: 00039 Exception(string const &msg, int _savedErrno = 0) 00040 : message(msg), 00041 savedErrno(_savedErrno) 00042 {} 00043 00044 virtual char const *what() const { return message.c_str(); }
00045 int getErrno() const { return savedErrno; }
00046 }; 00047 00048 00049 00050 00051 class EndOfFile: public Exception { 00052 public: 00053 EndOfFile(string const &msg) 00054 : Exception(msg) 00055 {} 00056 }; 00057
00058 00059 00060 00061 00062 class Callback: public Referenceable { 00063 public: 00064 00065 00066 00067 00068 typedef void (Callback::*Method)(ref const &desc); 00069 }; 00070 00071 private: 00072 ref fdMgr;
00073 int fd;
00074 char buf[1024];
00075 int buflen;
00076 int pos;
00077 00078 00079 struct callback_entry_t { 00080 ref callback;
00081 Callback::Method callbackMethod;
00082 00083 callback_entry_t() 00084 : callback(0), 00085 callbackMethod(0) 00086 {} 00087 }; 00088 00089 callback_entry_t readCallback;
00090 callback_entry_t writeCallback;
00091 00092 00093 bool fillBuffer(); 00094 00095
00096 FileDescriptor(FileDescriptor const &other); 00097 FileDescriptor const &operator=(FileDescriptor const &other); 00098 00099 00100 00101 00102 00103 void updateCallbacks(); 00104 00105 protected: 00106 00107 00108 00109 00110 00111 00112 virtual int lowlevel_read(int handle, char *buf, int len); 00113 virtual int lowlevel_write(int handle, char const *buf, int len); 00114 virtual int lowlevel_close(int handle); 00115 00116 00117 public: 00118 00119 FileDescriptor(ref const &_fdMgr, int _fd); 00120 00121 00122 virtual ~FileDescriptor(); 00123 00124 bool isOpen() const { return (fd != -1); }
00125 00126 00127 bool inputReady() { 00128 fillBuffer(); 00129 return isOpen() && (pos < buflen); 00130 } 00131 00132 int getFd() const { return fd; }
00133 ref const &getFdMgr() const;
00134 00135 virtual void close();
00136 00137 bool setNonBlocking(bool on);
00138 00139 00140 00141 void setReadCallback(ref const &cb, Callback::Method cbm); 00142 00143 void setWriteCallback(ref const &cb, Callback::Method cbm); 00144 00145 00146 void clearReadCallback(); 00147 00148 void clearWriteCallback(); 00149 00150 void fireReadCallback();
00151 void fireWriteCallback();
00152 00153 00154 00155 00156 00157 00158 00159 00160 00161 00162 void block(bool forRead, bool forWrite); 00163 00164 00165 00166 00167 00168 00169 00170 int read(char *inbuf, int len, bool complete = false); 00171 int write(char const *outbuf, int len, bool complete = false); 00172 00173 00174 00175 bool read(int &ch) { 00176 if (fillBuffer()) 00177 return false; 00178 ch = buf[pos++]; 00179 return true; 00180 } 00181 }; 00182 00183 00184 00185 00186 class FileDescriptorManager: public Referenceable { 00187 private: 00188 typedef vector< ref > descVec_t;
00189 00190 descVec_t allFds;
00191 int countRegistered;
00192 int maxFd;
00193 fd_set readFds;
00194 fd_set writeFds;
00195 00196 00197 friend class FileDescriptor; 00198 00199 void update(ref const &fd, bool forRead, bool forWrite); 00200 00201 void remove(int fdnum); 00202 00203 00204 public: 00205 FileDescriptorManager(); 00206 00207 void closeAll();
00208 00209 00210 int getMaxFd() const { return maxFd; }
00211 void fillFdSet(fd_set *rfds, fd_set *wfds) const;
00212 void processFdSet(fd_set *rfds, fd_set *wfds);
00213 00214 00215 00216 00217 00218 00219 00220 00221 bool poll(struct timeval const *timeout); 00222 00223 00224 void mainloop(); 00225 00226 00227 00228 00229 int getCountRegistered() const { return countRegistered; } 00230 00231 }; 00232 00233 #endif