Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/externals/g4tools/include/tools/rroot/rbuf

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_rroot_rbuf
  5 #define tools_rroot_rbuf
  6 
  7 #include "../stype"
  8 #include "../long_out"
  9 #include "../charp_out"
 10 
 11 #ifdef TOOLS_MEM
 12 #include "../mem"
 13 #endif
 14 
 15 #include <ostream>
 16 #include <vector>
 17 #include <cstring> //memcpy
 18 
 19 namespace tools {
 20 namespace rroot {
 21 
 22 class rbuf {
 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 read_swap_2(char* a_pos,char* a_x) {
 34     *a_x++ = *(a_pos+1);
 35     *a_x++ = *a_pos;
 36   }
 37   static void read_swap_4(char* a_pos,char* a_x) {
 38     a_pos += 3;
 39     *a_x++ = *a_pos--;
 40     *a_x++ = *a_pos--;
 41     *a_x++ = *a_pos--;
 42     *a_x++ = *a_pos;
 43   }
 44   static void read_swap_8(char* a_pos,char* a_x) {
 45     a_pos += 7;
 46     *a_x++ = *a_pos--;
 47     *a_x++ = *a_pos--;
 48     *a_x++ = *a_pos--;
 49     *a_x++ = *a_pos--;
 50     *a_x++ = *a_pos--;
 51     *a_x++ = *a_pos--;
 52     *a_x++ = *a_pos--;
 53     *a_x++ = *a_pos;
 54   }
 55   /////////////////////////////////////////////////////////
 56   /// nswp ////////////////////////////////////////////////
 57   /////////////////////////////////////////////////////////
 58   static void read_nswp_2(char* a_pos,char* a_x) {
 59     ::memcpy(a_x,a_pos,2);
 60   }
 61   static void read_nswp_4(char* a_pos,char* a_x) {
 62     ::memcpy(a_x,a_pos,4);
 63   }
 64   static void read_nswp_8(char* a_pos,char* a_x) {
 65     ::memcpy(a_x,a_pos,8);
 66   }
 67   /////////////////////////////////////////////////////////
 68   /////////////////////////////////////////////////////////
 69   /////////////////////////////////////////////////////////
 70 
 71 
 72   static const std::string& s_class() {
 73     static const std::string s_v("tools::rroot::rbuf");
 74     return s_v;
 75   }
 76   typedef void (*r_2_func)(char*,char*);
 77   typedef void (*r_4_func)(char*,char*);
 78   typedef void (*r_8_func)(char*,char*);
 79 public:
 80   rbuf(std::ostream& a_out,bool a_byte_swap,const char* a_eob,char*& a_pos)
 81   :m_out(a_out)
 82   ,m_byte_swap(a_byte_swap)
 83   ,m_eob(a_eob)
 84   ,m_pos(a_pos)
 85 
 86   ,m_r_2_func(0)
 87   ,m_r_4_func(0)
 88   ,m_r_8_func(0)
 89   {
 90 #ifdef TOOLS_MEM
 91     mem::increment(s_class().c_str());
 92 #endif
 93     set_byte_swap(a_byte_swap);
 94   }
 95   virtual ~rbuf(){
 96 #ifdef TOOLS_MEM
 97     mem::decrement(s_class().c_str());
 98 #endif
 99   }
100 public:
101   rbuf(const rbuf& a_from)
102   :m_out(a_from.m_out)
103   ,m_byte_swap(a_from.m_byte_swap)
104   ,m_eob(a_from.m_eob)
105   ,m_pos(a_from.m_pos)
106   ,m_r_2_func(a_from.m_r_2_func)
107   ,m_r_4_func(a_from.m_r_4_func)
108   ,m_r_8_func(a_from.m_r_8_func)
109   {
110 #ifdef TOOLS_MEM
111     mem::increment(s_class().c_str());
112 #endif
113     set_byte_swap(a_from.m_byte_swap);
114   }
115   rbuf& operator=(const rbuf& a_from){
116     set_byte_swap(a_from.m_byte_swap);
117     m_eob = a_from.m_eob;
118     //m_pos is a ref.
119     m_r_2_func = a_from.m_r_2_func;
120     m_r_4_func = a_from.m_r_4_func;
121     m_r_8_func = a_from.m_r_8_func;
122     return *this;
123   }
124 public:
125   std::ostream& out() const {return m_out;}
126 
127   void skip(unsigned int a_num) {m_pos += a_num;}
128 
129   void set_eob(const char* a_eob){m_eob = a_eob;}
130   char*& pos() {return m_pos;}
131   const char* eob() const {return m_eob;}
132 
133   void set_byte_swap(bool a_value) {
134     m_byte_swap = a_value;
135     if(m_byte_swap) {
136       m_r_2_func = read_swap_2;
137       m_r_4_func = read_swap_4;
138       m_r_8_func = read_swap_8;
139     } else {
140       m_r_2_func = read_nswp_2;
141       m_r_4_func = read_nswp_4;
142       m_r_8_func = read_nswp_8;
143     }
144   }
145 public:
146   bool read(unsigned char& a_x) {
147     if(!_check_eob<unsigned char>(a_x)) return false;
148     a_x = *m_pos;m_pos++;
149     return true;
150   }
151   bool read(unsigned short& a_x) {
152     if(!_check_eob<unsigned short>(a_x)) return false;
153     m_r_2_func(m_pos,(char*)&a_x);
154     m_pos += sizeof(unsigned short);
155     return true;
156   }
157 
158   bool read(unsigned int& a_x) {
159     if(!_check_eob<unsigned int>(a_x)) return false;
160     m_r_4_func(m_pos,(char*)&a_x);
161     m_pos += sizeof(unsigned int);
162     return true;
163   }
164 
165   bool read(uint64& a_x){
166     if(!_check_eob<uint64>(a_x)) return false;
167     m_r_8_func(m_pos,(char*)&a_x);
168     m_pos += 8;
169     return true;
170   }
171 
172   bool read(float& a_x) {
173     if(!_check_eob<float>(a_x)) return false;
174     m_r_4_func(m_pos,(char*)&a_x);
175     m_pos += sizeof(float);
176     return true;
177   }
178 
179   bool read(double& a_x) {
180     if(!_check_eob<double>(a_x)) return false;
181     m_r_8_func(m_pos,(char*)&a_x);
182     m_pos += sizeof(double);
183     return true;
184   }
185 
186   bool read(char& a_x) {
187     if(!_check_eob<char>(a_x)) return false;
188     a_x = *m_pos;m_pos++;
189     return true;
190   }
191   bool read(short& a_x) {
192     if(!_check_eob<short>(a_x)) return false;
193     m_r_2_func(m_pos,(char*)&a_x);
194     m_pos += sizeof(short);
195     return true;
196   }
197 
198   bool read(int& a_x) {
199     if(!_check_eob<int>(a_x)) return false;
200     m_r_4_func(m_pos,(char*)&a_x);
201     m_pos += sizeof(int);
202     return true;
203   }
204 
205   bool read(int64& a_x){
206     if(!_check_eob<int64>(a_x)) return false;
207     m_r_8_func(m_pos,(char*)&a_x);
208     m_pos += 8;
209     return true;
210   }
211 
212   bool read(std::string& a_x) {
213     unsigned char nwh;
214     if(!read(nwh)) {a_x.clear();return false;}
215     int nchars;
216     if(nwh == 255) {
217       if(!read(nchars)) {a_x.clear();return false;}
218     } else {
219       nchars = nwh;
220     }
221     if(nchars<0) {
222       m_out << s_class() << "::read(string) :"
223             << " negative char number " << nchars << "." << std::endl;
224       a_x.clear();
225       return false;
226     }
227     if((m_pos+nchars)>m_eob) {
228       m_out << s_class() << "::read(string) :"
229             << " try to access out of buffer " << long_out(nchars) << " bytes "
230             << " (pos=" << charp_out(m_pos)
231             << ", eob=" << charp_out(m_eob) << ")." << std::endl;
232       a_x.clear();
233       return false;
234     }
235     a_x.resize(nchars);
236     ::memcpy((char*)a_x.c_str(),m_pos,nchars);
237     m_pos += nchars;
238     return true;
239   }
240 
241   bool read(bool& x){
242     unsigned char uc = 0;
243     bool status = read(uc);
244     x = uc?true:false;
245     return status;
246   }
247   bool read(std::vector<std::string>& a_a) {
248     int n;
249     if(!read(n)) {a_a.clear();return false;}
250     for(int index=0;index<n;index++) {
251       std::string _s;
252       if(!read(_s)) {a_a.clear();return false;}
253       a_a.push_back(_s);
254     }
255     return true;
256   }
257 
258   //////////////////////////////////////////////////////////////
259   //////////////////////////////////////////////////////////////
260   //////////////////////////////////////////////////////////////
261   bool read_fast_array(bool* b,uint32 n){
262     if(!n) return true;
263     uint32 l = n * sizeof(unsigned char);
264     if(!check_eob(l)) return false;
265     for(uint32 i = 0; i < n; i++) {
266       unsigned char uc;
267       if(!read(uc)) return false;
268       b[i] = uc?true:false;
269     }
270     return true;
271   }
272   bool read_fast_array(char* c,uint32 n){
273     if(!n) return true;
274     uint32 l = n * sizeof(char);
275     if(!check_eob(l)) return false;
276     ::memcpy(c,m_pos,l);
277     m_pos += l;
278     return true;
279   }
280   bool read_fast_array(unsigned char* c,uint32 n){
281     if(!n) return true;
282     uint32 l = n * sizeof(unsigned char);
283     if(!check_eob(l)) return false;
284     ::memcpy(c, m_pos, l);
285     m_pos += l;
286     return true;
287   }
288 
289   template <class T>
290   bool read_fast_array(T* a_a,uint32 a_n){
291     if(!a_n) return true;
292 
293     uint32 l = a_n * sizeof(T);
294     if(!check_eob(l)) {
295       m_out << s_class() << "::read_fast_array :"
296             << " try to access out of buffer " << long_out(l) << " bytes "
297             << " (pos=" << charp_out(m_pos)
298             << ", eob=" << charp_out(m_eob) << ")." << std::endl;
299       return false;
300     }
301 
302     if(m_byte_swap) {
303       for(uint32 i=0;i<a_n;i++) {
304         if(!read(*(a_a+i))) return false;
305       }
306     } else {
307       ::memcpy(a_a,m_pos,l);
308       m_pos += l;
309     }
310     return true;
311   }
312 
313   template <class T>
314   bool read_array(uint32 a_sz,T*& a_a,uint32& a_n) {
315     a_n = 0;
316    {int n;
317     if(!read(n)) {a_n = 0;return false;}
318     a_n = n;}
319 
320     if(!a_n) return true;
321 
322     uint32 l = a_n * sizeof(T);
323     if(!check_eob(l)) return false;
324 
325     bool owner = false;
326     if(!a_a) {
327       //ignore a_sz
328       a_a = new T[a_n];
329       if(!a_a) {a_n=0;return false;}
330       owner = true;
331     } else {
332       if(a_n>a_sz) return false;
333     }
334 
335     if(m_byte_swap) {
336       for(uint32 i=0;i<a_n;i++) {
337         if(!read(*(a_a+i))) {
338           if(owner) {delete [] a_a;a_a = 0;}
339           a_n = 0;
340           return false;
341         }
342       }
343     } else {
344       ::memcpy(a_a,m_pos,l);
345       m_pos += l;
346     }
347     return true;
348   }
349 
350   template <class T>
351   bool read_array(std::vector<T>& a_v) {
352     T* buffer = 0;
353     uint32 n;
354     if(!read_array(0,buffer,n)) {a_v.clear();return false;}
355     if(!buffer) {a_v.clear();return true;}
356     a_v.resize(n);
357     for(uint32 index=0;index<n;index++) {
358       a_v[index] = buffer[index];
359     }
360     delete [] buffer;
361     return true;
362   }
363 
364   template <class T>
365   bool read_array2(std::vector< std::vector<T> >& a_v) {
366     int n;
367     if(!read(n)) {a_v.clear();return false;}
368     a_v.resize(n);
369     for(int index=0;index<n;index++) {
370       if(!read_array(a_v[index])) return false;
371     }
372     return true;
373   }
374 
375   bool check_eob(uint32 n){
376     if((m_pos+n)>m_eob) {
377       m_out << "tools::rroot::rbuf::check_eob :"
378             << " try to access out of buffer " << n << " bytes."
379             << std::endl;
380       return false;
381     }
382     return true;
383   }
384 
385 protected:
386   template <class T>
387   bool _check_eob(T& a_x){
388     if((m_pos+sizeof(T))>m_eob) {
389       a_x = T();
390       m_out << s_class() << " : " << stype(T()) << " : "
391            << " try to access out of buffer " << long_out(sizeof(T)) << " bytes"
392            << " (pos=" << charp_out(m_pos)
393            << ", eob=" << charp_out(m_eob) << ")." << std::endl;
394       return false;
395     }
396     return true;
397   }
398 
399 protected:
400   std::ostream& m_out;
401   bool m_byte_swap;
402   const char* m_eob;
403   char*& m_pos;
404 
405   r_2_func m_r_2_func;
406   r_4_func m_r_4_func;
407   r_8_func m_r_8_func;
408 };
409 
410 }}
411 
412 #endif