File indexing completed on 2025-02-21 09:30:08
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046 #pragma once
0047 #ifndef INCLUDED_LINE_SPLITTER_H
0048 #define INCLUDED_LINE_SPLITTER_H
0049
0050 #ifdef __GNUC__
0051 # pragma GCC system_header
0052 #endif
0053
0054 #include <stdexcept>
0055 #include <assimp/StreamReader.h>
0056 #include <assimp/ParsingUtils.h>
0057
0058 namespace Assimp {
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079 class LineSplitter {
0080 public:
0081 typedef size_t line_idx;
0082
0083
0084
0085
0086
0087 LineSplitter(StreamReaderLE& stream, bool skip_empty_lines = true, bool trim = true);
0088
0089 ~LineSplitter() = default;
0090
0091
0092
0093 LineSplitter& operator++();
0094
0095
0096 LineSplitter& operator++(int);
0097
0098
0099
0100 const char* operator[] (size_t idx) const;
0101
0102
0103
0104 template <size_t N>
0105 void get_tokens(const char* (&tokens)[N]) const;
0106
0107
0108
0109 const std::string* operator -> () const;
0110
0111 std::string operator* () const;
0112
0113 const char *getEnd() const;
0114
0115
0116
0117 operator bool() const;
0118
0119
0120
0121 operator line_idx() const;
0122
0123 line_idx get_index() const;
0124
0125
0126
0127 StreamReaderLE& get_stream();
0128
0129
0130
0131 bool match_start(const char* check);
0132
0133
0134
0135 void swallow_next_increment();
0136
0137 LineSplitter( const LineSplitter & ) = delete;
0138 LineSplitter(LineSplitter &&) = delete;
0139 LineSplitter &operator = ( const LineSplitter & ) = delete;
0140
0141 private:
0142 line_idx mIdx;
0143 std::string mCur;
0144 const char *mEnd;
0145 StreamReaderLE& mStream;
0146 bool mSwallow, mSkip_empty_lines, mTrim;
0147 };
0148
0149 AI_FORCE_INLINE LineSplitter::LineSplitter(StreamReaderLE& stream, bool skip_empty_lines, bool trim ) :
0150 mIdx(0),
0151 mCur(),
0152 mEnd(nullptr),
0153 mStream(stream),
0154 mSwallow(),
0155 mSkip_empty_lines(skip_empty_lines),
0156 mTrim(trim) {
0157 mCur.reserve(1024);
0158 mEnd = mCur.c_str() + 1024;
0159 operator++();
0160 mIdx = 0;
0161 }
0162
0163 AI_FORCE_INLINE LineSplitter& LineSplitter::operator++() {
0164 if (mSwallow) {
0165 mSwallow = false;
0166 return *this;
0167 }
0168
0169 if (!*this) {
0170 throw std::logic_error("End of file, no more lines to be retrieved.");
0171 }
0172
0173 char s;
0174 mCur.clear();
0175 while (mStream.GetRemainingSize() && (s = mStream.GetI1(), 1)) {
0176 if (s == '\n' || s == '\r') {
0177 if (mSkip_empty_lines) {
0178 while (mStream.GetRemainingSize() && ((s = mStream.GetI1()) == ' ' || s == '\r' || s == '\n'));
0179 if (mStream.GetRemainingSize()) {
0180 mStream.IncPtr(-1);
0181 }
0182 } else {
0183
0184 if (mStream.GetRemainingSize() && (s == '\r' && mStream.GetI1() != '\n')) {
0185 mStream.IncPtr(-1);
0186 }
0187 if (mTrim) {
0188 while (mStream.GetRemainingSize() && ((s = mStream.GetI1()) == ' ' || s == '\t'));
0189 if (mStream.GetRemainingSize()) {
0190 mStream.IncPtr(-1);
0191 }
0192 }
0193 }
0194 break;
0195 }
0196 mCur += s;
0197 }
0198 ++mIdx;
0199
0200 return *this;
0201 }
0202
0203 AI_FORCE_INLINE LineSplitter &LineSplitter::operator++(int) {
0204 return ++(*this);
0205 }
0206
0207 AI_FORCE_INLINE const char *LineSplitter::operator[] (size_t idx) const {
0208 const char* s = operator->()->c_str();
0209
0210 SkipSpaces(&s, mEnd);
0211 for (size_t i = 0; i < idx; ++i) {
0212 for (; !IsSpace(*s); ++s) {
0213 if (IsLineEnd(*s)) {
0214 throw std::range_error("Token index out of range, EOL reached");
0215 }
0216 }
0217 SkipSpaces(&s, mEnd);
0218 }
0219 return s;
0220 }
0221
0222 template <size_t N>
0223 AI_FORCE_INLINE void LineSplitter::get_tokens(const char* (&tokens)[N]) const {
0224 const char* s = operator->()->c_str();
0225
0226 SkipSpaces(&s, mEnd);
0227 for (size_t i = 0; i < N; ++i) {
0228 if (IsLineEnd(*s)) {
0229 throw std::range_error("Token count out of range, EOL reached");
0230 }
0231 tokens[i] = s;
0232
0233 for (; *s && !IsSpace(*s); ++s);
0234 SkipSpaces(&s, mEnd);
0235 }
0236 }
0237
0238 AI_FORCE_INLINE const std::string* LineSplitter::operator -> () const {
0239 return &mCur;
0240 }
0241
0242 AI_FORCE_INLINE std::string LineSplitter::operator* () const {
0243 return mCur;
0244 }
0245
0246 AI_FORCE_INLINE const char* LineSplitter::getEnd() const {
0247 return mEnd;
0248 }
0249
0250 AI_FORCE_INLINE LineSplitter::operator bool() const {
0251 return mStream.GetRemainingSize() > 0;
0252 }
0253
0254 AI_FORCE_INLINE LineSplitter::operator line_idx() const {
0255 return mIdx;
0256 }
0257
0258 AI_FORCE_INLINE LineSplitter::line_idx LineSplitter::get_index() const {
0259 return mIdx;
0260 }
0261
0262 AI_FORCE_INLINE StreamReaderLE &LineSplitter::get_stream() {
0263 return mStream;
0264 }
0265
0266 AI_FORCE_INLINE bool LineSplitter::match_start(const char* check) {
0267 const size_t len = ::strlen(check);
0268
0269 return len <= mCur.length() && std::equal(check, check + len, mCur.begin());
0270 }
0271
0272 AI_FORCE_INLINE void LineSplitter::swallow_next_increment() {
0273 mSwallow = true;
0274 }
0275
0276 }
0277
0278 #endif