Gaudi Framework, version v22r0

Home   Generated: 9 Feb 2011

StreamBuffer.h

Go to the documentation of this file.
00001 // $Header: /tmp/svngaudi/tmp.jEpFh25751/Gaudi/GaudiKernel/GaudiKernel/StreamBuffer.h,v 1.9 2008/10/27 16:41:33 marcocle 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 <cstring>
00011 #include <cstdlib>
00012 #include <typeinfo>
00013 
00014 #include "GaudiKernel/Kernel.h"
00015 #include "GaudiKernel/swab.h"
00016 
00017 // forward declarations
00018 class StreamBuffer;
00019 class DataObject;
00020 class ContainedObject;
00021 
00040 class StreamBuffer /* : public std::string  */  {
00041 public:
00043   class DataIO   {
00044   public:
00046     DataIO()    {
00047     }
00049     virtual ~DataIO()    {
00050     }
00052     void badStreamMode()    {
00053       throw("Not acceptable stream mode!");
00054     }
00056     virtual void serialize(StreamBuffer& stream)   {
00057       if (stream.isReading())
00058         load(stream);
00059       else if (stream.isWriting())
00060         dump(stream);
00061       else
00062         badStreamMode();
00063     }
00065     virtual void load(StreamBuffer&)   {
00066       badStreamMode();
00067     }
00069     virtual void dump(StreamBuffer&)   {
00070       badStreamMode();
00071     }
00072   };
00073 
00075   class Istream : public DataIO  {
00077     std::istream* m_stream;
00078   public:
00080     Istream(std::istream& str) : m_stream(&str)   {
00081     }
00083     virtual ~Istream()  {
00084     }
00086     virtual void load(StreamBuffer& stream)   {
00087       // Generic implementation for istreams:
00088       int  len;
00089       (*m_stream) >> len;
00090       stream.erase();
00091       stream.reserve(len);
00092       m_stream->read(stream.data(),len);
00093     }
00094   };
00096   class Ostream : public DataIO  {
00097     std::ostream* m_stream;
00098   public:
00100     Ostream(std::ostream& str) : m_stream(&str)   {
00101     }
00103     virtual ~Ostream()  {
00104     }
00106     virtual void dump(StreamBuffer& stream)   {
00107       // Generic implementation for ostreams:
00108       (*m_stream) << stream.buffPointer();
00109       m_stream->write(stream.data(), stream.buffPointer());
00110     }
00111   };
00112 public:
00114   enum Mode       {UNINITIALIZED, READING, WRITING};
00116   enum SwapAction {SINGLE_BYTE, SWAP, NOSWAP};
00118   enum    State   {INVALID=-1, VALID };
00120   class ContainedLink   {
00121   public:
00122     ContainedObject* first;
00123     long second;
00124     long third;
00125     ContainedLink() : first(0), second(INVALID), third(INVALID)  {
00126     }
00127     ContainedLink(const ContainedLink& copy)
00128       : first(copy.first), second(copy.second), third(copy.third)  {
00129     }
00130     ContainedLink(ContainedObject* pObj, long hint, long link)
00131       : first(pObj), second(hint), third(link)  {
00132     }
00133   };
00135   class IdentifiedLink   {
00136   public:
00137     DataObject* first;
00138     long second;
00139     IdentifiedLink() : first(0), second(INVALID)  {
00140     }
00141     IdentifiedLink(const IdentifiedLink& copy)
00142       : first(copy.first), second(copy.second)  {
00143     }
00144     IdentifiedLink(DataObject* pObj, long hint)
00145       : first(pObj), second(hint)  {
00146     }
00147   };
00148 
00149   typedef std::vector<ContainedLink>   ContainedLinks;
00151   typedef std::vector<IdentifiedLink>  IdentifiedLinks;
00153   typedef void (*AnalyzeFunction)(const void* data, int siz, const std::type_info& type);
00155   friend class DataObject;
00156 
00157 protected:
00159   Mode             m_mode;
00160 
00162   long             m_pointer;
00163 
00165   long             m_length;
00166 
00168   char*            m_buffer;
00169 
00171   bool             m_swapEnabled;
00172 
00174   ContainedLinks   m_containedLinks;
00175 
00177   IdentifiedLinks  m_identifiedLinks;
00178 
00180   AnalyzeFunction  m_analyzer;
00181 
00183   SwapAction swapBuffer(int siz)  const;
00184 
00188   template <class TYPE> StreamBuffer& getObjectPointer(const DataObject* pObject, TYPE*& refpObject) {
00189     IdentifiedLink& link = m_identifiedLinks.back();
00190     DataObject* pObj = link.first;
00191     m_identifiedLinks.pop_back();
00192     refpObject = dynamic_cast<TYPE*>(pObj);
00193     return *this;
00194   }
00198   template <class TYPE> StreamBuffer& getObjectPointer(const ContainedObject* pObject, TYPE*& refpObject) {
00199     ContainedLink& link = m_containedLinks.back();
00200     ContainedObject* pObj = link.first;
00201     m_containedLinks.pop_back();
00202     refpObject = dynamic_cast<TYPE*>(pObj);
00203     return *this;
00204   }
00205 public:
00207   StreamBuffer(bool do_swap=true) :
00208     m_mode(UNINITIALIZED),
00209     m_pointer(0),
00210     m_length(0),
00211     m_buffer(0),
00212     m_swapEnabled(do_swap)
00213   {
00214     m_analyzer = 0;
00215   }
00217   virtual ~StreamBuffer()   {
00218     ::free( m_buffer );
00219   }
00221   const char* data()    const   {
00222     return m_buffer;
00223   }
00225   char* data()   {
00226     return m_buffer;
00227   }
00229   void erase()    {
00230     m_pointer = 0;
00231   }
00233   void reserve(long len)   {
00234     if ( len > m_length )   {
00235       m_length = (len < 16384) ? 16384 : len;
00236       m_buffer = (char*)::realloc (m_buffer,m_length);
00237     }
00238   }
00240   void extend(long len)    {
00241     if ( len + m_pointer > m_length )    {
00242       // We have to be a bit generous here in order not to run too often
00243       // into ::realloc().
00244         long new_len = (m_length < 16384) ? 16384 : 2*m_length;
00245       if ( m_length < len ) new_len += len;
00246       reserve(new_len);
00247     }
00248   }
00250   long size ()  const   {
00251     return m_length;
00252   }
00254   ContainedLinks& containedLinks()   {
00255     return m_containedLinks;
00256   }
00258   const ContainedLinks& containedLinks()   const {
00259     return m_containedLinks;
00260   }
00261 
00263   IdentifiedLinks& identifiedLinks()   {
00264     return m_identifiedLinks;
00265   }
00267   const IdentifiedLinks& identifiedLinks()   const {
00268     return m_identifiedLinks;
00269   }
00270 
00272   void setMode(Mode m)  {
00273     m_mode = m;
00274     m_pointer = 0;
00275     m_containedLinks.erase (m_containedLinks.begin(), m_containedLinks.end());
00276     m_identifiedLinks.erase(m_identifiedLinks.begin(),m_identifiedLinks.end());
00277   }
00278 
00280   bool isReading()    const     {
00281     return m_mode == READING;
00282   }
00283 
00285   bool isWriting()    const     {
00286     return m_mode == WRITING;
00287   }
00289   long buffPointer()    const   {
00290     return m_pointer;
00291   }
00293   void setBuffPointer(long ptr)   {
00294     m_pointer = ptr;
00295   }
00297   void setAnalyzer(AnalyzeFunction fun=0)  {
00298     m_analyzer = fun;
00299   }
00301   void swapToBuffer(const void* source, int siz);
00302 
00304   void swapFromBuffer(void* target, int siz);
00305 
00307   StreamBuffer& writeBytes  (const char* str, long len)    {
00308     extend( m_pointer+len+4 );
00309     *this << len;
00310     memcpy(data()+buffPointer(), str, len);
00311     m_pointer += len;
00312     return *this;
00313   }
00314 
00315   void getIdentifiedLink (DataObject*& pObject, long& hint)   {
00316     IdentifiedLink& l = m_identifiedLinks.back();
00317     pObject = l.first;
00318     hint    = l.second;
00319     m_identifiedLinks.pop_back();
00320   }
00321   void addIdentifiedLink (const DataObject* pObject, long hint)   {
00322     m_identifiedLinks.push_back( IdentifiedLink((DataObject*)pObject, hint) );
00323   }
00324 
00325   void getContainedLink (ContainedObject*& pObject, long& hint, long& link)   {
00326     ContainedLink& l = m_containedLinks.back();
00327     pObject = l.first;
00328     hint    = l.second;
00329     link    = l.third;
00330     m_containedLinks.pop_back();
00331   }
00332   void addContainedLink (const ContainedObject* pObject, long hint, long link)   {
00333     m_containedLinks.push_back( ContainedLink((ContainedObject*)pObject, hint, link) );
00334   }
00335 
00336 #ifdef USE_STREAM_ANALYSER
00337   #define STREAM_ANALYSE(data, len)   if ( 0 != m_analyzer ) m_analyzer(&data, len, typeid(data))
00338 #else
00339   #define STREAM_ANALYSE(data, len)
00340 #endif
00341 
00342   // Implement streamer macros for primivive data types.
00343 #define IMPLEMENT_STREAMER(TYPE)                                    \
00344   /*  Output Streamer                                   */          \
00345   StreamBuffer& operator<<(TYPE   data)     {                       \
00346     swapToBuffer(&data, sizeof(data));                              \
00347     STREAM_ANALYSE(data, sizeof(data));                             \
00348     return *this;                                                   \
00349   }                                                                 \
00350   /*  Input Streamer                                    */          \
00351   StreamBuffer& operator>>(TYPE & data)     {                       \
00352     swapFromBuffer(&data, sizeof(data));                            \
00353     return *this;                                                   \
00354   }
00355 // RootCint does not understand this macro....
00356 // But we can easily live without it!
00357 #undef IMPLEMENT_STREAMER
00358 
00360   StreamBuffer& operator<<(longlong   data)     {
00361     swapToBuffer(&data, sizeof(data));
00362     STREAM_ANALYSE(data, sizeof(data));
00363     return *this;
00364   }
00366   StreamBuffer& operator>>(longlong & data)     {
00367     swapFromBuffer(&data, sizeof(data));
00368     return *this;
00369   }
00371   StreamBuffer& operator<<(int   data)     {
00372     swapToBuffer(&data, sizeof(data));
00373     STREAM_ANALYSE(data, sizeof(data));
00374     return *this;
00375   }
00377   StreamBuffer& operator>>(int & data)     {
00378     swapFromBuffer(&data, sizeof(data));
00379     return *this;
00380   }
00382   StreamBuffer& operator<<(unsigned int   data)     {
00383     swapToBuffer(&data, sizeof(data));
00384     STREAM_ANALYSE(data, sizeof(data));
00385     return *this;
00386   }
00388   StreamBuffer& operator>>(unsigned int & data)     {
00389     swapFromBuffer(&data, sizeof(data));
00390     return *this;
00391   }
00393   StreamBuffer& operator<<(long   data)     {
00394     swapToBuffer(&data, sizeof(data));
00395     STREAM_ANALYSE(data, sizeof(data));
00396     return *this;
00397   }
00399   StreamBuffer& operator>>(long & data)     {
00400     swapFromBuffer(&data, sizeof(data));
00401     return *this;
00402   }
00404   StreamBuffer& operator<<(unsigned long   data)     {
00405     swapToBuffer(&data, sizeof(data));
00406     STREAM_ANALYSE(data, sizeof(data));
00407     return *this;
00408   }
00410   StreamBuffer& operator>>(unsigned long & data)     {
00411     swapFromBuffer(&data, sizeof(data));
00412     return *this;
00413   }
00415   StreamBuffer& operator<<(short   data)     {
00416     swapToBuffer(&data, sizeof(data));
00417     STREAM_ANALYSE(data, sizeof(data));
00418     return *this;
00419   }
00421   StreamBuffer& operator>>(short & data)     {
00422     swapFromBuffer(&data, sizeof(data));
00423     return *this;
00424   }
00426   StreamBuffer& operator<<(unsigned short   data)     {
00427     swapToBuffer(&data, sizeof(data));
00428     STREAM_ANALYSE(data, sizeof(data));
00429     return *this;
00430   }
00432   StreamBuffer& operator>>(unsigned short & data)     {
00433     swapFromBuffer(&data, sizeof(data));
00434     return *this;
00435   }
00437   StreamBuffer& operator<<(char   data)     {
00438     swapToBuffer(&data, sizeof(data));
00439     STREAM_ANALYSE(data, sizeof(data));
00440     return *this;
00441   }
00443   StreamBuffer& operator>>(char & data)     {
00444     swapFromBuffer(&data, sizeof(data));
00445     return *this;
00446   }
00448   StreamBuffer& operator<<(unsigned char   data)     {
00449     swapToBuffer(&data, sizeof(data));
00450     STREAM_ANALYSE(data, sizeof(data));
00451     return *this;
00452   }
00454   StreamBuffer& operator>>(unsigned char & data)     {
00455     swapFromBuffer(&data, sizeof(data));
00456     return *this;
00457   }
00459   StreamBuffer& operator<<(float   data)     {
00460     swapToBuffer(&data, sizeof(data));
00461     STREAM_ANALYSE(data, sizeof(data));
00462     return *this;
00463   }
00465   StreamBuffer& operator>>(float & data)     {
00466     swapFromBuffer(&data, sizeof(data));
00467     return *this;
00468   }
00470   StreamBuffer& operator<<(double   data)     {
00471     swapToBuffer(&data, sizeof(data));
00472     STREAM_ANALYSE(data, sizeof(data));
00473     return *this;
00474   }
00476   StreamBuffer& operator>>(double & data)     {
00477     swapFromBuffer(&data, sizeof(data));
00478     return *this;
00479   }
00481   StreamBuffer& operator>>(char* data)    {
00482     long i, len;
00483     *this >> len;
00484     for ( i = 0, data[0]=0; i < len; i++ )    {
00485       data[i] = m_buffer[m_pointer++];
00486     }
00487     return *this;
00488   }
00490   StreamBuffer& operator<<(const char *data)     {
00491     const char* ptr = 0 == data ? "" : data;
00492     int len = strlen(ptr)+1;
00493     if ( 0 == m_analyzer )
00494       writeBytes(ptr, len);
00495     else  {
00496       STREAM_ANALYSE(data, len);
00497     }
00498     return *this;
00499   }
00501   StreamBuffer& operator>>(std::string& data)   {
00502     long i, len;
00503     *this >> len;
00504     for ( i = 0, data = ""; i < len; i++ )    {
00505       data.append( 1, m_buffer[m_pointer++] );
00506     }
00507     return *this;
00508   }
00510   StreamBuffer& operator<<(const std::string& data)   {
00511     if ( 0 == m_analyzer)   {
00512       const char* ptr = data.c_str();
00513       long len = data.length();
00514       writeBytes(ptr, len);
00515     }
00516     else    {
00517       STREAM_ANALYSE(data, sizeof(data));
00518     }
00519     return *this;
00520   }
00527   template<class TYPE> StreamBuffer& operator>>(TYPE*& refpObject)        {
00528     return getObjectPointer(refpObject, refpObject);
00529   }
00530 
00537   StreamBuffer& operator<<(const ContainedObject* pObject)   {
00538     STREAM_ANALYSE(pObject, sizeof(pObject));
00539     addContainedLink(pObject, INVALID, INVALID);
00540     return *this;
00541   }
00542 
00549   StreamBuffer& operator<<(const DataObject* pObject)   {
00550     STREAM_ANALYSE(pObject, sizeof(pObject));
00551     addIdentifiedLink(pObject, INVALID);
00552     return *this;
00553   }
00554 
00561   void serialize(DataIO& ioObject)   {
00562     ioObject.serialize ( *this );
00563     m_pointer = 0;
00564   }
00565 };
00566 
00567 #undef STREAM_ANALYSE
00568 
00570 inline StreamBuffer::SwapAction StreamBuffer::swapBuffer(int siz)  const    {
00571   switch(siz)   {
00572   case 1:
00573     return SINGLE_BYTE;
00574   default:
00575 #if defined(__alpha) && !defined(__VMS)
00576 //    return m_swapEnabled ? SWAP : NOSWAP;
00577     return NOSWAP;
00578 #elif defined(__sun) && defined(__SVR4) && defined(__i386)
00579 //    return m_swapEnabled ? SWAP : NOSWAP;
00580     return NOSWAP;
00581 #elif defined(__APPLE__)
00582 //    return m_swapEnabled ? SWAP : NOSWAP;
00583     return SWAP;
00584 #elif defined(__linux) && !defined(__powerpc)
00585 //    return m_swapEnabled ? SWAP : NOSWAP;
00586     return NOSWAP;
00587 #elif defined(BORLAND) || defined(_WIN32) || defined(WIN32)
00588 //    return m_swapEnabled ? SWAP : NOSWAP;
00589     return NOSWAP;
00590 #else
00591     return m_swapEnabled ? SWAP : NOSWAP;
00592 //    return NOSWAP;
00593 #endif
00594   }
00595 }
00596 
00598 inline void StreamBuffer::swapToBuffer(const void* source, int siz)   {
00599   char buff[8], *tar, *src = (char*)source;
00600   extend (m_pointer+siz);
00601   tar = (char*)m_buffer+m_pointer;
00602   switch ( swapBuffer(siz) )   {
00603   case SINGLE_BYTE:
00604     *tar = *src;
00605     break;
00606   case SWAP:
00607 #ifdef __APPLE__
00608     for(int i = 0,j = siz-1;i<siz;i++,j--) tar[j] = src[i];
00609 #else
00610     ::_swab (src, buff, siz);
00611 #endif
00612     src = buff;
00613   case NOSWAP:
00614     memcpy(tar, src, siz);
00615     break;
00616   }
00617   m_pointer += siz;
00618 }
00619 
00621 inline void StreamBuffer::swapFromBuffer(void* target, int siz)   {
00622   char* tar = (char*)target;
00623   char* src = (char*)m_buffer+m_pointer;
00624   switch ( swapBuffer(siz) )   {
00625   case SINGLE_BYTE:
00626     *tar = *src;
00627     break;
00628   case SWAP:
00629 #ifdef __APPLE__
00630     for(int i = 0,j = siz-1;i<siz;i++,j--) tar[j] = src[i];
00631 #else
00632     ::_swab (src, tar, siz);
00633 #endif
00634     break;
00635   case NOSWAP:
00636     ::memcpy(tar, src, siz);
00637     break;
00638   }
00639   m_pointer += siz;
00640 }
00641 
00642 // Output serialize a vector of items
00643 template <class T> inline
00644 StreamBuffer& operator << (StreamBuffer& s, const std::vector<T>& v)  {
00645   s << v.size();
00646   for ( typename std::vector<T>::const_iterator i = v.begin(); i != v.end(); i++ )  {
00647     s << (*i);
00648   }
00649   return s;
00650 }
00651 
00652 // Input serialize a vector of items
00653 template <class T> inline
00654 StreamBuffer& operator >> (StreamBuffer& s, std::vector<T>& v)  {
00655   long i, len;
00656   s >> len;
00657   v.clear();
00658   for ( i = 0; i < len; i++ )  {
00659     T    temp;
00660     s >> temp;
00661     v.push_back(temp);
00662   }
00663   return s;
00664 }
00665 
00666 // Output serialize a list of items
00667 template <class T> inline
00668 StreamBuffer& operator << (StreamBuffer& s, const std::list<T>& l)  {
00669   s << l.size();
00670   for ( typename std::list<T>::const_iterator i = l.begin(); i != l.end(); i++ )  {
00671     s << (*i);
00672   }
00673   return s;
00674 }
00675 
00676 // Input serialize a list of items
00677 template <class T> inline
00678 StreamBuffer& operator >> (StreamBuffer& s, std::list<T>& l)  {
00679   long i, len;
00680   s >> len;
00681   l.clear();
00682   for ( i = 0; i < len; i++ )  {
00683     T    temp;
00684     s >> temp;
00685     l.push_back(temp);
00686   }
00687   return s;
00688 }
00689 #endif // GAUDIKERNEL_STREAMBUFFER_H
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines

Generated at Wed Feb 9 16:24:54 2011 for Gaudi Framework, version v22r0 by Doxygen version 1.6.2 written by Dimitri van Heesch, © 1997-2004