g4tools  5.4.0
wbuf
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_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 
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  }
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);}
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;
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
tools::wroot::wbuf::~wbuf
virtual ~wbuf()
Definition: wbuf:89
tools::uint64
unsigned long long uint64
Definition: typedefs:72
tools::int64
long long int64
Definition: typedefs:67
tools::wroot::wbuf::wbuf
wbuf(std::ostream &a_out, bool a_byte_swap, const char *a_eob, char *&a_pos)
Definition: wbuf:74
tools::wroot::wbuf::m_eob
const char * m_eob
Definition: wbuf:256
tools::wroot::wbuf::write
bool write(short a_x)
Definition: wbuf:176
tools::wroot::wbuf::write
bool write(char a_x)
Definition: wbuf:175
tools::wroot::wbuf::write
bool write(uint64 a_x)
Definition: wbuf:154
tools::wroot::wbuf::byte_swap
bool byte_swap() const
Definition: wbuf:120
tools::wroot::wbuf::check_eob
bool check_eob(size_t a_n, const char *a_cmt)
Definition: wbuf:241
tools::wroot::wbuf::write
bool write(const T *a_a, uint32 a_n)
Definition: wbuf:201
tools::wroot::wbuf::set_eob
void set_eob(const char *a_eob)
Definition: wbuf:119
tools::wroot::wbuf
Definition: wbuf:22
tools::wroot::wbuf::wbuf
wbuf(const wbuf &a_from)
Definition: wbuf:95
tools::wroot::wbuf::set_byte_swap
void set_byte_swap(bool a_value)
Definition: wbuf:121
tools::wroot::wbuf::write
bool write(float a_x)
Definition: wbuf:161
tools::wroot::wbuf::write
bool write(unsigned int a_x)
Definition: wbuf:147
tools::wroot::wbuf::m_out
std::ostream & m_out
Definition: wbuf:254
tools::charp_out
Definition: charp_out:12
tools::wroot::wbuf::write
bool write(unsigned short a_x)
Definition: wbuf:140
tools::wroot::wbuf::check_eob
bool check_eob()
Definition: wbuf:230
tools::wroot::wbuf::operator=
wbuf & operator=(const wbuf &a_from)
Definition: wbuf:109
tools
inlined C code : ///////////////////////////////////
Definition: aida_ntuple:26
tools::wroot::wbuf::m_w_8_func
w_8_func m_w_8_func
Definition: wbuf:261
tools::wroot::wbuf::m_byte_swap
bool m_byte_swap
Definition: wbuf:255
tools::wroot::wbuf::write
bool write(int64 a_x)
Definition: wbuf:178
tools::wroot::wbuf::write
bool write(const std::string &a_x)
Definition: wbuf:180
tools::wroot::wbuf::m_w_4_func
w_4_func m_w_4_func
Definition: wbuf:260
tools::wroot::wbuf::write
bool write(int a_x)
Definition: wbuf:177
tools::stype
const std::string & stype(const mat4f &)
Definition: mat4f:73
tools::wroot::wbuf::write
bool write(double a_x)
Definition: wbuf:168
tools::wroot::wbuf::m_w_2_func
w_2_func m_w_2_func
Definition: wbuf:259
tools::uint32
unsigned int uint32
Definition: typedefs:71
tools::wroot::wbuf::write
bool write(unsigned char a_x)
Definition: wbuf:134
tools::wroot::wbuf::m_pos
char *& m_pos
Definition: wbuf:257
tools::wroot::wbuf::write
bool write(const std::vector< T > &a_v)
Definition: wbuf:217