Path Tracer
LineSplitter.h
Go to the documentation of this file.
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 
47 #pragma once
48 #ifndef INCLUDED_LINE_SPLITTER_H
49 #define INCLUDED_LINE_SPLITTER_H
50 
51 #ifdef __GNUC__
52 # pragma GCC system_header
53 #endif
54 
55 #include <stdexcept>
56 #include <assimp/StreamReader.h>
57 #include <assimp/ParsingUtils.h>
58 
59 namespace Assimp {
60 
61 // ------------------------------------------------------------------------------------------------
79 // ------------------------------------------------------------------------------------------------
80 class LineSplitter {
81 public:
82  typedef size_t line_idx;
83 
84  // -----------------------------------------
88  LineSplitter(StreamReaderLE& stream, bool skip_empty_lines = true, bool trim = true);
89 
90  ~LineSplitter();
91 
92  // -----------------------------------------
95 
96  // -----------------------------------------
98 
99  // -----------------------------------------
101  const char* operator[] (size_t idx) const;
102 
103  // -----------------------------------------
105  template <size_t N>
106  void get_tokens(const char* (&tokens)[N]) const;
107 
108  // -----------------------------------------
110  const std::string* operator -> () const;
111 
112  std::string operator* () const;
113 
114  // -----------------------------------------
116  operator bool() const;
117 
118  // -----------------------------------------
120  operator line_idx() const;
121 
122  line_idx get_index() const;
123 
124  // -----------------------------------------
127 
128  // -----------------------------------------
130  bool match_start(const char* check);
131 
132  // -----------------------------------------
134  void swallow_next_increment();
135 
136  LineSplitter( const LineSplitter & ) = delete;
137  LineSplitter(LineSplitter &&) = delete;
138  LineSplitter &operator = ( const LineSplitter & ) = delete;
139 
140 private:
141  line_idx mIdx;
142  std::string mCur;
143  StreamReaderLE& mStream;
144  bool mSwallow, mSkip_empty_lines, mTrim;
145 };
146 
147 AI_FORCE_INLINE
148 LineSplitter::LineSplitter(StreamReaderLE& stream, bool skip_empty_lines, bool trim )
149 : mIdx(0)
150 , mCur()
151 , mStream(stream)
152 , mSwallow()
153 , mSkip_empty_lines(skip_empty_lines)
154 , mTrim(trim) {
155  mCur.reserve(1024);
156  operator++();
157  mIdx = 0;
158 }
159 
160 AI_FORCE_INLINE
161 LineSplitter::~LineSplitter() {
162  // empty
163 }
164 
165 AI_FORCE_INLINE
167  if (mSwallow) {
168  mSwallow = false;
169  return *this;
170  }
171 
172  if (!*this) {
173  throw std::logic_error("End of file, no more lines to be retrieved.");
174  }
175 
176  char s;
177  mCur.clear();
178  while (mStream.GetRemainingSize() && (s = mStream.GetI1(), 1)) {
179  if (s == '\n' || s == '\r') {
180  if (mSkip_empty_lines) {
181  while (mStream.GetRemainingSize() && ((s = mStream.GetI1()) == ' ' || s == '\r' || s == '\n'));
182  if (mStream.GetRemainingSize()) {
183  mStream.IncPtr(-1);
184  }
185  } else {
186  // skip both potential line terminators but don't read past this line.
187  if (mStream.GetRemainingSize() && (s == '\r' && mStream.GetI1() != '\n')) {
188  mStream.IncPtr(-1);
189  }
190  if (mTrim) {
191  while (mStream.GetRemainingSize() && ((s = mStream.GetI1()) == ' ' || s == '\t'));
192  if (mStream.GetRemainingSize()) {
193  mStream.IncPtr(-1);
194  }
195  }
196  }
197  break;
198  }
199  mCur += s;
200  }
201  ++mIdx;
202 
203  return *this;
204 }
205 
206 AI_FORCE_INLINE
208  return ++(*this);
209 }
210 
211 AI_FORCE_INLINE
212 const char *LineSplitter::operator[] (size_t idx) const {
213  const char* s = operator->()->c_str();
214 
215  SkipSpaces(&s);
216  for (size_t i = 0; i < idx; ++i) {
217 
218  for (; !IsSpace(*s); ++s) {
219  if (IsLineEnd(*s)) {
220  throw std::range_error("Token index out of range, EOL reached");
221  }
222  }
223  SkipSpaces(&s);
224  }
225  return s;
226 }
227 
228 template <size_t N>
229 AI_FORCE_INLINE
230 void LineSplitter::get_tokens(const char* (&tokens)[N]) const {
231  const char* s = operator->()->c_str();
232 
233  SkipSpaces(&s);
234  for (size_t i = 0; i < N; ++i) {
235  if (IsLineEnd(*s)) {
236  throw std::range_error("Token count out of range, EOL reached");
237  }
238  tokens[i] = s;
239 
240  for (; *s && !IsSpace(*s); ++s);
241  SkipSpaces(&s);
242  }
243 }
244 
245 AI_FORCE_INLINE
246 const std::string* LineSplitter::operator -> () const {
247  return &mCur;
248 }
249 
250 AI_FORCE_INLINE
251 std::string LineSplitter::operator* () const {
252  return mCur;
253 }
254 
255 AI_FORCE_INLINE
256 LineSplitter::operator bool() const {
257  return mStream.GetRemainingSize() > 0;
258 }
259 
260 AI_FORCE_INLINE
261 LineSplitter::operator line_idx() const {
262  return mIdx;
263 }
264 
265 AI_FORCE_INLINE
266 LineSplitter::line_idx LineSplitter::get_index() const {
267  return mIdx;
268 }
269 
270 AI_FORCE_INLINE
272  return mStream;
273 }
274 
275 AI_FORCE_INLINE
276 bool LineSplitter::match_start(const char* check) {
277  const size_t len = ::strlen(check);
278 
279  return len <= mCur.length() && std::equal(check, check + len, mCur.begin());
280 }
281 
282 AI_FORCE_INLINE
284  mSwallow = true;
285 }
286 
287 } // Namespace Assimp
288 
289 #endif // INCLUDED_LINE_SPLITTER_H
Assimp::StreamReader::GetI1
int8_t GetI1()
Definition: StreamReader.h:140
Assimp::LineSplitter::swallow_next_increment
void swallow_next_increment()
Definition: LineSplitter.h:283
Assimp::StreamReader::GetRemainingSize
size_t GetRemainingSize() const
Get the remaining stream size (to the end of the stream)
Definition: StreamReader.h:182
Assimp::StreamReader::IncPtr
void IncPtr(intptr_t plus)
Definition: StreamReader.h:196
Assimp::StreamReader
Definition: StreamReader.h:73
Assimp::LineSplitter
Definition: LineSplitter.h:80
Assimp::LineSplitter::operator->
const std::string * operator->() const
Definition: LineSplitter.h:246
Assimp::LineSplitter::operator[]
const char * operator[](size_t idx) const
Definition: LineSplitter.h:212
Assimp::LineSplitter::get_stream
StreamReaderLE & get_stream()
Definition: LineSplitter.h:271
Assimp::LineSplitter::get_tokens
void get_tokens(const char *(&tokens)[N]) const
Assimp::LineSplitter::match_start
bool match_start(const char *check)
Definition: LineSplitter.h:276
Assimp::LineSplitter::LineSplitter
LineSplitter(StreamReaderLE &stream, bool skip_empty_lines=true, bool trim=true)
Definition: LineSplitter.h:148
ParsingUtils.h
Defines helper functions for text parsing.
Assimp
Definition: ai_assert.h:50
Assimp::LineSplitter::operator++
LineSplitter & operator++()
Definition: LineSplitter.h:166