5 #include "MatrixFile.h"
9 #include "../../Constants.h"
11 #include "../parse_error.h"
13 #include "../invalid_odb_error.h"
14 #include "../../ProtoBuf/enums.pb.h"
15 #include "../../enums.h"
16 #include "../OdbFile.h"
20 namespace 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);
86 if (token != StepRecord::RECORD_TOKEN)
88 throw_parse_error(m_path, line, token, lineNumber);
91 if (lineStream >> token)
94 if (token == Constants::ARRAY_RECORD_OPEN_TOKEN)
96 openBraceFound =
true;
102 pCurrentStepRecord = std::make_shared<StepRecord>();
106 else if (line.find(LayerRecord::RECORD_TOKEN) == 0)
109 if (!(lineStream >> token))
111 throw_parse_error(m_path, line, token, lineNumber);
114 if (token != LayerRecord::RECORD_TOKEN)
116 throw_parse_error(m_path, line, token, lineNumber);
119 if (lineStream >> token)
122 if (token == Constants::ARRAY_RECORD_OPEN_TOKEN)
124 openBraceFound =
true;
130 pCurrentLayerRecord = std::make_shared<LayerRecord>();
134 else if (line.find(Constants::ARRAY_RECORD_OPEN_TOKEN) == 0)
140 if (pCurrentStepRecord ==
nullptr && pCurrentLayerRecord ==
nullptr)
142 throw_parse_error(m_path, line,
"", lineNumber);
148 throw_parse_error(m_path, line,
"", lineNumber);
151 openBraceFound =
true;
159 else if (line.find(Constants::ARRAY_RECORD_CLOSE_TOKEN) == 0)
161 if (pCurrentStepRecord !=
nullptr && openBraceFound)
163 m_stepRecords.push_back(pCurrentStepRecord);
164 pCurrentStepRecord.reset();
165 openBraceFound =
false;
167 else if (pCurrentLayerRecord !=
nullptr && openBraceFound)
169 m_layerRecords.push_back(pCurrentLayerRecord);
170 pCurrentLayerRecord.reset();
171 openBraceFound =
false;
176 throw_parse_error(m_path, line,
"", lineNumber);
182 std::string attribute;
185 if (!std::getline(lineStream, attribute,
'='))
187 throw_parse_error(m_path, line, attribute, lineNumber);
190 if (std::getline(lineStream, value))
192 Utils::str_trim(attribute);
193 Utils::str_trim(value);
195 if (pCurrentStepRecord !=
nullptr && openBraceFound)
197 if (attribute == StepRecord::COLUMN_KEY || attribute ==
"col")
199 pCurrentStepRecord->column = std::stoi(value);
201 else if (attribute == StepRecord::NAME_KEY || attribute ==
"name")
203 pCurrentStepRecord->name = value;
205 else if (attribute == StepRecord::ID_KEY || attribute ==
"id")
207 pCurrentStepRecord->id =
static_cast<unsigned int>(std::stoul(value));
211 throw_parse_error(m_path, line, attribute, lineNumber);
214 else if (pCurrentLayerRecord !=
nullptr && openBraceFound)
216 if (attribute ==
"ROW" || attribute ==
"row")
218 pCurrentLayerRecord->row = std::stoi(value);
220 else if (attribute ==
"NAME" || attribute ==
"name")
222 pCurrentLayerRecord->name = value;
224 else if (attribute ==
"ID" || attribute ==
"id")
226 pCurrentLayerRecord->id = (
unsigned int)std::stoul(value);
228 else if (attribute ==
"TYPE" || attribute ==
"type")
230 if (LayerRecord::typeMap.contains(value))
232 pCurrentLayerRecord->type = LayerRecord::typeMap.getValue(value);
236 throw_parse_error(m_path, line, attribute, lineNumber);
239 else if (attribute == LayerRecord::CONTEXT_KEY || attribute ==
"context")
241 if (LayerRecord::contextMap.contains(value))
243 pCurrentLayerRecord->context = LayerRecord::contextMap.getValue(value);
247 throw_parse_error(m_path, line, attribute, lineNumber);
250 else if (attribute ==
"OLD_NAME" || attribute ==
"old_name")
252 pCurrentLayerRecord->oldName = value;
254 else if (attribute == LayerRecord::POLARITY_KEY || attribute ==
"polarity")
256 if (LayerRecord::polarityMap.contains(value))
258 pCurrentLayerRecord->polarity = LayerRecord::polarityMap.getValue(value);
262 throw_parse_error(m_path, line, attribute, lineNumber);
265 else if (attribute == LayerRecord::DIELECTRIC_TYPE_KEY || attribute ==
"dielectric_type")
267 if (LayerRecord::dielectricTypeMap.contains(value))
269 pCurrentLayerRecord->dielectricType = LayerRecord::dielectricTypeMap.getValue(value);
273 throw_parse_error(m_path, line, attribute, lineNumber);
276 else if (attribute ==
"DIELECTRIC_NAME" || attribute ==
"dielectric_name")
278 pCurrentLayerRecord->dielectricName = value;
280 else if (attribute == LayerRecord::FORM_KEY || attribute ==
"form")
282 if (LayerRecord::formMap.contains(value))
284 pCurrentLayerRecord->form = LayerRecord::formMap.getValue(value);
288 throw_parse_error(m_path, line, attribute, lineNumber);
291 else if (attribute ==
"CU_TOP" || attribute ==
"cu_top")
293 pCurrentLayerRecord->cuTop = std::stoul(value);
295 else if (attribute ==
"CU_TOP" || attribute ==
"cu_top")
297 pCurrentLayerRecord->cuTop = std::stoul(value);
299 else if (attribute ==
"CU_BOTTOM" || attribute ==
"cu_bottom")
301 pCurrentLayerRecord->cuBottom = std::stoul(value);
303 else if (attribute ==
"REF" || attribute ==
"ref")
305 pCurrentLayerRecord->ref = std::stoul(value);
307 else if (attribute ==
"START_NAME" || attribute ==
"start_name")
309 pCurrentLayerRecord->startName = value;
311 else if (attribute ==
"END_NAME" || attribute ==
"end_name")
313 pCurrentLayerRecord->endName = value;
315 else if (attribute ==
"ADD_TYPE" || attribute ==
"add_type")
317 pCurrentLayerRecord->addType = value;
319 else if (attribute ==
"COLOR" || attribute ==
"color")
321 if (!pCurrentLayerRecord->color.from_string(value))
return false;
325 throw_parse_error(m_path, line, attribute, lineNumber);
332 throw_parse_error(m_path, line, attribute, lineNumber);
335 else if (!attributeValueIsOptional(attribute))
337 logwarn(
"matrix/matrix file: no value for non-optional attribute: " + attribute);
345 catch (parse_error& pe)
347 auto m = pe.toString(
"Parse Error:");
353 catch (invalid_odb_error& ioe)
355 parse_info pi(m_path, line, lineNumber);
356 const auto m = pi.toString();
357 logexception_msg(ioe, m);
366 bool MatrixFile::attributeValueIsOptional(
const std::string& attribute)
368 for (
const auto& optionalAttribute : OPTIONAL_ATTRIBUTES)
370 if (attribute == optionalAttribute)
378 std::unique_ptr<Odb::Lib::Protobuf::MatrixFile> Odb::Lib::FileModel::Design::MatrixFile::to_protobuf()
const
380 std::unique_ptr<Odb::Lib::Protobuf::MatrixFile> pMatrixFileMessage(
new Odb::Lib::Protobuf::MatrixFile);
381 for (
const auto& stepRecord : m_stepRecords)
383 auto pStepRecordMessage = pMatrixFileMessage->add_steps();
384 pStepRecordMessage->CopyFrom(*stepRecord->to_protobuf());
386 for (
const auto& layerRecord : m_layerRecords)
388 auto pLayerRecordMessage = pMatrixFileMessage->add_layers();
389 pLayerRecordMessage->CopyFrom(*layerRecord->to_protobuf());
391 return pMatrixFileMessage;
395 void Odb::Lib::FileModel::Design::MatrixFile::from_protobuf(
const Odb::Lib::Protobuf::MatrixFile& message)
397 for (
const auto& stepRecord : message.steps())
399 auto pStepRecord = std::make_shared<StepRecord>();
400 pStepRecord->from_protobuf(stepRecord);
401 m_stepRecords.push_back(pStepRecord);
403 for (
const auto& layerRecord : message.layers())
405 auto pLayerRecord = std::make_shared<LayerRecord>();
406 pLayerRecord->from_protobuf(layerRecord);
407 m_layerRecords.push_back(pLayerRecord);
411 bool MatrixFile::Save(std::ostream& os)
413 for (
const auto& stepRecord : m_stepRecords)
415 os << StepRecord::RECORD_TOKEN <<
" " << Constants::ARRAY_RECORD_OPEN_TOKEN << std::endl;
417 os <<
'\t' << StepRecord::COLUMN_KEY <<
"=" << stepRecord->column << std::endl;
418 os <<
'\t' << StepRecord::NAME_KEY <<
"=" << stepRecord->name << std::endl;
419 os <<
'\t' << StepRecord::ID_KEY <<
"=" << stepRecord->id << std::endl;
421 os << Constants::ARRAY_RECORD_CLOSE_TOKEN << std::endl;
425 for (
const auto& layerRecord : m_layerRecords)
427 os << LayerRecord::RECORD_TOKEN <<
" " << Constants::ARRAY_RECORD_OPEN_TOKEN << std::endl;
429 os <<
'\t' << LayerRecord::ROW_KEY <<
"=" << layerRecord->row << std::endl;
430 os <<
'\t' << LayerRecord::CONTEXT_KEY <<
"=" << LayerRecord::contextMap.getValue(layerRecord->context) << std::endl;
431 os <<
'\t' << LayerRecord::TYPE_KEY <<
"=" << LayerRecord::typeMap.getValue(layerRecord->type) << std::endl;
432 os <<
'\t' << LayerRecord::NAME_KEY <<
"=" << layerRecord->name << std::endl;
433 os <<
'\t' << LayerRecord::POLARITY_KEY <<
"=" << LayerRecord::polarityMap.getValue(layerRecord->polarity) << std::endl;
434 os <<
'\t' << LayerRecord::FORM_KEY <<
"=" << LayerRecord::formMap.getValue(layerRecord->form) << std::endl;
435 os <<
'\t' << LayerRecord::DIELECTRIC_TYPE_KEY <<
"=" << LayerRecord::dielectricTypeMap.getValue(layerRecord->dielectricType) << std::endl;
436 os <<
'\t' << LayerRecord::DIELECTRIC_NAME_KEY <<
"=" << layerRecord->dielectricName << std::endl;
437 os <<
'\t' << LayerRecord::CU_TOP_KEY <<
"=";
438 if (layerRecord->cuTop != (
unsigned int)-1)
440 os << layerRecord->cuTop;
443 os <<
'\t' << LayerRecord::CU_BOTTOM_KEY <<
"=";
444 if (layerRecord->cuBottom != (
unsigned int)-1)
446 os << layerRecord->cuBottom;
449 os <<
'\t' << LayerRecord::REF_KEY <<
"=";
450 if (layerRecord->ref != (
unsigned int)-1)
452 os << layerRecord->ref;
455 os <<
'\t' << LayerRecord::START_NAME_KEY <<
"=" << layerRecord->startName << std::endl;
456 os <<
'\t' << LayerRecord::END_NAME_KEY <<
"=" << layerRecord->endName << std::endl;
457 os <<
'\t' << LayerRecord::OLD_NAME_KEY <<
"=" << layerRecord->oldName << std::endl;
458 os <<
'\t' << LayerRecord::ADD_TYPE_KEY <<
"=" << layerRecord->addType << std::endl;
459 os <<
'\t' << LayerRecord::COLOR_KEY <<
"=" << layerRecord->color.to_string() << std::endl;
460 os <<
'\t' << LayerRecord::ID_KEY <<
"=" << layerRecord->id << std::endl;
462 os << Constants::ARRAY_RECORD_CLOSE_TOKEN << std::endl;
469 std::unique_ptr<Odb::Lib::Protobuf::MatrixFile::StepRecord> Odb::Lib::FileModel::Design::MatrixFile::StepRecord::to_protobuf()
const
471 std::unique_ptr<Odb::Lib::Protobuf::MatrixFile::StepRecord> pStepRecordMessage(
new Odb::Lib::Protobuf::MatrixFile::StepRecord);
472 pStepRecordMessage->set_column(column);
473 pStepRecordMessage->set_name(name);
474 pStepRecordMessage->set_id(
id);
475 return pStepRecordMessage;
478 void Odb::Lib::FileModel::Design::MatrixFile::StepRecord::from_protobuf(
const Odb::Lib::Protobuf::MatrixFile::StepRecord& message)
480 column = message.column();
481 name = message.name();
485 std::unique_ptr<Odb::Lib::Protobuf::MatrixFile::LayerRecord> Odb::Lib::FileModel::Design::MatrixFile::LayerRecord::to_protobuf()
const
487 std::unique_ptr<Odb::Lib::Protobuf::MatrixFile::LayerRecord> pLayerRecordMessage(
new Odb::Lib::Protobuf::MatrixFile::LayerRecord);
488 pLayerRecordMessage->set_addtype(addType);
489 pLayerRecordMessage->set_context(
static_cast<Odb::Lib::Protobuf::MatrixFile::LayerRecord::Context
>(context));
490 pLayerRecordMessage->set_cubottom(cuBottom);
491 pLayerRecordMessage->set_cutop(cuTop);
492 pLayerRecordMessage->set_dielectricname(dielectricName);
493 pLayerRecordMessage->set_dielectrictype(
static_cast<Odb::Lib::Protobuf::MatrixFile::LayerRecord::DielectricType
>(dielectricType));
494 pLayerRecordMessage->set_endname(endName);
495 pLayerRecordMessage->set_form(
static_cast<Odb::Lib::Protobuf::MatrixFile::LayerRecord::Form
>(form));
496 pLayerRecordMessage->set_id(
id);
497 pLayerRecordMessage->set_name(name);
498 pLayerRecordMessage->set_oldname(oldName);
499 pLayerRecordMessage->set_polarity(
static_cast<Odb::Lib::Protobuf::Polarity
>(polarity));
500 pLayerRecordMessage->set_ref(ref);
501 pLayerRecordMessage->set_row(row);
502 pLayerRecordMessage->set_startname(startName);
503 pLayerRecordMessage->set_type(
static_cast<Odb::Lib::Protobuf::MatrixFile::LayerRecord::Type
>(type));
509 return pLayerRecordMessage;
512 void Odb::Lib::FileModel::Design::MatrixFile::LayerRecord::from_protobuf(
const Odb::Lib::Protobuf::MatrixFile::LayerRecord& message)
514 addType = message.addtype();
515 context =
static_cast<Context
>(message.context());
516 cuBottom = message.cubottom();
517 cuTop = message.cutop();
518 dielectricName = message.dielectricname();
519 dielectricType =
static_cast<DielectricType
>(message.dielectrictype());
520 endName = message.endname();
521 form =
static_cast<Form
>(message.form());
523 name = message.name();
524 oldName = message.oldname();
525 polarity =
static_cast<Polarity
>(message.polarity());
528 startName = message.startname();
529 type =
static_cast<Type
>(message.type());