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#include "../../Text/Utf8Sanitizer.h"
9
10
11namespace 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 bool StepDirectory::Save(const std::filesystem::path& directory)
176 {
177 auto stepDir = directory / m_name;
178 if (!create_directory(stepDir)) return false;
179
180 // eda/data
181 auto edaPath = stepDir / "eda";
182 if (!create_directory(edaPath)) return false;
183 std::ofstream edaDataFile(edaPath / "data");
184 if (!m_edaData.Save(edaDataFile)) return false;
185 edaDataFile.close();
186
187 // attrlist
188 std::ofstream attrlistFile(stepDir / "attrlist");
189 if (!m_attrListFile.Save(attrlistFile)) return false;
190 attrlistFile.close();
191
192 // profile
193 std::ofstream profileFile(stepDir / "profile");
194 if (!m_profileFile.Save(profileFile)) return false;
195 profileFile.close();
196
197 // StepHdrFile
198 std::ofstream stephdrFile(stepDir / "stephdr");
199 if (!m_stepHdrFile.Save(stephdrFile)) return false;
200 stephdrFile.close();
201
202 // layers
203 auto layersPath = stepDir / "layers";
204 if (!create_directory(layersPath)) return false;
205 for (auto& kvLayer : m_layersByName)
206 {
207 if (!kvLayer.second->Save(layersPath)) return false;
208 }
209
210 // m_netlistsByName;
211 auto netlistsPath = stepDir / "netlists";
212 if (!create_directory(netlistsPath)) return false;
213 for (auto& kvNetlist : m_netlistsByName)
214 {
215 if (!kvNetlist.second->Save(netlistsPath)) return false;
216 }
217
218 return true;
219 }
220
221 std::unique_ptr<Odb::Lib::Protobuf::StepDirectory> StepDirectory::to_protobuf() const
222 {
223 std::unique_ptr<Odb::Lib::Protobuf::StepDirectory> pStepDirectoryMessage(new Odb::Lib::Protobuf::StepDirectory);
224 pStepDirectoryMessage->set_name(Odb::Lib::Text::ToUtf8(m_name));
225 pStepDirectoryMessage->set_path(Odb::Lib::Text::ToUtf8(m_path.string()));
226 pStepDirectoryMessage->mutable_edadatafile()->CopyFrom(*m_edaData.to_protobuf());
227 pStepDirectoryMessage->mutable_attrlistfile()->CopyFrom(*m_attrListFile.to_protobuf());
228 pStepDirectoryMessage->mutable_profilefile()->CopyFrom(*m_profileFile.to_protobuf());
229 pStepDirectoryMessage->mutable_stephdrfile()->CopyFrom(*m_stepHdrFile.to_protobuf());
230
231 for (const auto& kvNetlistFile : m_netlistsByName)
232 {
233 (*pStepDirectoryMessage->mutable_netlistsbyname())[Odb::Lib::Text::ToUtf8(kvNetlistFile.first)] = *kvNetlistFile.second->to_protobuf();
234 }
235
236 for (const auto& kvLayerDirectoryRecord : m_layersByName)
237 {
238 (*pStepDirectoryMessage->mutable_layersbyname())[Odb::Lib::Text::ToUtf8(kvLayerDirectoryRecord.first)] = *kvLayerDirectoryRecord.second->to_protobuf();
239 }
240
241 return pStepDirectoryMessage;
242 }
243
244 void StepDirectory::from_protobuf(const Odb::Lib::Protobuf::StepDirectory& message)
245 {
246 m_name = message.name();
247 m_path = message.path();
248 m_edaData.from_protobuf(message.edadatafile());
249 m_attrListFile.from_protobuf(message.attrlistfile());
250 m_profileFile.from_protobuf(message.profilefile());
251 m_stepHdrFile.from_protobuf(message.stephdrfile());
252
253 for (const auto& kvNetlistFile : message.netlistsbyname())
254 {
255 auto pNetlistFile = std::make_shared<NetlistFile>(std::filesystem::path(kvNetlistFile.second.path()));
256 pNetlistFile->from_protobuf(kvNetlistFile.second);
257 m_netlistsByName[kvNetlistFile.first] = pNetlistFile;
258 }
259
260 for (const auto& kvLayerDirectoryRecord : message.layersbyname())
261 {
262 auto pLayerDirectory = std::make_shared<LayerDirectory>(std::filesystem::path(kvLayerDirectoryRecord.second.path()));
263 pLayerDirectory->from_protobuf(kvLayerDirectoryRecord.second);
264 m_layersByName[kvLayerDirectoryRecord.first] = pLayerDirectory;
265 }
266 }
267
268 bool StepDirectory::ParseNetlistFiles(std::filesystem::path netlistsPath)
269 {
270 loginfo("Parsing netlist files...");
271
272 std::size_t netListDirectoriesFound = 0;
273
274 if (std::filesystem::exists(netlistsPath))
275 {
276 if (std::filesystem::is_directory(netlistsPath))
277 {
278 // parse net name records
279 for (auto& d : std::filesystem::directory_iterator(netlistsPath))
280 {
281 if (std::filesystem::is_directory(d))
282 {
283 netListDirectoriesFound++;
284
285 auto pNetlist = std::make_shared<NetlistFile>(d.path());
286 if (pNetlist->Parse())
287 {
288 m_netlistsByName[pNetlist->GetName()] = pNetlist;
289 }
290 else
291 {
292 // pNetList will be freed when exiting the above scope
293 logerror("Failed to parse netlist directory: " + pNetlist->GetName());
294 }
295 }
296 }
297 }
298 }
299
300 if (netListDirectoriesFound == 0) // netlist dirs found, but none parsed successfully
301 {
302 logwarn("No netlist directories found");
303 }
304 else if (netListDirectoriesFound == m_netlistsByName.size())
305 {
306 loginfo("netlist directories parsed successfully");
307 }
308
309 return true;
310 }
311
312 const ComponentsFile* StepDirectory::GetTopComponentsFile() const
313 {
314 auto findIt = m_layersByName.find(ComponentsFile::TOP_COMPONENTS_LAYER_NAME);
315 if (findIt != m_layersByName.end())
316 {
317 return &(findIt->second->GetComponentsFile());
318 }
319 else
320 {
321 return nullptr;
322 }
323 }
324
325 const ComponentsFile* StepDirectory::GetBottomComponentsFile() const
326 {
327 auto findIt = m_layersByName.find(ComponentsFile::BOTTOM_COMPONENTS_LAYER_NAME);
328 if (findIt != m_layersByName.end())
329 {
330 return &(findIt->second->GetComponentsFile());
331 }
332 else
333 {
334 return nullptr;
335 }
336 }
337}