inlib  1.2.0
/Users/barrand/private/dev/softinex/old/inexlib-1.2/inlib/inlib/wroot/wbuf
Go to the documentation of this file.
00001 // Copyright (C) 2010, Guy Barrand. All rights reserved.
00002 // See the file inlib.license for terms.
00003 
00004 #ifndef inlib_wroot_wbuf
00005 #define inlib_wroot_wbuf
00006 
00007 #include <ostream>
00008 #include "../pointer"
00009 #include "../stype"
00010 
00011 #ifdef INLIB_MEM
00012 #include "../mem"
00013 #endif
00014 
00015 #include <cstring> //memcpy
00016 
00017 namespace inlib {
00018 namespace wroot {
00019 
00020 class wbuf {
00021 
00025   // NOTE : on most common platforms (including Android, iPad)
00026   //        CERN-ROOT byte swaps ! (Bad luck). We have arranged to
00027   //        optimize this operation. The below "_swap_" functions
00028   //        do not have local variables and manipulates pointers
00029   //        directly.
00030 
00031   static void write_swap_2(char* a_pos,char* a_x) {
00032     *a_pos++ = *(a_x+1);
00033     *a_pos++ = *a_x;
00034   }
00035   static void write_swap_4(char* a_pos,char* a_x) {
00036     a_x += 3;
00037     *a_pos++ = *a_x--;
00038     *a_pos++ = *a_x--;
00039     *a_pos++ = *a_x--;
00040     *a_pos++ = *a_x;
00041   }
00042   static void write_swap_8(char* a_pos,char* a_x) {
00043     a_x += 7;
00044     *a_pos++ = *a_x--;
00045     *a_pos++ = *a_x--;
00046     *a_pos++ = *a_x--;
00047     *a_pos++ = *a_x--;
00048     *a_pos++ = *a_x--;
00049     *a_pos++ = *a_x--;
00050     *a_pos++ = *a_x--;
00051     *a_pos++ = *a_x;
00052   }
00056   static void write_nswp_2(char* a_pos,char* a_x) {
00057     ::memcpy(a_pos,a_x,2);
00058   }
00059   static void write_nswp_4(char* a_pos,char* a_x) {
00060     ::memcpy(a_pos,a_x,4);
00061   }
00062   static void write_nswp_8(char* a_pos,char* a_x) {
00063     ::memcpy(a_pos,a_x,8);
00064   }
00068   
00069   
00070   static const std::string& s_class() {
00071     static const std::string s_v("inlib::wroot::wbuf");
00072     return s_v;
00073   }
00074   typedef void (*w_2_func)(char*,char*);
00075   typedef void (*w_4_func)(char*,char*);
00076   typedef void (*w_8_func)(char*,char*);
00077 public:
00078   wbuf(std::ostream& a_out,bool a_byte_swap,
00079               const char* a_eob,char*& a_pos)
00080   :m_out(a_out)
00081   ,m_byte_swap(a_byte_swap)
00082   ,m_eob(a_eob)
00083   ,m_pos(a_pos)
00084 
00085   ,m_w_2_func(0)
00086   ,m_w_4_func(0)
00087   ,m_w_8_func(0)
00088   {
00089 #ifdef INLIB_MEM
00090     mem::increment(s_class().c_str());
00091 #endif
00092     if(m_byte_swap) {
00093       m_w_2_func = write_swap_2;
00094       m_w_4_func = write_swap_4;
00095       m_w_8_func = write_swap_8;
00096     } else {
00097       m_w_2_func = write_nswp_2;
00098       m_w_4_func = write_nswp_4;
00099       m_w_8_func = write_nswp_8;
00100     }
00101   }
00102   virtual ~wbuf(){
00103 #ifdef INLIB_MEM
00104     mem::decrement(s_class().c_str());
00105 #endif
00106   }
00107 protected:
00108   wbuf(const wbuf& a_from)
00109   :m_out(a_from.m_out),m_eob(a_from.m_eob),m_pos(a_from.m_pos){
00110 #ifdef INLIB_MEM
00111     mem::increment(s_class().c_str());
00112 #endif
00113   }
00114   wbuf& operator=(const wbuf&){return *this;}
00115 public:
00116   void set_eob(const char* a_eob){m_eob = a_eob;}
00117 
00118 public:
00119   bool write(unsigned char a_x) {
00120     if(!check_eob<unsigned char>()) return false;
00121     *m_pos++ = a_x;
00122     return true;
00123   }
00124 
00125   bool write(unsigned short a_x) {
00126     if(!check_eob<unsigned short>()) return false;
00127     m_w_2_func(m_pos,(char*)&a_x);
00128     m_pos += sizeof(unsigned short);
00129     return true;
00130   }
00131 
00132   bool write(unsigned int a_x) {
00133     if(!check_eob<unsigned int>()) return false;
00134     m_w_4_func(m_pos,(char*)&a_x);
00135     m_pos += sizeof(unsigned int);
00136     return true;
00137   }
00138 
00139   bool write(uint64 a_x){
00140     if(!check_eob<uint64>()) return false;
00141     m_w_8_func(m_pos,(char*)&a_x);
00142     m_pos += 8;
00143     return true;
00144   }
00145 
00146   bool write(float a_x) {
00147     if(!check_eob<float>()) return false;
00148     m_w_4_func(m_pos,(char*)&a_x);
00149     m_pos += sizeof(float);
00150     return true;
00151   }
00152 
00153   bool write(double a_x) {
00154     if(!check_eob<double>()) return false;
00155     m_w_8_func(m_pos,(char*)&a_x);
00156     m_pos += sizeof(double);
00157     return true;
00158   }
00159 
00160   bool write(char a_x)  {return write((unsigned char)a_x);}
00161   bool write(short a_x) {return write((unsigned short)a_x);}
00162   bool write(int a_x)   {return write((unsigned int)a_x);}
00163   bool write(int64 a_x) {return write((uint64)a_x);}
00164 
00165   bool write(const std::string& a_x) {
00166     unsigned char nwh;
00167     unsigned int nchars = a_x.size();
00168     if(nchars>254) {
00169       if(!check_eob(1+4,"std::string")) return false;
00170       nwh = 255;
00171       if(!write(nwh)) return false;
00172       if(!write(nchars)) return false;
00173     } else {
00174       if(!check_eob(1,"std::string")) return false;
00175       nwh = (unsigned char)nchars;
00176       if(!write(nwh)) return false;
00177     }
00178     if(!check_eob(nchars,"std::string")) return false;
00179     for (unsigned int i = 0; i < nchars; i++) m_pos[i] = a_x[i];
00180     m_pos += nchars;
00181     return true;
00182   }
00183 
00184 
00185   template <class T>
00186   bool write(const T* a_a,uint32 a_n) {
00187     if(!a_n) return true;
00188     uint32 l = a_n * sizeof(T);
00189     if(!check_eob(l,"array")) return false;
00190     if(m_byte_swap) {
00191       for(uint32 i=0;i<a_n;i++) {
00192         if(!write(a_a[i])) return false;
00193       }
00194     } else {
00195       ::memcpy(m_pos,a_a,l);
00196       m_pos += l;
00197     }
00198     return true;
00199   }
00200 
00201 protected:
00202   template <class T>
00203   bool check_eob(){
00204     if((m_pos+sizeof(T))>m_eob) {
00205       m_out << s_class() << " : " << stype(T()) << " : "
00206            << " try to access out of buffer " << long2s(sizeof(T)) << " bytes"
00207            << " (pos=" << char_p2s(m_pos)
00208            << ", eob=" << char_p2s(m_eob) << ")." << std::endl;
00209       return false;
00210     }
00211     return true;
00212   }
00213   bool check_eob(size_t a_n,const char* a_cmt){
00214     if((m_pos+a_n)>m_eob) {
00215       m_out << s_class() << " : " << a_cmt << " : "
00216            << " try to access out of buffer " << long2s(a_n) << " bytes"
00217            << " (pos=" << char_p2s(m_pos)
00218            << ", eob=" << char_p2s(m_eob) << ")." << std::endl;
00219       return false;
00220     }
00221     return true;
00222   }
00223 protected:
00224   std::ostream& m_out;
00225   bool m_byte_swap;
00226   const char* m_eob;
00227   char*& m_pos;
00228 
00229   w_2_func m_w_2_func;
00230   w_4_func m_w_4_func;
00231   w_8_func m_w_8_func;
00232 };
00233 
00234 }}
00235 
00236 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines