Back to index

nordugrid-arc-nox  1.1.0~rc6
PayloadRaw.cpp
Go to the documentation of this file.
00001 #ifdef HAVE_CONFIG_H
00002 #include <config.h>
00003 #endif
00004 
00005 #include <cstring>
00006 #include <iostream>
00007 
00008 #include "PayloadRaw.h"
00009 
00010 namespace Arc {
00011 
00012 PayloadRaw::~PayloadRaw(void) {
00013   for(std::vector<PayloadRawBuf>::iterator b = buf_.begin();b!=buf_.end();++b) {
00014     if(b->allocated) free(b->data);
00015   };
00016 }
00017 
00018 static bool BufferAtPos(const std::vector<PayloadRawBuf>& buf_,PayloadRawInterface::Size_t pos,unsigned int& bufnum,PayloadRawInterface::Size_t& bufpos) {
00019   if(pos == -1) pos=0;
00020   if(pos < 0) return false;
00021   PayloadRawInterface::Size_t cpos = 0;
00022   for(bufnum = 0;bufnum<buf_.size();++bufnum) {
00023     cpos+=buf_[bufnum].length;
00024     if(cpos>pos) {
00025       bufpos=pos-(cpos-buf_[bufnum].length);
00026       return true;
00027     };
00028   };
00029   return false;
00030 }
00031 
00032 static bool BufferAtPos(std::vector<PayloadRawBuf>& buf_,PayloadRawInterface::Size_t pos,std::vector<PayloadRawBuf>::iterator& bufref,PayloadRawInterface::Size_t& bufpos) {
00033   if(pos == -1) pos=0;
00034   if(pos < 0) return false;
00035   PayloadRawInterface::Size_t cpos = 0;
00036   for(bufref = buf_.begin();bufref!=buf_.end();++bufref) {
00037     cpos+=bufref->length;
00038     if(cpos>pos) {
00039       bufpos=pos-(cpos-bufref->length);
00040       return true;
00041     };
00042   };
00043   return false;
00044 }
00045 
00046 char* PayloadRaw::Content(Size_t pos) {
00047   unsigned int bufnum;
00048   Size_t bufpos;
00049   if(!BufferAtPos(buf_,pos-offset_,bufnum,bufpos)) return NULL;
00050   return buf_[bufnum].data+bufpos;
00051 }
00052 
00053 char PayloadRaw::operator[](Size_t pos) const {
00054   unsigned int bufnum;
00055   Size_t bufpos;
00056   if(!BufferAtPos(buf_,pos-offset_,bufnum,bufpos)) return 0;
00057   return buf_[bufnum].data[bufpos];
00058 }
00059 
00060 PayloadRaw::Size_t PayloadRaw::Size(void) const {
00061   return size_;
00062   //Size_t cpos = 0;
00063   //for(unsigned int bufnum = 0;bufnum<buf_.size();bufnum++) {
00064   //  cpos+=buf_[bufnum].length;
00065   //};
00066   //return cpos;
00067 }
00068 
00069 char* PayloadRaw::Insert(Size_t pos,Size_t size) {
00070   std::vector<PayloadRawBuf>::iterator bufref;
00071   Size_t bufpos;
00072   if(!BufferAtPos(buf_,pos-offset_,bufref,bufpos)) {
00073     bufref=buf_.end(); bufpos=0;
00074     if(buf_.size() == 0) {
00075       offset_=pos;
00076     } else {
00077       pos = 0;
00078       for(unsigned int bufnum = 0;bufnum<buf_.size();bufnum++) {
00079         pos+=buf_[bufnum].length;
00080       };
00081     };
00082   };
00083   PayloadRawBuf buf;
00084   if(bufpos != 0) {
00085     // Need to split buffers
00086     buf.size=bufref->length - bufpos;
00087     buf.data=(char*)malloc(buf.size+1);
00088     if(!buf.data) return NULL;
00089     buf.data[buf.size]=0;
00090     memcpy(buf.data,bufref->data+bufpos,buf.size);
00091     buf.length=buf.size;
00092     buf.allocated=true;
00093     bufref->length=bufpos;
00094     bufref->data[bufref->length]=0;
00095     if(bufref->allocated) {
00096       char* b = (char*)realloc(bufref->data,bufref->length+1);
00097       if(b) {
00098         bufref->size=bufref->length;
00099         bufref->data=b;
00100       };
00101     };
00102     ++bufref;
00103     bufref=buf_.insert(bufref,buf);
00104   };
00105   // Inserting between buffers
00106   buf.data=(char*)malloc(size+1);
00107   if(!buf.data) return NULL;
00108   buf.data[size]=0;
00109   buf.size=size;
00110   buf.length=size;
00111   buf.allocated=true;
00112   buf_.insert(bufref,buf);
00113   if((pos+size) > size_) size_=pos+size;
00114   return buf.data;
00115 }
00116 
00117 char* PayloadRaw::Insert(const char* s,Size_t pos,Size_t size) {
00118   if(size < 0) size=strlen(s);
00119   char* s_ = Insert(pos,size);
00120   if(s_) memcpy(s_,s,size);
00121   return s_;
00122 }
00123 
00124 char* PayloadRaw::Buffer(unsigned int num) {
00125   if(num>=buf_.size()) return NULL;
00126   return buf_[num].data;
00127 }
00128 
00129 PayloadRaw::Size_t PayloadRaw::BufferSize(unsigned int num) const {
00130   if(num>=buf_.size()) return 0;
00131   return buf_[num].length;
00132 }
00133 
00134 PayloadRaw::Size_t PayloadRaw::BufferPos(unsigned int num) const {
00135   Size_t pos = offset_;
00136   std::vector<PayloadRawBuf>::const_iterator b = buf_.begin();
00137   for(;b!=buf_.end();++b) {
00138     if(!num) break;
00139     pos+=(b->length);
00140   };
00141   return pos;
00142 }
00143 
00144 bool PayloadRaw::Truncate(Size_t size) {
00145   if(size_ == size) return true; // Buffer is already of right size
00146   if(size_ < size) { // Buffer needs to be extended
00147     size_=size; return true;
00148   };
00149   if(size <= offset_) {
00150     // All buffers must be released
00151     offset_=size;
00152     for(std::vector<PayloadRawBuf>::iterator b = buf_.begin();b!=buf_.end();) {
00153       if(b->allocated) free(b->data);
00154       b=buf_.erase(b);
00155     };
00156     size_=size;
00157     return true;
00158   };
00159   Size_t l = offset_;
00160   for(unsigned int bufnum = 0;bufnum<buf_.size();bufnum++) {
00161     l+=buf_[bufnum].length;
00162   };
00163   if(l == size) {
00164     size_=size; return true;
00165   };
00166   // Buffer must be truncated
00167   std::vector<PayloadRawBuf>::iterator b;
00168   Size_t p;
00169   if(!BufferAtPos(buf_,size-offset_,b,p)) return false;
00170   if(p != 0) {
00171     b->length=p; ++b;
00172   };
00173   for(;b!=buf_.end();) {
00174     if(b->allocated) free(b->data);
00175     b=buf_.erase(b);
00176   };
00177   size_=size;
00178   return true;
00179 }
00180 
00181 const char* ContentFromPayload(const MessagePayload& payload) {
00182   try {
00183     const PayloadRawInterface& buffer = dynamic_cast<const PayloadRawInterface&>(payload);
00184     return ((PayloadRawInterface&)buffer).Content();
00185   } catch(std::exception& e) { };
00186   return "";
00187 }
00188 
00189 } // namespace Arc