Geant4 Cross Reference |
1 // Copyright (C) 2010, Guy Barrand. All rights 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 (includin 28 // CERN-ROOT byte swaps ! (Bad luck). 29 // optimize this operation. The below 30 // do not have local variables and ma 31 // directly. 32 33 static void write_swap_2(char* a_pos,char* a 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 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 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 59 static void write_nswp_4(char* a_pos,char* a 60 static void write_nswp_8(char* a_pos,char* a 61 //////////////////////////////////////////// 62 //////////////////////////////////////////// 63 //////////////////////////////////////////// 64 65 66 static const std::string& s_class() { 67 static const std::string s_v("tools::wroot 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,co 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_eo 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 fal 136 *m_pos++ = a_x; 137 return true; 138 } 139 140 bool write(unsigned short a_x) { 141 if(!check_eob<unsigned short>()) return fa 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 fals 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((unsigne 176 bool write(short a_x) {return write((unsigne 177 bool write(int a_x) {return write((unsigne 178 bool write(int64 a_x) {return write((uint64) 179 180 bool write(const std::string& a_x) { 181 unsigned char nwh; 182 unsigned int nchars = (unsigned int)a_x.si 183 if(nchars>254) { 184 if(!check_eob(1+4,"std::string")) return 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 f 190 nwh = (unsigned char)nchars; 191 if(!write(nwh)) return false; 192 } 193 if(!check_eob(nchars,"std::string")) retur 194 for (unsigned int i = 0; i < nchars; 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 234 << " try to access out of buffer " 235 << " (pos=" << charp_out(m_pos) 236 << ", eob=" << charp_out(m_eob) << 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 245 << " try to access out of buffer " 246 << " (pos=" << charp_out(m_pos) 247 << ", eob=" << charp_out(m_eob) << 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