diff options
Diffstat (limited to 'toj/center/src/netio.h')
-rw-r--r-- | toj/center/src/netio.h | 192 |
1 files changed, 192 insertions, 0 deletions
diff --git a/toj/center/src/netio.h b/toj/center/src/netio.h new file mode 100644 index 0000000..db54b23 --- /dev/null +++ b/toj/center/src/netio.h @@ -0,0 +1,192 @@ +class netio_protoiofn{ +public: + virtual void operator()(void *buf,size_t len,void *data) = 0; +}; + +template<typename C> +class netio_iofn : public netio_protoiofn{ +private: + typedef void (C::*netio_iofn_type)(void *buf,size_t len,void *data); + C *obj; + netio_iofn_type fn; + +public: + netio_iofn(C *obj,netio_iofn_type fn){ + this->obj = obj; + this->fn = fn; + } + void operator()(void *buf,size_t len,void *data){ + (obj->*fn)(buf,len,data); + } +}; + +#define NETIO_IOTYPE_PLAIN 0 +#define NETIO_IOTYPE_FILE 1 +class netio_iocb{ +public: + int type; + + void *buf; + int fd; + off_t off; + size_t len; + netio_protoiofn *cb_fn; + void *cb_data; + + netio_iocb(void *buf,size_t len,netio_protoiofn *cb_fn,void *cb_data){ + this->type = NETIO_IOTYPE_PLAIN; + this->buf = buf; + this->off = 0; + this->len = len; + this->cb_fn = cb_fn; + this->cb_data = cb_data; + } + netio_iocb(int fd,size_t len,netio_protoiofn *cb_fn,void *cb_data){ + this->type = NETIO_IOTYPE_FILE; + this->buf = &this->fd; + this->fd = fd; + this->off = 0; + this->len = len; + this->cb_fn = cb_fn; + this->cb_data = cb_data; + } +}; + +#define NETIO_IOSIZE 65536 +class netio{ +private: + netio_iocb *read_iocb; + std::queue<netio_iocb*> write_queue; + bool readio_reen; + char readio_buf[NETIO_IOSIZE]; + +public: + int fd; + virtual int readidle() = 0; + + netio(int fd){ + this->fd = fd; + this->read_iocb = NULL; + this->readio_reen = false; + } + ~netio(){ + close(this->fd); + } + int readio(){ + int ret; + size_t len; + netio_iocb *iocb; + + if(readio_reen == true){ + return -1; + } + readio_reen = true; + + while(true){ + if(read_iocb == NULL){ + readidle(); + } + + iocb = read_iocb; + if(iocb->type == NETIO_IOTYPE_PLAIN){ + while((ret = read(fd,(char*)iocb->buf + iocb->off,iocb->len - iocb->off)) > 0){ + iocb->off += ret; + } + }else if(iocb->type == NETIO_IOTYPE_FILE){ + while(true){ + len = iocb->len - iocb->off; + if(len >= NETIO_IOSIZE){ + len = NETIO_IOSIZE; + } + if((ret = read(fd,readio_buf,len)) <= 0){ + break; + } + + write(iocb->fd,readio_buf,ret); + iocb->off += ret; + } + } + if(iocb->off == iocb->len){ + read_iocb = NULL; + + if(iocb->cb_fn != NULL){ + (*iocb->cb_fn)(iocb->buf,iocb->len,iocb->cb_data); + }else{ + if(iocb->type == NETIO_IOTYPE_PLAIN){ + delete (char*)iocb->buf; + }else if(iocb->type == NETIO_IOTYPE_FILE){ + close(iocb->fd); + } + } + + delete iocb; + }else{ + break; + } + } + + readio_reen = false; + return 0; + } + int readbytes(void *buf,size_t len,netio_protoiofn *cb_fn,void *cb_data){ + read_iocb = new netio_iocb(buf,len,cb_fn,cb_data); + readio(); + return 0; + } + int readfile(int fd,size_t len,netio_protoiofn *cb_fn,void *cb_data){ + read_iocb = new netio_iocb(fd,len,cb_fn,cb_data); + readio(); + return 0; + } + int writeio(){ + int ret; + size_t len; + netio_iocb *iocb; + + while(!write_queue.empty()){ + iocb = write_queue.front(); + if(iocb->type == NETIO_IOTYPE_PLAIN){ + while((ret = write(fd,(char*)iocb->buf + iocb->off,iocb->len - iocb->off)) > 0){ + iocb->off += ret; + } + }else if(iocb->type == NETIO_IOTYPE_FILE){ + len = iocb->len - iocb->off; + if(len >= NETIO_IOSIZE){ + len = NETIO_IOSIZE; + } + while((ret = sendfile(fd,iocb->fd,NULL,len)) > 0){ + iocb->off += ret; + } + } + if(iocb->off == iocb->len){ + write_queue.pop(); + + if(iocb->cb_fn != NULL){ + (*iocb->cb_fn)(iocb->buf,iocb->len,iocb->cb_data); + }else{ + if(iocb->type == NETIO_IOTYPE_PLAIN){ + delete (char*)iocb->buf; + }else if(iocb->type == NETIO_IOTYPE_FILE){ + close(iocb->fd); + } + } + + delete iocb; + }else{ + break; + } + } + + return 0; + } + int writebytes(void *buf,size_t len,netio_protoiofn *cb_fn,void *cb_data){ + write_queue.push(new netio_iocb(buf,len,cb_fn,cb_data)); + writeio(); + return 0; + } + int writefile(int fd,size_t len,netio_protoiofn *cb_fn,void *cb_data){ + write_queue.push(new netio_iocb(fd,len,cb_fn,cb_data)); + writeio(); + return 0; + } +}; |