Warning, /include/Geant4/tools/wroot/wbuf 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_wroot_wbuf
0005 #define tools_wroot_wbuf
0006
0007 #include <ostream>
0008 #include "../long_out"
0009 #include "../charp_out"
0010 #include "../stype"
0011
0012 #include <cstring> //memcpy
0013 #include <vector>
0014
0015 namespace tools {
0016 namespace wroot {
0017
0018 class wbuf {
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 write_swap_2(char* a_pos,char* a_x) {
0030 *a_pos = *(a_x+1);a_pos++;
0031 *a_pos = *a_x;a_pos++;
0032 }
0033 static void write_swap_4(char* a_pos,char* a_x) {
0034 a_x += 3;
0035 *a_pos = *a_x;a_pos++;a_x--;
0036 *a_pos = *a_x;a_pos++;a_x--;
0037 *a_pos = *a_x;a_pos++;a_x--;
0038 *a_pos = *a_x;a_pos++;
0039 }
0040 static void write_swap_8(char* a_pos,char* a_x) {
0041 a_x += 7;
0042 *a_pos = *a_x;a_pos++;a_x--;
0043 *a_pos = *a_x;a_pos++;a_x--;
0044 *a_pos = *a_x;a_pos++;a_x--;
0045 *a_pos = *a_x;a_pos++;a_x--;
0046 *a_pos = *a_x;a_pos++;a_x--;
0047 *a_pos = *a_x;a_pos++;a_x--;
0048 *a_pos = *a_x;a_pos++;a_x--;
0049 *a_pos = *a_x;a_pos++;
0050 }
0051 /////////////////////////////////////////////////////////
0052 /// nswp ////////////////////////////////////////////////
0053 /////////////////////////////////////////////////////////
0054 static void write_nswp_2(char* a_pos,char* a_x) {::memcpy(a_pos,a_x,2);}
0055 static void write_nswp_4(char* a_pos,char* a_x) {::memcpy(a_pos,a_x,4);}
0056 static void write_nswp_8(char* a_pos,char* a_x) {::memcpy(a_pos,a_x,8);}
0057 /////////////////////////////////////////////////////////
0058 /////////////////////////////////////////////////////////
0059 /////////////////////////////////////////////////////////
0060
0061
0062 static const std::string& s_class() {
0063 static const std::string s_v("tools::wroot::wbuf");
0064 return s_v;
0065 }
0066 typedef void (*w_2_func)(char*,char*);
0067 typedef void (*w_4_func)(char*,char*);
0068 typedef void (*w_8_func)(char*,char*);
0069 public:
0070 wbuf(std::ostream& a_out,bool a_byte_swap,const char* a_eob,char*& a_pos)
0071 :m_out(a_out)
0072 ,m_byte_swap(a_byte_swap)
0073 ,m_eob(a_eob)
0074 ,m_pos(a_pos)
0075
0076 ,m_w_2_func(0)
0077 ,m_w_4_func(0)
0078 ,m_w_8_func(0)
0079 {
0080 set_byte_swap(a_byte_swap);
0081 }
0082 virtual ~wbuf(){
0083 }
0084 public:
0085 wbuf(const wbuf& a_from)
0086 :m_out(a_from.m_out) //a ref.
0087 ,m_byte_swap(a_from.m_byte_swap)
0088 ,m_eob(a_from.m_eob)
0089 ,m_pos(a_from.m_pos) //a ref.
0090 ,m_w_2_func(a_from.m_w_2_func)
0091 ,m_w_4_func(a_from.m_w_4_func)
0092 ,m_w_8_func(a_from.m_w_8_func)
0093 {
0094 set_byte_swap(a_from.m_byte_swap);
0095 }
0096 wbuf& operator=(const wbuf& a_from){
0097 set_byte_swap(a_from.m_byte_swap);
0098 m_eob = a_from.m_eob;
0099 //m_pos is a ref.
0100 m_w_2_func = a_from.m_w_2_func;
0101 m_w_4_func = a_from.m_w_4_func;
0102 m_w_8_func = a_from.m_w_8_func;
0103 return *this;
0104 }
0105 public:
0106 void set_eob(const char* a_eob){m_eob = a_eob;}
0107 bool byte_swap() const {return m_byte_swap;}
0108 void set_byte_swap(bool a_value) {
0109 m_byte_swap = a_value;
0110 if(m_byte_swap) {
0111 m_w_2_func = write_swap_2;
0112 m_w_4_func = write_swap_4;
0113 m_w_8_func = write_swap_8;
0114 } else {
0115 m_w_2_func = write_nswp_2;
0116 m_w_4_func = write_nswp_4;
0117 m_w_8_func = write_nswp_8;
0118 }
0119 }
0120 public:
0121 bool write(unsigned char a_x) {
0122 if(!check_eob<unsigned char>()) return false;
0123 *m_pos++ = a_x;
0124 return true;
0125 }
0126
0127 bool write(unsigned short a_x) {
0128 if(!check_eob<unsigned short>()) return false;
0129 m_w_2_func(m_pos,(char*)&a_x);
0130 m_pos += sizeof(unsigned short);
0131 return true;
0132 }
0133
0134 bool write(unsigned int a_x) {
0135 if(!check_eob<unsigned int>()) return false;
0136 m_w_4_func(m_pos,(char*)&a_x);
0137 m_pos += sizeof(unsigned int);
0138 return true;
0139 }
0140
0141 bool write(uint64 a_x){
0142 if(!check_eob<uint64>()) return false;
0143 m_w_8_func(m_pos,(char*)&a_x);
0144 m_pos += 8;
0145 return true;
0146 }
0147
0148 bool write(float a_x) {
0149 if(!check_eob<float>()) return false;
0150 m_w_4_func(m_pos,(char*)&a_x);
0151 m_pos += sizeof(float);
0152 return true;
0153 }
0154
0155 bool write(double a_x) {
0156 if(!check_eob<double>()) return false;
0157 m_w_8_func(m_pos,(char*)&a_x);
0158 m_pos += sizeof(double);
0159 return true;
0160 }
0161
0162 bool write(char a_x) {return write((unsigned char)a_x);}
0163 bool write(short a_x) {return write((unsigned short)a_x);}
0164 bool write(int a_x) {return write((unsigned int)a_x);}
0165 bool write(int64 a_x) {return write((uint64)a_x);}
0166
0167 bool write(const std::string& a_x) {
0168 unsigned char nwh;
0169 unsigned int nchars = (unsigned int)a_x.size();
0170 if(nchars>254) {
0171 if(!check_eob(1+4,"std::string")) return false;
0172 nwh = 255;
0173 if(!write(nwh)) return false;
0174 if(!write(nchars)) return false;
0175 } else {
0176 if(!check_eob(1,"std::string")) return false;
0177 nwh = (unsigned char)nchars;
0178 if(!write(nwh)) return false;
0179 }
0180 if(!check_eob(nchars,"std::string")) return false;
0181 for (unsigned int i = 0; i < nchars; i++) m_pos[i] = a_x[i];
0182 m_pos += nchars;
0183 return true;
0184 }
0185
0186
0187 template <class T>
0188 bool write(const T* a_a,uint32 a_n) {
0189 if(!a_n) return true;
0190 uint32 l = a_n * sizeof(T);
0191 if(!check_eob(l,"array")) return false;
0192 if(m_byte_swap) {
0193 for(uint32 i=0;i<a_n;i++) {
0194 if(!write(a_a[i])) return false;
0195 }
0196 } else {
0197 ::memcpy(m_pos,a_a,l);
0198 m_pos += l;
0199 }
0200 return true;
0201 }
0202
0203 template <class T>
0204 bool write(const std::vector<T>& a_v) {
0205 if(a_v.empty()) return true;
0206 uint32 n = uint32(a_v.size());
0207 uint32 l = n * sizeof(T);
0208 if(!check_eob(l,"array")) return false;
0209 for(uint32 i=0;i<n;i++) {
0210 if(!write(a_v[i])) return false;
0211 }
0212 return true;
0213 }
0214
0215 protected:
0216 template <class T>
0217 bool check_eob(){
0218 if((m_pos+sizeof(T))>m_eob) {
0219 m_out << s_class() << " : " << stype(T()) << " : "
0220 << " try to access out of buffer " << sizeof(T) << " bytes"
0221 << " (pos=" << charp_out(m_pos)
0222 << ", eob=" << charp_out(m_eob) << ")." << std::endl;
0223 return false;
0224 }
0225 return true;
0226 }
0227 bool check_eob(size_t a_n,const char* a_cmt){
0228 if((m_pos+a_n)>m_eob) {
0229 m_out << s_class() << " : " << a_cmt << " : "
0230 << " try to access out of buffer " << a_n << " bytes"
0231 << " (pos=" << charp_out(m_pos)
0232 << ", eob=" << charp_out(m_eob) << ")." << std::endl;
0233 return false;
0234 }
0235 return true;
0236 }
0237
0238 protected:
0239 std::ostream& m_out;
0240 bool m_byte_swap;
0241 const char* m_eob;
0242 char*& m_pos;
0243
0244 w_2_func m_w_2_func;
0245 w_4_func m_w_4_func;
0246 w_8_func m_w_8_func;
0247 };
0248
0249 }}
0250
0251 #endif