Gaudi Framework, version v20r2

Generated: 18 Jul 2008

StreamBuffer.h

Go to the documentation of this file.
00001 // $Header: /local/reps/Gaudi/GaudiKernel/GaudiKernel/StreamBuffer.h,v 1.8 2003/11/26 08:33:59 mato Exp $
00002 #ifndef GAUDIKERNEL_STREAMBUFFER_H
00003 #define GAUDIKERNEL_STREAMBUFFER_H 1
00004 
00005 // STL include files
00006 #include <list>
00007 #include <vector>
00008 #include <string>
00009 #include <iostream>
00010 #include "GaudiKernel/Kernel.h"
00011 #include "GaudiKernel/swab.h"
00012 
00013 // forward declarations
00014 class StreamBuffer;
00015 class DataObject;
00016 class ContainedObject;
00017 
00036 class StreamBuffer /* : public std::string  */  {
00037 public:
00039   class DataIO   {
00040   public:
00042     DataIO()    {
00043     }
00045     virtual ~DataIO()    {
00046     }
00048     void badStreamMode()    {
00049       throw("Not acceptable stream mode!");
00050     }
00052     virtual void serialize(StreamBuffer& stream)   {
00053       if (stream.isReading())
00054         load(stream);
00055       else if (stream.isWriting())
00056         dump(stream);
00057       else
00058         badStreamMode();
00059     }
00061     virtual void load(StreamBuffer&)   {
00062       badStreamMode();
00063     }
00065     virtual void dump(StreamBuffer&)   {
00066       badStreamMode();
00067     }
00068   };
00069 
00071   class Istream : public DataIO  {
00073     std::istream* m_stream;
00074   public:
00076     Istream(std::istream& str) : m_stream(&str)   {
00077     }
00079     virtual ~Istream()  {
00080     }
00082     virtual void load(StreamBuffer& stream)   {
00083       // Generic implementation for istreams:
00084       int  len;
00085       (*m_stream) >> len;
00086       stream.erase();
00087       stream.reserve(len);
00088       m_stream->read(stream.data(),len);
00089     }
00090   };
00092   class Ostream : public DataIO  {
00093     std::ostream* m_stream;
00094   public:
00096     Ostream(std::ostream& str) : m_stream(&str)   {
00097     }
00099     virtual ~Ostream()  {
00100     }
00102     virtual void dump(StreamBuffer& stream)   {
00103       // Generic implementation for ostreams:
00104       (*m_stream) << stream.buffPointer();
00105       m_stream->write(stream.data(), stream.buffPointer());
00106     }
00107   };
00108 public:
00110   enum Mode       {UNINITIALIZED, READING, WRITING};
00112   enum SwapAction {SINGLE_BYTE, SWAP, NOSWAP};
00114   enum    State   {INVALID=-1, VALID };
00116   class ContainedLink   {
00117   public:
00118     ContainedObject* first;
00119     long second;
00120     long third;
00121     ContainedLink() : first(0), second(INVALID), third(INVALID)  {
00122     }
00123     ContainedLink(const ContainedLink& copy)
00124       : first(copy.first), second(copy.second), third(copy.third)  {
00125     }
00126     ContainedLink(ContainedObject* pObj, long hint, long link)
00127       : first(pObj), second(hint), third(link)  {
00128     }
00129   };
00131   class IdentifiedLink   {
00132   public:
00133     DataObject* first;
00134     long second;
00135     IdentifiedLink() : first(0), second(INVALID)  {
00136     }
00137     IdentifiedLink(const IdentifiedLink& copy)
00138       : first(copy.first), second(copy.second)  {
00139     }
00140     IdentifiedLink(DataObject* pObj, long hint)
00141       : first(pObj), second(hint)  {
00142     }
00143   };
00144 
00145   typedef std::vector<ContainedLink>   ContainedLinks;
00147   typedef std::vector<IdentifiedLink>  IdentifiedLinks;
00149   typedef void (*AnalyzeFunction)(const void* data, int siz, const std::type_info& type);
00151   friend class DataObject;
00152 
00153 protected:
00155   Mode             m_mode;
00156 
00158   long             m_pointer;
00159 
00161   long             m_length;
00162 
00164   char*            m_buffer;
00165 
00167   bool             m_swapEnabled;
00168   
00170   ContainedLinks   m_containedLinks;
00171 
00173   IdentifiedLinks  m_identifiedLinks;
00174 
00176   AnalyzeFunction  m_analyzer;
00177 
00179   SwapAction swapBuffer(int siz)  const;
00180 
00184   template <class TYPE> StreamBuffer& getObjectPointer(const DataObject* pObject, TYPE*& refpObject) {
00185     IdentifiedLink& link = m_identifiedLinks.back();
00186     DataObject* pObj = link.first;
00187     m_identifiedLinks.pop_back();
00188     refpObject = dynamic_cast<TYPE*>(pObj);
00189     return *this;
00190   }
00194   template <class TYPE> StreamBuffer& getObjectPointer(const ContainedObject* pObject, TYPE*& refpObject) {
00195     ContainedLink& link = m_containedLinks.back();
00196     ContainedObject* pObj = link.first;
00197     m_containedLinks.pop_back();
00198     refpObject = dynamic_cast<TYPE*>(pObj);
00199     return *this;
00200   }
00201 public:
00203   StreamBuffer(bool do_swap=true) : 
00204     m_mode(UNINITIALIZED), 
00205     m_pointer(0), 
00206     m_length(0), 
00207     m_buffer(0),
00208     m_swapEnabled(do_swap)
00209   {
00210     m_analyzer = 0;
00211   }
00213   virtual ~StreamBuffer()   {
00214     ::free( m_buffer );
00215   }
00217   const char* data()    const   {
00218     return m_buffer;
00219   }
00221   char* data()   {
00222     return m_buffer;
00223   }
00225   void erase()    {
00226     m_pointer = 0;
00227   }
00229   void reserve(long len)   {
00230     if ( len > m_length )   {
00231       m_length = (len < 16384) ? 16384 : len; 
00232       m_buffer = (char*)::realloc (m_buffer,m_length);
00233     }
00234   }
00236   void extend(long len)    {
00237     if ( len + m_pointer > m_length )    {
00238       // We have to be a bit generous here in order not to run too often
00239       // into ::realloc().
00240         long new_len = (m_length < 16384) ? 16384 : 2*m_length;
00241       if ( m_length < len ) new_len += len;
00242       reserve(new_len);
00243     }
00244   }
00246   long size ()  const   {
00247     return m_length;
00248   }
00250   ContainedLinks& containedLinks()   {
00251     return m_containedLinks;
00252   }
00254   const ContainedLinks& containedLinks()   const {
00255     return m_containedLinks;
00256   }
00257 
00259   IdentifiedLinks& identifiedLinks()   {
00260     return m_identifiedLinks;
00261   }
00263   const IdentifiedLinks& identifiedLinks()   const {
00264     return m_identifiedLinks;
00265   }
00266 
00268   void setMode(Mode m)  {
00269     m_mode = m;
00270     m_pointer = 0;
00271     m_containedLinks.erase (m_containedLinks.begin(), m_containedLinks.end());
00272     m_identifiedLinks.erase(m_identifiedLinks.begin(),m_identifiedLinks.end());
00273   }
00274   
00276   bool isReading()    const     {
00277     return m_mode == READING;
00278   }
00279 
00281   bool isWriting()    const     {
00282     return m_mode == WRITING;
00283   }
00285   long buffPointer()    const   {
00286     return m_pointer;
00287   }
00289   void setBuffPointer(long ptr)   {
00290     m_pointer = ptr;
00291   }
00293   void setAnalyzer(AnalyzeFunction fun=0)  {
00294     m_analyzer = fun;
00295   }
00297   void swapToBuffer(const void* source, int siz);
00298 
00300   void swapFromBuffer(void* target, int siz);
00301 
00303   StreamBuffer& writeBytes  (const char* str, long len)    {
00304     extend( m_pointer+len+4 );
00305     *this << len;
00306     memcpy(data()+buffPointer(), str, len);
00307     m_pointer += len;
00308     return *this;
00309   }
00310 
00311   void getIdentifiedLink (DataObject*& pObject, long& hint)   {
00312     IdentifiedLink& l = m_identifiedLinks.back();
00313     pObject = l.first;
00314     hint    = l.second;
00315     m_identifiedLinks.pop_back();
00316   }
00317   void addIdentifiedLink (const DataObject* pObject, long hint)   {
00318     m_identifiedLinks.push_back( IdentifiedLink((DataObject*)pObject, hint) );
00319   }
00320 
00321   void getContainedLink (ContainedObject*& pObject, long& hint, long& link)   {
00322     ContainedLink& l = m_containedLinks.back();
00323     pObject = l.first;
00324     hint    = l.second;
00325     link    = l.third;
00326     m_containedLinks.pop_back();
00327   }
00328   void addContainedLink (const ContainedObject* pObject, long hint, long link)   {
00329     m_containedLinks.push_back( ContainedLink((ContainedObject*)pObject, hint, link) );
00330   }
00331 
00332 #ifdef USE_STREAM_ANALYSER
00333   #define STREAM_ANALYSE(data, len)   if ( 0 != m_analyzer ) m_analyzer(&data, len, typeid(data))
00334 #else
00335   #define STREAM_ANALYSE(data, len)
00336 #endif
00337 
00338   // Implement streamer macros for primivive data types.
00339 #define IMPLEMENT_STREAMER(TYPE)                                    \
00340   /*  Output Streamer                                   */          \
00341   StreamBuffer& operator<<(TYPE   data)     {                       \
00342     swapToBuffer(&data, sizeof(data));                              \
00343     STREAM_ANALYSE(data, sizeof(data));                             \
00344     return *this;                                                   \
00345   }                                                                 \
00346   /*  Input Streamer                                    */          \
00347   StreamBuffer& operator>>(TYPE & data)     {                       \
00348     swapFromBuffer(&data, sizeof(data));                            \
00349     return *this;                                                   \
00350   }
00351 // RootCint does not understand this macro....
00352 // But we can easily live without it!
00353 #undef IMPLEMENT_STREAMER
00354 
00356   StreamBuffer& operator<<(longlong   data)     {                       
00357     swapToBuffer(&data, sizeof(data));                              
00358     STREAM_ANALYSE(data, sizeof(data));                             
00359     return *this;                                                   
00360   }                                                                 
00362   StreamBuffer& operator>>(longlong & data)     {                       
00363     swapFromBuffer(&data, sizeof(data));                            
00364     return *this;                                                   
00365   }
00367   StreamBuffer& operator<<(int   data)     {                       
00368     swapToBuffer(&data, sizeof(data));                              
00369     STREAM_ANALYSE(data, sizeof(data));                             
00370     return *this;                                                   
00371   }                                                                 
00373   StreamBuffer& operator>>(int & data)     {                       
00374     swapFromBuffer(&data, sizeof(data));                            
00375     return *this;                                                   
00376   }
00378   StreamBuffer& operator<<(unsigned int   data)     {                       
00379     swapToBuffer(&data, sizeof(data));                              
00380     STREAM_ANALYSE(data, sizeof(data));                             
00381     return *this;                                                   
00382   }                                                                 
00384   StreamBuffer& operator>>(unsigned int & data)     {                       
00385     swapFromBuffer(&data, sizeof(data));                            
00386     return *this;                                                   
00387   }
00389   StreamBuffer& operator<<(long   data)     {                       
00390     swapToBuffer(&data, sizeof(data));                              
00391     STREAM_ANALYSE(data, sizeof(data));                             
00392     return *this;                                                   
00393   }                                                                 
00395   StreamBuffer& operator>>(long & data)     {                       
00396     swapFromBuffer(&data, sizeof(data));                            
00397     return *this;                                                   
00398   }
00400   StreamBuffer& operator<<(unsigned long   data)     {                       
00401     swapToBuffer(&data, sizeof(data));                              
00402     STREAM_ANALYSE(data, sizeof(data));                             
00403     return *this;                                                   
00404   }                                                                 
00406   StreamBuffer& operator>>(unsigned long & data)     {                       
00407     swapFromBuffer(&data, sizeof(data));                            
00408     return *this;                                                   
00409   }
00411   StreamBuffer& operator<<(short   data)     {                       
00412     swapToBuffer(&data, sizeof(data));                              
00413     STREAM_ANALYSE(data, sizeof(data));                             
00414     return *this;                                                   
00415   }                                                                 
00417   StreamBuffer& operator>>(short & data)     {                       
00418     swapFromBuffer(&data, sizeof(data));                            
00419     return *this;                                                   
00420   }
00422   StreamBuffer& operator<<(unsigned short   data)     {                       
00423     swapToBuffer(&data, sizeof(data));                              
00424     STREAM_ANALYSE(data, sizeof(data));                             
00425     return *this;                                                   
00426   }                                                                 
00428   StreamBuffer& operator>>(unsigned short & data)     {                       
00429     swapFromBuffer(&data, sizeof(data));                            
00430     return *this;                                                   
00431   }
00433   StreamBuffer& operator<<(char   data)     {                       
00434     swapToBuffer(&data, sizeof(data));                              
00435     STREAM_ANALYSE(data, sizeof(data));                             
00436     return *this;                                                   
00437   }                                                                 
00439   StreamBuffer& operator>>(char & data)     {                       
00440     swapFromBuffer(&data, sizeof(data));                            
00441     return *this;                                                   
00442   }
00444   StreamBuffer& operator<<(unsigned char   data)     {                       
00445     swapToBuffer(&data, sizeof(data));                              
00446     STREAM_ANALYSE(data, sizeof(data));                             
00447     return *this;                                                   
00448   }                                                                 
00450   StreamBuffer& operator>>(unsigned char & data)     {                       
00451     swapFromBuffer(&data, sizeof(data));                            
00452     return *this;                                                   
00453   }
00455   StreamBuffer& operator<<(float   data)     {                       
00456     swapToBuffer(&data, sizeof(data));                              
00457     STREAM_ANALYSE(data, sizeof(data));                             
00458     return *this;                                                   
00459   }                                                                 
00461   StreamBuffer& operator>>(float & data)     {                       
00462     swapFromBuffer(&data, sizeof(data));                            
00463     return *this;                                                   
00464   }
00466   StreamBuffer& operator<<(double   data)     {                       
00467     swapToBuffer(&data, sizeof(data));                              
00468     STREAM_ANALYSE(data, sizeof(data));                             
00469     return *this;                                                   
00470   }                                                                 
00472   StreamBuffer& operator>>(double & data)     {                       
00473     swapFromBuffer(&data, sizeof(data));                            
00474     return *this;                                                   
00475   }
00477   StreamBuffer& operator>>(char* data)    {
00478     long i, len;
00479     *this >> len;
00480     for ( i = 0, data[0]=0; i < len; i++ )    {
00481       data[i] = m_buffer[m_pointer++];
00482     }
00483     return *this;
00484   }
00486   StreamBuffer& operator<<(const char *data)     {
00487     const char* ptr = 0 == data ? "" : data;
00488     int len = strlen(ptr)+1;
00489     if ( 0 == m_analyzer ) 
00490       writeBytes(ptr, len);
00491     else  {
00492       STREAM_ANALYSE(data, len);
00493     }
00494     return *this;
00495   }
00497   StreamBuffer& operator>>(std::string& data)   {
00498     long i, len;
00499     *this >> len;
00500     for ( i = 0, data = ""; i < len; i++ )    {
00501       data.append( 1, m_buffer[m_pointer++] );
00502     }
00503     return *this;
00504   }
00506   StreamBuffer& operator<<(const std::string& data)   {
00507     if ( 0 == m_analyzer)   {
00508       const char* ptr = data.c_str();
00509       long len = data.length();
00510       writeBytes(ptr, len);
00511     }
00512     else    {
00513       STREAM_ANALYSE(data, sizeof(data));
00514     }
00515     return *this;
00516   }
00523   template<class TYPE> StreamBuffer& operator>>(TYPE*& refpObject)        {
00524     return getObjectPointer(refpObject, refpObject);
00525   }
00526 
00533   StreamBuffer& operator<<(const ContainedObject* pObject)   {
00534     STREAM_ANALYSE(pObject, sizeof(pObject));
00535     addContainedLink(pObject, INVALID, INVALID);
00536     return *this;
00537   }
00538 
00545   StreamBuffer& operator<<(const DataObject* pObject)   {
00546     STREAM_ANALYSE(pObject, sizeof(pObject));
00547     addIdentifiedLink(pObject, INVALID);
00548     return *this;
00549   }
00550 
00557   void serialize(DataIO& ioObject)   {
00558     ioObject.serialize ( *this );
00559     m_pointer = 0;
00560   }
00561 };
00562 
00563 #undef STREAM_ANALYSE
00564 
00566 inline StreamBuffer::SwapAction StreamBuffer::swapBuffer(int siz)  const    {
00567   switch(siz)   {
00568   case 1:  
00569     return SINGLE_BYTE;
00570   default:
00571 #if defined(__alpha) && !defined(__VMS)
00572 //    return m_swapEnabled ? SWAP : NOSWAP;
00573     return NOSWAP;
00574 #elif defined(__sun) && defined(__SVR4) && defined(__i386)
00575 //    return m_swapEnabled ? SWAP : NOSWAP;
00576     return NOSWAP;
00577 #elif defined(__APPLE__)
00578 //    return m_swapEnabled ? SWAP : NOSWAP;
00579     return SWAP;
00580 #elif defined(__linux) && !defined(__powerpc)
00581 //    return m_swapEnabled ? SWAP : NOSWAP;
00582     return NOSWAP;
00583 #elif defined(BORLAND) || defined(_WIN32) || defined(WIN32)
00584 //    return m_swapEnabled ? SWAP : NOSWAP;
00585     return NOSWAP;
00586 #else
00587     return m_swapEnabled ? SWAP : NOSWAP;
00588 //    return NOSWAP;
00589 #endif
00590   }
00591 }
00592 
00594 inline void StreamBuffer::swapToBuffer(const void* source, int siz)   {
00595   char buff[8], *tar, *src = (char*)source;
00596   extend (m_pointer+siz);
00597   tar = (char*)m_buffer+m_pointer;
00598   switch ( swapBuffer(siz) )   {
00599   case SINGLE_BYTE:
00600     *tar = *src;
00601     break;
00602   case SWAP:
00603 #ifdef __APPLE__
00604     for(int i = 0,j = siz-1;i<siz;i++,j--) tar[j] = src[i];
00605 #else
00606     ::_swab (src, buff, siz);
00607 #endif
00608     src = buff;
00609   case NOSWAP:
00610     memcpy(tar, src, siz);
00611     break;
00612   }
00613   m_pointer += siz;
00614 }
00615 
00617 inline void StreamBuffer::swapFromBuffer(void* target, int siz)   {
00618   char* tar = (char*)target;
00619   char* src = (char*)m_buffer+m_pointer;
00620   switch ( swapBuffer(siz) )   {
00621   case SINGLE_BYTE:
00622     *tar = *src;
00623     break;
00624   case SWAP:
00625 #ifdef __APPLE__
00626     for(int i = 0,j = siz-1;i<siz;i++,j--) tar[j] = src[i];
00627 #else
00628     ::_swab (src, tar, siz);
00629 #endif
00630     break;
00631   case NOSWAP:
00632     ::memcpy(tar, src, siz);
00633     break;
00634   }
00635   m_pointer += siz;
00636 }
00637 
00638 // Output serialize a vector of items
00639 template <class T> inline 
00640 StreamBuffer& operator << (StreamBuffer& s, const std::vector<T>& v)  {
00641   s << v.size();
00642   for ( typename std::vector<T>::const_iterator i = v.begin(); i != v.end(); i++ )  {
00643     s << (*i);
00644   }
00645   return s;
00646 }
00647 
00648 // Input serialize a vector of items
00649 template <class T> inline
00650 StreamBuffer& operator >> (StreamBuffer& s, std::vector<T>& v)  {
00651   long i, len;
00652   s >> len;
00653   v.clear();
00654   for ( i = 0; i < len; i++ )  {
00655     T    temp;
00656     s >> temp;
00657     v.push_back(temp);
00658   }
00659   return s;
00660 }
00661 
00662 // Output serialize a list of items
00663 template <class T> inline 
00664 StreamBuffer& operator << (StreamBuffer& s, const std::list<T>& l)  {
00665   s << l.size();
00666   for ( typename std::list<T>::const_iterator i = l.begin(); i != l.end(); i++ )  {
00667     s << (*i);
00668   }
00669   return s;
00670 }
00671 
00672 // Input serialize a list of items
00673 template <class T> inline
00674 StreamBuffer& operator >> (StreamBuffer& s, std::list<T>& l)  {
00675   long i, len;
00676   s >> len;
00677   l.clear();
00678   for ( i = 0; i < len; i++ )  {
00679     T    temp;
00680     s >> temp;
00681     l.push_back(temp);
00682   }
00683   return s;
00684 }
00685 #endif // GAUDIKERNEL_STREAMBUFFER_H

Generated at Fri Jul 18 11:59:21 2008 for Gaudi Framework, version v20r2 by Doxygen version 1.5.1 written by Dimitri van Heesch, © 1997-2004