1#include "StepHdrFile.h"
2#include "../invalid_odb_error.h"
4#include "../../Constants.h"
5#include "../parse_error.h"
7#include "../../Text/Utf8Sanitizer.h"
9namespace Odb::Lib::FileModel::Design
11 StepHdrFile::~StepHdrFile()
13 m_stepRepeatRecords.clear();
16 bool StepHdrFile::Parse(std::filesystem::path path)
18 std::ifstream stepHdrFile;
24 if (!OdbFile::Parse(path))
return false;
26 auto stepHdrFilePath = path /
"stephdr";
27 if (!std::filesystem::exists(stepHdrFilePath))
29 auto message =
"stephdr file does not exist: [" + stepHdrFilePath.string() +
"]";
30 throw invalid_odb_error(message.c_str());
33 stepHdrFile.open(stepHdrFilePath, std::ios::in);
34 if (!stepHdrFile.is_open())
36 auto message =
"unable to open stephdr file: [" + stepHdrFilePath.string() +
"]";
37 throw invalid_odb_error(message.c_str());
40 m_path = stepHdrFilePath;
42 std::shared_ptr<StepRepeatRecord> pCurrentStepRepeatRecord;
43 bool openBraceFound =
false;
45 while (std::getline(stepHdrFile, line))
49 Utils::str_trim(line);
52 std::stringstream lineStream(line);
53 if (line.find(Constants::COMMENT_TOKEN) == 0)
57 else if (line.find(StepRepeatRecord::ARRAY_HEADER_TOKEN) == 0)
60 if (!(lineStream >> token))
62 throw_parse_error(m_path, line, token, lineNumber);
65 if (token != StepRepeatRecord::ARRAY_HEADER_TOKEN)
67 throw_parse_error(m_path, line, token, lineNumber);
70 if (lineStream >> token)
73 if (token == Constants::ARRAY_RECORD_OPEN_TOKEN)
75 openBraceFound =
true;
81 pCurrentStepRepeatRecord = std::make_shared<StepRepeatRecord>();
85 else if (line.find(Constants::ARRAY_RECORD_OPEN_TOKEN) == 0)
90 if (pCurrentStepRepeatRecord ==
nullptr)
92 throw_parse_error(m_path, line,
"", lineNumber);
98 throw_parse_error(m_path, line,
"", lineNumber);
101 openBraceFound =
true;
109 else if (line.find(Constants::ARRAY_RECORD_CLOSE_TOKEN) == 0)
111 if (pCurrentStepRepeatRecord !=
nullptr && openBraceFound)
113 m_stepRepeatRecords.push_back(pCurrentStepRepeatRecord);
114 pCurrentStepRepeatRecord.reset();
115 openBraceFound =
false;
120 throw_parse_error(m_path, line,
"", lineNumber);
126 std::string attribute;
129 if (!std::getline(lineStream, attribute,
'='))
131 throw_parse_error(m_path, line, attribute, lineNumber);
134 if (std::getline(lineStream, value))
136 Utils::str_trim(attribute);
137 Utils::str_trim(value);
139 if (pCurrentStepRepeatRecord !=
nullptr && openBraceFound)
141 if (attribute ==
"NAME" || attribute ==
"name")
143 pCurrentStepRepeatRecord->name = value;
145 else if (attribute ==
"X" || attribute ==
"x")
147 pCurrentStepRepeatRecord->x = std::stof(value);
149 else if (attribute ==
"Y" || attribute ==
"y")
151 pCurrentStepRepeatRecord->y = std::stof(value);
153 else if (attribute ==
"DX" || attribute ==
"dx")
155 pCurrentStepRepeatRecord->dx = std::stof(value);
157 else if (attribute ==
"DY" || attribute ==
"dy")
159 pCurrentStepRepeatRecord->dy = std::stof(value);
161 else if (attribute ==
"NX" || attribute ==
"nx")
163 pCurrentStepRepeatRecord->nx = std::stoi(value);
165 else if (attribute ==
"NY" || attribute ==
"ny")
167 pCurrentStepRepeatRecord->ny = std::stoi(value);
169 else if (attribute ==
"ANGLE" || attribute ==
"angle")
171 pCurrentStepRepeatRecord->angle = std::stof(value);
173 else if (attribute ==
"FLIP" || attribute ==
"flip")
175 if (value ==
"YES" || value ==
"yes")
177 pCurrentStepRepeatRecord->flip =
true;
179 else if (value ==
"NO" || value ==
"no")
181 pCurrentStepRepeatRecord->flip =
false;
185 throw_parse_error(m_path, line, attribute, lineNumber);
188 else if (attribute ==
"MIRROR" || attribute ==
"mirror")
190 if (value ==
"YES" || value ==
"yes")
192 pCurrentStepRepeatRecord->mirror =
true;
194 else if (value ==
"NO" || value ==
"no")
196 pCurrentStepRepeatRecord->mirror =
false;
200 throw_parse_error(m_path, line, attribute, lineNumber);
205 throw_parse_error(m_path, line, attribute, lineNumber);
210 if (attribute ==
"X_DATUM" || attribute ==
"x_datum")
212 xDatum = std::stof(value);
214 else if (attribute ==
"Y_DATUM" || attribute ==
"y_datum")
216 yDatum = stof(value);
218 else if (attribute ==
"ID" || attribute ==
"id")
220 id = (
unsigned int)std::stoul(value);
222 else if (attribute ==
"X_ORIGIN" || attribute ==
"x_origin")
224 xOrigin = std::stof(value);
226 else if (attribute ==
"Y_ORIGIN" || attribute ==
"y_origin")
228 yOrigin = std::stof(value);
230 else if (attribute ==
"TOP_ACTIVE" || attribute ==
"top_active")
232 topActive = std::stof(value);
234 else if (attribute ==
"BOTTOM_ACTIVE" || attribute ==
"bottom_active")
236 bottomActive = std::stof(value);
238 else if (attribute ==
"RIGHT_ACTIVE" || attribute ==
"right_active")
240 rightActive = std::stof(value);
242 else if (attribute ==
"LEFT_ACTIVE" || attribute ==
"left_active")
244 leftActive = std::stof(value);
246 else if (attribute ==
"AFFECTING_BOM" || attribute ==
"affecting_bom")
248 affectingBom = value;
250 else if (attribute ==
"AFFECTING_BOM_CHANGED" || attribute ==
"affecting_bom_changed")
252 affectingBomChanged = std::stoi(value);
254 else if (attribute ==
"UNITS" || attribute ==
"units")
258 else if (attribute.find(
"ONLINE_") == 0)
260 m_onlineValues[attribute] = value;
264 throw_parse_error(m_path, line, attribute, lineNumber);
278 catch (parse_error& pe)
280 auto m = pe.toString(
"Parse Error:");
286 catch (invalid_odb_error& ioe)
288 parse_info pi(m_path, line, lineNumber);
289 const auto m = pi.toString();
290 logexception_msg(ioe, m);
299 std::unique_ptr<Odb::Lib::Protobuf::StepHdrFile> StepHdrFile::to_protobuf()
const
301 auto message = std::make_unique<Odb::Lib::Protobuf::StepHdrFile>();
302 message->set_xdatum(xDatum);
303 message->set_ydatum(yDatum);
305 message->set_xorigin(xOrigin);
306 message->set_yorigin(yOrigin);
307 message->set_topactive(topActive);
308 message->set_bottomactive(bottomActive);
309 message->set_leftactive(leftActive);
310 message->set_rightactive(rightActive);
311 message->set_affectingbom(Odb::Lib::Text::ToUtf8(affectingBom));
312 message->set_affectingbomchanged(affectingBomChanged);
314 for (
const auto& stepRepeatRecord : m_stepRepeatRecords)
316 auto stepRepeatRecordPtr = message->add_steprepeatrecords();
317 stepRepeatRecordPtr->CopyFrom(*stepRepeatRecord->to_protobuf());
320 for (
const auto& kvOnlineValue : m_onlineValues)
322 (*message->mutable_onlinevalues())[Odb::Lib::Text::ToUtf8(kvOnlineValue.first)] =
Odb::Lib::Text::ToUtf8(kvOnlineValue.second);
328 void StepHdrFile::from_protobuf(
const Odb::Lib::Protobuf::StepHdrFile& message)
330 xDatum = message.xdatum();
331 yDatum = message.ydatum();
333 xOrigin = message.xorigin();
334 yOrigin = message.yorigin();
335 topActive = message.topactive();
336 bottomActive = message.bottomactive();
337 leftActive = message.leftactive();
338 rightActive = message.rightactive();
339 affectingBom = message.affectingbom();
340 affectingBomChanged = message.affectingbomchanged();
342 for (
const auto& stepRepeatRecord : message.steprepeatrecords())
344 auto stepRepeatRecordPtr = std::make_unique<StepRepeatRecord>();
345 stepRepeatRecordPtr->from_protobuf(stepRepeatRecord);
346 m_stepRepeatRecords.push_back(std::move(stepRepeatRecordPtr));
349 for (
const auto& kvOnlineValue : message.onlinevalues())
351 m_onlineValues[kvOnlineValue.first] = kvOnlineValue.second;
355 bool StepHdrFile::Save(std::ostream& os)
360 std::unique_ptr<Odb::Lib::Protobuf::StepHdrFile::StepRepeatRecord> StepHdrFile::StepRepeatRecord::to_protobuf()
const
362 auto message = std::make_unique<Odb::Lib::Protobuf::StepHdrFile::StepRepeatRecord>();
363 message->set_name(Odb::Lib::Text::ToUtf8(name));
370 message->set_angle(angle);
371 message->set_flip(flip);
372 message->set_mirror(mirror);
376 void StepHdrFile::StepRepeatRecord::from_protobuf(
const Odb::Lib::Protobuf::StepHdrFile::StepRepeatRecord& message)
378 name = message.name();
385 flip = message.flip();
386 mirror = message.mirror();
387 angle = message.angle();
std::string ToUtf8(std::string_view input)
Converts input to valid UTF-8.