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