OdbDesignLib
OdbDesign ODB++ Parsing Library
StepDirectory.cpp
1 #include "StepDirectory.h"
2 #include "StepDirectory.h"
3 #include "StepDirectory.h"
4 #include <filesystem>
5 #include "LayerDirectory.h"
6 #include <fstream>
7 #include <sstream>
8 #include "Logger.h"
9 
10 
11 namespace Odb::Lib::FileModel::Design
12 {
13  StepDirectory::StepDirectory(std::filesystem::path path)
14  : m_path(path)
15  {
16  }
17 
18  StepDirectory::~StepDirectory()
19  {
20  m_layersByName.clear();
21  m_netlistsByName.clear();
22  }
23 
24  std::string StepDirectory::GetName()
25  {
26  return m_name;
27  }
28 
29  std::filesystem::path StepDirectory::GetPath()
30  {
31  return m_path;
32  }
33 
34  const EdaDataFile& StepDirectory::GetEdaDataFile() const { return m_edaData; }
35  const LayerDirectory::StringMap& StepDirectory::GetLayersByName() const { return m_layersByName; }
36  const NetlistFile::StringMap& StepDirectory::GetNetlistsByName() const { return m_netlistsByName; }
37 
38  const AttrListFile& StepDirectory::GetAttrListFile() const
39  {
40  return m_attrListFile;
41  }
42 
43  const FeaturesFile& StepDirectory::GetProfileFile() const
44  {
45  return m_profileFile;
46  }
47 
48  const StepHdrFile& StepDirectory::GetStepHdrFile() const
49  {
50  return m_stepHdrFile;
51  }
52 
53  bool StepDirectory::Parse()
54  {
55  if (!std::filesystem::exists(m_path)) return false;
56  else if (!std::filesystem::is_directory(m_path)) return false;
57 
58  m_name = std::filesystem::path(m_path).filename().string();
59 
60  loginfo("Parsing step directory: " + m_name + "...");
61 
62  auto layersPath = m_path / "layers";
63  if (!ParseLayerFiles(layersPath)) return false;
64 
65  auto netlistsPath = m_path / "netlists";
66  if (!ParseNetlistFiles(netlistsPath)) return false;
67 
68  auto edaPath = m_path / "eda";
69  if (!ParseEdaDataFiles(edaPath)) return false;
70 
71  auto attrListPath = m_path;
72  if (!ParseAttrListFile(attrListPath)) return false;
73 
74  auto profilePath = m_path;
75  if (!ParseProfileFile(profilePath)) return false;
76 
77  auto stepHdrPath = m_path;
78  if (!ParseStepHdrFile(stepHdrPath)) return false;
79 
80  loginfo("Parsing step directory: " + m_name + " complete");
81 
82  return true;
83  }
84 
85  bool StepDirectory::ParseLayerFiles(std::filesystem::path layersPath)
86  {
87  loginfo("Parsing layer directories...");
88 
89  if (!std::filesystem::exists(layersPath)) return false;
90  else if (!std::filesystem::is_directory(layersPath)) return false;
91 
92  for (auto& d : std::filesystem::directory_iterator(layersPath))
93  {
94  if (std::filesystem::is_directory(d))
95  {
96  auto pLayer = std::make_shared<LayerDirectory>(d.path());
97  if (pLayer->Parse())
98  {
99  loginfo("Parsing layer: " + pLayer->GetName() + " complete");
100 
101  m_layersByName[pLayer->GetName()] = pLayer;
102  }
103  else
104  {
105  return false;
106  }
107  }
108  }
109 
110  loginfo("Parsing layer directories complete");
111 
112  return true;
113  }
114 
115  bool StepDirectory::ParseEdaDataFiles(std::filesystem::path edaPath)
116  {
117  loginfo("Parsing eda/data file...");
118 
119  if (!std::filesystem::exists(edaPath)) return false;
120  else if (!std::filesystem::is_directory(edaPath)) return false;
121 
122  // parse nets and packages definitions
123  auto success = m_edaData.Parse(edaPath);
124 
125  loginfo("Parsing eda/data file complete");
126 
127  return success;
128  }
129 
130  bool StepDirectory::ParseAttrListFile(std::filesystem::path attrListFileDirectory)
131  {
132  loginfo("Parsing attrlist file...");
133 
134  if (!std::filesystem::exists(attrListFileDirectory)) return false;
135  if (!std::filesystem::is_directory(attrListFileDirectory)) return false;
136 
137  // parse nets and packages definitions
138  auto success = m_attrListFile.Parse(attrListFileDirectory);
139 
140  loginfo("Parsing attrlist file complete");
141 
142  return success;
143  }
144 
145  bool StepDirectory::ParseProfileFile(std::filesystem::path profileFileDirectory)
146  {
147  loginfo("Parsing profile file...");
148 
149  if (!std::filesystem::exists(profileFileDirectory)) return false;
150  if (!std::filesystem::is_directory(profileFileDirectory)) return false;
151 
152  // parse nets and packages definitions
153  auto success = m_profileFile.Parse(profileFileDirectory, PROFILE_FILENAME);
154 
155  loginfo("Parsing profile file complete");
156 
157  return success;
158  }
159 
160  bool StepDirectory::ParseStepHdrFile(std::filesystem::path stepHdrFileDirectory)
161  {
162  loginfo("Parsing stephdr file...");
163 
164  if (!std::filesystem::exists(stepHdrFileDirectory)) return false;
165  if (!std::filesystem::is_directory(stepHdrFileDirectory)) return false;
166 
167  // parse nets and packages definitions
168  auto success = m_stepHdrFile.Parse(stepHdrFileDirectory);
169 
170  loginfo("Parsing stephdr file complete");
171 
172  return success;
173  }
174 
175  std::unique_ptr<Odb::Lib::Protobuf::StepDirectory> StepDirectory::to_protobuf() const
176  {
177  std::unique_ptr<Odb::Lib::Protobuf::StepDirectory> pStepDirectoryMessage(new Odb::Lib::Protobuf::StepDirectory);
178  pStepDirectoryMessage->set_name(m_name);
179  pStepDirectoryMessage->set_path(m_path.string());
180  pStepDirectoryMessage->mutable_edadatafile()->CopyFrom(*m_edaData.to_protobuf());
181  pStepDirectoryMessage->mutable_attrlistfile()->CopyFrom(*m_attrListFile.to_protobuf());
182  pStepDirectoryMessage->mutable_profilefile()->CopyFrom(*m_profileFile.to_protobuf());
183  pStepDirectoryMessage->mutable_stephdrfile()->CopyFrom(*m_stepHdrFile.to_protobuf());
184 
185  for (const auto& kvNetlistFile : m_netlistsByName)
186  {
187  (*pStepDirectoryMessage->mutable_netlistsbyname())[kvNetlistFile.first] = *kvNetlistFile.second->to_protobuf();
188  }
189 
190  for (const auto& kvLayerDirectoryRecord : m_layersByName)
191  {
192  (*pStepDirectoryMessage->mutable_layersbyname())[kvLayerDirectoryRecord.first] = *kvLayerDirectoryRecord.second->to_protobuf();
193  }
194 
195  return pStepDirectoryMessage;
196  }
197 
198  void StepDirectory::from_protobuf(const Odb::Lib::Protobuf::StepDirectory& message)
199  {
200  m_name = message.name();
201  m_path = message.path();
202  m_edaData.from_protobuf(message.edadatafile());
203  m_attrListFile.from_protobuf(message.attrlistfile());
204  m_profileFile.from_protobuf(message.profilefile());
205  m_stepHdrFile.from_protobuf(message.stephdrfile());
206 
207  for (const auto& kvNetlistFile : message.netlistsbyname())
208  {
209  auto pNetlistFile = std::make_shared<NetlistFile>(std::filesystem::path(kvNetlistFile.second.path()));
210  pNetlistFile->from_protobuf(kvNetlistFile.second);
211  m_netlistsByName[kvNetlistFile.first] = pNetlistFile;
212  }
213 
214  for (const auto& kvLayerDirectoryRecord : message.layersbyname())
215  {
216  auto pLayerDirectory = std::make_shared<LayerDirectory>(std::filesystem::path(kvLayerDirectoryRecord.second.path()));
217  pLayerDirectory->from_protobuf(kvLayerDirectoryRecord.second);
218  m_layersByName[kvLayerDirectoryRecord.first] = pLayerDirectory;
219  }
220  }
221 
222  bool StepDirectory::ParseNetlistFiles(std::filesystem::path netlistsPath)
223  {
224  loginfo("Parsing netlist files...");
225 
226  std::size_t netListDirectoriesFound = 0;
227 
228  if (std::filesystem::exists(netlistsPath))
229  {
230  if (std::filesystem::is_directory(netlistsPath))
231  {
232  // parse net name records
233  for (auto& d : std::filesystem::directory_iterator(netlistsPath))
234  {
235  if (std::filesystem::is_directory(d))
236  {
237  netListDirectoriesFound++;
238 
239  auto pNetlist = std::make_shared<NetlistFile>(d.path());
240  if (pNetlist->Parse())
241  {
242  m_netlistsByName[pNetlist->GetName()] = pNetlist;
243  }
244  else
245  {
246  // pNetList will be freed when exiting the above scope
247  logerror("Failed to parse netlist directory: " + pNetlist->GetName());
248  }
249  }
250  }
251  }
252  }
253 
254  if (netListDirectoriesFound == 0) // netlist dirs found, but none parsed successfully
255  {
256  logwarn("No netlist directories found");
257  }
258  else if (netListDirectoriesFound == m_netlistsByName.size())
259  {
260  loginfo("netlist directories parsed successfully");
261  }
262 
263  return true;
264  }
265 
266  const ComponentsFile* StepDirectory::GetTopComponentsFile() const
267  {
268  auto findIt = m_layersByName.find(ComponentsFile::TOP_COMPONENTS_LAYER_NAME);
269  if (findIt != m_layersByName.end())
270  {
271  return &(findIt->second->GetComponentsFile());
272  }
273  else
274  {
275  return nullptr;
276  }
277  }
278 
279  const ComponentsFile* StepDirectory::GetBottomComponentsFile() const
280  {
281  auto findIt = m_layersByName.find(ComponentsFile::BOTTOM_COMPONENTS_LAYER_NAME);
282  if (findIt != m_layersByName.end())
283  {
284  return &(findIt->second->GetComponentsFile());
285  }
286  else
287  {
288  return nullptr;
289  }
290  }
291 }