lean cpp library
A lean C++ library providing efficient utility classes for high-performance C++ applications.
raw_file_inserter.h
00001 /*****************************************************/
00002 /* lean I/O                     (c) Tobias Zirr 2011 */
00003 /*****************************************************/
00004 
00005 #ifndef LEAN_LOGGING_IO_RAW_FILE_INSERTER
00006 #define LEAN_LOGGING_IO_RAW_FILE_INSERTER
00007 
00008 #include "../lean.h"
00009 #include "../strings/types.h"
00010 #include "../tags/noncopyable.h"
00011 #include "raw_file.h"
00012 
00013 namespace lean
00014 {
00015 namespace io
00016 {
00017 
00019 template <size_t BufferSize = 4096>
00020 class raw_file_inserter : public noncopyable
00021 {
00022 private:
00023     raw_file *m_file;
00024     char m_buffer[BufferSize];
00025     char *m_end;
00026 
00027     LEAN_STATIC_ASSERT_MSG_ALT(BufferSize > 0,
00028         "Buffer size is required to be greater than 0",
00029         Buffer_size_is_required_to_be_greater_than_0);
00030 
00032     void flush()
00033     {
00034         size_t count = m_end - m_buffer;
00035 
00036         if (count != 0)
00037         {
00038             m_file->write(m_buffer, count);
00039             m_end = m_buffer;
00040         }
00041     }
00042 
00043 public:
00045     typedef char& reference;
00047     typedef const char& const_reference;
00048 
00050     class iterator
00051     {
00052     private:
00053         raw_file_inserter *m_inserter;
00054 
00055     public:
00057         LEAN_INLINE explicit iterator(raw_file_inserter &inserter)
00058             : m_inserter(&inserter) { }
00059 
00061         LEAN_INLINE iterator& operator =(const_reference value)
00062         {
00063             m_inserter->insert(value);
00064             return *this;
00065         }
00066 
00068         LEAN_INLINE iterator& operator ++()
00069         {
00070             // Follow the STL pattern and fake increment
00071             return *this;
00072         }
00074         LEAN_INLINE iterator& operator ++(int)
00075         {
00076             // Follow the STL pattern and fake increment
00077             return *this;
00078         }
00080         LEAN_INLINE iterator operator *()
00081         {
00082             // Follow the STL pattern and fake dereferencing
00083             return *this;
00084         }
00085     };
00086 
00088     LEAN_INLINE explicit raw_file_inserter(raw_file &file)
00089         : m_file(&file),
00090         m_end(m_buffer) { }
00092 /*  LEAN_INLINE raw_file_inserter(const raw_file_inserter &right)
00093         : m_file(right.m_file),
00094         m_end(m_buffer) { }
00095 */  
00096     LEAN_INLINE ~raw_file_inserter()
00097     {
00098         flush();
00099     }
00100 
00102 /*  LEAN_INLINE raw_file_inserter& operator =(const raw_file_inserter &right)
00103     {
00104         flush();
00105         m_file = right.m_file;
00106         return *this;
00107     }
00108 */
00110     LEAN_INLINE void insert(const_reference value)
00111     {
00112         *(m_end++) = value;
00113 
00114         if (m_end == m_buffer + BufferSize)
00115             flush();
00116     }
00117 
00119     LEAN_INLINE iterator iter()
00120     {
00121         return iterator(*this);
00122     }
00123 };
00124 
00125 } // namespace
00126 
00127 using io::raw_file_inserter;
00128 
00129 } // namespace
00130 
00131 #endif