OdbDesignLib
OdbDesign ODB++ Parsing Library
 
Loading...
Searching...
No Matches
StepHdrFile.cpp
1#include "StepHdrFile.h"
2#include "../invalid_odb_error.h"
3#include "str_utils.h"
4#include "../../Constants.h"
5#include "../parse_error.h"
6#include <Logger.h>
7
8namespace Odb::Lib::FileModel::Design
9{
10 StepHdrFile::~StepHdrFile()
11 {
12 m_stepRepeatRecords.clear();
13 }
14
15 bool StepHdrFile::Parse(std::filesystem::path path)
16 {
17 std::ifstream stepHdrFile;
18 int lineNumber = 0;
19 std::string line;
20
21 try
22 {
23 if (!OdbFile::Parse(path)) return false;
24
25 auto stepHdrFilePath = path / "stephdr";
26 if (!std::filesystem::exists(stepHdrFilePath))
27 {
28 auto message = "stephdr file does not exist: [" + stepHdrFilePath.string() + "]";
29 throw invalid_odb_error(message.c_str());
30 }
31
32 stepHdrFile.open(stepHdrFilePath, std::ios::in);
33 if (!stepHdrFile.is_open())
34 {
35 auto message = "unable to open stephdr file: [" + stepHdrFilePath.string() + "]";
36 throw invalid_odb_error(message.c_str());
37 }
38
39 m_path = stepHdrFilePath;
40
41 std::shared_ptr<StepRepeatRecord> pCurrentStepRepeatRecord;
42 bool openBraceFound = false;
43
44 while (std::getline(stepHdrFile, line))
45 {
46 lineNumber++;
47 // trim whitespace from beginning and end of line
48 Utils::str_trim(line);
49 if (!line.empty())
50 {
51 std::stringstream lineStream(line);
52 if (line.find(Constants::COMMENT_TOKEN) == 0)
53 {
54 // comment line
55 }
56 else if (line.find(StepRepeatRecord::ARRAY_HEADER_TOKEN) == 0)
57 {
58 std::string token;
59 if (!(lineStream >> token))
60 {
61 throw_parse_error(m_path, line, token, lineNumber);
62 }
63
64 if (token != StepRepeatRecord::ARRAY_HEADER_TOKEN)
65 {
66 throw_parse_error(m_path, line, token, lineNumber);
67 }
68
69 if (lineStream >> token)
70 {
71 // open brace is at the end on the same line as the step array record open token
72 if (token == Constants::ARRAY_RECORD_OPEN_TOKEN)
73 {
74 openBraceFound = true;
75
76 // TODO: finish any existing previous step record
77 // (same code as finding a close brace on an empty line)
78
79 // open a new STEP-REPEAT array record
80 pCurrentStepRepeatRecord = std::make_shared<StepRepeatRecord>();
81 }
82 }
83 }
84 else if (line.find(Constants::ARRAY_RECORD_OPEN_TOKEN) == 0)
85 {
86 // TODO: how to determine if you are opening a step or layer array record?
87 // (maybe a boolean flag? stepArrayOpen = true/false)
88 // no current opening of a layer or step array record found yet
89 if (pCurrentStepRepeatRecord == nullptr)
90 {
91 throw_parse_error(m_path, line, "", lineNumber);
92 }
93
94 // found another open brace while still parsing after the previous record's open brace
95 if (openBraceFound)
96 {
97 throw_parse_error(m_path, line, "", lineNumber);
98 }
99
100 openBraceFound = true;
101
102 // TODO: finish any existing previous layer or step record
103 // (same code as finding a close brace on an empty line)
104
105 // open a new LAYER array record
106 //pCurrentLayerRecord = std::make_shared<LayerRecord>();
107 }
108 else if (line.find(Constants::ARRAY_RECORD_CLOSE_TOKEN) == 0)
109 {
110 if (pCurrentStepRepeatRecord != nullptr && openBraceFound)
111 {
112 m_stepRepeatRecords.push_back(pCurrentStepRepeatRecord);
113 pCurrentStepRepeatRecord.reset();
114 openBraceFound = false;
115 }
116 else
117 {
118 // found a close brace but aren't currently parsing a step or layer array record
119 throw_parse_error(m_path, line, "", lineNumber);
120 }
121 }
122 else
123 {
124 // it should be a name-value pair line (i.e. element of a step or layer array)
125 std::string attribute;
126 std::string value;
127
128 if (!std::getline(lineStream, attribute, '='))
129 {
130 throw_parse_error(m_path, line, attribute, lineNumber);
131 }
132
133 if (std::getline(lineStream, value))
134 {
135 Utils::str_trim(attribute);
136 Utils::str_trim(value);
137
138 if (pCurrentStepRepeatRecord != nullptr && openBraceFound)
139 {
140 if (attribute == "NAME" || attribute == "name")
141 {
142 pCurrentStepRepeatRecord->name = value;
143 }
144 else if (attribute == "X" || attribute == "x")
145 {
146 pCurrentStepRepeatRecord->x = std::stof(value);
147 }
148 else if (attribute == "Y" || attribute == "y")
149 {
150 pCurrentStepRepeatRecord->y = std::stof(value);
151 }
152 else if (attribute == "DX" || attribute == "dx")
153 {
154 pCurrentStepRepeatRecord->dx = std::stof(value);
155 }
156 else if (attribute == "DY" || attribute == "dy")
157 {
158 pCurrentStepRepeatRecord->dy = std::stof(value);
159 }
160 else if (attribute == "NX" || attribute == "nx")
161 {
162 pCurrentStepRepeatRecord->nx = std::stoi(value);
163 }
164 else if (attribute == "NY" || attribute == "ny")
165 {
166 pCurrentStepRepeatRecord->ny = std::stoi(value);
167 }
168 else if (attribute == "ANGLE" || attribute == "angle")
169 {
170 pCurrentStepRepeatRecord->angle = std::stof(value);
171 }
172 else if (attribute == "FLIP" || attribute == "flip")
173 {
174 if (value == "YES" || value == "yes")
175 {
176 pCurrentStepRepeatRecord->flip = true;
177 }
178 else if (value == "NO" || value == "no")
179 {
180 pCurrentStepRepeatRecord->flip = false;
181 }
182 else
183 {
184 throw_parse_error(m_path, line, attribute, lineNumber);
185 }
186 }
187 else if (attribute == "MIRROR" || attribute == "mirror")
188 {
189 if (value == "YES" || value == "yes")
190 {
191 pCurrentStepRepeatRecord->mirror = true;
192 }
193 else if (value == "NO" || value == "no")
194 {
195 pCurrentStepRepeatRecord->mirror = false;
196 }
197 else
198 {
199 throw_parse_error(m_path, line, attribute, lineNumber);
200 }
201 }
202 else
203 {
204 throw_parse_error(m_path, line, attribute, lineNumber);
205 }
206 }
207 else
208 {
209 if (attribute == "X_DATUM" || attribute == "x_datum")
210 {
211 xDatum = std::stof(value);
212 }
213 else if (attribute == "Y_DATUM" || attribute == "y_datum")
214 {
215 yDatum = stof(value);
216 }
217 else if (attribute == "ID" || attribute == "id")
218 {
219 id = (unsigned int)std::stoul(value);
220 }
221 else if (attribute == "X_ORIGIN" || attribute == "x_origin")
222 {
223 xOrigin = std::stof(value);
224 }
225 else if (attribute == "Y_ORIGIN" || attribute == "y_origin")
226 {
227 yOrigin = std::stof(value);
228 }
229 else if (attribute == "TOP_ACTIVE" || attribute == "top_active")
230 {
231 topActive = std::stof(value);
232 }
233 else if (attribute == "BOTTOM_ACTIVE" || attribute == "bottom_active")
234 {
235 bottomActive = std::stof(value);
236 }
237 else if (attribute == "RIGHT_ACTIVE" || attribute == "right_active")
238 {
239 rightActive = std::stof(value);
240 }
241 else if (attribute == "LEFT_ACTIVE" || attribute == "left_active")
242 {
243 leftActive = std::stof(value);
244 }
245 else if (attribute == "AFFECTING_BOM" || attribute == "affecting_bom")
246 {
247 affectingBom = value;
248 }
249 else if (attribute == "AFFECTING_BOM_CHANGED" || attribute == "affecting_bom_changed")
250 {
251 affectingBomChanged = std::stoi(value);
252 }
253 else if (attribute == "UNITS" || attribute == "units")
254 {
255 m_units = value;
256 }
257 else if (attribute.find("ONLINE_") == 0)
258 {
259 m_onlineValues[attribute] = value;
260 }
261 else
262 {
263 throw_parse_error(m_path, line, attribute, lineNumber);
264 }
265 }
266 }
267 //else if (!attributeValueIsOptional(attribute))
268 //{
269 // logwarn("matrix/matrix file: no value for non-optional attribute: " + attribute);
270 //}
271 }
272 }
273 }
274
275 stepHdrFile.close();
276 }
277 catch (parse_error& pe)
278 {
279 auto m = pe.toString("Parse Error:");
280 logerror(m);
281 // cleanup file
282 stepHdrFile.close();
283 throw pe;
284 }
285 catch (invalid_odb_error& ioe)
286 {
287 parse_info pi(m_path, line, lineNumber);
288 const auto m = pi.toString();
289 logexception_msg(ioe, m);
290 // cleanup file
291 stepHdrFile.close();
292 throw ioe;
293 }
294
295 return true;
296 }
297
298 std::unique_ptr<Odb::Lib::Protobuf::StepHdrFile> StepHdrFile::to_protobuf() const
299 {
300 auto message = std::make_unique<Odb::Lib::Protobuf::StepHdrFile>();
301 message->set_xdatum(xDatum);
302 message->set_ydatum(yDatum);
303 message->set_id(id);
304 message->set_xorigin(xOrigin);
305 message->set_yorigin(yOrigin);
306 message->set_topactive(topActive);
307 message->set_bottomactive(bottomActive);
308 message->set_leftactive(leftActive);
309 message->set_rightactive(rightActive);
310 message->set_affectingbom(affectingBom);
311 message->set_affectingbomchanged(affectingBomChanged);
312
313 for (const auto& stepRepeatRecord : m_stepRepeatRecords)
314 {
315 auto stepRepeatRecordPtr = message->add_steprepeatrecords();
316 stepRepeatRecordPtr->CopyFrom(*stepRepeatRecord->to_protobuf());
317 }
318
319 for (const auto& kvOnlineValue : m_onlineValues)
320 {
321 (*message->mutable_onlinevalues())[kvOnlineValue.first] = kvOnlineValue.second;
322 }
323
324 return message;
325 }
326
327 void StepHdrFile::from_protobuf(const Odb::Lib::Protobuf::StepHdrFile& message)
328 {
329 xDatum = message.xdatum();
330 yDatum = message.ydatum();
331 id = message.id();
332 xOrigin = message.xorigin();
333 yOrigin = message.yorigin();
334 topActive = message.topactive();
335 bottomActive = message.bottomactive();
336 leftActive = message.leftactive();
337 rightActive = message.rightactive();
338 affectingBom = message.affectingbom();
339 affectingBomChanged = message.affectingbomchanged();
340
341 for (const auto& stepRepeatRecord : message.steprepeatrecords())
342 {
343 auto stepRepeatRecordPtr = std::make_unique<StepRepeatRecord>();
344 stepRepeatRecordPtr->from_protobuf(stepRepeatRecord);
345 m_stepRepeatRecords.push_back(std::move(stepRepeatRecordPtr));
346 }
347
348 for (const auto& kvOnlineValue : message.onlinevalues())
349 {
350 m_onlineValues[kvOnlineValue.first] = kvOnlineValue.second;
351 }
352 }
353
354 bool StepHdrFile::Save(std::ostream& os)
355 {
356 return true;
357 }
358
359 std::unique_ptr<Odb::Lib::Protobuf::StepHdrFile::StepRepeatRecord> StepHdrFile::StepRepeatRecord::to_protobuf() const
360 {
361 auto message = std::make_unique<Odb::Lib::Protobuf::StepHdrFile::StepRepeatRecord>();
362 message->set_name(name);
363 message->set_x(x);
364 message->set_y(y);
365 message->set_dx(dx);
366 message->set_dy(dy);
367 message->set_nx(nx);
368 message->set_ny(ny);
369 message->set_angle(angle);
370 message->set_flip(flip);
371 message->set_mirror(mirror);
372 return message;
373 }
374
375 void StepHdrFile::StepRepeatRecord::from_protobuf(const Odb::Lib::Protobuf::StepHdrFile::StepRepeatRecord& message)
376 {
377 name = message.name();
378 x = message.x();
379 y = message.y();
380 dx = message.dx();
381 dy = message.dy();
382 nx = message.nx();
383 ny = message.ny();
384 flip = message.flip();
385 mirror = message.mirror();
386 angle = message.angle();
387 }
388}