7#include "../parse_error.h"
8#include "../invalid_odb_error.h"
11#include "../../Constants.h"
12#include <ArchiveExtractor.h>
14namespace Odb::Lib::FileModel::Design
16 ToolsFile::ToolsFile()
25 ToolsFile::~ToolsFile()
30 std::string ToolsFile::GetUnits()
const
35 double ToolsFile::GetThickness()
const
40 std::string ToolsFile::GetUserParams()
const
45 const ToolsFile::ToolsMap& ToolsFile::GetTools()
const
50 bool Lib::FileModel::Design::ToolsFile::Parse(std::filesystem::path directory)
52 std::ifstream toolsFile;
58 m_directory = directory;
60 loginfo(
"checking for extraction...");
62 std::filesystem::path toolsFilePath;
63 for (
const std::string toolsFilename : TOOLS_FILENAMES)
65 loginfo(
"trying tools file: [" + toolsFilename +
"]...");
67 toolsFilePath = Utils::ArchiveExtractor::getUncompressedFilePath(m_directory, toolsFilename);
68 if (exists(toolsFilePath) && is_regular_file(toolsFilePath))
70 loginfo(
"found tools file: [" + toolsFilePath.string() +
"]");
75 m_path = toolsFilePath;
77 loginfo(
"any extraction complete, parsing data...");
79 if (!std::filesystem::exists(m_path))
81 auto message =
"tools file does not exist: [" + m_directory.string() +
"]";
86 else if (!std::filesystem::is_regular_file(m_path))
88 auto message =
"tools is not a file: [" + m_path.string() +
"]";
89 throw invalid_odb_error(message.c_str());
92 toolsFile.open(m_path.string(), std::ios::in);
93 if (!toolsFile.is_open())
95 auto message =
"unable to open tools file: [" + m_path.string() +
"]";
96 throw invalid_odb_error(message.c_str());
99 std::shared_ptr<ToolsRecord> pCurrentToolsRecord;
100 bool openBraceFound =
false;
102 while (std::getline(toolsFile, line))
107 Utils::str_trim(line);
110 std::stringstream lineStream(line);
113 if (line.find(Constants::COMMENT_TOKEN) == 0)
117 else if (line.find(ToolsFile::UNITS_TOKEN) == 0)
121 if (!std::getline(lineStream, token,
'='))
123 throw_parse_error(m_path, line, token, lineNumber);
128 else if (line.find(ToolsFile::THICKNESS_TOKEN) == 0)
132 if (!std::getline(lineStream, value,
'='))
134 throw_parse_error(m_path, line, value, lineNumber);
137 if (std::getline(lineStream, value))
139 Utils::str_trim(value);
140 m_thickness = std::stod(value);
149 else if (line.find(ToolsFile::USER_PARAMS_TOKEN) == 0)
153 if (!std::getline(lineStream, value,
'='))
155 throw_parse_error(m_path, line, value, lineNumber);
158 if (std::getline(lineStream, value))
160 Utils::str_trim(value);
161 m_user_params = value;
164 else if (line.find(ToolsRecord::RECORD_TOKEN) == 0)
167 if (!(lineStream >> token))
169 throw_parse_error(m_path, line, token, lineNumber);
172 if (token != ToolsRecord::RECORD_TOKEN || pCurrentToolsRecord !=
nullptr)
174 throw_parse_error(m_path, line, token, lineNumber);
178 pCurrentToolsRecord = std::make_shared<ToolsRecord>();
180 if (lineStream >> token)
183 if (token == Constants::ARRAY_RECORD_OPEN_TOKEN)
185 openBraceFound =
true;
189 else if (line.find(Constants::ARRAY_RECORD_OPEN_TOKEN) == 0)
192 if (pCurrentToolsRecord ==
nullptr)
194 throw_parse_error(m_path, line,
"", lineNumber);
200 throw_parse_error(m_path, line,
"", lineNumber);
203 openBraceFound =
true;
205 else if (line.find(Constants::ARRAY_RECORD_CLOSE_TOKEN) == 0)
207 if (pCurrentToolsRecord !=
nullptr && openBraceFound && pCurrentToolsRecord->toolNum != 0)
209 m_toolsByNum[pCurrentToolsRecord->toolNum] = pCurrentToolsRecord;
210 pCurrentToolsRecord.reset();
211 openBraceFound =
false;
216 throw_parse_error(m_path, line,
"", lineNumber);
221 std::string attribute;
224 if (!std::getline(lineStream, attribute,
'='))
226 throw_parse_error(m_path, line,
"", lineNumber);
229 if (std::getline(lineStream, value))
231 Utils::str_trim(attribute);
232 Utils::str_trim(value);
234 if (pCurrentToolsRecord !=
nullptr && openBraceFound)
236 if (attribute == ToolsRecord::NUM_KEY || attribute ==
"num")
238 pCurrentToolsRecord->toolNum = std::stoi(value);
240 else if (attribute == ToolsRecord::TYPE_KEY || attribute ==
"type")
242 if (ToolsRecord::typeMap.contains(value))
244 pCurrentToolsRecord->type = ToolsRecord::typeMap.getValue(value);
248 throw_parse_error(m_path, line, attribute, lineNumber);
251 else if (attribute == ToolsRecord::TYPE2_KEY || attribute ==
"type2")
253 if (ToolsRecord::type2Map.contains(value))
255 auto type = pCurrentToolsRecord->type;
256 auto type2 = ToolsRecord::type2Map.getValue(value);
258 if (type2 != ToolsRecord::Type2::Standard)
260 bool invalid =
false;
263 case ToolsRecord::Type2::PressFit:
264 invalid = (type != ToolsRecord::Type::Plated);
267 case ToolsRecord::Type2::Photo:
268 case ToolsRecord::Type2::Laser:
269 invalid = (type != ToolsRecord::Type::Via);
274 throw_parse_error(m_path, line, attribute, lineNumber);
277 pCurrentToolsRecord->type2 = type2;
281 pCurrentToolsRecord->type2 = ToolsRecord::Type2::Standard;
284 else if (attribute == ToolsRecord::MIN_TOL_KEY || attribute ==
"min_tol")
286 pCurrentToolsRecord->minTOL = std::stod(value);
288 else if (attribute == ToolsRecord::MAX_TOL_KEY || attribute ==
"max_tol")
290 pCurrentToolsRecord->maxTOL = std::stod(value);
292 else if (attribute == ToolsRecord::BIT_KEY || attribute ==
"bit")
294 pCurrentToolsRecord->drillBit = value;
296 else if (attribute == ToolsRecord::FINISH_SIZE_KEY || attribute ==
"finish_size")
298 pCurrentToolsRecord->finishSize = std::stod(value);
300 else if (attribute == ToolsRecord::DRILL_SIZE_KEY || attribute ==
"drill_size")
302 pCurrentToolsRecord->drillSize = std::stod(value);
306 throw_parse_error(m_path, line, attribute, lineNumber);
313 throw_parse_error(m_path, line, attribute, lineNumber);
324 catch (parse_error& pe)
326 auto m = pe.toString(
"Parse Error:");
331 catch (std::exception& e)
333 parse_info pi(m_path, line, lineNumber);
334 const auto m = pi.toString();
335 logexception_msg(e, m);
343 bool ToolsFile::Save(std::ostream& os)
345 os << Constants::UNITS_TOKEN <<
" = " << m_units << std::endl;
346 os << ToolsFile::THICKNESS_TOKEN <<
" = " << std::to_string(m_thickness) << std::endl;
347 os << ToolsFile::USER_PARAMS_TOKEN <<
" = " << m_user_params << std::endl;
349 for (
const auto& [toolNum, tool_info] : m_toolsByNum)
351 os << ToolsRecord::RECORD_TOKEN <<
" " << Constants::ARRAY_RECORD_OPEN_TOKEN << std::endl;
353 os <<
'\t' << ToolsRecord::NUM_KEY <<
"=" << toolNum << std::endl;
354 os <<
'\t' << ToolsRecord::TYPE_KEY <<
"=" << ToolsRecord::typeMap.getValue(tool_info->type) << std::endl;
355 os <<
'\t' << ToolsRecord::TYPE2_KEY <<
"=" << ToolsRecord::type2Map.getValue(tool_info->type2) << std::endl;
356 os <<
'\t' << ToolsRecord::MIN_TOL_KEY <<
"=" << tool_info->minTOL << std::endl;
357 os <<
'\t' << ToolsRecord::MAX_TOL_KEY <<
"=" << tool_info->maxTOL << std::endl;
358 os <<
'\t' << ToolsRecord::BIT_KEY <<
"=" << tool_info->drillBit << std::endl;
359 os <<
'\t' << ToolsRecord::FINISH_SIZE_KEY <<
"=" << tool_info->finishSize << std::endl;
360 os <<
'\t' << ToolsRecord::DRILL_SIZE_KEY <<
"=" << tool_info->drillSize << std::endl;
362 os << Constants::ARRAY_RECORD_CLOSE_TOKEN << std::endl;
369 std::unique_ptr<Odb::Lib::Protobuf::ToolsFile::ToolsRecord>Odb::Lib::FileModel::Design::ToolsFile::ToolsRecord::to_protobuf()
const
371 std::unique_ptr<Odb::Lib::Protobuf::ToolsFile::ToolsRecord> pToolsRecordMessage(
new Odb::Lib::Protobuf::ToolsFile::ToolsRecord);
372 pToolsRecordMessage->set_tool_num(toolNum);
373 pToolsRecordMessage->set_type(
static_cast<Odb::Lib::Protobuf::ToolsFile::ToolsRecord::Type
>(type));
374 pToolsRecordMessage->set_type2(
static_cast<Odb::Lib::Protobuf::ToolsFile::ToolsRecord::Type2
>(type2));
375 pToolsRecordMessage->set_min_tol(minTOL);
376 pToolsRecordMessage->set_max_tol(maxTOL);
377 pToolsRecordMessage->set_drill_bit(drillBit);
378 pToolsRecordMessage->set_finish_size(finishSize);
379 pToolsRecordMessage->set_drill_size(drillSize);
381 return pToolsRecordMessage;
384 void Odb::Lib::FileModel::Design::ToolsFile::ToolsRecord::from_protobuf(
const Odb::Lib::Protobuf::ToolsFile::ToolsRecord& message)
386 toolNum = message.tool_num();
387 type =
static_cast<Type
>(message.type());
388 type2 =
static_cast<Type2
>(message.type2());
389 minTOL = message.min_tol();
390 maxTOL = message.max_tol();
391 drillBit = message.drill_bit();
392 finishSize = message.finish_size();
393 drillSize = message.drill_size();
396 std::unique_ptr<Odb::Lib::Protobuf::ToolsFile> Lib::FileModel::Design::ToolsFile::to_protobuf()
const
398 auto message = std::make_unique<Odb::Lib::Protobuf::ToolsFile>();
400 message->set_directory(m_directory.string());
401 message->set_path(m_path.string());
402 message->set_units(m_units);
404 message->set_thickness(m_thickness);
405 message->set_user_params(m_user_params);
407 auto* tools_map = message->mutable_tools();
408 for (
const auto& [toolNum, toolsRecord] : m_toolsByNum)
410 auto& recordMsg = (*tools_map)[toolNum];
411 recordMsg.CopyFrom(*toolsRecord->to_protobuf());
417 void Lib::FileModel::Design::ToolsFile::from_protobuf(
const Odb::Lib::Protobuf::ToolsFile& message)
419 m_directory = message.directory();
420 m_path = message.path();
422 m_units = message.units();
423 m_thickness = message.thickness();
424 m_user_params = message.user_params();
426 for (
const auto& [toolNum, toolsRecord] : message.tools())
428 auto ptoolsRecord = std::make_shared<ToolsRecord>();
429 ptoolsRecord->from_protobuf(toolsRecord);
430 m_toolsByNum.emplace(toolNum, ptoolsRecord);