Back to index

nordugrid-arc-nox  1.1.0~rc6
PayloadFile.cpp
Go to the documentation of this file.
00001 #ifdef HAVE_CONFIG_H
00002 #include <config.h>
00003 #endif
00004 
00005 #include <sys/types.h>
00006 #include <sys/stat.h>
00007 #include <unistd.h>
00008 #include <fcntl.h>
00009 #ifndef WIN32 
00010 #include <sys/mman.h>
00011 #endif
00012 #include <iostream>
00013 #include "PayloadFile.h"
00014 
00015 namespace Hopi {
00016 
00017 PayloadBigFile::Size_t PayloadBigFile::threshold_ = 1024*1024*10; // 10MB by default
00018 
00019 #ifndef WIN32 
00020 
00021 PayloadFile::PayloadFile(const char* filename,Size_t start,Size_t end):handle_(-1),addr_(NULL),size_(0) {
00022   start_=start;
00023   end_=end;
00024   handle_=open(filename,O_RDONLY);
00025   if(handle_ == -1) return;
00026   struct stat st;
00027   if(fstat(handle_,&st) != 0) goto error;
00028   size_=st.st_size;
00029   if(end_ > size_) {
00030     end_=size_;
00031   }
00032   if(start_ >= size_) {
00033     start_=size_;
00034     end_=start_;
00035     return;
00036   }
00037   if(size_ > 0) {
00038     addr_=(char*)mmap(NULL,size_,PROT_READ,MAP_SHARED,handle_,0);
00039     if(addr_ == MAP_FAILED) goto error;
00040   }
00041 
00042   return;
00043 error:
00044   perror("PayloadFile");
00045   if(handle_ != -1) close(handle_);
00046   handle_=-1; size_=0; addr_=NULL;
00047   return;
00048 }
00049 
00050 PayloadFile::~PayloadFile(void) {
00051   if(addr_ != NULL) munmap(addr_,size_);
00052   close(handle_);
00053   handle_=-1; size_=0; addr_=NULL;
00054   return;
00055 }
00056 
00057 char* PayloadFile::Content(Size_t pos) {
00058   if(handle_ == -1) return NULL;
00059   if(pos >= end_) return NULL;
00060   if(pos < start_) return NULL;
00061   return (addr_+pos);
00062 }
00063 
00064 char PayloadFile::operator[](Size_t pos) const {
00065   if(handle_ == -1) return 0;
00066   if(pos >= end_) return 0;
00067   if(pos < start_) return 0;
00068   return addr_[pos];
00069 }
00070 
00071 PayloadFile::Size_t PayloadFile::Size(void) const {
00072   return size_;
00073 }
00074 
00075 char* PayloadFile::Insert(Size_t /*pos*/,Size_t /*size*/) {
00076   // Not supported
00077   return NULL;
00078 }
00079 
00080 char* PayloadFile::Insert(const char*,Size_t /*pos*/,Size_t /*size*/) {
00081   // Not supported
00082   return NULL;
00083 }
00084 
00085 char* PayloadFile::Buffer(unsigned int num) {
00086   if(handle_ == -1) return NULL;
00087   if(num>0) return NULL;
00088   if(addr_ == NULL) return NULL;
00089   return addr_+start_;
00090 }
00091 
00092 PayloadFile::Size_t PayloadFile::BufferSize(unsigned int num) const {
00093   if(handle_ == -1) return 0;
00094   if(num>0) return 0;
00095   return (end_-start_);
00096 }
00097 
00098 PayloadFile::Size_t PayloadFile::BufferPos(unsigned int num) const {
00099   if(num == 0) return start_;
00100   return end_;
00101 }
00102 
00103 bool PayloadFile::Truncate(Size_t /*size*/) {
00104   // Not supported
00105   return false;
00106 }
00107 
00108 #endif
00109 
00110 static int open_file_read(const char* filename) {
00111   return ::open(filename,O_RDONLY);
00112 }
00113 
00114 static int open_file_write(const char* filename) {
00115   return ::open(filename,O_WRONLY | O_CREAT,S_IRUSR | S_IWUSR);
00116 }
00117 
00118 PayloadBigFile::PayloadBigFile(const char* filename,Size_t start,Size_t end):
00119                        PayloadStream(open_file_read(filename)) {
00120   seekable_ = false;
00121   if(handle_ == -1) return;
00122   ::lseek(handle_,start,SEEK_SET);
00123   limit_ = end;
00124 }
00125 
00126 //PayloadBigFile::PayloadBigFile(const char* filename,Size_t size):
00127 //                       PayloadStream(open_file_write(filename)){
00128 //  seekable_ = false;
00129 //}
00130 
00131 PayloadBigFile::~PayloadBigFile(void) {
00132   if(handle_ != -1) ::close(handle_);
00133 }
00134 
00135 Arc::PayloadStream::Size_t PayloadBigFile::Pos(void) const {
00136   if(handle_ == -1) return 0;
00137   return ::lseek(handle_,0,SEEK_CUR);
00138 }
00139 
00140 Arc::PayloadStream::Size_t PayloadBigFile::Size(void) const {
00141   if(handle_ == -1) return 0;
00142   struct stat st;
00143   if(fstat(handle_,&st) != 0) return 0;
00144   return st.st_size;
00145 }
00146 
00147 Arc::PayloadStream::Size_t PayloadBigFile::Limit(void) const {
00148   Size_t s = Size();
00149   if((limit_ == (size_t)(-1)) || (limit_ > s)) return s;
00150   return limit_;
00151 }
00152 
00153 bool PayloadBigFile::Get(char* buf,int& size) {
00154   if(handle_ == -1) return false;
00155   if(limit_ == (size_t)(-1)) return PayloadStream::Get(buf,size);
00156   Size_t cpos = Pos();
00157   if(cpos >= limit_) {
00158     size=0; return false;
00159   }
00160   if((cpos+size) > limit_) size=limit_-cpos;
00161   return PayloadStream::Get(buf,size);
00162 }
00163 
00164 Arc::MessagePayload* newFileRead(const char* filename,Arc::PayloadRawInterface::Size_t start,Arc::PayloadRawInterface::Size_t end) {
00165 #ifndef WIN32 
00166   PayloadBigFile* file1 = new PayloadBigFile(filename,start,end);
00167   if(!*file1) { delete file1; return NULL; };
00168   if(file1->Size() > PayloadBigFile::Threshold()) return file1;
00169   PayloadFile* file2 = new PayloadFile(filename,start,end);
00170   if(!*file2) { delete file2; return file1; };
00171   delete file1;
00172   return file2;
00173 #else
00174   PayloadBigFile* file1 = new PayloadBigFile(filename,start,end);
00175   if(!*file1) { delete file1; return NULL; };
00176   return file1;
00177 #endif
00178 }
00179 
00180 } // namespace Hopi
00181