1 #include "FileArchive.h"
3 #include "ArchiveExtractor.h"
4 #include "MiscInfoFile.h"
10 using namespace std::filesystem;
12 namespace Odb::Lib::FileModel::Design
15 FileArchive::FileArchive(std::string path)
20 FileArchive::~FileArchive()
22 m_stepsByName.clear();
23 m_symbolsDirectoriesByName.clear();
26 std::string FileArchive::GetRootDir()
const
31 std::string FileArchive::GetProductName()
const
36 std::string FileArchive::GetFilePath()
const
41 std::string FileArchive::GetFilename()
const
44 return path(m_filePath).filename().string();
47 const StepDirectory::StringMap& FileArchive::GetStepsByName()
const
52 const SymbolsDirectory::StringMap& FileArchive::GetSymbolsDirectoriesByName()
const
54 return m_symbolsDirectoriesByName;
57 bool FileArchive::ParseFileModel()
61 StopWatch timer(
true);
63 if (!exists(m_filePath))
return false;
65 if (is_regular_file(m_filePath))
67 std::filesystem::path extractedPath;
68 if (!ExtractDesignArchive(m_filePath, extractedPath))
70 logerror(
"failed to extract archive: (" + m_filePath +
")");
74 m_rootDir = findRootDir(extractedPath);
77 if (is_directory(m_rootDir))
79 loginfo(
"Parsing... ");
81 if (ParseDesignDirectory(m_rootDir))
84 auto s = timer.getElapsedSecondsString();
85 loginfo(
"Successfully parsed. (" + s +
"s)");
91 logerror(
"Parsing failed.");
92 throw std::runtime_error(
"Parsing failed.");
97 logerror(
"Failed to find root directory");
109 bool FileArchive::ExtractDesignArchive(
const std::filesystem::path& path, std::filesystem::path& extractedPath)
111 loginfo(
"Extracting... ");
113 if (!Utils::ArchiveExtractor::IsArchiveTypeSupported(path))
115 logerror(
"Unsupported archive type: (" + path.string() +
")");
119 Utils::ArchiveExtractor extractor(path.string());
120 if (!extractor.Extract())
return false;
122 auto extracted = std::filesystem::path(extractor.GetExtractionDirectory());
123 if (!exists(extracted))
return false;
125 extractedPath = extracted;
127 loginfo(
"Successfully extracted.");
133 std::string FileArchive::findRootDir(
const path& extractedPath)
135 if (pathContainsTopLevelDesignDirs(extractedPath))
137 return extractedPath.string();
141 for (
const auto& p : directory_iterator(extractedPath))
145 if (pathContainsTopLevelDesignDirs(p.path()))
147 return p.path().string();
156 bool FileArchive::pathContainsTopLevelDesignDirs(
const std::filesystem::path& path)
158 for (
const auto& topLevelRootDirName : TOPLEVEL_DESIGN_DIR_NAMES)
160 auto rootLevelDirPath = path / topLevelRootDirName;
161 if (!exists(rootLevelDirPath))
return false;
166 std::unique_ptr<Odb::Lib::Protobuf::FileArchive> FileArchive::to_protobuf()
const
168 std::unique_ptr<Odb::Lib::Protobuf::FileArchive> pFileArchiveMessage(
new Odb::Lib::Protobuf::FileArchive);
169 pFileArchiveMessage->set_productname(m_productName);
170 pFileArchiveMessage->set_filename(m_filename);
171 pFileArchiveMessage->mutable_matrixfile()->CopyFrom(*m_matrixFile.to_protobuf());
172 pFileArchiveMessage->mutable_miscinfofile()->CopyFrom(*m_miscInfoFile.to_protobuf());
173 pFileArchiveMessage->mutable_standardfontsfile()->CopyFrom(*m_standardFontsFile.to_protobuf());
174 pFileArchiveMessage->mutable_miscattrlistfile()->CopyFrom(*m_miscAttrListFile.to_protobuf());
176 for (
const auto& kvStepDirectoryRecord : m_stepsByName)
178 (*pFileArchiveMessage->mutable_stepsbyname())[kvStepDirectoryRecord.first] = *kvStepDirectoryRecord.second->to_protobuf();
181 for (
const auto& kvSymbolsDirectory : m_symbolsDirectoriesByName)
183 (*pFileArchiveMessage->mutable_symbolsdirectoriesbyname())[kvSymbolsDirectory.first] = *kvSymbolsDirectory.second->to_protobuf();
186 return pFileArchiveMessage;
189 void FileArchive::from_protobuf(
const Odb::Lib::Protobuf::FileArchive& message)
191 m_productName = message.productname();
192 m_filename = message.filename();
193 m_matrixFile.from_protobuf(message.matrixfile());
194 m_miscInfoFile.from_protobuf(message.miscinfofile());
195 m_standardFontsFile.from_protobuf(message.standardfontsfile());
196 m_miscAttrListFile.from_protobuf(message.miscattrlistfile());
198 for (
const auto& kvStepDirectoryRecord : message.stepsbyname())
200 auto pStepDirectory = std::make_shared<StepDirectory>(
"");
201 pStepDirectory->from_protobuf(kvStepDirectoryRecord.second);
202 m_stepsByName[kvStepDirectoryRecord.first] = pStepDirectory;
205 for (
const auto& kvSymbolsDirectory : message.symbolsdirectoriesbyname())
207 auto pSymbolsDirectory = std::make_shared<SymbolsDirectory>(
"");
208 pSymbolsDirectory->from_protobuf(kvSymbolsDirectory.second);
209 m_symbolsDirectoriesByName[kvSymbolsDirectory.first] = pSymbolsDirectory;
213 bool FileArchive::ParseDesignDirectory(
const std::filesystem::path& path)
215 if (!exists(path))
return false;
216 else if (!is_directory(path))
return false;
218 m_productName = path.stem().string();
220 if (! ParseStepDirectories(path))
return false;
221 if (! ParseMiscInfoFile(path))
return false;
222 if (! ParseMatrixFile(path))
return false;
223 if (! ParseStandardFontsFile(path))
return false;
224 if (! ParseSymbolsDirectories(path))
return false;
225 if (! ParseMiscAttrListFile(path))
return false;
230 bool FileArchive::ParseStepDirectories(
const std::filesystem::path& path)
232 loginfo(
"Parsing steps...");
234 auto stepsPath = path /
"steps";
235 for (
auto& d : directory_iterator(stepsPath))
239 auto pStep = std::make_shared<StepDirectory>(d.path());
242 m_stepsByName[pStep->GetName()] = pStep;
246 logwarn(
"Failed to parse step: " + pStep->GetName());
252 loginfo(
"Parsing steps complete");
257 bool FileArchive::ParseMiscInfoFile(
const path& path)
259 loginfo(
"Parsing misc/info file...");
261 auto miscDirectory = path /
"misc";
262 if (!exists(miscDirectory))
return false;
263 if (!is_directory(miscDirectory))
return false;
265 if (!m_miscInfoFile.Parse(miscDirectory))
return false;
267 loginfo(
"Parsing misc/info file complete");
272 bool FileArchive::ParseMiscAttrListFile(
const std::filesystem::path& path)
274 loginfo(
"Parsing misc/attrlist file...");
276 auto miscDirectory = path /
"misc";
277 if (!exists(miscDirectory))
return false;
278 if (!is_directory(miscDirectory))
return false;
280 if (!m_miscAttrListFile.Parse(miscDirectory))
return false;
282 loginfo(
"Parsing misc/attrlist file complete");
287 bool FileArchive::ParseMatrixFile(
const std::filesystem::path& path)
289 loginfo(
"Parsing matrix/matrix file...");
291 auto matrixDir = path /
"matrix";
292 if (!exists(matrixDir))
return false;
293 if (!is_directory(matrixDir))
return false;
295 if (!m_matrixFile.Parse(matrixDir))
return false;
297 loginfo(
"Parsing matrix/matrix file complete");
301 bool FileArchive::ParseStandardFontsFile(
const std::filesystem::path& path)
303 loginfo(
"Parsing fonts/standard file...");
305 auto fontsDir = path /
"fonts";
306 if (!exists(fontsDir))
return false;
307 if (!is_directory(fontsDir))
return false;
309 if (!m_standardFontsFile.Parse(fontsDir))
return false;
311 loginfo(
"Parsing fonts/standard file complete");
316 bool FileArchive::ParseSymbolsDirectories(
const std::filesystem::path& path)
318 loginfo(
"Parsing symbols root directory...");
320 auto symbolsDirectory = path /
"symbols";
322 if (!std::filesystem::exists(symbolsDirectory))
324 logwarn(
"symbols root directory does not exist (" + symbolsDirectory.string() +
")");
327 else if (!std::filesystem::is_directory(symbolsDirectory))
329 logerror(
"symbols root directory exists but is a regular file/not a directory (" + symbolsDirectory.string() +
")");
333 for (
auto& d : std::filesystem::directory_iterator(symbolsDirectory))
335 if (std::filesystem::is_directory(d))
337 auto pSymbolsDirectory = std::make_shared<SymbolsDirectory>(d.path());
338 if (pSymbolsDirectory->Parse())
342 m_symbolsDirectoriesByName[pSymbolsDirectory->GetName()] = pSymbolsDirectory;
346 logerror(
"Parsing symbol directory: " + pSymbolsDirectory->GetName() +
" failed");
352 loginfo(
"Parsing symbols root directory complete");
357 const MiscInfoFile &FileArchive::GetMiscInfoFile()
const
359 return m_miscInfoFile;
362 const MatrixFile& FileArchive::GetMatrixFile()
const
367 const StandardFontsFile& FileArchive::GetStandardFontsFile()
const
369 return m_standardFontsFile;
372 const AttrListFile& FileArchive::GetMiscAttrListFile()
const
374 return m_miscAttrListFile;
377 std::shared_ptr<StepDirectory> FileArchive::GetStepDirectory(
const std::string& stepName )
const
379 std::shared_ptr<FileModel::Design::StepDirectory> pStepDirectory;
381 const auto& steps = GetStepsByName();
384 if (stepName.empty())
387 pStepDirectory = steps.begin()->second;
391 auto findIt = steps.find(stepName);
392 if (findIt != steps.end())
394 pStepDirectory = findIt->second;
399 return pStepDirectory;