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