Warning, /include/Geant4/tools/rroot/rbuf is written in an unsupported language. File is not indexed.
0001 // Copyright (C) 2010, Guy Barrand. All rights reserved.
0002 // See the file tools.license for terms.
0003
0004 #ifndef tools_rroot_rbuf
0005 #define tools_rroot_rbuf
0006
0007 #include "../stype"
0008 #include "../long_out"
0009 #include "../charp_out"
0010
0011 #include <ostream>
0012 #include <vector>
0013 #include <cstring> //memcpy
0014
0015 namespace tools {
0016 namespace rroot {
0017
0018 class rbuf {
0019
0020 /////////////////////////////////////////////////////////
0021 /// swap ////////////////////////////////////////////////
0022 /////////////////////////////////////////////////////////
0023 // NOTE : on most common platforms (including Android, iPad)
0024 // CERN-ROOT byte swaps ! (Bad luck). We have arranged to
0025 // optimize this operation. The below "_swap_" functions
0026 // do not have local variables and manipulates pointers
0027 // directly.
0028
0029 static void read_swap_2(char* a_pos,char* a_x) {
0030 *a_x++ = *(a_pos+1);
0031 *a_x++ = *a_pos;
0032 }
0033 static void read_swap_4(char* a_pos,char* a_x) {
0034 a_pos += 3;
0035 *a_x++ = *a_pos--;
0036 *a_x++ = *a_pos--;
0037 *a_x++ = *a_pos--;
0038 *a_x++ = *a_pos;
0039 }
0040 static void read_swap_8(char* a_pos,char* a_x) {
0041 a_pos += 7;
0042 *a_x++ = *a_pos--;
0043 *a_x++ = *a_pos--;
0044 *a_x++ = *a_pos--;
0045 *a_x++ = *a_pos--;
0046 *a_x++ = *a_pos--;
0047 *a_x++ = *a_pos--;
0048 *a_x++ = *a_pos--;
0049 *a_x++ = *a_pos;
0050 }
0051 /////////////////////////////////////////////////////////
0052 /// nswp ////////////////////////////////////////////////
0053 /////////////////////////////////////////////////////////
0054 static void read_nswp_2(char* a_pos,char* a_x) {
0055 ::memcpy(a_x,a_pos,2);
0056 }
0057 static void read_nswp_4(char* a_pos,char* a_x) {
0058 ::memcpy(a_x,a_pos,4);
0059 }
0060 static void read_nswp_8(char* a_pos,char* a_x) {
0061 ::memcpy(a_x,a_pos,8);
0062 }
0063 /////////////////////////////////////////////////////////
0064 /////////////////////////////////////////////////////////
0065 /////////////////////////////////////////////////////////
0066
0067
0068 static const std::string& s_class() {
0069 static const std::string s_v("tools::rroot::rbuf");
0070 return s_v;
0071 }
0072 typedef void (*r_2_func)(char*,char*);
0073 typedef void (*r_4_func)(char*,char*);
0074 typedef void (*r_8_func)(char*,char*);
0075 public:
0076 rbuf(std::ostream& a_out,bool a_byte_swap,const char* a_eob,char*& a_pos)
0077 :m_out(a_out)
0078 ,m_byte_swap(a_byte_swap)
0079 ,m_eob(a_eob)
0080 ,m_pos(a_pos)
0081
0082 ,m_r_2_func(0)
0083 ,m_r_4_func(0)
0084 ,m_r_8_func(0)
0085 {
0086 set_byte_swap(a_byte_swap);
0087 }
0088 virtual ~rbuf(){
0089 }
0090 public:
0091 rbuf(const rbuf& a_from)
0092 :m_out(a_from.m_out)
0093 ,m_byte_swap(a_from.m_byte_swap)
0094 ,m_eob(a_from.m_eob)
0095 ,m_pos(a_from.m_pos)
0096 ,m_r_2_func(a_from.m_r_2_func)
0097 ,m_r_4_func(a_from.m_r_4_func)
0098 ,m_r_8_func(a_from.m_r_8_func)
0099 {
0100 set_byte_swap(a_from.m_byte_swap);
0101 }
0102 rbuf& operator=(const rbuf& a_from){
0103 set_byte_swap(a_from.m_byte_swap);
0104 m_eob = a_from.m_eob;
0105 //m_pos is a ref.
0106 m_r_2_func = a_from.m_r_2_func;
0107 m_r_4_func = a_from.m_r_4_func;
0108 m_r_8_func = a_from.m_r_8_func;
0109 return *this;
0110 }
0111 public:
0112 std::ostream& out() const {return m_out;}
0113
0114 void skip(unsigned int a_num) {m_pos += a_num;}
0115
0116 void set_eob(const char* a_eob){m_eob = a_eob;}
0117 char*& pos() {return m_pos;}
0118 const char* eob() const {return m_eob;}
0119
0120 void set_byte_swap(bool a_value) {
0121 m_byte_swap = a_value;
0122 if(m_byte_swap) {
0123 m_r_2_func = read_swap_2;
0124 m_r_4_func = read_swap_4;
0125 m_r_8_func = read_swap_8;
0126 } else {
0127 m_r_2_func = read_nswp_2;
0128 m_r_4_func = read_nswp_4;
0129 m_r_8_func = read_nswp_8;
0130 }
0131 }
0132 public:
0133 bool read(unsigned char& a_x) {
0134 if(!_check_eob<unsigned char>(a_x)) return false;
0135 a_x = *m_pos;m_pos++;
0136 return true;
0137 }
0138 bool read(unsigned short& a_x) {
0139 if(!_check_eob<unsigned short>(a_x)) return false;
0140 m_r_2_func(m_pos,(char*)&a_x);
0141 m_pos += sizeof(unsigned short);
0142 return true;
0143 }
0144
0145 bool read(unsigned int& a_x) {
0146 if(!_check_eob<unsigned int>(a_x)) return false;
0147 m_r_4_func(m_pos,(char*)&a_x);
0148 m_pos += sizeof(unsigned int);
0149 return true;
0150 }
0151
0152 bool read(uint64& a_x){
0153 if(!_check_eob<uint64>(a_x)) return false;
0154 m_r_8_func(m_pos,(char*)&a_x);
0155 m_pos += 8;
0156 return true;
0157 }
0158
0159 bool read(float& a_x) {
0160 if(!_check_eob<float>(a_x)) return false;
0161 m_r_4_func(m_pos,(char*)&a_x);
0162 m_pos += sizeof(float);
0163 return true;
0164 }
0165
0166 bool read(double& a_x) {
0167 if(!_check_eob<double>(a_x)) return false;
0168 m_r_8_func(m_pos,(char*)&a_x);
0169 m_pos += sizeof(double);
0170 return true;
0171 }
0172
0173 bool read(char& a_x) {
0174 if(!_check_eob<char>(a_x)) return false;
0175 a_x = *m_pos;m_pos++;
0176 return true;
0177 }
0178 bool read(short& a_x) {
0179 if(!_check_eob<short>(a_x)) return false;
0180 m_r_2_func(m_pos,(char*)&a_x);
0181 m_pos += sizeof(short);
0182 return true;
0183 }
0184
0185 bool read(int& a_x) {
0186 if(!_check_eob<int>(a_x)) return false;
0187 m_r_4_func(m_pos,(char*)&a_x);
0188 m_pos += sizeof(int);
0189 return true;
0190 }
0191
0192 bool read(int64& a_x){
0193 if(!_check_eob<int64>(a_x)) return false;
0194 m_r_8_func(m_pos,(char*)&a_x);
0195 m_pos += 8;
0196 return true;
0197 }
0198
0199 bool read(std::string& a_x) {
0200 unsigned char nwh;
0201 if(!read(nwh)) {a_x.clear();return false;}
0202 int nchars;
0203 if(nwh == 255) {
0204 if(!read(nchars)) {a_x.clear();return false;}
0205 } else {
0206 nchars = nwh;
0207 }
0208 if(nchars<0) {
0209 m_out << s_class() << "::read(string) :"
0210 << " negative char number " << nchars << "." << std::endl;
0211 a_x.clear();
0212 return false;
0213 }
0214 if((m_pos+nchars)>m_eob) {
0215 m_out << s_class() << "::read(string) :"
0216 << " try to access out of buffer " << long_out(nchars) << " bytes "
0217 << " (pos=" << charp_out(m_pos)
0218 << ", eob=" << charp_out(m_eob) << ")." << std::endl;
0219 a_x.clear();
0220 return false;
0221 }
0222 a_x.resize(nchars);
0223 ::memcpy((char*)a_x.c_str(),m_pos,nchars);
0224 m_pos += nchars;
0225 return true;
0226 }
0227
0228 bool read(bool& x){
0229 unsigned char uc = 0;
0230 bool status = read(uc);
0231 x = uc?true:false;
0232 return status;
0233 }
0234 bool read(std::vector<std::string>& a_a) {
0235 int n;
0236 if(!read(n)) {a_a.clear();return false;}
0237 for(int index=0;index<n;index++) {
0238 std::string _s;
0239 if(!read(_s)) {a_a.clear();return false;}
0240 a_a.push_back(_s);
0241 }
0242 return true;
0243 }
0244
0245 //////////////////////////////////////////////////////////////
0246 //////////////////////////////////////////////////////////////
0247 //////////////////////////////////////////////////////////////
0248 bool read_fast_array(bool* b,uint32 n){
0249 if(!n) return true;
0250 uint32 l = n * sizeof(unsigned char);
0251 if(!check_eob(l)) return false;
0252 for(uint32 i = 0; i < n; i++) {
0253 unsigned char uc;
0254 if(!read(uc)) return false;
0255 b[i] = uc?true:false;
0256 }
0257 return true;
0258 }
0259 bool read_fast_array(char* c,uint32 n){
0260 if(!n) return true;
0261 uint32 l = n * sizeof(char);
0262 if(!check_eob(l)) return false;
0263 ::memcpy(c,m_pos,l);
0264 m_pos += l;
0265 return true;
0266 }
0267 bool read_fast_array(unsigned char* c,uint32 n){
0268 if(!n) return true;
0269 uint32 l = n * sizeof(unsigned char);
0270 if(!check_eob(l)) return false;
0271 ::memcpy(c, m_pos, l);
0272 m_pos += l;
0273 return true;
0274 }
0275
0276 template <class T>
0277 bool read_fast_array(T* a_a,uint32 a_n){
0278 if(!a_n) return true;
0279
0280 uint32 l = a_n * sizeof(T);
0281 if(!check_eob(l)) {
0282 m_out << s_class() << "::read_fast_array :"
0283 << " try to access out of buffer " << long_out(l) << " bytes "
0284 << " (pos=" << charp_out(m_pos)
0285 << ", eob=" << charp_out(m_eob) << ")." << std::endl;
0286 return false;
0287 }
0288
0289 if(m_byte_swap) {
0290 for(uint32 i=0;i<a_n;i++) {
0291 if(!read(*(a_a+i))) return false;
0292 }
0293 } else {
0294 ::memcpy(a_a,m_pos,l);
0295 m_pos += l;
0296 }
0297 return true;
0298 }
0299
0300 template <class T>
0301 bool read_array(uint32 a_sz,T*& a_a,uint32& a_n) {
0302 a_n = 0;
0303 {int n;
0304 if(!read(n)) {a_n = 0;return false;}
0305 a_n = n;}
0306
0307 if(!a_n) return true;
0308
0309 uint32 l = a_n * sizeof(T);
0310 if(!check_eob(l)) return false;
0311
0312 bool owner = false;
0313 if(!a_a) {
0314 //ignore a_sz
0315 a_a = new T[a_n];
0316 if(!a_a) {a_n=0;return false;}
0317 owner = true;
0318 } else {
0319 if(a_n>a_sz) return false;
0320 }
0321
0322 if(m_byte_swap) {
0323 for(uint32 i=0;i<a_n;i++) {
0324 if(!read(*(a_a+i))) {
0325 if(owner) {delete [] a_a;a_a = 0;}
0326 a_n = 0;
0327 return false;
0328 }
0329 }
0330 } else {
0331 ::memcpy(a_a,m_pos,l);
0332 m_pos += l;
0333 }
0334 return true;
0335 }
0336
0337 template <class T>
0338 bool read_array(std::vector<T>& a_v) {
0339 T* buffer = 0;
0340 uint32 n;
0341 if(!read_array(0,buffer,n)) {a_v.clear();return false;}
0342 if(!buffer) {a_v.clear();return true;}
0343 a_v.resize(n);
0344 for(uint32 index=0;index<n;index++) {
0345 a_v[index] = buffer[index];
0346 }
0347 delete [] buffer;
0348 return true;
0349 }
0350
0351 template <class T>
0352 bool read_array2(std::vector< std::vector<T> >& a_v) {
0353 int n;
0354 if(!read(n)) {a_v.clear();return false;}
0355 a_v.resize(n);
0356 for(int index=0;index<n;index++) {
0357 if(!read_array(a_v[index])) return false;
0358 }
0359 return true;
0360 }
0361
0362 bool check_eob(uint32 n){
0363 if((m_pos+n)>m_eob) {
0364 m_out << "tools::rroot::rbuf::check_eob :"
0365 << " try to access out of buffer " << n << " bytes."
0366 << std::endl;
0367 return false;
0368 }
0369 return true;
0370 }
0371
0372 protected:
0373 template <class T>
0374 bool _check_eob(T& a_x){
0375 if((m_pos+sizeof(T))>m_eob) {
0376 a_x = T();
0377 m_out << s_class() << " : " << stype(T()) << " : "
0378 << " try to access out of buffer " << long_out(sizeof(T)) << " bytes"
0379 << " (pos=" << charp_out(m_pos)
0380 << ", eob=" << charp_out(m_eob) << ")." << std::endl;
0381 return false;
0382 }
0383 return true;
0384 }
0385
0386 protected:
0387 std::ostream& m_out;
0388 bool m_byte_swap;
0389 const char* m_eob;
0390 char*& m_pos;
0391
0392 r_2_func m_r_2_func;
0393 r_4_func m_r_4_func;
0394 r_8_func m_r_8_func;
0395 };
0396
0397 }}
0398
0399 #endif