| # Gaudi Framework, version v20r2
Generated: 18 Jul 2008

- Main Page
- Namespaces
- Classes
- Files
- Directories
- Related Pages

- Search for |

- File List
- File Members

# 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