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