Back to home page

EIC code displayed by LXR

 
 

    


Warning, /include/Geant4/tools/wroot/wbuf 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_wroot_wbuf
0005 #define tools_wroot_wbuf
0006 
0007 #include <ostream>
0008 #include "../long_out"
0009 #include "../charp_out"
0010 #include "../stype"
0011 
0012 #include <cstring> //memcpy
0013 #include <vector>
0014 
0015 namespace tools {
0016 namespace wroot {
0017 
0018 class wbuf {
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 write_swap_2(char* a_pos,char* a_x) {
0030     *a_pos = *(a_x+1);a_pos++;
0031     *a_pos = *a_x;a_pos++;
0032   }
0033   static void write_swap_4(char* a_pos,char* a_x) {
0034     a_x += 3;
0035     *a_pos = *a_x;a_pos++;a_x--;
0036     *a_pos = *a_x;a_pos++;a_x--;
0037     *a_pos = *a_x;a_pos++;a_x--;
0038     *a_pos = *a_x;a_pos++;
0039   }
0040   static void write_swap_8(char* a_pos,char* a_x) {
0041     a_x += 7;
0042     *a_pos = *a_x;a_pos++;a_x--;
0043     *a_pos = *a_x;a_pos++;a_x--;
0044     *a_pos = *a_x;a_pos++;a_x--;
0045     *a_pos = *a_x;a_pos++;a_x--;
0046     *a_pos = *a_x;a_pos++;a_x--;
0047     *a_pos = *a_x;a_pos++;a_x--;
0048     *a_pos = *a_x;a_pos++;a_x--;
0049     *a_pos = *a_x;a_pos++;
0050   }
0051   /////////////////////////////////////////////////////////
0052   /// nswp ////////////////////////////////////////////////
0053   /////////////////////////////////////////////////////////
0054   static void write_nswp_2(char* a_pos,char* a_x) {::memcpy(a_pos,a_x,2);}
0055   static void write_nswp_4(char* a_pos,char* a_x) {::memcpy(a_pos,a_x,4);}
0056   static void write_nswp_8(char* a_pos,char* a_x) {::memcpy(a_pos,a_x,8);}
0057   /////////////////////////////////////////////////////////
0058   /////////////////////////////////////////////////////////
0059   /////////////////////////////////////////////////////////
0060 
0061 
0062   static const std::string& s_class() {
0063     static const std::string s_v("tools::wroot::wbuf");
0064     return s_v;
0065   }
0066   typedef void (*w_2_func)(char*,char*);
0067   typedef void (*w_4_func)(char*,char*);
0068   typedef void (*w_8_func)(char*,char*);
0069 public:
0070   wbuf(std::ostream& a_out,bool a_byte_swap,const char* a_eob,char*& a_pos)
0071   :m_out(a_out)
0072   ,m_byte_swap(a_byte_swap)
0073   ,m_eob(a_eob)
0074   ,m_pos(a_pos)
0075 
0076   ,m_w_2_func(0)
0077   ,m_w_4_func(0)
0078   ,m_w_8_func(0)
0079   {
0080     set_byte_swap(a_byte_swap);
0081   }
0082   virtual ~wbuf(){
0083   }
0084 public:
0085   wbuf(const wbuf& a_from)
0086   :m_out(a_from.m_out) //a ref.
0087   ,m_byte_swap(a_from.m_byte_swap)
0088   ,m_eob(a_from.m_eob)
0089   ,m_pos(a_from.m_pos) //a ref.
0090   ,m_w_2_func(a_from.m_w_2_func)
0091   ,m_w_4_func(a_from.m_w_4_func)
0092   ,m_w_8_func(a_from.m_w_8_func)
0093   {
0094     set_byte_swap(a_from.m_byte_swap);
0095   }
0096   wbuf& operator=(const wbuf& a_from){
0097     set_byte_swap(a_from.m_byte_swap);
0098     m_eob = a_from.m_eob;
0099     //m_pos is a ref.
0100     m_w_2_func = a_from.m_w_2_func;
0101     m_w_4_func = a_from.m_w_4_func;
0102     m_w_8_func = a_from.m_w_8_func;
0103     return *this;
0104   }
0105 public:
0106   void set_eob(const char* a_eob){m_eob = a_eob;}
0107   bool byte_swap() const {return m_byte_swap;}
0108   void set_byte_swap(bool a_value) {
0109     m_byte_swap = a_value;
0110     if(m_byte_swap) {
0111       m_w_2_func = write_swap_2;
0112       m_w_4_func = write_swap_4;
0113       m_w_8_func = write_swap_8;
0114     } else {
0115       m_w_2_func = write_nswp_2;
0116       m_w_4_func = write_nswp_4;
0117       m_w_8_func = write_nswp_8;
0118     }
0119   }
0120 public:
0121   bool write(unsigned char a_x) {
0122     if(!check_eob<unsigned char>()) return false;
0123     *m_pos++ = a_x;
0124     return true;
0125   }
0126 
0127   bool write(unsigned short a_x) {
0128     if(!check_eob<unsigned short>()) return false;
0129     m_w_2_func(m_pos,(char*)&a_x);
0130     m_pos += sizeof(unsigned short);
0131     return true;
0132   }
0133 
0134   bool write(unsigned int a_x) {
0135     if(!check_eob<unsigned int>()) return false;
0136     m_w_4_func(m_pos,(char*)&a_x);
0137     m_pos += sizeof(unsigned int);
0138     return true;
0139   }
0140 
0141   bool write(uint64 a_x){
0142     if(!check_eob<uint64>()) return false;
0143     m_w_8_func(m_pos,(char*)&a_x);
0144     m_pos += 8;
0145     return true;
0146   }
0147 
0148   bool write(float a_x) {
0149     if(!check_eob<float>()) return false;
0150     m_w_4_func(m_pos,(char*)&a_x);
0151     m_pos += sizeof(float);
0152     return true;
0153   }
0154 
0155   bool write(double a_x) {
0156     if(!check_eob<double>()) return false;
0157     m_w_8_func(m_pos,(char*)&a_x);
0158     m_pos += sizeof(double);
0159     return true;
0160   }
0161 
0162   bool write(char a_x)  {return write((unsigned char)a_x);}
0163   bool write(short a_x) {return write((unsigned short)a_x);}
0164   bool write(int a_x)   {return write((unsigned int)a_x);}
0165   bool write(int64 a_x) {return write((uint64)a_x);}
0166 
0167   bool write(const std::string& a_x) {
0168     unsigned char nwh;
0169     unsigned int nchars = (unsigned int)a_x.size();
0170     if(nchars>254) {
0171       if(!check_eob(1+4,"std::string")) return false;
0172       nwh = 255;
0173       if(!write(nwh)) return false;
0174       if(!write(nchars)) return false;
0175     } else {
0176       if(!check_eob(1,"std::string")) return false;
0177       nwh = (unsigned char)nchars;
0178       if(!write(nwh)) return false;
0179     }
0180     if(!check_eob(nchars,"std::string")) return false;
0181     for (unsigned int i = 0; i < nchars; i++) m_pos[i] = a_x[i];
0182     m_pos += nchars;
0183     return true;
0184   }
0185 
0186 
0187   template <class T>
0188   bool write(const T* a_a,uint32 a_n) {
0189     if(!a_n) return true;
0190     uint32 l = a_n * sizeof(T);
0191     if(!check_eob(l,"array")) return false;
0192     if(m_byte_swap) {
0193       for(uint32 i=0;i<a_n;i++) {
0194         if(!write(a_a[i])) return false;
0195       }
0196     } else {
0197       ::memcpy(m_pos,a_a,l);
0198       m_pos += l;
0199     }
0200     return true;
0201   }
0202 
0203   template <class T>
0204   bool write(const std::vector<T>& a_v) {
0205     if(a_v.empty()) return true;
0206     uint32 n = uint32(a_v.size());
0207     uint32 l = n * sizeof(T);
0208     if(!check_eob(l,"array")) return false;
0209     for(uint32 i=0;i<n;i++) {
0210       if(!write(a_v[i])) return false;
0211     }
0212     return true;
0213   }
0214 
0215 protected:
0216   template <class T>
0217   bool check_eob(){
0218     if((m_pos+sizeof(T))>m_eob) {
0219       m_out << s_class() << " : " << stype(T()) << " : "
0220            << " try to access out of buffer " << sizeof(T) << " bytes"
0221            << " (pos=" << charp_out(m_pos)
0222            << ", eob=" << charp_out(m_eob) << ")." << std::endl;
0223       return false;
0224     }
0225     return true;
0226   }
0227   bool check_eob(size_t a_n,const char* a_cmt){
0228     if((m_pos+a_n)>m_eob) {
0229       m_out << s_class() << " : " << a_cmt << " : "
0230            << " try to access out of buffer " << a_n << " bytes"
0231            << " (pos=" << charp_out(m_pos)
0232            << ", eob=" << charp_out(m_eob) << ")." << std::endl;
0233       return false;
0234     }
0235     return true;
0236   }
0237 
0238 protected:
0239   std::ostream& m_out;
0240   bool m_byte_swap;
0241   const char* m_eob;
0242   char*& m_pos;
0243 
0244   w_2_func m_w_2_func;
0245   w_4_func m_w_4_func;
0246   w_8_func m_w_8_func;
0247 };
0248 
0249 }}
0250 
0251 #endif