Work on the blender exporter.
[fail.git] / src / io / BufferedInputStream.h
blobbd9bf94d59cf3a69313306887475d1b07635491b
1 /*
2 Fail game engine
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
34 public:
35 typedef EndianessPolicy endianess_policy;
37 BufferedInputStream( shared_ptr< StreamType > pInStream_ ) :
38 m_pInStream( pInStream_ )
40 m_ReadIndex = 0;
41 m_EndIndex = 0;
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;
61 if( available() )
63 amountread = Size_ > available() ? available() : Size_;
64 std::memcpy( pBuffer, &m_Buffer[ m_ReadIndex ], amountread );
65 Size_ -= amountread;
67 m_ReadIndex += amountread;
68 if( m_ReadIndex == m_EndIndex )
69 m_ReadIndex = m_EndIndex = 0;
72 if( Size_ )
74 uint8_t* pbuf = static_cast< uint8_t* >( pBuffer );
75 amountread += m_pInStream->read( pbuf + amountread, Size_ );
78 if( !available() )
80 unsigned int read = m_pInStream->read( &m_Buffer[ m_EndIndex ], remaining() );
81 m_EndIndex += read;
84 return amountread;
87 uint8_t readU8()
89 uint8_t tmp;
90 read( &tmp, sizeof( tmp ) );
91 return tmp;
94 uint16_t readU16()
96 uint16_t tmp;
97 read( &tmp, sizeof( tmp ) );
98 EndianessPolicy::FixEndianessU16( tmp );
99 return tmp;
102 uint32_t readU32()
104 uint32_t tmp;
105 read( &tmp, sizeof( tmp ) );
106 EndianessPolicy::FixEndianessU32( tmp );
107 return tmp;
110 uint64_t readU64()
112 uint64_t tmp;
113 read( &tmp, sizeof( tmp ) );
114 EndianessPolicy::FixEndianessU64( tmp );
115 return tmp;
118 float readFloat()
120 float tmp;
121 read( &tmp, sizeof( tmp ) );
122 EndianessPolicy::FixEndianessFloat( tmp );
123 return tmp;
126 float readDouble()
128 double tmp;
129 read( &tmp, sizeof( tmp ) );
130 EndianessPolicy::FixEndianessDouble( tmp );
131 return tmp;
134 void readString( std::string& Str_ )
136 int32_t len = readVarLenInt();
138 Str_ = "";
139 Str_.resize( len );
140 read( &Str_[0], len );
143 // Is this shit really useful? I'm wondering.
144 int32_t readVarLenInt()
146 uint8_t in;
147 in = readU8();
149 bool bNeg = !!( in & 0x40 );
151 int32_t val = in & 0x3f;
153 while( in & 0x80 )
155 in = readU8();
156 val <<= 7;
157 val |= in & 0x7f;
160 if( bNeg )
161 val = -val;
163 return val;
166 protected:
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.
169 void discardbuffer()
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 >
186 base;
187 public:
188 BufferedSeekableInputStream( SeekableInputStream* pInStream_ ) :
189 base( 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();
212 #endif