cel_stream.h

Go to the documentation of this file.
00001 //----------------------------------------------------------------------------
00004 //
00005 // (C) 2003-2006 Celartem Technology Inc. All rights reserved.
00006 //----------------------------------------------------------------------------
00007 
00008 #ifndef _cel_stream_h_
00009 #define _cel_stream_h_
00010 
00011 #include "cel_types.h"
00012 #include "cel_referable.h"
00013 #include "cel_string.h"
00014 #include "cel_datatraits.h"
00015 #include "cel_exception.h"
00016 #include "cel_lockable.h"
00017 
00018 namespace Celartem
00019 {
00030     typedef void (*DuplicateStreamCallback)(
00031         void* inContext,
00032         size_t inBytesCopied,
00033         size_t inMaximumBytesToCopy);
00034 
00035     //========================================================================
00041     class Stream : public Referable, public Lockable
00042     {
00043     public:
00066         virtual size_t readBytes(
00067             void *buffer, size_t inSize, bool wouldBlock = false) = 0;
00068 
00080         virtual void writeBytes(const void *buffer, size_t inSize) = 0;
00081 
00086         virtual void flushBuffer() = 0;
00087 
00095         virtual bool isEof() const = 0;
00096 
00113         virtual size_t duplicateStream(
00114             Stream *inStream,
00115             size_t inBufferSize = 1024,
00116             DuplicateStreamCallback inCallback = NULL,
00117             void* inCallbackContext = NULL);
00118 
00139         virtual size_t duplicateStreamBytes(
00140             Stream *inStream,
00141             size_t inMaximumByteSize,
00142             size_t inBufferSize = 1024,
00143             DuplicateStreamCallback inCallback = NULL,
00144             void* inCallbackContext = NULL);
00145     };
00146 
00147     //========================================================================
00154     template<typename T, StoragePolicy storagePolicy>
00155     struct WriteData
00156     {
00157         static void writeData(
00158             Stream *inStream, const T& n, Endian inEndian = endianHost);
00159     };
00160 
00166     template<typename T>
00167     struct WriteData<T, notToBeStored>
00168     {
00169         static void writeData(
00170             Stream *inStream, const T& n, Endian inEndian = endianHost)
00171         {
00172             celThrow2(
00173                 errNotPermitted,
00174                 "The object should not be stored in the storage or it might lack DataTraits implementation for the type.");
00175         }
00176     };
00177 
00183     template<typename T>
00184     struct WriteData<T, byCopyBytes>
00185     {
00186         static void writeData(
00187             Stream *inStream, const T& n, Endian inEndian = endianHost)
00188         {
00189             inStream->writeBytes(&n, sizeof(T));
00190         }
00191     };
00192 
00199     template<typename T>
00200     struct WriteData<T, bySwapCopyBytes>
00201     {
00202         static void writeData(
00203             Stream *inStream, const T& n, Endian inEndian = endianHost)
00204         {
00205             u8 buffer[sizeof(T)];
00206             write<T>(buffer, n, inEndian);
00207             inStream->writeBytes(buffer, sizeof(T));
00208         }
00209     };
00210 
00225     template<typename T>
00226     struct WriteData<T, byClassMethods>
00227     {
00228         static void writeData(
00229             Stream *inStream, const T& n, Endian inEndian = endianHost)
00230         {
00231             n.serialize(inStream, 0, inEndian);
00232         }
00233     };
00234 
00235     //------------------------------------------------------------------------
00242     template<typename T, StoragePolicy storagePolicy>
00243     struct ReadData
00244     {
00245         static T readData(Stream *inStream, Endian inEndian = endianHost);
00246     };
00247 
00253     template<typename T>
00254     struct ReadData<T, notToBeStored>
00255     {
00256         static T readData(
00257             Stream *inStream, Endian inEndian = endianHost)
00258         {
00259             celThrow2(
00260                 errNotPermitted,
00261                 "The object should not be load from the storage.");
00262             return T();
00263         }
00264     };
00265 
00271     template<typename T>
00272     struct ReadData<T, byCopyBytes>
00273     {
00274         static T readData(
00275             Stream *inStream, Endian inEndian = endianHost)
00276         {
00277             T tmp;
00278             inStream->readBytes(&tmp, sizeof(T), true);
00279             return tmp;
00280         }
00281     };
00282 
00289     template<typename T>
00290     struct ReadData<T, bySwapCopyBytes>
00291     {
00292         static T readData(
00293             Stream *inStream, Endian inEndian = endianHost)
00294         {
00295             u8 buffer[sizeof(T)];
00296             inStream->readBytes(buffer, sizeof(T), true);
00297             return read<T>(buffer, inEndian);
00298         }
00299     };
00300 
00314     template<typename T>
00315     struct ReadData<T, byClassMethods>
00316     {
00317         static T readData(
00318             Stream *inStream, Endian inEndian = endianHost)
00319         {
00320             T t;
00321             t.deserialize(inStream, 0, inEndian);
00322             return t;
00323         }
00324     };
00325 
00326     //========================================================================
00349     template<typename T>
00350     void write(
00351         Stream *inStream, const T& n, Endian inEndian /*= endianHost*/)
00352     {
00353         WriteData<T, DataTraits<T>::storagePolicy>::writeData(
00354             inStream, n, inEndian);
00355     }
00356 
00377     template<typename T>
00378     T read(
00379         Stream *inStream, Endian inEndian /*= endianHost*/)
00380     {
00381         return ReadData<T, DataTraits<T>::storagePolicy>::readData(
00382             inStream, inEndian);
00383     }
00384 
00385     //========================================================================
00390     class NullStream : public Stream
00391     {
00392     public:
00396         static AutoPtr<NullStream> create()
00397         {
00398             return new NullStream();
00399         }
00400         
00401         virtual size_t readBytes(
00402             void *buffer, size_t inSize, bool wouldBlock = false)
00403         {
00404             celThrow2(errNotImplemented,
00405                 "NullStream::readBytes should not be called.");
00406         }
00407         
00408         virtual void writeBytes(const void *buffer, size_t inSize)
00409         {
00410             // do nothing
00411         }
00412         
00413         virtual void flushBuffer()
00414         {
00415             // do nothing
00416         }
00417         
00418         virtual bool isEof() const
00419         {
00420             // always EOF.
00421             return true;
00422         }
00423         
00424         virtual void lock() const {}
00425         virtual void unlock() const {}
00426     
00427     private:
00428         NullStream() {}
00429     };
00430     
00431     //========================================================================
00436     class ByteCounterStream : public Stream
00437     {
00438     public:
00444         static AutoPtr<ByteCounterStream> create(Stream* inStream)
00445         {
00446             return new ByteCounterStream(inStream);
00447         }
00448         
00454         size_t getNumOfBytesRead() const {return m_bytesRead;}
00455         
00461         size_t getNumOfBytesWritten() const {return m_bytesWritten;}
00462 
00466         void resetByteRead() {m_bytesRead = 0;}
00467 
00471         void resetByteWritten() {m_bytesWritten = 0;}
00472 
00473         virtual size_t readBytes(
00474             void *buffer, size_t inSize, bool wouldBlock = false)
00475         {
00476             size_t sizeRead = m_stream->readBytes(buffer, inSize, wouldBlock);
00477             m_bytesRead += sizeRead;
00478             return sizeRead;
00479         }
00480         virtual void writeBytes(const void *buffer, size_t inSize)
00481         {
00482             m_stream->writeBytes(buffer, inSize);
00483             m_bytesWritten += inSize;
00484         }
00485         
00486         virtual void flushBuffer() {m_stream->flushBuffer();}
00487         
00488         virtual bool isEof() const {return m_stream->isEof();}
00489 
00490         virtual void lock() const {m_stream->lock();}
00491         
00492         virtual void unlock() const {m_stream->unlock();}
00493 
00494     private:
00495         // This reduces the risk of inproper use of this class.
00496         ByteCounterStream(Stream* inStream)
00497             : m_stream(inStream), m_bytesRead(0), m_bytesWritten(0)
00498         {}
00499         ByteCounterStream();
00500         ByteCounterStream(ByteCounterStream& inRef);
00501         ByteCounterStream& operator=(ByteCounterStream& inRef);
00502 
00503         AutoPtr<Stream> m_stream;
00504         size_t m_bytesRead;
00505         size_t m_bytesWritten;
00506     };
00507 
00508     //========================================================================
00512     class PartialStream : public Stream
00513     {
00514     public:
00522         static AutoPtr<PartialStream> create(Stream* inStream, uint64_t inSize)
00523         {
00524             return new PartialStream(inStream, inSize);
00525         }
00526 
00527         virtual size_t readBytes(
00528             void *buffer, size_t inSize, bool wouldBlock = false)
00529         {
00530             uint64_t bytes = m_bytesProcessed + inSize;
00531             if(bytes > m_size)
00532             {
00533                 if(wouldBlock)
00534                     celThrow2(errReadFailed, "Cannot read so many bytes!");
00535                 inSize = (size_t)(m_size - m_bytesProcessed);
00536             }
00537             size_t sizeRead = m_stream->readBytes(buffer, inSize, wouldBlock);
00538             m_bytesProcessed += sizeRead;
00539             return sizeRead;
00540         }
00541         
00542         virtual void writeBytes(const void *buffer, size_t inSize)
00543         {
00544             if(m_bytesProcessed + inSize > m_size)
00545                 celThrow2(errReadFailed, "Cannot write so many bytes!");
00546             m_stream->writeBytes(buffer, inSize);
00547             m_bytesProcessed += inSize;
00548         }
00549         
00550         virtual void flushBuffer()
00551         {
00552             m_stream->flushBuffer();
00553         }
00554         
00555         virtual bool isEof() const
00556         {
00557             if(m_bytesProcessed >= m_size)
00558                 return true;
00559             return m_stream->isEof();
00560         }
00561 
00562         virtual void lock() const {m_stream->lock();}
00563         
00564         virtual void unlock() const {m_stream->unlock();}
00565 
00566     private:
00567         // This reduces the risk of inproper use of this class.
00568         PartialStream(Stream* inStream, uint64_t inSize)
00569             : m_stream(inStream), m_size(inSize), m_bytesProcessed(0)
00570         {}
00571         PartialStream();
00572         PartialStream(PartialStream& inRef);
00573         PartialStream& operator=(PartialStream& inRef);
00574 
00575         AutoPtr<Stream> m_stream;
00576         uint64_t m_size;
00577         uint64_t m_bytesProcessed;
00578     };
00579 
00580 } // namespace Celartem
00581 
00582 #endif // _cel_stream_h_

This document is automatically generated using doxygen 1.5.4 at Fri Jun 27 18:21:55 2008.