g4tools  5.4.0
rbuf
Go to the documentation of this file.
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 
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  }
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  }
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 
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;
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
tools::rroot::rbuf::read
bool read(short &a_x)
Definition: rbuf:191
tools::uint64
unsigned long long uint64
Definition: typedefs:72
tools::int64
long long int64
Definition: typedefs:67
tools::rroot::rbuf::read
bool read(std::vector< std::string > &a_a)
Definition: rbuf:247
tools::rroot::rbuf::set_byte_swap
void set_byte_swap(bool a_value)
Definition: rbuf:133
tools::rroot::rbuf::m_r_8_func
r_8_func m_r_8_func
Definition: rbuf:407
tools::rroot::rbuf::read_fast_array
bool read_fast_array(bool *b, uint32 n)
Definition: rbuf:261
tools::rroot::rbuf::read
bool read(uint64 &a_x)
Definition: rbuf:165
tools::rroot::rbuf::skip
void skip(unsigned int a_num)
Definition: rbuf:127
tools::rroot::rbuf::read
bool read(unsigned short &a_x)
Definition: rbuf:151
tools::rroot::rbuf::read
bool read(float &a_x)
Definition: rbuf:172
tools::rroot::rbuf::read_array2
bool read_array2(std::vector< std::vector< T > > &a_v)
Definition: rbuf:365
tools::rroot::rbuf::operator=
rbuf & operator=(const rbuf &a_from)
Definition: rbuf:115
tools::rroot::rbuf::read_array
bool read_array(std::vector< T > &a_v)
Definition: rbuf:351
tools::rroot::rbuf::read
bool read(char &a_x)
Definition: rbuf:186
tools::rroot::rbuf::rbuf
rbuf(std::ostream &a_out, bool a_byte_swap, const char *a_eob, char *&a_pos)
Definition: rbuf:80
tools::rroot::rbuf::set_eob
void set_eob(const char *a_eob)
Definition: rbuf:129
tools::rroot::rbuf::read_array
bool read_array(uint32 a_sz, T *&a_a, uint32 &a_n)
Definition: rbuf:314
tools::rroot::rbuf::read
bool read(double &a_x)
Definition: rbuf:179
tools::rroot::rbuf::out
std::ostream & out() const
Definition: rbuf:125
tools::long_out
Definition: long_out:12
tools::rroot::rbuf::check_eob
bool check_eob(uint32 n)
Definition: rbuf:375
tools::rroot::rbuf::_check_eob
bool _check_eob(T &a_x)
Definition: rbuf:387
tools::charp_out
Definition: charp_out:12
tools::rroot::rbuf::pos
char *& pos()
Definition: rbuf:130
tools::rroot::rbuf::~rbuf
virtual ~rbuf()
Definition: rbuf:95
tools::rroot::rbuf::m_pos
char *& m_pos
Definition: rbuf:403
tools::rroot::rbuf::read
bool read(std::string &a_x)
Definition: rbuf:212
tools::rroot::rbuf::rbuf
rbuf(const rbuf &a_from)
Definition: rbuf:101
tools::rroot::rbuf
Definition: rbuf:22
tools::rroot::rbuf::read_fast_array
bool read_fast_array(char *c, uint32 n)
Definition: rbuf:272
tools::rroot::rbuf::read
bool read(unsigned int &a_x)
Definition: rbuf:158
tools::rroot::rbuf::read
bool read(bool &x)
Definition: rbuf:241
tools
inlined C code : ///////////////////////////////////
Definition: aida_ntuple:26
tools::rroot::rbuf::m_r_2_func
r_2_func m_r_2_func
Definition: rbuf:405
tools::rroot::rbuf::m_byte_swap
bool m_byte_swap
Definition: rbuf:401
tools::rroot::buffer
Definition: buffer:43
tools::rroot::rbuf::read_fast_array
bool read_fast_array(T *a_a, uint32 a_n)
Definition: rbuf:290
tools::rroot::rbuf::m_eob
const char * m_eob
Definition: rbuf:402
tools::rroot::rbuf::read
bool read(unsigned char &a_x)
Definition: rbuf:146
tools::rroot::rbuf::read
bool read(int &a_x)
Definition: rbuf:198
tools::rroot::rbuf::read
bool read(int64 &a_x)
Definition: rbuf:205
tools::stype
const std::string & stype(const mat4f &)
Definition: mat4f:73
tools::rroot::rbuf::read_fast_array
bool read_fast_array(unsigned char *c, uint32 n)
Definition: rbuf:280
tools::uint32
unsigned int uint32
Definition: typedefs:71
tools::rroot::rbuf::eob
const char * eob() const
Definition: rbuf:131
tools::rroot::rbuf::m_out
std::ostream & m_out
Definition: rbuf:400
tools::rroot::rbuf::m_r_4_func
r_4_func m_r_4_func
Definition: rbuf:406