OdbDesignLib
OdbDesign ODB++ Parsing Library
 
Loading...
Searching...
No Matches
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
10namespace 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}