3 Copyright 2007 Antoine Chavasse <a.chavasse@gmail.com>
5 This file is part of Fail.
7 Fail is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License version 3
9 as published by the Free Software Foundation.
11 Fail is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
19 #ifndef FAIL_IO_BUFFEREDINPUTSTREAM_H_
20 #define FAIL_IO_BUFFEREDINPUTSTREAM_H_
22 #include "core/core.h"
23 #include "InputStream.h"
24 #include "SeekableInputStream.h"
26 namespace fail
{ namespace io
28 // TODO: see comment in BufferedOutputBuffer regarding templates, compile-time buffer size and
29 // related neat optimizations.
30 template< class EndianessPolicy
= endianess::Native
, int BufferSize
= 4096,
31 class StreamType
= InputStream
>
32 class BufferedInputStream
35 typedef EndianessPolicy endianess_policy
;
37 BufferedInputStream( shared_ptr
< StreamType
> pInStream_
) :
38 m_pInStream( pInStream_
)
44 const shared_ptr
< StreamType
>& getInStream() const { return m_pInStream
; }
45 void setInStream( const shared_ptr
< StreamType
>& s
) { m_pInStream
= s
; }
47 unsigned int available() const
49 return m_EndIndex
- m_ReadIndex
;
52 unsigned int remaining() const
54 return BufferSize
- m_EndIndex
;
57 unsigned int read( void* pBuffer
, uint32_t Size_
)
59 unsigned int amountread
= 0;
63 amountread
= Size_
> available() ? available() : Size_
;
64 std::memcpy( pBuffer
, &m_Buffer
[ m_ReadIndex
], amountread
);
67 m_ReadIndex
+= amountread
;
68 if( m_ReadIndex
== m_EndIndex
)
69 m_ReadIndex
= m_EndIndex
= 0;
74 uint8_t* pbuf
= static_cast< uint8_t* >( pBuffer
);
75 amountread
+= m_pInStream
->read( pbuf
+ amountread
, Size_
);
80 unsigned int read
= m_pInStream
->read( &m_Buffer
[ m_EndIndex
], remaining() );
90 read( &tmp
, sizeof( tmp
) );
97 read( &tmp
, sizeof( tmp
) );
98 EndianessPolicy::FixEndianessU16( tmp
);
105 read( &tmp
, sizeof( tmp
) );
106 EndianessPolicy::FixEndianessU32( tmp
);
113 read( &tmp
, sizeof( tmp
) );
114 EndianessPolicy::FixEndianessU64( tmp
);
121 read( &tmp
, sizeof( tmp
) );
122 EndianessPolicy::FixEndianessFloat( tmp
);
129 read( &tmp
, sizeof( tmp
) );
130 EndianessPolicy::FixEndianessDouble( tmp
);
134 void readString( std::string
& Str_
)
136 int32_t len
= readVarLenInt();
140 read( &Str_
[0], len
);
143 // Is this shit really useful? I'm wondering.
144 int32_t readVarLenInt()
149 bool bNeg
= !!( in
& 0x40 );
151 int32_t val
= in
& 0x3f;
167 // This is protected because it basically trash data away. On a non-seekable stream it means
168 // you just loose whatever was left in the buffer forever. This is mostly useful for BufferedSeekableInputStream anyway.
171 m_ReadIndex
= m_EndIndex
= 0;
174 shared_ptr
< StreamType
> m_pInStream
;
176 unsigned long m_ReadIndex
;
177 unsigned long m_EndIndex
;
178 uint8_t m_Buffer
[ BufferSize
];
181 template< class EndianessPolicy
= endianess::Native
, int BufferSize
= 4096 >
182 class BufferedSeekableInputStream
:
183 public BufferedInputStream
< EndianessPolicy
, BufferSize
, SeekableInputStream
>
185 typedef BufferedInputStream
< EndianessPolicy
, BufferSize
, SeekableInputStream
>
188 BufferedSeekableInputStream( SeekableInputStream
* pInStream_
) :
193 void seek( uint32_t Pos_
)
195 base::discardbuffer();
196 base::m_pInStream
->seek( Pos_
);
199 void seek( uint64_t Pos_
)
201 base::discardbuffer();
202 base::m_pInStream
->seek( Pos_
);
205 uint64_t tell() const
207 return base::m_pInStream
->tell() - base::available();