Main Page   Namespace List   Class Hierarchy   Compound List   File List   Namespace Members   Compound Members   File Members  

StreamBuffer.h

Go to the documentation of this file.
00001 // $Header: /nfs/slac/g/glast/ground/cvs/GaudiKernel/GaudiKernel/StreamBuffer.h,v 1.1.1.1 2001/04/18 18:14:18 tlindner Exp $
00002 #ifndef GAUDIKERNEL_STREAMBUFFER_H
00003 #define GAUDIKERNEL_STREAMBUFFER_H 1
00004 
00005 // STL include files
00006 #include <vector>
00007 #include <string>
00008 #include <iostream>
00009 #include "GaudiKernel/swab.h"
00010 
00011 // forward declarations
00012 class IDataDirectory;
00013 class StreamBuffer;
00014 class DataObject;
00015 class ContainedObject;
00016 
00035 class StreamBuffer /* : public std::string  */  {
00036 public:
00038   class DataIO   {
00039   public:
00041     DataIO()    {
00042     }
00044     virtual ~DataIO()    {
00045     }
00047     void badStreamMode()    {
00048       throw("Not acceptable stream mode!");
00049     }
00051     virtual void serialize(StreamBuffer& stream)   {
00052       if (stream.isReading())
00053         load(stream);
00054       else if (stream.isWriting())
00055         dump(stream);
00056       else
00057         badStreamMode();
00058     }
00060     virtual void load(StreamBuffer&)   {
00061       badStreamMode();
00062     }
00064     virtual void dump(StreamBuffer&)   {
00065       badStreamMode();
00066     }
00067   };
00068 
00070   class Istream : public DataIO  {
00072     std::istream* m_stream;
00073   public:
00075     Istream(std::istream& str) : m_stream(&str)   {
00076     }
00078     virtual ~Istream()  {
00079     }
00081     virtual void load(StreamBuffer& stream)   {
00082       // Generic implementation for istreams:
00083       int  len;
00084       (*m_stream) >> len;
00085       stream.erase();
00086       stream.reserve(len);
00087       m_stream->read(stream.data(),len);
00088     }
00089   };
00091   class Ostream : public DataIO  {
00092     std::ostream* m_stream;
00093   public:
00095     Ostream(std::ostream& str) : m_stream(&str)   {
00096     }
00098     virtual ~Ostream()  {
00099     }
00101     virtual void dump(StreamBuffer& stream)   {
00102       // Generic implementation for ostreams:
00103       (*m_stream) << stream.buffPointer();
00104       m_stream->write(stream.data(), stream.buffPointer());
00105     }
00106   };
00107 public:
00109   enum Mode       {UNINITIALIZED, READING, WRITING};
00111   enum SwapAction {SINGLE_BYTE, SWAP, NOSWAP};
00113   enum    State   {INVALID=-1, VALID };
00115   class ContainedLink   {
00116   public:
00117     ContainedObject* first;
00118     long second;
00119     long third;
00120     ContainedLink() : first(0), second(INVALID), third(INVALID)  {
00121     }
00122     ContainedLink(const ContainedLink& copy)
00123       : first(copy.first), second(copy.second), third(copy.third)  {
00124     }
00125     ContainedLink(ContainedObject* pObj, long hint, long link)
00126       : first(pObj), second(hint), third(link)  {
00127     }
00128   };
00130   class IdentifiedLink   {
00131   public:
00132     DataObject* first;
00133     long second;
00134     IdentifiedLink() : first(0), second(INVALID)  {
00135     }
00136     IdentifiedLink(const IdentifiedLink& copy)
00137       : first(copy.first), second(copy.second)  {
00138     }
00139     IdentifiedLink(DataObject* pObj, long hint)
00140       : first(pObj), second(hint)  {
00141     }
00142   };
00143 
00144   typedef std::vector<ContainedLink>   ContainedLinks;
00146   typedef std::vector<IdentifiedLink>  IdentifiedLinks;
00148   typedef void (*AnalyzeFunction)(const void* data, int siz, const std::type_info& type);
00150   friend class DataObject;
00151 
00152 protected:
00154   Mode             m_mode;
00155 
00157   long             m_pointer;
00158 
00160   long             m_length;
00161 
00163   char*            m_buffer;
00164 
00166   bool             m_swapEnabled;
00167   
00169   ContainedLinks   m_containedLinks;
00170 
00172   IdentifiedLinks  m_identifiedLinks;
00173 
00175   AnalyzeFunction  m_analyzer;
00176 
00178   SwapAction swapBuffer(int siz)  const;
00179 
00183   template <class TYPE> StreamBuffer& getObjectPointer(const DataObject* pObject, TYPE*& refpObject) {
00184     IdenfifiedLink& link = m_identifiedLinks.back();
00185     DataObject* pObj = link.first;
00186     m_identifiedLinks.pop_back();
00187     refpObject = dynamic_cast<TYPE*>(pObj);
00188     return *this;
00189   }
00193   template <class TYPE> StreamBuffer& getObjectPointer(const ContainedObject* pObject, TYPE*& refpObject) {
00194     ContainedLink& link = m_containedLinks.back();
00195     ContainedObject* pObj = link.first;
00196     m_containedLinks.pop_back();
00197     refpObject = dynamic_cast<TYPE*>(pObj);
00198     return *this;
00199   }
00200 public:
00202   StreamBuffer(bool do_swap=true) : 
00203     m_mode(UNINITIALIZED), 
00204     m_pointer(0), 
00205     m_length(0), 
00206     m_buffer(0),
00207     m_swapEnabled(do_swap)
00208   {
00209     m_analyzer = 0;
00210   }
00212   virtual ~StreamBuffer()   {
00213     ::free( m_buffer );
00214   }
00216   const char* data()    const   {
00217     return m_buffer;
00218   }
00220   char* data()   {
00221     return m_buffer;
00222   }
00224   void erase()    {
00225     m_pointer = 0;
00226   }
00228   void reserve(long len)   {
00229     if ( len > m_length )   {
00230       m_length = (len < 16384) ? 16384 : len; 
00231       m_buffer = (char*)::realloc (m_buffer,m_length);
00232     }
00233   }
00235   void extend(long len)    {
00236     if ( len + m_pointer > m_length )    {
00237       // We have to be a bit generous here in order not to run too often
00238       // into ::realloc().
00239         long new_len = (m_length < 16384) ? 16384 : 2*m_length;
00240       if ( m_length < len ) new_len += len;
00241       reserve(new_len);
00242     }
00243   }
00245   long size ()  const   {
00246     return m_length;
00247   }
00249   ContainedLinks& containedLinks()   {
00250     return m_containedLinks;
00251   }
00253   const ContainedLinks& containedLinks()   const {
00254     return m_containedLinks;
00255   }
00256 
00258   IdentifiedLinks& identifiedLinks()   {
00259     return m_identifiedLinks;
00260   }
00262   const IdentifiedLinks& identifiedLinks()   const {
00263     return m_identifiedLinks;
00264   }
00265 
00267   void setMode(Mode m)  {
00268     m_mode = m;
00269     m_pointer = 0;
00270     m_containedLinks.erase (m_containedLinks.begin(), m_containedLinks.end());
00271     m_identifiedLinks.erase(m_identifiedLinks.begin(),m_identifiedLinks.end());
00272   }
00273   
00275   bool isReading()    const     {
00276     return m_mode == READING;
00277   }
00278 
00280   bool isWriting()    const     {
00281     return m_mode == WRITING;
00282   }
00284   long buffPointer()    const   {
00285     return m_pointer;
00286   }
00288   void setBuffPointer(long ptr)   {
00289     m_pointer = ptr;
00290   }
00292   void setAnalyzer(AnalyzeFunction fun=0)  {
00293     m_analyzer = fun;
00294   }
00296   void swapToBuffer(const void* source, int siz);
00297 
00299   void swapFromBuffer(void* target, int siz);
00300 
00302   StreamBuffer& writeBytes  (const char* str, long len)    {
00303     extend( m_pointer+len+4 );
00304     *this << len;
00305     memcpy(data()+buffPointer(), str, len);
00306     m_pointer += len;
00307     return *this;
00308   }
00309 
00310   void getIdentifiedLink (DataObject*& pObject, long& hint)   {
00311     IdentifiedLink& l = m_identifiedLinks.back();
00312     pObject = l.first;
00313     hint    = l.second;
00314     m_identifiedLinks.pop_back();
00315   }
00316   void addIdentifiedLink (const DataObject* pObject, long hint)   {
00317     m_identifiedLinks.push_back( IdentifiedLink((DataObject*)pObject, hint) );
00318   }
00319 
00320   void getContainedLink (ContainedObject*& pObject, long& hint, long& link)   {
00321     ContainedLink& l = m_containedLinks.back();
00322     pObject = l.first;
00323     hint    = l.second;
00324     link    = l.third;
00325     m_containedLinks.pop_back();
00326   }
00327   void addContainedLink (const ContainedObject* pObject, long hint, long link)   {
00328     m_containedLinks.push_back( ContainedLink((ContainedObject*)pObject, hint, link) );
00329   }
00330 
00331 #ifdef USE_STREAM_ANALYSER
00332   #define STREAM_ANALYSE(data, len)   if ( 0 != m_analyzer ) m_analyzer(&data, len, typeid(data))
00333 #else
00334   #define STREAM_ANALYSE(data, len)
00335 #endif
00336 
00337   // Implement streamer macros for primivive data types.
00338 #define IMPLEMENT_STREAMER(TYPE)                                    \
00339   /*  Output Streamer                                   */          \
00340   StreamBuffer& operator<<(TYPE   data)     {                       \
00341     swapToBuffer(&data, sizeof(data));                              \
00342     STREAM_ANALYSE(data, sizeof(data));                             \
00343     return *this;                                                   \
00344   }                                                                 \
00345   /*  Input Streamer                                    */          \
00346   StreamBuffer& operator>>(TYPE & data)     {                       \
00347     swapFromBuffer(&data, sizeof(data));                            \
00348     return *this;                                                   \
00349   }
00350 // RootCint does not understand this macro....
00351 // But we can easily live without it!
00352 #undef IMPLEMENT_STREAMER
00353 
00355   StreamBuffer& operator<<(int   data)     {                       
00356     swapToBuffer(&data, sizeof(data));                              
00357     STREAM_ANALYSE(data, sizeof(data));                             
00358     return *this;                                                   
00359   }                                                                 
00361   StreamBuffer& operator>>(int & data)     {                       
00362     swapFromBuffer(&data, sizeof(data));                            
00363     return *this;                                                   
00364   }
00366   StreamBuffer& operator<<(unsigned int   data)     {                       
00367     swapToBuffer(&data, sizeof(data));                              
00368     STREAM_ANALYSE(data, sizeof(data));                             
00369     return *this;                                                   
00370   }                                                                 
00372   StreamBuffer& operator>>(unsigned int & data)     {                       
00373     swapFromBuffer(&data, sizeof(data));                            
00374     return *this;                                                   
00375   }
00377   StreamBuffer& operator<<(long   data)     {                       
00378     swapToBuffer(&data, sizeof(data));                              
00379     STREAM_ANALYSE(data, sizeof(data));                             
00380     return *this;                                                   
00381   }                                                                 
00383   StreamBuffer& operator>>(long & data)     {                       
00384     swapFromBuffer(&data, sizeof(data));                            
00385     return *this;                                                   
00386   }
00388   StreamBuffer& operator<<(unsigned long   data)     {                       
00389     swapToBuffer(&data, sizeof(data));                              
00390     STREAM_ANALYSE(data, sizeof(data));                             
00391     return *this;                                                   
00392   }                                                                 
00394   StreamBuffer& operator>>(unsigned long & data)     {                       
00395     swapFromBuffer(&data, sizeof(data));                            
00396     return *this;                                                   
00397   }
00399   StreamBuffer& operator<<(short   data)     {                       
00400     swapToBuffer(&data, sizeof(data));                              
00401     STREAM_ANALYSE(data, sizeof(data));                             
00402     return *this;                                                   
00403   }                                                                 
00405   StreamBuffer& operator>>(short & data)     {                       
00406     swapFromBuffer(&data, sizeof(data));                            
00407     return *this;                                                   
00408   }
00410   StreamBuffer& operator<<(unsigned short   data)     {                       
00411     swapToBuffer(&data, sizeof(data));                              
00412     STREAM_ANALYSE(data, sizeof(data));                             
00413     return *this;                                                   
00414   }                                                                 
00416   StreamBuffer& operator>>(unsigned short & data)     {                       
00417     swapFromBuffer(&data, sizeof(data));                            
00418     return *this;                                                   
00419   }
00421   StreamBuffer& operator<<(char   data)     {                       
00422     swapToBuffer(&data, sizeof(data));                              
00423     STREAM_ANALYSE(data, sizeof(data));                             
00424     return *this;                                                   
00425   }                                                                 
00427   StreamBuffer& operator>>(char & data)     {                       
00428     swapFromBuffer(&data, sizeof(data));                            
00429     return *this;                                                   
00430   }
00432   StreamBuffer& operator<<(unsigned char   data)     {                       
00433     swapToBuffer(&data, sizeof(data));                              
00434     STREAM_ANALYSE(data, sizeof(data));                             
00435     return *this;                                                   
00436   }                                                                 
00438   StreamBuffer& operator>>(unsigned char & data)     {                       
00439     swapFromBuffer(&data, sizeof(data));                            
00440     return *this;                                                   
00441   }
00443   StreamBuffer& operator<<(float   data)     {                       
00444     swapToBuffer(&data, sizeof(data));                              
00445     STREAM_ANALYSE(data, sizeof(data));                             
00446     return *this;                                                   
00447   }                                                                 
00449   StreamBuffer& operator>>(float & data)     {                       
00450     swapFromBuffer(&data, sizeof(data));                            
00451     return *this;                                                   
00452   }
00454   StreamBuffer& operator<<(double   data)     {                       
00455     swapToBuffer(&data, sizeof(data));                              
00456     STREAM_ANALYSE(data, sizeof(data));                             
00457     return *this;                                                   
00458   }                                                                 
00460   StreamBuffer& operator>>(double & data)     {                       
00461     swapFromBuffer(&data, sizeof(data));                            
00462     return *this;                                                   
00463   }
00465   StreamBuffer& operator>>(char* data)    {
00466     long i, len;
00467     *this >> len;
00468     for ( i = 0, data[0]=0; i < len; i++ )    {
00469       *data = m_buffer[m_pointer++];
00470     }
00471     return *this;
00472   }
00474   StreamBuffer& operator<<(const char *data)     {
00475     const char* ptr = 0 == data ? "" : data;
00476     int len = strlen(ptr)+1;
00477     if ( 0 == m_analyzer ) 
00478       writeBytes(ptr, len);
00479     else  {
00480       STREAM_ANALYSE(data, len);
00481     }
00482     return *this;
00483   }
00485   StreamBuffer& operator>>(std::string& data)   {
00486     long i, len;
00487     *this >> len;
00488     for ( i = 0, data = ""; i < len; i++ )    {
00489       data.append( 1, m_buffer[m_pointer++] );
00490     }
00491     return *this;
00492   }
00494   StreamBuffer& operator<<(const std::string& data)   {
00495     if ( 0 == m_analyzer)   {
00496       const char* ptr = data.c_str();
00497       long len = data.length();
00498       writeBytes(ptr, len);
00499     }
00500     else    {
00501       STREAM_ANALYSE(&data, sizeof(data));
00502     }
00503     return *this;
00504   }
00511   template<class TYPE> StreamBuffer& operator>>(TYPE*& refpObject)        {
00512     return getObjectPointer(refpObject, refpObject);
00513   }
00514 
00521   StreamBuffer& operator<<(const ContainedObject* pObject)   {
00522     STREAM_ANALYSE(pObjecta, sizeof(pObject));
00523     addContainedLink(pObject, INVALID, INVALID);
00524     return *this;
00525   }
00526 
00533   StreamBuffer& operator<<(const DataObject* pObject)   {
00534     STREAM_ANALYSE(pObjecta, sizeof(pObject));
00535     addIdentifiedLink(pObject, INVALID);
00536     return *this;
00537   }
00538 
00545   void serialize(DataIO& ioObject)   {
00546     ioObject.serialize ( *this );
00547     m_pointer = 0;
00548   }
00549 };
00550 
00551 #undef STREAM_ANALYSE
00552 
00554 inline StreamBuffer::SwapAction StreamBuffer::swapBuffer(int siz)  const    {
00555   switch(siz)   {
00556   case 1:  
00557     return SINGLE_BYTE;
00558   default:
00559 #if defined(__alpha) && !defined(__VMS)
00560 //    return m_swapEnabled ? SWAP : NOSWAP;
00561     return NOSWAP;
00562 #elif defined(__sun) && defined(__SVR4) && defined(__i386)
00563 //    return m_swapEnabled ? SWAP : NOSWAP;
00564     return NOSWAP;
00565 #elif defined(__linux) && !defined(__powerpc)
00566 //    return m_swapEnabled ? SWAP : NOSWAP;
00567     return NOSWAP;
00568 #elif defined(BORLAND) || defined(_WIN32) || defined(WIN32)
00569 //    return m_swapEnabled ? SWAP : NOSWAP;
00570     return NOSWAP;
00571 #else
00572     return m_swapEnabled ? SWAP : NOSWAP;
00573 //    return NOSWAP;
00574 #endif
00575   }
00576 }
00577 
00579 inline void StreamBuffer::swapToBuffer(const void* source, int siz)   {
00580   char buff[8], *tar, *src = (char*)source;
00581   extend (m_pointer+siz);
00582   tar = (char*)m_buffer+m_pointer;
00583   switch ( swapBuffer(siz) )   {
00584   case SINGLE_BYTE:
00585     *tar = *src;
00586     break;
00587   case SWAP:
00588     ::_swab (src, buff, siz);
00589     src = buff;
00590   case NOSWAP:
00591     memcpy(tar, src, siz);
00592     break;
00593   }
00594   m_pointer += siz;
00595 }
00596 
00598 inline void StreamBuffer::swapFromBuffer(void* target, int siz)   {
00599   char* tar = (char*)target;
00600   char* src = (char*)m_buffer+m_pointer;
00601   switch ( swapBuffer(siz) )   {
00602   case SINGLE_BYTE:
00603     *tar = *src;
00604     break;
00605   case SWAP:
00606     ::_swab (src, tar, siz);
00607     break;
00608   case NOSWAP:
00609     ::memcpy(tar, src, siz);
00610     break;
00611   }
00612   m_pointer += siz;
00613 }
00614 #endif // GAUDIKERNEL_STREAMBUFFER_H

Generated at Wed Nov 21 12:22:05 2001 by doxygen1.2.3 written by Dimitri van Heesch, © 1997-2000