Back to index

nordugrid-arc-nox  1.1.0~rc6
PayloadStream.cpp
Go to the documentation of this file.
00001 #ifdef HAVE_CONFIG_H
00002 #include <config.h>
00003 #endif
00004 
00005 #include <ctime>
00006 #include <sys/types.h>
00007 #include <sys/stat.h>
00008 #ifndef WIN32
00009 #include <unistd.h>
00010 #include <sys/poll.h>
00011 #else
00012 #include <arc/win32.h>
00013 #endif
00014 
00015 #include "PayloadStream.h"
00016 
00017 namespace Arc {
00018 
00019 PayloadStream::PayloadStream(int h):timeout_(60),handle_(h),seekable_(false) {
00020   struct stat st;
00021   if(fstat(handle_,&st) != 0) return;
00022   if(!(S_ISREG(st.st_mode))) return;
00023   seekable_=true;
00024 #ifdef WIN32
00025   COMMTIMEOUTS to;
00026   if(GetCommTimeouts((HANDLE)handle_,&to)) {
00027     to.ReadIntervalTimeout=timeout_*1000;
00028     to.ReadTotalTimeoutMultiplier=0;
00029     to.ReadTotalTimeoutConstant=timeout_*1000;
00030     to.WriteTotalTimeoutMultiplier=0;
00031     to.WriteTotalTimeoutConstant=timeout_*1000;
00032     SetCommTimeouts((HANDLE)handle_,&to);
00033   };
00034 #endif  
00035   return;
00036 }
00037 
00038 bool PayloadStream::Get(char* buf,int& size) {
00039   if(handle_ == -1) return false;
00040   ssize_t l = size;
00041   size=0;
00042   if(seekable_) { // check for EOF
00043     struct stat st;
00044     if(fstat(handle_,&st) != 0) return false;
00045     off_t o = lseek(handle_,0,SEEK_CUR);
00046     if(o == (off_t)(-1)) return false;
00047     o++;
00048     if(o >= st.st_size) return false;
00049   };
00050 #ifndef WIN32
00051   struct pollfd fd;
00052   fd.fd=handle_; fd.events=POLLIN | POLLPRI | POLLERR; fd.revents=0;
00053   if(poll(&fd,1,timeout_*1000) != 1) return false;
00054   if(!(fd.revents & (POLLIN | POLLPRI))) return false;
00055 #endif
00056   l=::read(handle_,buf,l);
00057   if(l == -1) return false;
00058   size=l;
00059 #ifndef WIN32
00060   if((l == 0) && (fd.revents && POLLERR)) return false;
00061 #else
00062   if(l == 0) return false;
00063 #endif
00064   return true;
00065 }
00066 
00067 bool PayloadStream::Get(std::string& buf) {
00068   char tbuf[1024];
00069   int l = sizeof(tbuf);
00070   bool result = Get(tbuf,l);
00071   buf.assign(tbuf,l);
00072   return result;
00073 }
00074 
00075 bool PayloadStream::Put(const char* buf,Size_t size) {
00076   ssize_t l;
00077   if(handle_ == -1) return false;
00078   time_t start = time(NULL);
00079   for(;size;) {
00080 #ifndef WIN32
00081     struct pollfd fd;
00082     fd.fd=handle_; fd.events=POLLOUT | POLLERR; fd.revents=0;
00083     int to = timeout_-(unsigned int)(time(NULL)-start);
00084     if(to < 0) to=0;
00085     if(poll(&fd,1,to*1000) != 1) return false;
00086     if(!(fd.revents & POLLOUT)) return false;
00087 #endif
00088     l=::write(handle_,buf,size);
00089     if(l == -1) {
00090            return false;
00091     }
00092     buf+=l; size-=l;
00093 #ifdef WIN32
00094     int to = timeout_-(unsigned int)(time(NULL)-start);
00095     if(to < 0) return false;
00096 #endif
00097   };  
00098   return true;
00099 }
00100 
00101 } // namespace Arc