Path Tracer
StreamReader.h
1 /*
2 ---------------------------------------------------------------------------
3 Open Asset Import Library (assimp)
4 ---------------------------------------------------------------------------
5 
6 Copyright (c) 2006-2020, assimp team
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 following
12 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 
45 #pragma once
46 #ifndef AI_STREAMREADER_H_INCLUDED
47 #define AI_STREAMREADER_H_INCLUDED
48 
49 #ifdef __GNUC__
50 #pragma GCC system_header
51 #endif
52 
53 #include <assimp/ByteSwapper.h>
54 #include <assimp/Defines.h>
55 #include <assimp/Exceptional.h>
56 #include <assimp/IOStream.hpp>
57 
58 #include <memory>
59 
60 namespace Assimp {
61 
62 // --------------------------------------------------------------------------------------------
71 // --------------------------------------------------------------------------------------------
72 template <bool SwapEndianess = false, bool RuntimeSwitch = false>
73 class StreamReader {
74 public:
75  using diff = size_t;
76  using pos = size_t;
77 
78  // ---------------------------------------------------------------------
90  StreamReader(std::shared_ptr<IOStream> stream, bool le = false) :
91  mStream(stream),
92  mBuffer(nullptr),
93  mCurrent(nullptr),
94  mEnd(nullptr),
95  mLimit(nullptr),
96  mLe(le) {
97  ai_assert(stream);
98  InternBegin();
99  }
100 
101  // ---------------------------------------------------------------------
102  StreamReader(IOStream *stream, bool le = false) :
103  mStream(std::shared_ptr<IOStream>(stream)),
104  mBuffer(nullptr),
105  mCurrent(nullptr),
106  mEnd(nullptr),
107  mLimit(nullptr),
108  mLe(le) {
109  ai_assert(nullptr != stream);
110  InternBegin();
111  }
112 
113  // ---------------------------------------------------------------------
114  ~StreamReader() {
115  delete[] mBuffer;
116  }
117 
118  // deprecated, use overloaded operator>> instead
119 
120  // ---------------------------------------------------------------------
122  float GetF4() {
123  return Get<float>();
124  }
125 
126  // ---------------------------------------------------------------------
128  double GetF8() {
129  return Get<double>();
130  }
131 
132  // ---------------------------------------------------------------------
134  int16_t GetI2() {
135  return Get<int16_t>();
136  }
137 
138  // ---------------------------------------------------------------------
140  int8_t GetI1() {
141  return Get<int8_t>();
142  }
143 
144  // ---------------------------------------------------------------------
146  int32_t GetI4() {
147  return Get<int32_t>();
148  }
149 
150  // ---------------------------------------------------------------------
152  int64_t GetI8() {
153  return Get<int64_t>();
154  }
155 
156  // ---------------------------------------------------------------------
158  uint16_t GetU2() {
159  return Get<uint16_t>();
160  }
161 
162  // ---------------------------------------------------------------------
164  uint8_t GetU1() {
165  return Get<uint8_t>();
166  }
167 
168  // ---------------------------------------------------------------------
170  uint32_t GetU4() {
171  return Get<uint32_t>();
172  }
173 
174  // ---------------------------------------------------------------------
176  uint64_t GetU8() {
177  return Get<uint64_t>();
178  }
179 
180  // ---------------------------------------------------------------------
182  size_t GetRemainingSize() const {
183  return (unsigned int)(mEnd - mCurrent);
184  }
185 
186  // ---------------------------------------------------------------------
190  size_t GetRemainingSizeToLimit() const {
191  return (unsigned int)(mLimit - mCurrent);
192  }
193 
194  // ---------------------------------------------------------------------
196  void IncPtr(intptr_t plus) {
197  mCurrent += plus;
198  if (mCurrent > mLimit) {
199  throw DeadlyImportError("End of file or read limit was reached");
200  }
201  }
202 
203  // ---------------------------------------------------------------------
205  int8_t *GetPtr() const {
206  return mCurrent;
207  }
208 
209  // ---------------------------------------------------------------------
215  void SetPtr(int8_t *p) {
216  mCurrent = p;
217  if (mCurrent > mLimit || mCurrent < mBuffer) {
218  throw DeadlyImportError("End of file or read limit was reached");
219  }
220  }
221 
222  // ---------------------------------------------------------------------
226  void CopyAndAdvance(void *out, size_t bytes) {
227  int8_t *ur = GetPtr();
228  SetPtr(ur + bytes); // fire exception if eof
229 
230  ::memcpy(out, ur, bytes);
231  }
232 
234  int GetCurrentPos() const {
235  return (unsigned int)(mCurrent - mBuffer);
236  }
237 
238  void SetCurrentPos(size_t pos) {
239  SetPtr(mBuffer + pos);
240  }
241 
242  // ---------------------------------------------------------------------
249  unsigned int SetReadLimit(unsigned int _limit) {
250  unsigned int prev = GetReadLimit();
251  if (UINT_MAX == _limit) {
252  mLimit = mEnd;
253  return prev;
254  }
255 
256  mLimit = mBuffer + _limit;
257  if (mLimit > mEnd) {
258  throw DeadlyImportError("StreamReader: Invalid read limit");
259  }
260  return prev;
261  }
262 
263  // ---------------------------------------------------------------------
266  unsigned int GetReadLimit() const {
267  return (unsigned int)(mLimit - mBuffer);
268  }
269 
270  // ---------------------------------------------------------------------
274  mCurrent = mLimit;
275  }
276 
277  // ---------------------------------------------------------------------
279  template <typename T>
281  f = Get<T>();
282  return *this;
283  }
284 
285  // ---------------------------------------------------------------------
287  template <typename T>
288  T Get() {
289  if (mCurrent + sizeof(T) > mLimit) {
290  throw DeadlyImportError("End of file or stream limit was reached");
291  }
292 
293  T f;
294  ::memcpy(&f, mCurrent, sizeof(T));
296  mCurrent += sizeof(T);
297 
298  return f;
299  }
300 
301 private:
302  // ---------------------------------------------------------------------
303  void InternBegin() {
304  if (nullptr == mStream) {
305  throw DeadlyImportError("StreamReader: Unable to open file");
306  }
307 
308  const size_t filesize = mStream->FileSize() - mStream->Tell();
309  if (0 == filesize) {
310  throw DeadlyImportError("StreamReader: File is empty or EOF is already reached");
311  }
312 
313  mCurrent = mBuffer = new int8_t[filesize];
314  const size_t read = mStream->Read(mCurrent, 1, filesize);
315  // (read < s) can only happen if the stream was opened in text mode, in which case FileSize() is not reliable
316  ai_assert(read <= filesize);
317  mEnd = mLimit = &mBuffer[read - 1] + 1;
318  }
319 
320 private:
321  std::shared_ptr<IOStream> mStream;
322  int8_t *mBuffer;
323  int8_t *mCurrent;
324  int8_t *mEnd;
325  int8_t *mLimit;
326  bool mLe;
327 };
328 
329 // --------------------------------------------------------------------------------------------
330 // `static` StreamReaders. Their byte order is fixed and they might be a little bit faster.
331 #ifdef AI_BUILD_BIG_ENDIAN
332 typedef StreamReader<true> StreamReaderLE;
333 typedef StreamReader<false> StreamReaderBE;
334 #else
335 typedef StreamReader<true> StreamReaderBE;
336 typedef StreamReader<false> StreamReaderLE;
337 #endif
338 
339 // `dynamic` StreamReader. The byte order of the input data is specified in the
340 // c'tor. This involves runtime branching and might be a little bit slower.
341 typedef StreamReader<true, true> StreamReaderAny;
342 
343 } // end namespace Assimp
344 
345 #endif // !! AI_STREAMREADER_H_INCLUDED
Assimp::StreamReader::GetI1
int8_t GetI1()
Definition: StreamReader.h:140
Assimp::StreamReader::CopyAndAdvance
void CopyAndAdvance(void *out, size_t bytes)
Definition: StreamReader.h:226
Assimp::StreamReader::GetPtr
int8_t * GetPtr() const
Definition: StreamReader.h:205
Assimp::StreamReader::GetRemainingSize
size_t GetRemainingSize() const
Get the remaining stream size (to the end of the stream)
Definition: StreamReader.h:182
Assimp::StreamReader::GetF4
float GetF4()
Read a float from the stream.
Definition: StreamReader.h:122
Assimp::StreamReader::IncPtr
void IncPtr(intptr_t plus)
Definition: StreamReader.h:196
Assimp::StreamReader::GetU1
uint8_t GetU1()
Read a unsigned 8 bit integer from the stream.
Definition: StreamReader.h:164
Assimp::StreamReader::GetU8
uint64_t GetU8()
Read a unsigned 64 bit integer from the stream.
Definition: StreamReader.h:176
Assimp::StreamReader::SetPtr
void SetPtr(int8_t *p)
Definition: StreamReader.h:215
Assimp::StreamReader
Definition: StreamReader.h:73
Assimp::StreamReader::GetCurrentPos
int GetCurrentPos() const
Get the current offset from the beginning of the file.
Definition: StreamReader.h:234
Assimp::StreamReader::GetU2
uint16_t GetU2()
Definition: StreamReader.h:158
Assimp::Intern::Getter
Definition: ByteSwapper.h:267
Assimp::StreamReader::Get
T Get()
Definition: StreamReader.h:288
Assimp::StreamReader::GetF8
double GetF8()
Read a double from the stream.
Definition: StreamReader.h:128
Assimp::StreamReader::GetI8
int64_t GetI8()
Definition: StreamReader.h:152
Assimp::StreamReader::GetU4
uint32_t GetU4()
Read an unsigned 32 bit integer from the stream.
Definition: StreamReader.h:170
DeadlyImportError
Definition: Exceptional.h:72
Assimp::StreamReader::operator>>
StreamReader & operator>>(T &f)
Definition: StreamReader.h:280
Assimp::StreamReader::GetI4
int32_t GetI4()
Definition: StreamReader.h:146
Assimp::StreamReader::GetReadLimit
unsigned int GetReadLimit() const
Definition: StreamReader.h:266
Assimp::StreamReader::GetI2
int16_t GetI2()
Definition: StreamReader.h:134
Assimp::StreamReader::GetRemainingSizeToLimit
size_t GetRemainingSizeToLimit() const
Definition: StreamReader.h:190
IOStream.hpp
File I/O wrappers for C++.
Assimp::StreamReader::SkipToReadLimit
void SkipToReadLimit()
Definition: StreamReader.h:273
Assimp
Definition: ai_assert.h:50
Assimp::StreamReader::SetReadLimit
unsigned int SetReadLimit(unsigned int _limit)
Definition: StreamReader.h:249
Assimp::IOStream
CPP-API: Class to handle file I/O for C++.
Definition: IOStream.hpp:75
Assimp::StreamReader::StreamReader
StreamReader(std::shared_ptr< IOStream > stream, bool le=false)
Definition: StreamReader.h:90