Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/externals/g4tools/include/tools/wroot/wbuf

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

  1 // Copyright (C) 2010, Guy Barrand. All rights reserved.
  2 // See the file tools.license for terms.
  3 
  4 #ifndef tools_wroot_wbuf
  5 #define tools_wroot_wbuf
  6 
  7 #include <ostream>
  8 #include "../long_out"
  9 #include "../charp_out"
 10 #include "../stype"
 11 
 12 #ifdef TOOLS_MEM
 13 #include "../mem"
 14 #endif
 15 
 16 #include <cstring> //memcpy
 17 #include <vector>
 18 
 19 namespace tools {
 20 namespace wroot {
 21 
 22 class wbuf {
 23 
 24   /////////////////////////////////////////////////////////
 25   /// swap ////////////////////////////////////////////////
 26   /////////////////////////////////////////////////////////
 27   // NOTE : on most common platforms (including Android, iPad)
 28   //        CERN-ROOT byte swaps ! (Bad luck). We have arranged to
 29   //        optimize this operation. The below "_swap_" functions
 30   //        do not have local variables and manipulates pointers
 31   //        directly.
 32 
 33   static void write_swap_2(char* a_pos,char* a_x) {
 34     *a_pos = *(a_x+1);a_pos++;
 35     *a_pos = *a_x;a_pos++;
 36   }
 37   static void write_swap_4(char* a_pos,char* a_x) {
 38     a_x += 3;
 39     *a_pos = *a_x;a_pos++;a_x--;
 40     *a_pos = *a_x;a_pos++;a_x--;
 41     *a_pos = *a_x;a_pos++;a_x--;
 42     *a_pos = *a_x;a_pos++;
 43   }
 44   static void write_swap_8(char* a_pos,char* a_x) {
 45     a_x += 7;
 46     *a_pos = *a_x;a_pos++;a_x--;
 47     *a_pos = *a_x;a_pos++;a_x--;
 48     *a_pos = *a_x;a_pos++;a_x--;
 49     *a_pos = *a_x;a_pos++;a_x--;
 50     *a_pos = *a_x;a_pos++;a_x--;
 51     *a_pos = *a_x;a_pos++;a_x--;
 52     *a_pos = *a_x;a_pos++;a_x--;
 53     *a_pos = *a_x;a_pos++;
 54   }
 55   /////////////////////////////////////////////////////////
 56   /// nswp ////////////////////////////////////////////////
 57   /////////////////////////////////////////////////////////
 58   static void write_nswp_2(char* a_pos,char* a_x) {::memcpy(a_pos,a_x,2);}
 59   static void write_nswp_4(char* a_pos,char* a_x) {::memcpy(a_pos,a_x,4);}
 60   static void write_nswp_8(char* a_pos,char* a_x) {::memcpy(a_pos,a_x,8);}
 61   /////////////////////////////////////////////////////////
 62   /////////////////////////////////////////////////////////
 63   /////////////////////////////////////////////////////////
 64 
 65 
 66   static const std::string& s_class() {
 67     static const std::string s_v("tools::wroot::wbuf");
 68     return s_v;
 69   }
 70   typedef void (*w_2_func)(char*,char*);
 71   typedef void (*w_4_func)(char*,char*);
 72   typedef void (*w_8_func)(char*,char*);
 73 public:
 74   wbuf(std::ostream& a_out,bool a_byte_swap,const char* a_eob,char*& a_pos)
 75   :m_out(a_out)
 76   ,m_byte_swap(a_byte_swap)
 77   ,m_eob(a_eob)
 78   ,m_pos(a_pos)
 79 
 80   ,m_w_2_func(0)
 81   ,m_w_4_func(0)
 82   ,m_w_8_func(0)
 83   {
 84 #ifdef TOOLS_MEM
 85     mem::increment(s_class().c_str());
 86 #endif
 87     set_byte_swap(a_byte_swap);
 88   }
 89   virtual ~wbuf(){
 90 #ifdef TOOLS_MEM
 91     mem::decrement(s_class().c_str());
 92 #endif
 93   }
 94 public:
 95   wbuf(const wbuf& a_from)
 96   :m_out(a_from.m_out) //a ref.
 97   ,m_byte_swap(a_from.m_byte_swap)
 98   ,m_eob(a_from.m_eob)
 99   ,m_pos(a_from.m_pos) //a ref.
100   ,m_w_2_func(a_from.m_w_2_func)
101   ,m_w_4_func(a_from.m_w_4_func)
102   ,m_w_8_func(a_from.m_w_8_func)
103   {
104 #ifdef TOOLS_MEM
105     mem::increment(s_class().c_str());
106 #endif
107     set_byte_swap(a_from.m_byte_swap);
108   }
109   wbuf& operator=(const wbuf& a_from){
110     set_byte_swap(a_from.m_byte_swap);
111     m_eob = a_from.m_eob;
112     //m_pos is a ref.
113     m_w_2_func = a_from.m_w_2_func;
114     m_w_4_func = a_from.m_w_4_func;
115     m_w_8_func = a_from.m_w_8_func;
116     return *this;
117   }
118 public:
119   void set_eob(const char* a_eob){m_eob = a_eob;}
120   bool byte_swap() const {return m_byte_swap;}
121   void set_byte_swap(bool a_value) {
122     m_byte_swap = a_value;
123     if(m_byte_swap) {
124       m_w_2_func = write_swap_2;
125       m_w_4_func = write_swap_4;
126       m_w_8_func = write_swap_8;
127     } else {
128       m_w_2_func = write_nswp_2;
129       m_w_4_func = write_nswp_4;
130       m_w_8_func = write_nswp_8;
131     }
132   }
133 public:
134   bool write(unsigned char a_x) {
135     if(!check_eob<unsigned char>()) return false;
136     *m_pos++ = a_x;
137     return true;
138   }
139 
140   bool write(unsigned short a_x) {
141     if(!check_eob<unsigned short>()) return false;
142     m_w_2_func(m_pos,(char*)&a_x);
143     m_pos += sizeof(unsigned short);
144     return true;
145   }
146 
147   bool write(unsigned int a_x) {
148     if(!check_eob<unsigned int>()) return false;
149     m_w_4_func(m_pos,(char*)&a_x);
150     m_pos += sizeof(unsigned int);
151     return true;
152   }
153 
154   bool write(uint64 a_x){
155     if(!check_eob<uint64>()) return false;
156     m_w_8_func(m_pos,(char*)&a_x);
157     m_pos += 8;
158     return true;
159   }
160 
161   bool write(float a_x) {
162     if(!check_eob<float>()) return false;
163     m_w_4_func(m_pos,(char*)&a_x);
164     m_pos += sizeof(float);
165     return true;
166   }
167 
168   bool write(double a_x) {
169     if(!check_eob<double>()) return false;
170     m_w_8_func(m_pos,(char*)&a_x);
171     m_pos += sizeof(double);
172     return true;
173   }
174 
175   bool write(char a_x)  {return write((unsigned char)a_x);}
176   bool write(short a_x) {return write((unsigned short)a_x);}
177   bool write(int a_x)   {return write((unsigned int)a_x);}
178   bool write(int64 a_x) {return write((uint64)a_x);}
179 
180   bool write(const std::string& a_x) {
181     unsigned char nwh;
182     unsigned int nchars = (unsigned int)a_x.size();
183     if(nchars>254) {
184       if(!check_eob(1+4,"std::string")) return false;
185       nwh = 255;
186       if(!write(nwh)) return false;
187       if(!write(nchars)) return false;
188     } else {
189       if(!check_eob(1,"std::string")) return false;
190       nwh = (unsigned char)nchars;
191       if(!write(nwh)) return false;
192     }
193     if(!check_eob(nchars,"std::string")) return false;
194     for (unsigned int i = 0; i < nchars; i++) m_pos[i] = a_x[i];
195     m_pos += nchars;
196     return true;
197   }
198 
199 
200   template <class T>
201   bool write(const T* a_a,uint32 a_n) {
202     if(!a_n) return true;
203     uint32 l = a_n * sizeof(T);
204     if(!check_eob(l,"array")) return false;
205     if(m_byte_swap) {
206       for(uint32 i=0;i<a_n;i++) {
207         if(!write(a_a[i])) return false;
208       }
209     } else {
210       ::memcpy(m_pos,a_a,l);
211       m_pos += l;
212     }
213     return true;
214   }
215 
216   template <class T>
217   bool write(const std::vector<T>& a_v) {
218     if(a_v.empty()) return true;
219     uint32 n = uint32(a_v.size());
220     uint32 l = n * sizeof(T);
221     if(!check_eob(l,"array")) return false;
222     for(uint32 i=0;i<n;i++) {
223       if(!write(a_v[i])) return false;
224     }
225     return true;
226   }
227 
228 protected:
229   template <class T>
230   bool check_eob(){
231     if((m_pos+sizeof(T))>m_eob) {
232       m_out << s_class() << " : " << stype(T()) << " : "
233 //           << " try to access out of buffer " << long_out(sizeof(T)) << " bytes"
234            << " try to access out of buffer " << sizeof(T) << " bytes"
235            << " (pos=" << charp_out(m_pos)
236            << ", eob=" << charp_out(m_eob) << ")." << std::endl;
237       return false;
238     }
239     return true;
240   }
241   bool check_eob(size_t a_n,const char* a_cmt){
242     if((m_pos+a_n)>m_eob) {
243       m_out << s_class() << " : " << a_cmt << " : "
244 //           << " try to access out of buffer " << long_out(a_n) << " bytes"
245            << " try to access out of buffer " << a_n << " bytes"
246            << " (pos=" << charp_out(m_pos)
247            << ", eob=" << charp_out(m_eob) << ")." << std::endl;
248       return false;
249     }
250     return true;
251   }
252 
253 protected:
254   std::ostream& m_out;
255   bool m_byte_swap;
256   const char* m_eob;
257   char*& m_pos;
258 
259   w_2_func m_w_2_func;
260   w_4_func m_w_4_func;
261   w_8_func m_w_8_func;
262 };
263 
264 }}
265 
266 #endif