inlib  1.2.0
/Users/barrand/private/dev/softinex/old/inexlib-1.2/inlib/inlib/io/xwbuf
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_io_xwbuf
00005 #define inlib_io_xwbuf
00006 
00007 // used to produce exsg XML files.
00008 
00009 #include "iwbuf"
00010 
00011 #include "../realloc"
00012 
00013 #ifdef INLIB_MEM
00014 #include "../mem"
00015 #endif
00016 
00017 #include <ostream>
00018 
00019 #include "../mnmx"
00020 
00021 namespace inlib {
00022 namespace io {
00023 
00024 class xwbuf : public virtual iwbuf {
00025 #ifdef INLIB_MEM
00026   static const std::string& s_class() {
00027     static const std::string s_v("inlib::io::xwbuf");
00028     return s_v;
00029   }
00030 #endif
00031 public: //iwbuf
00032   virtual bool write(uchar a_x) {
00033     if(!_write_cstr("<uchar v=\"")) return false;
00034     if(!_write<uchar>(a_x,write_format(a_x).c_str())) return false;
00035     if(!_write_cstr("\"/>")) return false;
00036     return true;
00037   }
00038   virtual bool write(char a_x) {
00039     if(!_write_cstr("<char v=\"")) return false;
00040     if(!_write<char>(a_x,write_format(a_x).c_str())) return false;
00041     if(!_write_cstr("\"/>")) return false;
00042     return true;
00043   }
00044   virtual bool write(uint16 a_x) {
00045     if(!_write_cstr("<uint16 v=\"")) return false;
00046     if(!_write<uint16>(a_x,write_format(a_x).c_str())) return false;
00047     if(!_write_cstr("\"/>")) return false;
00048     return true;
00049   }
00050   virtual bool write(int16 a_x) {
00051     if(!_write_cstr("<int16 v=\"")) return false;
00052     if(!_write<int16>(a_x,write_format(a_x).c_str())) return false;
00053     if(!_write_cstr("\"/>")) return false;
00054     return true;
00055   }
00056   virtual bool write(uint32 a_x) {
00057     if(!_write_cstr("<uint32 v=\"")) return false;
00058     if(!_write<uint32>(a_x,write_format(a_x).c_str())) return false;
00059     if(!_write_cstr("\"/>")) return false;
00060     return true;
00061   }
00062   virtual bool write(int32 a_x) {
00063     if(!_write_cstr("<int32 v=\"")) return false;
00064     if(!_write<int32>(a_x,write_format(a_x).c_str())) return false;
00065     if(!_write_cstr("\"/>")) return false;
00066     return true;
00067   }
00068   virtual bool write(uint64 a_x) {
00069     if(!_write_cstr("<uint64 v=\"")) return false;
00070     if(!_write<uint64>(a_x,write_format(a_x).c_str())) return false;
00071     if(!_write_cstr("\"/>")) return false;
00072     return true;
00073   }
00074   virtual bool write(int64 a_x) {
00075     if(!_write_cstr("<int64 v=\"")) return false;
00076     if(!_write<int64>(a_x,write_format(a_x).c_str())) return false;
00077     if(!_write_cstr("\"/>")) return false;
00078     return true;
00079   }
00080   virtual bool write(float a_x) {
00081     if(!_write_cstr("<float v=\"")) return false;
00082     if(!_write<float>(a_x,write_format(a_x).c_str())) return false;
00083     if(!_write_cstr("\"/>")) return false;
00084     return true;
00085   }
00086   virtual bool write(double a_x) {
00087     if(!_write_cstr("<double v=\"")) return false;
00088     if(!_write<double>(a_x,write_format(a_x).c_str())) return false;
00089     if(!_write_cstr("\"/>")) return false;
00090     return true;
00091   }
00092 
00093   virtual bool write(bool a_v) {
00094     if(!_write_cstr("<bool v=\"")) return false;
00095     if((m_pos+MAX_SPRINTF_SIZE())>m_max) {
00096       if(!expand(inlib::mx<uint32>(2*m_size,m_size+MAX_SPRINTF_SIZE()))) 
00097         return false;
00098     }
00099     if(!m_buffer) return false;
00100     //NOTE : the below writes an ending null char.
00101 #ifdef WIN32
00102     int sz = _snprintf(m_pos,MAX_SPRINTF_SIZE(),"%u",a_v?1:0);
00103 #else
00104     int sz = ::snprintf(m_pos,MAX_SPRINTF_SIZE(),"%u",a_v?1:0);
00105 #endif
00106     if(sz>(MAX_SPRINTF_SIZE()-1)) return false;
00107     m_pos += sz;
00108     if(!_write_cstr("\"/>")) return false;
00109     return true;
00110   }
00111 
00112   virtual bool write_cstr(const char* a_cstr) {
00113     if(!_write_cstr("<string v=\"")) return false;
00114     if(!_write_xml_cstr(a_cstr)) return false;
00115     if(!_write_cstr("\"/>")) return false;
00116     return true;
00117   }
00118 
00119   virtual bool write_vec(uint32 a_n,const uchar* a_x){
00120     return _write_array<uchar>(a_n,a_x);
00121   }
00122   virtual bool write_vec(uint32 a_n,const char* a_x){
00123     return _write_array<char>(a_n,a_x);
00124   }
00125   virtual bool write_vec(uint32 a_n,const uint16* a_x){
00126     return _write_array<uint16>(a_n,a_x);
00127   }
00128   virtual bool write_vec(uint32 a_n,const int16* a_x){
00129     return _write_array<int16>(a_n,a_x);
00130   }
00131   virtual bool write_vec(uint32 a_n,const uint32* a_x){
00132     return _write_array<uint32>(a_n,a_x);
00133   }
00134   virtual bool write_vec(uint32 a_n,const int32* a_x){
00135     return _write_array<int32>(a_n,a_x);
00136   }
00137   virtual bool write_vec(uint32 a_n,const uint64* a_x){
00138     return _write_array<uint64>(a_n,a_x);
00139   }
00140   virtual bool write_vec(uint32 a_n,const int64* a_x){
00141     return _write_array<int64>(a_n,a_x);
00142   }
00143   virtual bool write_vec(uint32 a_n,const float* a_x){
00144     return _write_array<float>(a_n,a_x);
00145   }
00146   virtual bool write_vec(uint32 a_n,const double* a_x){
00147     return _write_array<double>(a_n,a_x);
00148   }
00149   virtual bool write_vec(uint32 a_n,const bool* a_x){
00150     return _write_array<bool>(a_n,a_x);
00151   }
00152 
00153   virtual bool write_vec(const std::vector<std::string>& a_v){
00154     // <string>\n<string>\n<string>
00155     if(!_write_cstr("<array>")) return false;
00156     std::vector<std::string>::const_iterator it;    
00157     for(it=a_v.begin();it!=a_v.end();++it) {
00158       if(it!=a_v.begin()) {if(!_write_cstr("\\n")) return false;}
00159       if(!_write_xml_cstr((*it).c_str())) return false;
00160     }
00161     if(!_write_cstr("</array>")) return false;
00162     return true;
00163   }
00164 
00165   virtual bool write_std_vec_vec(const std_vec_vec_uint_t& a_vv) {
00166     return _write_std_vec_vec<unsigned int>(a_vv);
00167   }
00168   virtual bool write_std_vec_vec(const std_vec_vec_float_t& a_vv) {
00169     return _write_std_vec_vec<float>(a_vv);
00170   }
00171   virtual bool write_std_vec_vec(const std_vec_vec_string_t& a_vv) {
00172     if(!_write_cstr("<array>")) return false;
00173 
00174     typedef std::vector<std::string> vec_t;
00175 
00176     std::vector<vec_t>::const_iterator it;
00177     for(it=a_vv.begin();it!=a_vv.end();++it) {
00178       if(it!=a_vv.begin()) {if(!_write_cstr("\\t")) return false;}
00179       
00180       std::vector<std::string>::const_iterator it2;
00181       for(it2=(*it).begin();it2!=(*it).end();++it2) {
00182         if(it2!=(*it).begin()) {if(!_write_cstr("\\n")) return false;}
00183         if(!_write_xml_cstr((*it2).c_str())) return false;
00184       }
00185 
00186     }
00187 
00188     if(!_write_cstr("</array>")) return false;
00189 
00190     return true;
00191   }
00192 public:
00193   virtual const char* buf() const {return m_buffer;}
00194   virtual uint32 length() const {return m_pos-m_buffer;}
00195 public:
00196   xwbuf(std::ostream& a_out,uint32 a_size = 1014)
00197   :m_out(a_out)
00198   ,m_size(0)
00199   ,m_buffer(0)
00200   ,m_max(0)
00201   ,m_pos(0)
00202   {
00203 #ifdef INLIB_MEM
00204     mem::increment(s_class().c_str());
00205 #endif
00206     m_size = a_size;
00207     m_buffer = new char[m_size];
00208     m_max = m_buffer+m_size;
00209     m_pos = m_buffer;
00210   }
00211   virtual ~xwbuf(){
00212     delete [] m_buffer;
00213 #ifdef INLIB_MEM
00214     mem::decrement(s_class().c_str());
00215 #endif
00216   }
00217 protected:
00218   xwbuf(const xwbuf& a_from)
00219   : iwbuf(a_from)
00220   ,m_out(a_from.m_out){
00221 #ifdef INLIB_MEM
00222     mem::decrement(s_class().c_str());
00223 #endif
00224   }
00225   xwbuf& operator=(const xwbuf&){return *this;}
00226 public:
00227   bool write_verbatim(const char* a_cstr) {
00228     if(!_write_cstr(a_cstr)) return false;
00229     return true;
00230   }
00231   void reset_pos() {m_pos = m_buffer;}
00232 protected:
00236 
00237   bool _write_cstr(const char* a_cstr) {
00238     size_t sz = ::strlen(a_cstr);
00239     if((m_pos+sz)>m_max)
00240       if(!expand(inlib::mx<uint32>(2*m_size,m_size+sz))) return false;
00241     if(!m_buffer) return false;
00242     ::memcpy(m_pos,a_cstr,sz);
00243     m_pos += sz;
00244     return true;
00245   }
00246 
00247   bool _write_xml_cstr(const char* a_cstr) {
00248     size_t sz = ::strlen(a_cstr);
00249     if((m_pos+sz)>m_max)
00250       if(!expand(inlib::mx<uint32>(2*m_size,m_size+sz))) return false;
00251     if(!m_buffer) return false;
00252 
00253     char* pos = (char*)a_cstr;
00254     while(true){
00255       char c = *pos;pos++;
00256       if(c=='\0') {
00257         break;
00258       } else if(c=='<') {
00259         *m_pos = '&';m_pos++;
00260         *m_pos = 'l';m_pos++;
00261         *m_pos = 't';m_pos++;
00262         *m_pos = ';';m_pos++;
00263       } else if(c=='>') {
00264         *m_pos = '&';m_pos++;
00265         *m_pos = 'g';m_pos++;
00266         *m_pos = 't';m_pos++;
00267         *m_pos = ';';m_pos++;
00268       } else if(c=='&') {
00269         *m_pos = '&';m_pos++;
00270         *m_pos = 'a';m_pos++;
00271         *m_pos = 'm';m_pos++;
00272         *m_pos = 'p';m_pos++;
00273         *m_pos = ';';m_pos++;
00274       } else if(c=='"') {
00275         *m_pos = '&';m_pos++;
00276         *m_pos = 'q';m_pos++;
00277         *m_pos = 'u';m_pos++;
00278         *m_pos = 'o';m_pos++;
00279         *m_pos = 't';m_pos++;
00280         *m_pos = ';';m_pos++;
00281       } else if(c=='\'') {
00282         *m_pos = '&';m_pos++;
00283         *m_pos = 'a';m_pos++;
00284         *m_pos = 'p';m_pos++;
00285         *m_pos = 'o';m_pos++;
00286         *m_pos = 's';m_pos++;
00287         *m_pos = ';';m_pos++;
00288       } else {
00289         *m_pos = c;m_pos++;
00290       }
00291     }
00292 
00293     return true;
00294   }
00295 
00296   static int MAX_SPRINTF_SIZE() {return 256;}
00297 
00298   template <class ta_type>
00299   bool _write(ta_type a_v,const char* a_format) {
00300     if((m_pos+MAX_SPRINTF_SIZE())>m_max) {
00301       if(!expand(inlib::mx<uint32>(2*m_size,m_size+MAX_SPRINTF_SIZE())))
00302         return false;
00303     }
00304     if(!m_buffer) return false;
00305 #ifdef WIN32
00306     int sz = _snprintf(m_pos,MAX_SPRINTF_SIZE(),a_format,a_v);
00307 #else
00308     int sz = ::snprintf(m_pos,MAX_SPRINTF_SIZE(),a_format,a_v);
00309 #endif
00310     if(sz>(MAX_SPRINTF_SIZE()-1)) return false;
00311     m_pos += sz;
00312     return true;
00313   }
00314 
00315   template <class ta_type>
00316   bool _write_array(uint32 a_n,const ta_type* a_a) {
00317     if(!_write_cstr("<array>")) return false;
00318 
00319     for(uint32 i=0;i<a_n;i++) {
00320       if(i) {if(!_write_cstr(" ")) return false;}
00321       if(!_write<ta_type>(a_a[i],write_format(a_a[i]).c_str())) return false;
00322     }
00323 
00324     if(!_write_cstr("</array>")) return false;
00325     return true;
00326   }
00327 
00328   template <class T>
00329   bool _write_std_vec_vec(const std::vector< std::vector<T> >& a_vv) {
00330     // <num> <num> <num>\n<num> <num> <num>\n...\n<num> <num>
00331     if(!_write_cstr("<array>")) return false;
00332 
00333     typedef typename std::vector<T> vec_t;
00334 
00335     typedef typename std::vector<vec_t>::const_iterator cit_t;
00336     for(cit_t it=a_vv.begin();it!=a_vv.end();++it) {
00337       if(it!=a_vv.begin()) {if(!_write_cstr("\\n")) return false;}
00338       
00339       typedef typename std::vector<T>::const_iterator cit2_t;
00340       for(cit2_t it2=(*it).begin();it2!=(*it).end();++it2) {
00341         if(it2!=(*it).begin()) {if(!_write_cstr(" ")) return false;}
00342         if(!_write<T>(*it2,write_format(*it2).c_str())) return false;
00343       }
00344 
00345     }
00346 
00347     if(!_write_cstr("</array>")) return false;
00348 
00349     return true;
00350   }
00351 protected:
00352   static const std::string& write_format(uchar) {
00353     static const std::string s_v("%u");
00354     return s_v;    
00355   }
00356   static const std::string& write_format(char) {
00357     static const std::string s_v("%d");
00358     return s_v;    
00359   }
00360   static const std::string& write_format(uint16) {
00361     static const std::string s_v("%u");
00362     return s_v;    
00363   }
00364   static const std::string& write_format(int16) {
00365     static const std::string s_v("%d");
00366     return s_v;    
00367   }
00368   static const std::string& write_format(uint32) {
00369     static const std::string s_v("%u");
00370     return s_v;    
00371   }
00372   static const std::string& write_format(int32) {
00373     static const std::string s_v("%d");
00374     return s_v;    
00375   }
00376   static const std::string& write_format(uint64) {
00377     static const std::string s_v(uint64_format());
00378     return s_v;   
00379   }
00380   static const std::string& write_format(int64) {
00381     static const std::string s_v(int64_format());
00382     return s_v;   
00383   }
00384   static const std::string& write_format(float) {
00385     static const std::string s_v("%g");
00386     return s_v;    
00387   }
00388   static const std::string& write_format(double) {
00389     static const std::string s_v("%g");
00390     return s_v;    
00391   }
00392 
00393   bool expand(uint32 a_new_size) {
00394     unsigned long len = m_pos-m_buffer;
00395     if(!realloc<char>(m_buffer,a_new_size,m_size)) {
00396       m_out << "inlib::io::xwbuf::expand :"
00397             << " can't realloc " << a_new_size << " bytes."
00398             << std::endl;
00399       m_size = 0;
00400       m_max = 0;
00401       m_pos = 0;
00402       return false;
00403     }
00404     m_size = a_new_size;
00405     m_max = m_buffer + m_size;
00406     m_pos = m_buffer + len;
00407     return true;
00408   }
00409 protected:
00410   std::ostream& m_out;
00411   uint32 m_size;
00412   char* m_buffer;
00413   char* m_max;
00414   char* m_pos;
00415 };
00416 
00417 }}
00418 
00419 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines