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