23 #include "linetypes/edgeline.h" |
23 #include "linetypes/edgeline.h" |
24 #include "linetypes/empty.h" |
24 #include "linetypes/empty.h" |
25 #include "linetypes/quadrilateral.h" |
25 #include "linetypes/quadrilateral.h" |
26 #include "linetypes/triangle.h" |
26 #include "linetypes/triangle.h" |
27 |
27 |
|
28 /* |
|
29 * Constructs an LDraw parser |
|
30 */ |
28 Parser::Parser(QIODevice& device, QObject* parent) : |
31 Parser::Parser(QIODevice& device, QObject* parent) : |
29 QObject {parent}, |
32 QObject {parent}, |
30 device {device} {} |
33 device {device} {} |
31 |
34 |
|
35 /* |
|
36 * Reads a single line from the device. |
|
37 */ |
32 QString Parser::readLine() |
38 QString Parser::readLine() |
33 { |
39 { |
34 return QString::fromUtf8(this->device.readLine()).simplified(); |
40 return QString::fromUtf8(this->device.readLine()).simplified(); |
35 } |
41 } |
36 |
42 |
|
43 /* |
|
44 * Parses a single line of the header. |
|
45 * Possible parse results: |
|
46 * · ParseSuccess: the header line was parsed successfully. |
|
47 * · ParseFailure: the header line was parsed incorrectly and needs to be handled otherwise. |
|
48 * · StopParsing: the line does not belong in the header and header parsing needs to stop. |
|
49 */ |
37 Parser::HeaderParseResult Parser::parseHeaderLine(LDHeader& header, const QString& line) |
50 Parser::HeaderParseResult Parser::parseHeaderLine(LDHeader& header, const QString& line) |
38 { |
51 { |
39 if (line.isEmpty()) |
52 if (line.isEmpty()) |
40 { |
53 { |
41 return ParseSuccess; |
54 return ParseSuccess; |
200 const QString& line = this->readLine(); |
217 const QString& line = this->readLine(); |
201 auto result = parseHeaderLine(header, line); |
218 auto result = parseHeaderLine(header, line); |
202 |
219 |
203 if (result == ParseFailure) |
220 if (result == ParseFailure) |
204 { |
221 { |
|
222 // Failed to parse this header line, add it as a comment into the body later. |
205 this->bag.append(line); |
223 this->bag.append(line); |
206 } |
224 } |
207 else if (result == StopParsing) |
225 else if (result == StopParsing) |
208 { |
226 { |
|
227 // Header parsing stops, add this line to the body. |
209 this->bag.append(line); |
228 this->bag.append(line); |
210 break; |
229 break; |
211 } |
230 } |
212 } |
231 } |
213 } |
232 } |
298 static Vertex parseVertex(QStringList& tokens, const int n) |
320 static Vertex parseVertex(QStringList& tokens, const int n) |
299 { |
321 { |
300 return {tokens[n].toDouble(), tokens[n + 1].toDouble(), tokens[n + 2].toDouble()}; |
322 return {tokens[n].toDouble(), tokens[n + 1].toDouble(), tokens[n + 2].toDouble()}; |
301 } |
323 } |
302 |
324 |
303 // TODO: rewrite this using regular expressions |
325 /* |
|
326 * Parses the given model body line and inserts the result into the given model. |
|
327 * The resulting object is also returned. |
|
328 * |
|
329 * If an error happens, an error object is created. Result is guaranteed to be a valid pointer. |
|
330 * |
|
331 * TODO: rewrite this using regular expressions |
|
332 */ |
304 LDObject* Parser::parseFromString(Model& model, int position, QString line) |
333 LDObject* Parser::parseFromString(Model& model, int position, QString line) |
305 { |
334 { |
306 if (position == EndOfModel) |
335 if (position == EndOfModel) |
307 position = model.size(); |
336 position = model.size(); |
308 |
337 |