Path Tracer
IOStreamBuffer.h
1 /*
2 Open Asset Import Library (assimp)
3 ----------------------------------------------------------------------
4 
5 Copyright (c) 2006-2020, assimp team
6 
7 
8 All rights reserved.
9 
10 Redistribution and use of this software in source and binary forms,
11 with or without modification, are permitted provided that the
12 following conditions are met:
13 
14 * Redistributions of source code must retain the above
15 copyright notice, this list of conditions and the
16 following disclaimer.
17 
18 * Redistributions in binary form must reproduce the above
19 copyright notice, this list of conditions and the
20 following disclaimer in the documentation and/or other
21 materials provided with the distribution.
22 
23 * Neither the name of the assimp team, nor the names of its
24 contributors may be used to endorse or promote products
25 derived from this software without specific prior
26 written permission of the assimp team.
27 
28 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
33 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 
40 ----------------------------------------------------------------------
41 */
42 
43 #pragma once
44 #ifndef AI_IOSTREAMBUFFER_H_INC
45 #define AI_IOSTREAMBUFFER_H_INC
46 
47 #ifdef __GNUC__
48 # pragma GCC system_header
49 #endif
50 
51 #include <assimp/types.h>
52 #include <assimp/IOStream.hpp>
53 #include <assimp/ParsingUtils.h>
54 
55 #include <vector>
56 
57 namespace Assimp {
58 
59 // ---------------------------------------------------------------------------
63 template<class T>
65 public:
67  IOStreamBuffer( size_t cache = 4096 * 4096 );
68 
71 
75  bool open( IOStream *stream );
76 
79  bool close();
80 
83  size_t size() const;
84 
87  size_t cacheSize() const;
88 
91  bool readNextBlock();
92 
95  size_t getNumBlocks() const;
96 
99  size_t getCurrentBlockIndex() const;
100 
103  size_t getFilePos() const;
104 
108  bool getNextDataLine( std::vector<T> &buffer, T continuationToken );
109 
113  bool getNextLine(std::vector<T> &buffer);
114 
118  bool getNextBlock( std::vector<T> &buffer );
119 
120 private:
121  IOStream *m_stream;
122  size_t m_filesize;
123  size_t m_cacheSize;
124  size_t m_numBlocks;
125  size_t m_blockIdx;
126  std::vector<T> m_cache;
127  size_t m_cachePos;
128  size_t m_filePos;
129 };
130 
131 template<class T>
132 AI_FORCE_INLINE
134 : m_stream( nullptr )
135 , m_filesize( 0 )
136 , m_cacheSize( cache )
137 , m_numBlocks( 0 )
138 , m_blockIdx( 0 )
139 , m_cachePos( 0 )
140 , m_filePos( 0 ) {
141  m_cache.resize( cache );
142  std::fill( m_cache.begin(), m_cache.end(), '\n' );
143 }
144 
145 template<class T>
146 AI_FORCE_INLINE
148  // empty
149 }
150 
151 template<class T>
152 AI_FORCE_INLINE
154  // file still opened!
155  if ( nullptr != m_stream ) {
156  return false;
157  }
158 
159  // Invalid stream pointer
160  if ( nullptr == stream ) {
161  return false;
162  }
163 
164  m_stream = stream;
165  m_filesize = m_stream->FileSize();
166  if ( m_filesize == 0 ) {
167  return false;
168  }
169  if ( m_filesize < m_cacheSize ) {
170  m_cacheSize = m_filesize;
171  }
172 
173  m_numBlocks = m_filesize / m_cacheSize;
174  if ( ( m_filesize % m_cacheSize ) > 0 ) {
175  m_numBlocks++;
176  }
177 
178  return true;
179 }
180 
181 template<class T>
182 AI_FORCE_INLINE
184  if ( nullptr == m_stream ) {
185  return false;
186  }
187 
188  // init counters and state vars
189  m_stream = nullptr;
190  m_filesize = 0;
191  m_numBlocks = 0;
192  m_blockIdx = 0;
193  m_cachePos = 0;
194  m_filePos = 0;
195 
196  return true;
197 }
198 
199 template<class T>
200 AI_FORCE_INLINE
201 size_t IOStreamBuffer<T>::size() const {
202  return m_filesize;
203 }
204 
205 template<class T>
206 AI_FORCE_INLINE
208  return m_cacheSize;
209 }
210 
211 template<class T>
212 AI_FORCE_INLINE
214  m_stream->Seek( m_filePos, aiOrigin_SET );
215  size_t readLen = m_stream->Read( &m_cache[ 0 ], sizeof( T ), m_cacheSize );
216  if ( readLen == 0 ) {
217  return false;
218  }
219  if ( readLen < m_cacheSize ) {
220  m_cacheSize = readLen;
221  }
222  m_filePos += m_cacheSize;
223  m_cachePos = 0;
224  m_blockIdx++;
225 
226  return true;
227 }
228 
229 template<class T>
230 AI_FORCE_INLINE
232  return m_numBlocks;
233 }
234 
235 template<class T>
236 AI_FORCE_INLINE
238  return m_blockIdx;
239 }
240 
241 template<class T>
242 AI_FORCE_INLINE
244  return m_filePos;
245 }
246 
247 template<class T>
248 AI_FORCE_INLINE
249 bool IOStreamBuffer<T>::getNextDataLine( std::vector<T> &buffer, T continuationToken ) {
250  buffer.resize( m_cacheSize );
251  if ( m_cachePos >= m_cacheSize || 0 == m_filePos ) {
252  if ( !readNextBlock() ) {
253  return false;
254  }
255  }
256 
257  bool continuationFound( false );
258  size_t i = 0;
259  for( ;; ) {
260  if ( continuationToken == m_cache[ m_cachePos ] ) {
261  continuationFound = true;
262  ++m_cachePos;
263  }
264  if ( IsLineEnd( m_cache[ m_cachePos ] ) ) {
265  if ( !continuationFound ) {
266  // the end of the data line
267  break;
268  } else {
269  // skip line end
270  while ( m_cache[m_cachePos] != '\n') {
271  ++m_cachePos;
272  }
273  ++m_cachePos;
274  continuationFound = false;
275  }
276  }
277 
278  buffer[ i ] = m_cache[ m_cachePos ];
279  ++m_cachePos;
280  ++i;
281  if (m_cachePos >= size()) {
282  break;
283  }
284  if ( m_cachePos >= m_cacheSize ) {
285  if ( !readNextBlock() ) {
286  return false;
287  }
288  }
289  }
290 
291  buffer[ i ] = '\n';
292  ++m_cachePos;
293 
294  return true;
295 }
296 
297 static AI_FORCE_INLINE
298 bool isEndOfCache( size_t pos, size_t cacheSize ) {
299  return ( pos == cacheSize );
300 }
301 
302 template<class T>
303 AI_FORCE_INLINE
304 bool IOStreamBuffer<T>::getNextLine(std::vector<T> &buffer) {
305  buffer.resize(m_cacheSize);
306  if ( isEndOfCache( m_cachePos, m_cacheSize ) || 0 == m_filePos) {
307  if (!readNextBlock()) {
308  return false;
309  }
310  }
311 
312  if (IsLineEnd(m_cache[m_cachePos])) {
313  // skip line end
314  while (m_cache[m_cachePos] != '\n') {
315  ++m_cachePos;
316  }
317  ++m_cachePos;
318  if ( isEndOfCache( m_cachePos, m_cacheSize ) ) {
319  if ( !readNextBlock() ) {
320  return false;
321  }
322  }
323  }
324 
325  size_t i( 0 );
326  while (!IsLineEnd(m_cache[ m_cachePos ])) {
327  buffer[i] = m_cache[ m_cachePos ];
328  ++m_cachePos;
329  ++i;
330  if (m_cachePos >= m_cacheSize) {
331  if (!readNextBlock()) {
332  return false;
333  }
334  }
335  }
336  buffer[i] = '\n';
337  ++m_cachePos;
338 
339  return true;
340 }
341 
342 template<class T>
343 AI_FORCE_INLINE
344 bool IOStreamBuffer<T>::getNextBlock( std::vector<T> &buffer) {
345  // Return the last block-value if getNextLine was used before
346  if ( 0 != m_cachePos ) {
347  buffer = std::vector<T>( m_cache.begin() + m_cachePos, m_cache.end() );
348  m_cachePos = 0;
349  } else {
350  if ( !readNextBlock() ) {
351  return false;
352  }
353 
354  buffer = std::vector<T>(m_cache.begin(), m_cache.end());
355  }
356 
357  return true;
358 }
359 
360 } // !ns Assimp
361 
362 #endif // AI_IOSTREAMBUFFER_H_INC
Assimp::IOStreamBuffer::getNumBlocks
size_t getNumBlocks() const
Returns the number of blocks to read.
Definition: IOStreamBuffer.h:231
types.h
aiOrigin_SET
@ aiOrigin_SET
Definition: types.h:428
Assimp::IOStreamBuffer
Definition: IOStreamBuffer.h:64
Assimp::IOStreamBuffer::getFilePos
size_t getFilePos() const
Returns the current file pos.
Definition: IOStreamBuffer.h:243
Assimp::IOStream::FileSize
virtual size_t FileSize() const =0
Returns filesize Returns the filesize.
Assimp::IOStreamBuffer::open
bool open(IOStream *stream)
Will open the cached access for a given stream.
Definition: IOStreamBuffer.h:153
Assimp::IOStreamBuffer::readNextBlock
bool readNextBlock()
Will read the next block.
Definition: IOStreamBuffer.h:213
Assimp::IOStreamBuffer::getNextDataLine
bool getNextDataLine(std::vector< T > &buffer, T continuationToken)
Will read the next line.
Definition: IOStreamBuffer.h:249
Assimp::IOStreamBuffer::~IOStreamBuffer
~IOStreamBuffer()
The class destructor.
Definition: IOStreamBuffer.h:147
Assimp::IOStreamBuffer::getCurrentBlockIndex
size_t getCurrentBlockIndex() const
Returns the current block index.
Definition: IOStreamBuffer.h:237
Assimp::IOStreamBuffer::getNextBlock
bool getNextBlock(std::vector< T > &buffer)
Will read the next block.
Definition: IOStreamBuffer.h:344
Assimp::IOStreamBuffer::getNextLine
bool getNextLine(std::vector< T > &buffer)
Will read the next line ascii or binary end line char.
Definition: IOStreamBuffer.h:304
IOStream.hpp
File I/O wrappers for C++.
ParsingUtils.h
Defines helper functions for text parsing.
Assimp
Definition: ai_assert.h:50
Assimp::IOStreamBuffer::IOStreamBuffer
IOStreamBuffer(size_t cache=4096 *4096)
The class constructor.
Definition: IOStreamBuffer.h:133
Assimp::IOStreamBuffer::close
bool close()
Will close the cached access.
Definition: IOStreamBuffer.h:183
Assimp::IOStream
CPP-API: Class to handle file I/O for C++.
Definition: IOStream.hpp:75
Assimp::IOStreamBuffer::cacheSize
size_t cacheSize() const
Returns the cache size.
Definition: IOStreamBuffer.h:207
Assimp::IOStreamBuffer::size
size_t size() const
Returns the file-size.
Definition: IOStreamBuffer.h:201