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