00001 #ifndef BACKBUFFER_H
00002 #define BACKBUFFER_H
00003
00004 #include "zipios++/zipios-config.h"
00005
00006 #include <algorithm>
00007
00008 #include "zipios++/meta-iostreams.h"
00009 #include <vector>
00010
00011 #include "zipios++/fcollexceptions.h"
00012 #include "zipios++/ziphead.h"
00013 #include "zipios++/zipheadio.h"
00014 #include "zipios++/virtualseeker.h"
00015 #include "zipios_common.h"
00016
00017 namespace zipios {
00018
00019 using std::ios ;
00020 using std::cerr ;
00021 using std::endl ;
00022
00032 class BackBuffer : public vector< unsigned char > {
00033 public:
00042 inline explicit BackBuffer( istream &is, VirtualSeeker vs = VirtualSeeker(),
00043 int chunk_size = 1024 ) ;
00051 inline int readChunk( int &read_pointer ) ;
00052
00053 private:
00054 VirtualSeeker _vs ;
00055 int _chunk_size ;
00056 istream &_is ;
00057 streampos _file_pos ;
00058
00059 };
00060
00061 BackBuffer::BackBuffer( istream &is, VirtualSeeker vs, int chunk_size )
00062 : _vs ( vs ),
00063 _chunk_size( chunk_size ),
00064 _is ( is )
00065 {
00066 _vs.vseekg( is, 0, ios::end ) ;
00067 _file_pos = _vs.vtellg( is ) ;
00068
00069
00070
00071 if ( _file_pos < 0 )
00072 throw FCollException( "Invalid virtual file endings" ) ;
00073 }
00074
00075 int BackBuffer::readChunk( int &read_pointer ) {
00076
00077 _chunk_size = min<int> ( static_cast< int >( _file_pos ), _chunk_size ) ;
00078 _file_pos -= _chunk_size ;
00079 _vs.vseekg( _is, _file_pos, ios::beg ) ;
00080
00081 insert ( begin(), _chunk_size, static_cast< char > ( 0 ) ) ;
00082
00083
00084 readByteSeq ( _is, &( (*this)[ 0 ] ), _chunk_size ) ;
00085 read_pointer += _chunk_size ;
00086
00087 if ( _is.good() )
00088 return _chunk_size ;
00089 else
00090 return 0 ;
00091 }
00092
00093 }
00094 #endif
00095
00100 00101 00102 00103 00104 00105 00106 00107 00108 00109 00110 00111 00112 00113 00114 00115 00116 00117