9#include "../../Constants.h"
11#include "../parse_error.h"
13#include "../invalid_odb_error.h"
15#include "../../enums.h"
16#include "../OdbFile.h"
20namespace Odb::Lib::FileModel::Design
22 MatrixFile::~MatrixFile()
24 m_layerRecords.clear();
25 m_stepRecords.clear();
28 const MatrixFile::LayerRecord::Vector& MatrixFile::GetLayerRecords()
const
30 return m_layerRecords;
33 const MatrixFile::StepRecord::Vector& MatrixFile::GetStepRecords()
const
38 bool MatrixFile::Parse(std::filesystem::path path)
40 std::ifstream matrixFile;
46 if (!OdbFile::Parse(path))
return false;
48 auto matrixFilePath = path /
"matrix";
49 if (!std::filesystem::exists(matrixFilePath))
51 auto message =
"matrix/matrix file does not exist: [" + matrixFilePath.string() +
"]";
52 throw invalid_odb_error(message.c_str());
55 matrixFile.open(matrixFilePath, std::ios::in);
56 if (!matrixFile.is_open())
58 auto message =
"unable to open matrix/matrix file: [" + matrixFilePath.string() +
"]";
59 throw invalid_odb_error(message.c_str());
62 std::shared_ptr<StepRecord> pCurrentStepRecord;
63 std::shared_ptr<LayerRecord> pCurrentLayerRecord;
64 bool openBraceFound =
false;
66 while (std::getline(matrixFile, line))
70 Utils::str_trim(line);
73 std::stringstream lineStream(line);
74 if (line.find(Constants::COMMENT_TOKEN) == 0)
78 else if (line.find(StepRecord::RECORD_TOKEN) == 0)
81 if (!(lineStream >> token))
83 throw_parse_error(m_path, line, token, lineNumber);
87 if (token != StepRecord::RECORD_TOKEN || pCurrentStepRecord !=
nullptr)
89 throw_parse_error(m_path, line, token, lineNumber);
93 pCurrentStepRecord = std::make_shared<StepRecord>();
95 if (lineStream >> token)
98 if (token == Constants::ARRAY_RECORD_OPEN_TOKEN)
100 openBraceFound =
true;
104 else if (line.find(LayerRecord::RECORD_TOKEN) == 0)
107 if (!(lineStream >> token))
109 throw_parse_error(m_path, line, token, lineNumber);
113 if (token != LayerRecord::RECORD_TOKEN || pCurrentLayerRecord !=
nullptr)
115 throw_parse_error(m_path, line, token, lineNumber);
119 pCurrentLayerRecord = std::make_shared<LayerRecord>();
121 if (lineStream >> token)
124 if (token == Constants::ARRAY_RECORD_OPEN_TOKEN)
126 openBraceFound =
true;
130 else if (line.find(Constants::ARRAY_RECORD_OPEN_TOKEN) == 0)
136 if (pCurrentStepRecord ==
nullptr && pCurrentLayerRecord ==
nullptr)
138 throw_parse_error(m_path, line,
"", lineNumber);
144 throw_parse_error(m_path, line,
"", lineNumber);
147 openBraceFound =
true;
155 else if (line.find(Constants::ARRAY_RECORD_CLOSE_TOKEN) == 0)
157 if (pCurrentStepRecord !=
nullptr && openBraceFound)
159 m_stepRecords.push_back(pCurrentStepRecord);
160 pCurrentStepRecord.reset();
161 openBraceFound =
false;
163 else if (pCurrentLayerRecord !=
nullptr && openBraceFound)
165 m_layerRecords.push_back(pCurrentLayerRecord);
166 pCurrentLayerRecord.reset();
167 openBraceFound =
false;
172 throw_parse_error(m_path, line,
"", lineNumber);
178 std::string attribute;
181 if (!std::getline(lineStream, attribute,
'='))
183 throw_parse_error(m_path, line, attribute, lineNumber);
186 if (std::getline(lineStream, value))
188 Utils::str_trim(attribute);
189 Utils::str_trim(value);
191 if (pCurrentStepRecord !=
nullptr && openBraceFound)
193 if (attribute == StepRecord::COLUMN_KEY || attribute ==
"col")
195 pCurrentStepRecord->column = std::stoi(value);
197 else if (attribute == StepRecord::NAME_KEY || attribute ==
"name")
199 pCurrentStepRecord->name = value;
201 else if (attribute == StepRecord::ID_KEY || attribute ==
"id")
203 pCurrentStepRecord->id =
static_cast<unsigned int>(std::stoul(value));
207 throw_parse_error(m_path, line, attribute, lineNumber);
210 else if (pCurrentLayerRecord !=
nullptr && openBraceFound)
212 if (attribute ==
"ROW" || attribute ==
"row")
214 pCurrentLayerRecord->row = std::stoi(value);
216 else if (attribute ==
"NAME" || attribute ==
"name")
218 pCurrentLayerRecord->name = value;
220 else if (attribute ==
"ID" || attribute ==
"id")
222 pCurrentLayerRecord->id = (
unsigned int)std::stoul(value);
224 else if (attribute ==
"TYPE" || attribute ==
"type")
226 if (LayerRecord::typeMap.contains(value))
228 pCurrentLayerRecord->type = LayerRecord::typeMap.getValue(value);
232 throw_parse_error(m_path, line, attribute, lineNumber);
235 else if (attribute == LayerRecord::CONTEXT_KEY || attribute ==
"context")
237 if (LayerRecord::contextMap.contains(value))
239 pCurrentLayerRecord->context = LayerRecord::contextMap.getValue(value);
243 throw_parse_error(m_path, line, attribute, lineNumber);
246 else if (attribute ==
"OLD_NAME" || attribute ==
"old_name")
248 pCurrentLayerRecord->oldName = value;
250 else if (attribute == LayerRecord::POLARITY_KEY || attribute ==
"polarity")
252 if (LayerRecord::polarityMap.contains(value))
254 pCurrentLayerRecord->polarity = LayerRecord::polarityMap.getValue(value);
258 throw_parse_error(m_path, line, attribute, lineNumber);
261 else if (attribute == LayerRecord::DIELECTRIC_TYPE_KEY || attribute ==
"dielectric_type")
263 if (LayerRecord::dielectricTypeMap.contains(value))
265 pCurrentLayerRecord->dielectricType = LayerRecord::dielectricTypeMap.getValue(value);
269 throw_parse_error(m_path, line, attribute, lineNumber);
272 else if (attribute ==
"DIELECTRIC_NAME" || attribute ==
"dielectric_name")
274 pCurrentLayerRecord->dielectricName = value;
276 else if (attribute == LayerRecord::FORM_KEY || attribute ==
"form")
278 if (LayerRecord::formMap.contains(value))
280 pCurrentLayerRecord->form = LayerRecord::formMap.getValue(value);
284 throw_parse_error(m_path, line, attribute, lineNumber);
287 else if (attribute ==
"CU_TOP" || attribute ==
"cu_top")
289 pCurrentLayerRecord->cuTop = std::stoul(value);
291 else if (attribute ==
"CU_TOP" || attribute ==
"cu_top")
293 pCurrentLayerRecord->cuTop = std::stoul(value);
295 else if (attribute ==
"CU_BOTTOM" || attribute ==
"cu_bottom")
297 pCurrentLayerRecord->cuBottom = std::stoul(value);
299 else if (attribute ==
"REF" || attribute ==
"ref")
301 pCurrentLayerRecord->ref = std::stoul(value);
303 else if (attribute ==
"START_NAME" || attribute ==
"start_name")
305 pCurrentLayerRecord->startName = value;
307 else if (attribute ==
"END_NAME" || attribute ==
"end_name")
309 pCurrentLayerRecord->endName = value;
311 else if (attribute ==
"ADD_TYPE" || attribute ==
"add_type")
313 pCurrentLayerRecord->addType = value;
315 else if (attribute ==
"COLOR" || attribute ==
"color")
317 if (!pCurrentLayerRecord->color.from_string(value))
return false;
321 throw_parse_error(m_path, line, attribute, lineNumber);
328 throw_parse_error(m_path, line, attribute, lineNumber);
331 else if (!attributeValueIsOptional(attribute))
333 logwarn(
"matrix/matrix file: no value for non-optional attribute: " + attribute);
341 catch (parse_error& pe)
343 auto m = pe.toString(
"Parse Error:");
349 catch (invalid_odb_error& ioe)
351 parse_info pi(m_path, line, lineNumber);
352 const auto m = pi.toString();
353 logexception_msg(ioe, m);
362 std::unique_ptr<Odb::Lib::Protobuf::MatrixFile> Odb::Lib::FileModel::Design::MatrixFile::to_protobuf()
const
364 std::unique_ptr<Odb::Lib::Protobuf::MatrixFile> pMatrixFileMessage(
new Odb::Lib::Protobuf::MatrixFile);
365 for (
const auto& stepRecord : m_stepRecords)
367 auto pStepRecordMessage = pMatrixFileMessage->add_steps();
368 pStepRecordMessage->CopyFrom(*stepRecord->to_protobuf());
370 for (
const auto& layerRecord : m_layerRecords)
372 auto pLayerRecordMessage = pMatrixFileMessage->add_layers();
373 pLayerRecordMessage->CopyFrom(*layerRecord->to_protobuf());
375 return pMatrixFileMessage;
379 void Odb::Lib::FileModel::Design::MatrixFile::from_protobuf(
const Odb::Lib::Protobuf::MatrixFile& message)
381 for (
const auto& stepRecord : message.steps())
383 auto pStepRecord = std::make_shared<StepRecord>();
384 pStepRecord->from_protobuf(stepRecord);
385 m_stepRecords.push_back(pStepRecord);
387 for (
const auto& layerRecord : message.layers())
389 auto pLayerRecord = std::make_shared<LayerRecord>();
390 pLayerRecord->from_protobuf(layerRecord);
391 m_layerRecords.push_back(pLayerRecord);
395 bool MatrixFile::Save(std::ostream& os)
397 for (
const auto& stepRecord : m_stepRecords)
399 os << StepRecord::RECORD_TOKEN <<
" " << Constants::ARRAY_RECORD_OPEN_TOKEN << std::endl;
401 os <<
'\t' << StepRecord::COLUMN_KEY <<
"=" << stepRecord->column << std::endl;
402 os <<
'\t' << StepRecord::NAME_KEY <<
"=" << stepRecord->name << std::endl;
403 os <<
'\t' << StepRecord::ID_KEY <<
"=" << stepRecord->id << std::endl;
405 os << Constants::ARRAY_RECORD_CLOSE_TOKEN << std::endl;
409 for (
const auto& layerRecord : m_layerRecords)
411 os << LayerRecord::RECORD_TOKEN <<
" " << Constants::ARRAY_RECORD_OPEN_TOKEN << std::endl;
413 os <<
'\t' << LayerRecord::ROW_KEY <<
"=" << layerRecord->row << std::endl;
414 os <<
'\t' << LayerRecord::CONTEXT_KEY <<
"=" << LayerRecord::contextMap.getValue(layerRecord->context) << std::endl;
415 os <<
'\t' << LayerRecord::TYPE_KEY <<
"=" << LayerRecord::typeMap.getValue(layerRecord->type) << std::endl;
416 os <<
'\t' << LayerRecord::NAME_KEY <<
"=" << layerRecord->name << std::endl;
417 os <<
'\t' << LayerRecord::POLARITY_KEY <<
"=" << LayerRecord::polarityMap.getValue(layerRecord->polarity) << std::endl;
418 os <<
'\t' << LayerRecord::FORM_KEY <<
"=" << LayerRecord::formMap.getValue(layerRecord->form) << std::endl;
419 os <<
'\t' << LayerRecord::DIELECTRIC_TYPE_KEY <<
"=" << LayerRecord::dielectricTypeMap.getValue(layerRecord->dielectricType) << std::endl;
420 os <<
'\t' << LayerRecord::DIELECTRIC_NAME_KEY <<
"=" << layerRecord->dielectricName << std::endl;
421 os <<
'\t' << LayerRecord::CU_TOP_KEY <<
"=";
422 if (layerRecord->cuTop != (
unsigned int)-1)
424 os << layerRecord->cuTop;
427 os <<
'\t' << LayerRecord::CU_BOTTOM_KEY <<
"=";
428 if (layerRecord->cuBottom != (
unsigned int)-1)
430 os << layerRecord->cuBottom;
433 os <<
'\t' << LayerRecord::REF_KEY <<
"=";
434 if (layerRecord->ref != (
unsigned int)-1)
436 os << layerRecord->ref;
439 os <<
'\t' << LayerRecord::START_NAME_KEY <<
"=" << layerRecord->startName << std::endl;
440 os <<
'\t' << LayerRecord::END_NAME_KEY <<
"=" << layerRecord->endName << std::endl;
441 os <<
'\t' << LayerRecord::OLD_NAME_KEY <<
"=" << layerRecord->oldName << std::endl;
442 os <<
'\t' << LayerRecord::ADD_TYPE_KEY <<
"=" << layerRecord->addType << std::endl;
443 os <<
'\t' << LayerRecord::COLOR_KEY <<
"=" << layerRecord->color.to_string() << std::endl;
444 os <<
'\t' << LayerRecord::ID_KEY <<
"=" << layerRecord->id << std::endl;
446 os << Constants::ARRAY_RECORD_CLOSE_TOKEN << std::endl;
453 std::unique_ptr<Odb::Lib::Protobuf::MatrixFile::StepRecord> Odb::Lib::FileModel::Design::MatrixFile::StepRecord::to_protobuf()
const
455 std::unique_ptr<Odb::Lib::Protobuf::MatrixFile::StepRecord> pStepRecordMessage(
new Odb::Lib::Protobuf::MatrixFile::StepRecord);
456 pStepRecordMessage->set_column(column);
457 pStepRecordMessage->set_name(name);
458 pStepRecordMessage->set_id(
id);
459 return pStepRecordMessage;
462 void Odb::Lib::FileModel::Design::MatrixFile::StepRecord::from_protobuf(
const Odb::Lib::Protobuf::MatrixFile::StepRecord& message)
464 column = message.column();
465 name = message.name();
469 std::unique_ptr<Odb::Lib::Protobuf::MatrixFile::LayerRecord> Odb::Lib::FileModel::Design::MatrixFile::LayerRecord::to_protobuf()
const
471 std::unique_ptr<Odb::Lib::Protobuf::MatrixFile::LayerRecord> pLayerRecordMessage(
new Odb::Lib::Protobuf::MatrixFile::LayerRecord);
472 pLayerRecordMessage->set_addtype(addType);
473 pLayerRecordMessage->set_context(
static_cast<Odb::Lib::Protobuf::MatrixFile::LayerRecord::Context
>(context));
474 pLayerRecordMessage->set_cubottom(cuBottom);
475 pLayerRecordMessage->set_cutop(cuTop);
476 pLayerRecordMessage->set_dielectricname(dielectricName);
477 pLayerRecordMessage->set_dielectrictype(
static_cast<Odb::Lib::Protobuf::MatrixFile::LayerRecord::DielectricType
>(dielectricType));
478 pLayerRecordMessage->set_endname(endName);
479 pLayerRecordMessage->set_form(
static_cast<Odb::Lib::Protobuf::MatrixFile::LayerRecord::Form
>(form));
480 pLayerRecordMessage->set_id(
id);
481 pLayerRecordMessage->set_name(name);
482 pLayerRecordMessage->set_oldname(oldName);
483 pLayerRecordMessage->set_polarity(
static_cast<Odb::Lib::Protobuf::Polarity
>(polarity));
484 pLayerRecordMessage->set_ref(ref);
485 pLayerRecordMessage->set_row(row);
486 pLayerRecordMessage->set_startname(startName);
487 pLayerRecordMessage->set_type(
static_cast<Odb::Lib::Protobuf::MatrixFile::LayerRecord::Type
>(type));
488 pLayerRecordMessage->mutable_color()->set_red(color.red);
489 pLayerRecordMessage->mutable_color()->set_green(color.green);
490 pLayerRecordMessage->mutable_color()->set_blue(color.blue);
491 pLayerRecordMessage->mutable_color()->set_nopreference(color.noPreference);
494 return pLayerRecordMessage;
497 void Odb::Lib::FileModel::Design::MatrixFile::LayerRecord::from_protobuf(
const Odb::Lib::Protobuf::MatrixFile::LayerRecord& message)
499 addType = message.addtype();
500 context =
static_cast<Context
>(message.context());
501 cuBottom = message.cubottom();
502 cuTop = message.cutop();
503 dielectricName = message.dielectricname();
504 dielectricType =
static_cast<DielectricType
>(message.dielectrictype());
505 endName = message.endname();
506 form =
static_cast<Form
>(message.form());
508 name = message.name();
509 oldName = message.oldname();
510 polarity =
static_cast<Polarity
>(message.polarity());
513 startName = message.startname();
514 type =
static_cast<Type
>(message.type());
515 color.red = message.color().red();
516 color.green = message.color().green();
517 color.blue = message.color().blue();
518 color.noPreference = message.color().nopreference();