| Classes | Job Modules | Data Objects | Services | Algorithms | Tools | Packages | Directories | Tracs |

In This Package:

StreamBuffer.h

Go to the documentation of this file.
00001 // $Header: /local/reps/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 
00013 #include "GaudiKernel/Kernel.h"
00014 #include "GaudiKernel/swab.h"
00015 
00016 // forward declarations
00017 class StreamBuffer;
00018 class DataObject;
00019 class ContainedObject;
00020 
00039 class StreamBuffer /* : public std::string  */  {
00040 public:
00042   class DataIO   {
00043   public:
00045     DataIO()    {
00046     }
00048     virtual ~DataIO()    {
00049     }
00051     void badStreamMode()    {
00052       throw("Not acceptable stream mode!");
00053     }
00055     virtual void serialize(StreamBuffer& stream)   {
00056       if (stream.isReading())
00057         load(stream);
00058       else if (stream.isWriting())
00059         dump(stream);
00060       else
00061         badStreamMode();
00062     }
00064     virtual void load(StreamBuffer&)   {
00065       badStreamMode();
00066     }
00068     virtual void dump(StreamBuffer&)   {
00069       badStreamMode();
00070     }
00071   };
00072 
00074   class Istream : public DataIO  {
00076     std::istream* m_stream;
00077   public:
00079     Istream(std::istream& str) : m_stream(&str)   {
00080     }
00082     virtual ~Istream()  {
00083     }
00085     virtual void load(StreamBuffer& stream)   {
00086       // Generic implementation for istreams:
00087       int  len;
00088       (*m_stream) >> len;
00089       stream.erase();
00090       stream.reserve(len);
00091       m_stream->read(stream.data(),len);
00092     }
00093   };
00095   class Ostream : public DataIO  {
00096     std::ostream* m_stream;
00097   public:
00099     Ostream(std::ostream& str) : m_stream(&str)   {
00100     }
00102     virtual ~Ostream()  {
00103     }
00105     virtual void dump(StreamBuffer& stream)   {
00106       // Generic implementation for ostreams:
00107       (*m_stream) << stream.buffPointer();
00108       m_stream->write(stream.data(), stream.buffPointer());
00109     }
00110   };
00111 public:
00113   enum Mode       {UNINITIALIZED, READING, WRITING};
00115   enum SwapAction {SINGLE_BYTE, SWAP, NOSWAP};
00117   enum    State   {INVALID=-1, VALID };
00119   class ContainedLink   {
00120   public:
00121     ContainedObject* first;
00122     long second;
00123     long third;
00124     ContainedLink() : first(0), second(INVALID), third(INVALID)  {
00125     }
00126     ContainedLink(const ContainedLink& copy)
00127       : first(copy.first), second(copy.second), third(copy.third)  {
00128     }
00129     ContainedLink(ContainedObject* pObj, long hint, long link)
00130       : first(pObj), second(hint), third(link)  {
00131     }
00132   };
00134   class IdentifiedLink   {
00135   public:
00136     DataObject* first;
00137     long second;
00138     IdentifiedLink() : first(0), second(INVALID)  {
00139     }
00140     IdentifiedLink(const IdentifiedLink& copy)
00141       : first(copy.first), second(copy.second)  {
00142     }
00143     IdentifiedLink(DataObject* pObj, long hint)
00144       : first(pObj), second(hint)  {
00145     }
00146   };
00147 
00148   typedef std::vector<ContainedLink>   ContainedLinks;
00150   typedef std::vector<IdentifiedLink>  IdentifiedLinks;
00152   typedef void (*AnalyzeFunction)(const void* data, int siz, const std::type_info& type);
00154   friend class DataObject;
00155 
00156 protected:
00158   Mode             m_mode;
00159 
00161   long             m_pointer;
00162 
00164   long             m_length;
00165 
00167   char*            m_buffer;
00168 
00170   bool             m_swapEnabled;
00171   
00173   ContainedLinks   m_containedLinks;
00174 
00176   IdentifiedLinks  m_identifiedLinks;
00177 
00179   AnalyzeFunction  m_analyzer;
00180 
00182   SwapAction swapBuffer(int siz)  const;
00183 
00187   template <class TYPE> StreamBuffer& getObjectPointer(const DataObject* pObject, TYPE*& refpObject) {
00188     IdentifiedLink& link = m_identifiedLinks.back();
00189     DataObject* pObj = link.first;
00190     m_identifiedLinks.pop_back();
00191     refpObject = dynamic_cast<TYPE*>(pObj);
00192     return *this;
00193   }
00197   template <class TYPE> StreamBuffer& getObjectPointer(const ContainedObject* pObject, TYPE*& refpObject) {
00198     ContainedLink& link = m_containedLinks.back();
00199     ContainedObject* pObj = link.first;
00200     m_containedLinks.pop_back();
00201     refpObject = dynamic_cast<TYPE*>(pObj);
00202     return *this;
00203   }
00204 public:
00206   StreamBuffer(bool do_swap=true) : 
00207     m_mode(UNINITIALIZED), 
00208     m_pointer(0), 
00209     m_length(0), 
00210     m_buffer(0),
00211     m_swapEnabled(do_swap)
00212   {
00213     m_analyzer = 0;
00214   }
00216   virtual ~StreamBuffer()   {
00217     ::free( m_buffer );
00218   }
00220   const char* data()    const   {
00221     return m_buffer;
00222   }
00224   char* data()   {
00225     return m_buffer;
00226   }
00228   void erase()    {
00229     m_pointer = 0;
00230   }
00232   void reserve(long len)   {
00233     if ( len > m_length )   {
00234       m_length = (len < 16384) ? 16384 : len; 
00235       m_buffer = (char*)::realloc (m_buffer,m_length);
00236     }
00237   }
00239   void extend(long len)    {
00240     if ( len + m_pointer > m_length )    {
00241       // We have to be a bit generous here in order not to run too often
00242       // into ::realloc().
00243         long new_len = (m_length < 16384) ? 16384 : 2*m_length;
00244       if ( m_length < len ) new_len += len;
00245       reserve(new_len);
00246     }
00247   }
00249   long size ()  const   {
00250     return m_length;
00251   }
00253   ContainedLinks& containedLinks()   {
00254     return m_containedLinks;
00255   }
00257   const ContainedLinks& containedLinks()   const {
00258     return m_containedLinks;
00259   }
00260 
00262   IdentifiedLinks& identifiedLinks()   {
00263     return m_identifiedLinks;
00264   }
00266   const IdentifiedLinks& identifiedLinks()   const {
00267     return m_identifiedLinks;
00268   }
00269 
00271   void setMode(Mode m)  {
00272     m_mode = m;
00273     m_pointer = 0;
00274     m_containedLinks.erase (m_containedLinks.begin(), m_containedLinks.end());
00275     m_identifiedLinks.erase(m_identifiedLinks.begin(),m_identifiedLinks.end());
00276   }
00277   
00279   bool isReading()    const     {
00280     return m_mode == READING;
00281   }
00282 
00284   bool isWriting()    const     {
00285     return m_mode == WRITING;
00286   }
00288   long buffPointer()    const   {
00289     return m_pointer;
00290   }
00292   void setBuffPointer(long ptr)   {
00293     m_pointer = ptr;
00294   }
00296   void setAnalyzer(AnalyzeFunction fun=0)  {
00297     m_analyzer = fun;
00298   }
00300   void swapToBuffer(const void* source, int siz);
00301 
00303   void swapFromBuffer(void* target, int siz);
00304 
00306   StreamBuffer& writeBytes  (const char* str, long len)    {
00307     extend( m_pointer+len+4 );
00308     *this << len;
00309     memcpy(data()+buffPointer(), str, len);
00310     m_pointer += len;
00311     return *this;
00312   }
00313 
00314   void getIdentifiedLink (DataObject*& pObject, long& hint)   {
00315     IdentifiedLink& l = m_identifiedLinks.back();
00316     pObject = l.first;
00317     hint    = l.second;
00318     m_identifiedLinks.pop_back();
00319   }
00320   void addIdentifiedLink (const DataObject* pObject, long hint)   {
00321     m_identifiedLinks.push_back( IdentifiedLink((DataObject*)pObject, hint) );
00322   }
00323 
00324   void getContainedLink (ContainedObject*& pObject, long& hint, long& link)   {
00325     ContainedLink& l = m_containedLinks.back();
00326     pObject = l.first;
00327     hint    = l.second;
00328     link    = l.third;
00329     m_containedLinks.pop_back();
00330   }
00331   void addContainedLink (const ContainedObject* pObject, long hint, long link)   {
00332     m_containedLinks.push_back( ContainedLink((ContainedObject*)pObject, hint, link) );
00333   }
00334 
00335 #ifdef USE_STREAM_ANALYSER
00336   #define STREAM_ANALYSE(data, len)   if ( 0 != m_analyzer ) m_analyzer(&data, len, typeid(data))
00337 #else
00338   #define STREAM_ANALYSE(data, len)
00339 #endif
00340 
00341   // Implement streamer macros for primivive data types.
00342 #define IMPLEMENT_STREAMER(TYPE)                                    \
00343   /*  Output Streamer                                   */          \
00344   StreamBuffer& operator<<(TYPE   data)     {                       \
00345     swapToBuffer(&data, sizeof(data));                              \
00346     STREAM_ANALYSE(data, sizeof(data));                             \
00347     return *this;                                                   \
00348   }                                                                 \
00349   /*  Input Streamer                                    */          \
00350   StreamBuffer& operator>>(TYPE & data)     {                       \
00351     swapFromBuffer(&data, sizeof(data));                            \
00352     return *this;                                                   \
00353   }
00354 // RootCint does not understand this macro....
00355 // But we can easily live without it!
00356 #undef IMPLEMENT_STREAMER
00357 
00359   StreamBuffer& operator<<(longlong   data)     {                       
00360     swapToBuffer(&data, sizeof(data));                              
00361     STREAM_ANALYSE(data, sizeof(data));                             
00362     return *this;                                                   
00363   }                                                                 
00365   StreamBuffer& operator>>(longlong & data)     {                       
00366     swapFromBuffer(&data, sizeof(data));                            
00367     return *this;                                                   
00368   }
00370   StreamBuffer& operator<<(int   data)     {                       
00371     swapToBuffer(&data, sizeof(data));                              
00372     STREAM_ANALYSE(data, sizeof(data));                             
00373     return *this;                                                   
00374   }                                                                 
00376   StreamBuffer& operator>>(int & data)     {                       
00377     swapFromBuffer(&data, sizeof(data));                            
00378     return *this;                                                   
00379   }
00381   StreamBuffer& operator<<(unsigned int   data)     {                       
00382     swapToBuffer(&data, sizeof(data));                              
00383     STREAM_ANALYSE(data, sizeof(data));                             
00384     return *this;                                                   
00385   }                                                                 
00387   StreamBuffer& operator>>(unsigned int & data)     {                       
00388     swapFromBuffer(&data, sizeof(data));                            
00389     return *this;                                                   
00390   }
00392   StreamBuffer& operator<<(long   data)     {                       
00393     swapToBuffer(&data, sizeof(data));                              
00394     STREAM_ANALYSE(data, sizeof(data));                             
00395     return *this;                                                   
00396   }                                                                 
00398   StreamBuffer& operator>>(long & data)     {                       
00399     swapFromBuffer(&data, sizeof(data));                            
00400     return *this;                                                   
00401   }
00403   StreamBuffer& operator<<(unsigned long   data)     {                       
00404     swapToBuffer(&data, sizeof(data));                              
00405     STREAM_ANALYSE(data, sizeof(data));                             
00406     return *this;                                                   
00407   }                                                                 
00409   StreamBuffer& operator>>(unsigned long & data)     {                       
00410     swapFromBuffer(&data, sizeof(data));                            
00411     return *this;                                                   
00412   }
00414   StreamBuffer& operator<<(short   data)     {                       
00415     swapToBuffer(&data, sizeof(data));                              
00416     STREAM_ANALYSE(data, sizeof(data));                             
00417     return *this;                                                   
00418   }                                                                 
00420   StreamBuffer& operator>>(short & data)     {                       
00421     swapFromBuffer(&data, sizeof(data));                            
00422     return *this;                                                   
00423   }
00425   StreamBuffer& operator<<(unsigned short   data)     {                       
00426     swapToBuffer(&data, sizeof(data));                              
00427     STREAM_ANALYSE(data, sizeof(data));                             
00428     return *this;                                                   
00429   }                                                                 
00431   StreamBuffer& operator>>(unsigned short & data)     {                       
00432     swapFromBuffer(&data, sizeof(data));                            
00433     return *this;                                                   
00434   }
00436   StreamBuffer& operator<<(char   data)     {                       
00437     swapToBuffer(&data, sizeof(data));                              
00438     STREAM_ANALYSE(data, sizeof(data));                             
00439     return *this;                                                   
00440   }                                                                 
00442   StreamBuffer& operator>>(char & data)     {                       
00443     swapFromBuffer(&data, sizeof(data));                            
00444     return *this;                                                   
00445   }
00447   StreamBuffer& operator<<(unsigned char   data)     {                       
00448     swapToBuffer(&data, sizeof(data));                              
00449     STREAM_ANALYSE(data, sizeof(data));                             
00450     return *this;                                                   
00451   }                                                                 
00453   StreamBuffer& operator>>(unsigned char & data)     {                       
00454     swapFromBuffer(&data, sizeof(data));                            
00455     return *this;                                                   
00456   }
00458   StreamBuffer& operator<<(float   data)     {                       
00459     swapToBuffer(&data, sizeof(data));                              
00460     STREAM_ANALYSE(data, sizeof(data));                             
00461     return *this;                                                   
00462   }                                                                 
00464   StreamBuffer& operator>>(float & data)     {                       
00465     swapFromBuffer(&data, sizeof(data));                            
00466     return *this;                                                   
00467   }
00469   StreamBuffer& operator<<(double   data)     {                       
00470     swapToBuffer(&data, sizeof(data));                              
00471     STREAM_ANALYSE(data, sizeof(data));                             
00472     return *this;                                                   
00473   }                                                                 
00475   StreamBuffer& operator>>(double & data)     {                       
00476     swapFromBuffer(&data, sizeof(data));                            
00477     return *this;                                                   
00478   }
00480   StreamBuffer& operator>>(char* data)    {
00481     long i, len;
00482     *this >> len;
00483     for ( i = 0, data[0]=0; i < len; i++ )    {
00484       data[i] = m_buffer[m_pointer++];
00485     }
00486     return *this;
00487   }
00489   StreamBuffer& operator<<(const char *data)     {
00490     const char* ptr = 0 == data ? "" : data;
00491     int len = strlen(ptr)+1;
00492     if ( 0 == m_analyzer ) 
00493       writeBytes(ptr, len);
00494     else  {
00495       STREAM_ANALYSE(data, len);
00496     }
00497     return *this;
00498   }
00500   StreamBuffer& operator>>(std::string& data)   {
00501     long i, len;
00502     *this >> len;
00503     for ( i = 0, data = ""; i < len; i++ )    {
00504       data.append( 1, m_buffer[m_pointer++] );
00505     }
00506     return *this;
00507   }
00509   StreamBuffer& operator<<(const std::string& data)   {
00510     if ( 0 == m_analyzer)   {
00511       const char* ptr = data.c_str();
00512       long len = data.length();
00513       writeBytes(ptr, len);
00514     }
00515     else    {
00516       STREAM_ANALYSE(data, sizeof(data));
00517     }
00518     return *this;
00519   }
00526   template<class TYPE> StreamBuffer& operator>>(TYPE*& refpObject)        {
00527     return getObjectPointer(refpObject, refpObject);
00528   }
00529 
00536   StreamBuffer& operator<<(const ContainedObject* pObject)   {
00537     STREAM_ANALYSE(pObject, sizeof(pObject));
00538     addContainedLink(pObject, INVALID, INVALID);
00539     return *this;
00540   }
00541 
00548   StreamBuffer& operator<<(const DataObject* pObject)   {
00549     STREAM_ANALYSE(pObject, sizeof(pObject));
00550     addIdentifiedLink(pObject, INVALID);
00551     return *this;
00552   }
00553 
00560   void serialize(DataIO& ioObject)   {
00561     ioObject.serialize ( *this );
00562     m_pointer = 0;
00563   }
00564 };
00565 
00566 #undef STREAM_ANALYSE
00567 
00569 inline StreamBuffer::SwapAction StreamBuffer::swapBuffer(int siz)  const    {
00570   switch(siz)   {
00571   case 1:  
00572     return SINGLE_BYTE;
00573   default:
00574 #if defined(__alpha) && !defined(__VMS)
00575 //    return m_swapEnabled ? SWAP : NOSWAP;
00576     return NOSWAP;
00577 #elif defined(__sun) && defined(__SVR4) && defined(__i386)
00578 //    return m_swapEnabled ? SWAP : NOSWAP;
00579     return NOSWAP;
00580 #elif defined(__APPLE__)
00581 //    return m_swapEnabled ? SWAP : NOSWAP;
00582     return SWAP;
00583 #elif defined(__linux) && !defined(__powerpc)
00584 //    return m_swapEnabled ? SWAP : NOSWAP;
00585     return NOSWAP;
00586 #elif defined(BORLAND) || defined(_WIN32) || defined(WIN32)
00587 //    return m_swapEnabled ? SWAP : NOSWAP;
00588     return NOSWAP;
00589 #else
00590     return m_swapEnabled ? SWAP : NOSWAP;
00591 //    return NOSWAP;
00592 #endif
00593   }
00594 }
00595 
00597 inline void StreamBuffer::swapToBuffer(const void* source, int siz)   {
00598   char buff[8], *tar, *src = (char*)source;
00599   extend (m_pointer+siz);
00600   tar = (char*)m_buffer+m_pointer;
00601   switch ( swapBuffer(siz) )   {
00602   case SINGLE_BYTE:
00603     *tar = *src;
00604     break;
00605   case SWAP:
00606 #ifdef __APPLE__
00607     for(int i = 0,j = siz-1;i<siz;i++,j--) tar[j] = src[i];
00608 #else
00609     ::_swab (src, buff, siz);
00610 #endif
00611     src = buff;
00612   case NOSWAP:
00613     memcpy(tar, src, siz);
00614     break;
00615   }
00616   m_pointer += siz;
00617 }
00618 
00620 inline void StreamBuffer::swapFromBuffer(void* target, int siz)   {
00621   char* tar = (char*)target;
00622   char* src = (char*)m_buffer+m_pointer;
00623   switch ( swapBuffer(siz) )   {
00624   case SINGLE_BYTE:
00625     *tar = *src;
00626     break;
00627   case SWAP:
00628 #ifdef __APPLE__
00629     for(int i = 0,j = siz-1;i<siz;i++,j--) tar[j] = src[i];
00630 #else
00631     ::_swab (src, tar, siz);
00632 #endif
00633     break;
00634   case NOSWAP:
00635     ::memcpy(tar, src, siz);
00636     break;
00637   }
00638   m_pointer += siz;
00639 }
00640 
00641 // Output serialize a vector of items
00642 template <class T> inline 
00643 StreamBuffer& operator << (StreamBuffer& s, const std::vector<T>& v)  {
00644   s << v.size();
00645   for ( typename std::vector<T>::const_iterator i = v.begin(); i != v.end(); i++ )  {
00646     s << (*i);
00647   }
00648   return s;
00649 }
00650 
00651 // Input serialize a vector of items
00652 template <class T> inline
00653 StreamBuffer& operator >> (StreamBuffer& s, std::vector<T>& v)  {
00654   long i, len;
00655   s >> len;
00656   v.clear();
00657   for ( i = 0; i < len; i++ )  {
00658     T    temp;
00659     s >> temp;
00660     v.push_back(temp);
00661   }
00662   return s;
00663 }
00664 
00665 // Output serialize a list of items
00666 template <class T> inline 
00667 StreamBuffer& operator << (StreamBuffer& s, const std::list<T>& l)  {
00668   s << l.size();
00669   for ( typename std::list<T>::const_iterator i = l.begin(); i != l.end(); i++ )  {
00670     s << (*i);
00671   }
00672   return s;
00673 }
00674 
00675 // Input serialize a list of items
00676 template <class T> inline
00677 StreamBuffer& operator >> (StreamBuffer& s, std::list<T>& l)  {
00678   long i, len;
00679   s >> len;
00680   l.clear();
00681   for ( i = 0; i < len; i++ )  {
00682     T    temp;
00683     s >> temp;
00684     l.push_back(temp);
00685   }
00686   return s;
00687 }
00688 #endif // GAUDIKERNEL_STREAMBUFFER_H
| Classes | Job Modules | Data Objects | Services | Algorithms | Tools | Packages | Directories | Tracs |

Generated on Mon Apr 11 19:56:58 2011 for GaudiKernel by doxygen 1.4.7