Back to home page

EIC code displayed by LXR

 
 

    


Warning, /include/Geant4/tools/rroot/rbuf is written in an unsupported language. File is not indexed.

0001 // Copyright (C) 2010, Guy Barrand. All rights reserved.
0002 // See the file tools.license for terms.
0003 
0004 #ifndef tools_rroot_rbuf
0005 #define tools_rroot_rbuf
0006 
0007 #include "../stype"
0008 #include "../long_out"
0009 #include "../charp_out"
0010 
0011 #include <ostream>
0012 #include <vector>
0013 #include <cstring> //memcpy
0014 
0015 namespace tools {
0016 namespace rroot {
0017 
0018 class rbuf {
0019 
0020   /////////////////////////////////////////////////////////
0021   /// swap ////////////////////////////////////////////////
0022   /////////////////////////////////////////////////////////
0023   // NOTE : on most common platforms (including Android, iPad)
0024   //        CERN-ROOT byte swaps ! (Bad luck). We have arranged to
0025   //        optimize this operation. The below "_swap_" functions
0026   //        do not have local variables and manipulates pointers
0027   //        directly.
0028 
0029   static void read_swap_2(char* a_pos,char* a_x) {
0030     *a_x++ = *(a_pos+1);
0031     *a_x++ = *a_pos;
0032   }
0033   static void read_swap_4(char* a_pos,char* a_x) {
0034     a_pos += 3;
0035     *a_x++ = *a_pos--;
0036     *a_x++ = *a_pos--;
0037     *a_x++ = *a_pos--;
0038     *a_x++ = *a_pos;
0039   }
0040   static void read_swap_8(char* a_pos,char* a_x) {
0041     a_pos += 7;
0042     *a_x++ = *a_pos--;
0043     *a_x++ = *a_pos--;
0044     *a_x++ = *a_pos--;
0045     *a_x++ = *a_pos--;
0046     *a_x++ = *a_pos--;
0047     *a_x++ = *a_pos--;
0048     *a_x++ = *a_pos--;
0049     *a_x++ = *a_pos;
0050   }
0051   /////////////////////////////////////////////////////////
0052   /// nswp ////////////////////////////////////////////////
0053   /////////////////////////////////////////////////////////
0054   static void read_nswp_2(char* a_pos,char* a_x) {
0055     ::memcpy(a_x,a_pos,2);
0056   }
0057   static void read_nswp_4(char* a_pos,char* a_x) {
0058     ::memcpy(a_x,a_pos,4);
0059   }
0060   static void read_nswp_8(char* a_pos,char* a_x) {
0061     ::memcpy(a_x,a_pos,8);
0062   }
0063   /////////////////////////////////////////////////////////
0064   /////////////////////////////////////////////////////////
0065   /////////////////////////////////////////////////////////
0066 
0067 
0068   static const std::string& s_class() {
0069     static const std::string s_v("tools::rroot::rbuf");
0070     return s_v;
0071   }
0072   typedef void (*r_2_func)(char*,char*);
0073   typedef void (*r_4_func)(char*,char*);
0074   typedef void (*r_8_func)(char*,char*);
0075 public:
0076   rbuf(std::ostream& a_out,bool a_byte_swap,const char* a_eob,char*& a_pos)
0077   :m_out(a_out)
0078   ,m_byte_swap(a_byte_swap)
0079   ,m_eob(a_eob)
0080   ,m_pos(a_pos)
0081 
0082   ,m_r_2_func(0)
0083   ,m_r_4_func(0)
0084   ,m_r_8_func(0)
0085   {
0086     set_byte_swap(a_byte_swap);
0087   }
0088   virtual ~rbuf(){
0089   }
0090 public:
0091   rbuf(const rbuf& a_from)
0092   :m_out(a_from.m_out)
0093   ,m_byte_swap(a_from.m_byte_swap)
0094   ,m_eob(a_from.m_eob)
0095   ,m_pos(a_from.m_pos)
0096   ,m_r_2_func(a_from.m_r_2_func)
0097   ,m_r_4_func(a_from.m_r_4_func)
0098   ,m_r_8_func(a_from.m_r_8_func)
0099   {
0100     set_byte_swap(a_from.m_byte_swap);
0101   }
0102   rbuf& operator=(const rbuf& a_from){
0103     set_byte_swap(a_from.m_byte_swap);
0104     m_eob = a_from.m_eob;
0105     //m_pos is a ref.
0106     m_r_2_func = a_from.m_r_2_func;
0107     m_r_4_func = a_from.m_r_4_func;
0108     m_r_8_func = a_from.m_r_8_func;
0109     return *this;
0110   }
0111 public:
0112   std::ostream& out() const {return m_out;}
0113 
0114   void skip(unsigned int a_num) {m_pos += a_num;}
0115 
0116   void set_eob(const char* a_eob){m_eob = a_eob;}
0117   char*& pos() {return m_pos;}
0118   const char* eob() const {return m_eob;}
0119 
0120   void set_byte_swap(bool a_value) {
0121     m_byte_swap = a_value;
0122     if(m_byte_swap) {
0123       m_r_2_func = read_swap_2;
0124       m_r_4_func = read_swap_4;
0125       m_r_8_func = read_swap_8;
0126     } else {
0127       m_r_2_func = read_nswp_2;
0128       m_r_4_func = read_nswp_4;
0129       m_r_8_func = read_nswp_8;
0130     }
0131   }
0132 public:
0133   bool read(unsigned char& a_x) {
0134     if(!_check_eob<unsigned char>(a_x)) return false;
0135     a_x = *m_pos;m_pos++;
0136     return true;
0137   }
0138   bool read(unsigned short& a_x) {
0139     if(!_check_eob<unsigned short>(a_x)) return false;
0140     m_r_2_func(m_pos,(char*)&a_x);
0141     m_pos += sizeof(unsigned short);
0142     return true;
0143   }
0144 
0145   bool read(unsigned int& a_x) {
0146     if(!_check_eob<unsigned int>(a_x)) return false;
0147     m_r_4_func(m_pos,(char*)&a_x);
0148     m_pos += sizeof(unsigned int);
0149     return true;
0150   }
0151 
0152   bool read(uint64& a_x){
0153     if(!_check_eob<uint64>(a_x)) return false;
0154     m_r_8_func(m_pos,(char*)&a_x);
0155     m_pos += 8;
0156     return true;
0157   }
0158 
0159   bool read(float& a_x) {
0160     if(!_check_eob<float>(a_x)) return false;
0161     m_r_4_func(m_pos,(char*)&a_x);
0162     m_pos += sizeof(float);
0163     return true;
0164   }
0165 
0166   bool read(double& a_x) {
0167     if(!_check_eob<double>(a_x)) return false;
0168     m_r_8_func(m_pos,(char*)&a_x);
0169     m_pos += sizeof(double);
0170     return true;
0171   }
0172 
0173   bool read(char& a_x) {
0174     if(!_check_eob<char>(a_x)) return false;
0175     a_x = *m_pos;m_pos++;
0176     return true;
0177   }
0178   bool read(short& a_x) {
0179     if(!_check_eob<short>(a_x)) return false;
0180     m_r_2_func(m_pos,(char*)&a_x);
0181     m_pos += sizeof(short);
0182     return true;
0183   }
0184 
0185   bool read(int& a_x) {
0186     if(!_check_eob<int>(a_x)) return false;
0187     m_r_4_func(m_pos,(char*)&a_x);
0188     m_pos += sizeof(int);
0189     return true;
0190   }
0191 
0192   bool read(int64& a_x){
0193     if(!_check_eob<int64>(a_x)) return false;
0194     m_r_8_func(m_pos,(char*)&a_x);
0195     m_pos += 8;
0196     return true;
0197   }
0198 
0199   bool read(std::string& a_x) {
0200     unsigned char nwh;
0201     if(!read(nwh)) {a_x.clear();return false;}
0202     int nchars;
0203     if(nwh == 255) {
0204       if(!read(nchars)) {a_x.clear();return false;}
0205     } else {
0206       nchars = nwh;
0207     }
0208     if(nchars<0) {
0209       m_out << s_class() << "::read(string) :"
0210             << " negative char number " << nchars << "." << std::endl;
0211       a_x.clear();
0212       return false;
0213     }
0214     if((m_pos+nchars)>m_eob) {
0215       m_out << s_class() << "::read(string) :"
0216             << " try to access out of buffer " << long_out(nchars) << " bytes "
0217             << " (pos=" << charp_out(m_pos)
0218             << ", eob=" << charp_out(m_eob) << ")." << std::endl;
0219       a_x.clear();
0220       return false;
0221     }
0222     a_x.resize(nchars);
0223     ::memcpy((char*)a_x.c_str(),m_pos,nchars);
0224     m_pos += nchars;
0225     return true;
0226   }
0227 
0228   bool read(bool& x){
0229     unsigned char uc = 0;
0230     bool status = read(uc);
0231     x = uc?true:false;
0232     return status;
0233   }
0234   bool read(std::vector<std::string>& a_a) {
0235     int n;
0236     if(!read(n)) {a_a.clear();return false;}
0237     for(int index=0;index<n;index++) {
0238       std::string _s;
0239       if(!read(_s)) {a_a.clear();return false;}
0240       a_a.push_back(_s);
0241     }
0242     return true;
0243   }
0244 
0245   //////////////////////////////////////////////////////////////
0246   //////////////////////////////////////////////////////////////
0247   //////////////////////////////////////////////////////////////
0248   bool read_fast_array(bool* b,uint32 n){
0249     if(!n) return true;
0250     uint32 l = n * sizeof(unsigned char);
0251     if(!check_eob(l)) return false;
0252     for(uint32 i = 0; i < n; i++) {
0253       unsigned char uc;
0254       if(!read(uc)) return false;
0255       b[i] = uc?true:false;
0256     }
0257     return true;
0258   }
0259   bool read_fast_array(char* c,uint32 n){
0260     if(!n) return true;
0261     uint32 l = n * sizeof(char);
0262     if(!check_eob(l)) return false;
0263     ::memcpy(c,m_pos,l);
0264     m_pos += l;
0265     return true;
0266   }
0267   bool read_fast_array(unsigned char* c,uint32 n){
0268     if(!n) return true;
0269     uint32 l = n * sizeof(unsigned char);
0270     if(!check_eob(l)) return false;
0271     ::memcpy(c, m_pos, l);
0272     m_pos += l;
0273     return true;
0274   }
0275 
0276   template <class T>
0277   bool read_fast_array(T* a_a,uint32 a_n){
0278     if(!a_n) return true;
0279 
0280     uint32 l = a_n * sizeof(T);
0281     if(!check_eob(l)) {
0282       m_out << s_class() << "::read_fast_array :"
0283             << " try to access out of buffer " << long_out(l) << " bytes "
0284             << " (pos=" << charp_out(m_pos)
0285             << ", eob=" << charp_out(m_eob) << ")." << std::endl;
0286       return false;
0287     }
0288 
0289     if(m_byte_swap) {
0290       for(uint32 i=0;i<a_n;i++) {
0291         if(!read(*(a_a+i))) return false;
0292       }
0293     } else {
0294       ::memcpy(a_a,m_pos,l);
0295       m_pos += l;
0296     }
0297     return true;
0298   }
0299 
0300   template <class T>
0301   bool read_array(uint32 a_sz,T*& a_a,uint32& a_n) {
0302     a_n = 0;
0303    {int n;
0304     if(!read(n)) {a_n = 0;return false;}
0305     a_n = n;}
0306 
0307     if(!a_n) return true;
0308 
0309     uint32 l = a_n * sizeof(T);
0310     if(!check_eob(l)) return false;
0311 
0312     bool owner = false;
0313     if(!a_a) {
0314       //ignore a_sz
0315       a_a = new T[a_n];
0316       if(!a_a) {a_n=0;return false;}
0317       owner = true;
0318     } else {
0319       if(a_n>a_sz) return false;
0320     }
0321 
0322     if(m_byte_swap) {
0323       for(uint32 i=0;i<a_n;i++) {
0324         if(!read(*(a_a+i))) {
0325           if(owner) {delete [] a_a;a_a = 0;}
0326           a_n = 0;
0327           return false;
0328         }
0329       }
0330     } else {
0331       ::memcpy(a_a,m_pos,l);
0332       m_pos += l;
0333     }
0334     return true;
0335   }
0336 
0337   template <class T>
0338   bool read_array(std::vector<T>& a_v) {
0339     T* buffer = 0;
0340     uint32 n;
0341     if(!read_array(0,buffer,n)) {a_v.clear();return false;}
0342     if(!buffer) {a_v.clear();return true;}
0343     a_v.resize(n);
0344     for(uint32 index=0;index<n;index++) {
0345       a_v[index] = buffer[index];
0346     }
0347     delete [] buffer;
0348     return true;
0349   }
0350 
0351   template <class T>
0352   bool read_array2(std::vector< std::vector<T> >& a_v) {
0353     int n;
0354     if(!read(n)) {a_v.clear();return false;}
0355     a_v.resize(n);
0356     for(int index=0;index<n;index++) {
0357       if(!read_array(a_v[index])) return false;
0358     }
0359     return true;
0360   }
0361 
0362   bool check_eob(uint32 n){
0363     if((m_pos+n)>m_eob) {
0364       m_out << "tools::rroot::rbuf::check_eob :"
0365             << " try to access out of buffer " << n << " bytes."
0366             << std::endl;
0367       return false;
0368     }
0369     return true;
0370   }
0371 
0372 protected:
0373   template <class T>
0374   bool _check_eob(T& a_x){
0375     if((m_pos+sizeof(T))>m_eob) {
0376       a_x = T();
0377       m_out << s_class() << " : " << stype(T()) << " : "
0378            << " try to access out of buffer " << long_out(sizeof(T)) << " bytes"
0379            << " (pos=" << charp_out(m_pos)
0380            << ", eob=" << charp_out(m_eob) << ")." << std::endl;
0381       return false;
0382     }
0383     return true;
0384   }
0385 
0386 protected:
0387   std::ostream& m_out;
0388   bool m_byte_swap;
0389   const char* m_eob;
0390   char*& m_pos;
0391 
0392   r_2_func m_r_2_func;
0393   r_4_func m_r_4_func;
0394   r_8_func m_r_8_func;
0395 };
0396 
0397 }}
0398 
0399 #endif