OdbDesignLib
OdbDesign ODB++ Parsing Library
 
Loading...
Searching...
No Matches
MiscInfoFile.cpp
1#include "MiscInfoFile.h"
2#include "MiscInfoFile.h"
3//
4// Created by nmill on 10/13/2023.
5//
6
7#include <fstream>
8#include "MiscInfoFile.h"
9#include <string>
10#include <sstream>
11#include "str_utils.h"
12#include "../../Constants.h"
13#include "timestamp.h"
14#include "Logger.h"
15#include "../parse_error.h"
16#include "../invalid_odb_error.h"
17#include "../../Text/Utf8Sanitizer.h"
18
19using namespace std::chrono;
20
21namespace Odb::Lib::FileModel::Design
22{
23 bool MiscInfoFile::Parse(std::filesystem::path path)
24 {
25 std::ifstream infoFile;
26 int lineNumber = 0;
27 std::string line;
28
29 try
30 {
31 if (!OdbFile::Parse(path))
32 {
33 auto message = "\"misc\" directory does not exist: [" + path.string() + "]";
34 throw invalid_odb_error(message);
35 }
36
37 auto infoFilePath = path / "info";
38 if (!std::filesystem::exists(infoFilePath))
39 {
40 auto message = "misc/info file does not exist: [" + infoFilePath.string() + "]";
41 throw invalid_odb_error(message);
42 }
43
44 infoFile.open(infoFilePath, std::ios::in);
45 if (!infoFile.is_open())
46 {
47 auto message = "unable to open misc/info file: [" + infoFilePath.string() + "]";
48 throw invalid_odb_error(message);
49 }
50
51 while (std::getline(infoFile, line))
52 {
53 lineNumber++;
54
55 // trim whitespace from beginning and end of line
56 Utils::str_trim(line);
57 if (!line.empty())
58 {
59 std::stringstream lineStream(line);
60 if (line.find(Constants::COMMENT_TOKEN) == 0)
61 {
62 // comment line
63 }
64 else
65 {
66 // attribute line
67 std::string attribute;
68 std::string value;
69
70 if (!std::getline(lineStream, attribute, '=')) return false;
71 // attribute value may be blank?
72
73 if (!std::getline(lineStream, value))
74 {
75 if (!attributeValueIsOptional(attribute))
76 {
77 logwarn("misc/info file: no value for non-optional attribute: " + attribute);
78 }
79 }
80
81 Utils::str_trim(attribute);
82 Utils::str_trim(value);
83
84 if (attribute == "PRODUCT_MODEL_NAME" ||
85 attribute == "product_model_name")
86 {
87 m_productModelName = value;
88 }
89 else if (attribute == "JOB_NAME" ||
90 attribute == "job_name")
91 {
92 m_jobName = value;
93 }
94 else if (attribute == "odb_version_major" ||
95 attribute == "ODB_VERSION_MAJOR")
96 {
97 m_odbVersionMajor = value;
98 }
99 else if (attribute == "odb_version_minor" ||
100 attribute == "ODB_VERSION_MINOR")
101 {
102 m_odbVersionMinor = value;
103 }
104 else if (attribute == "odb_source" ||
105 attribute == "ODB_SOURCE")
106 {
107 m_odbSource = value;
108 }
109 else if (attribute == "creation_date" ||
110 attribute == "CREATION_DATE")
111 {
112 //std::istringstream iss(value);
114 //iss >> std::chrono::parse("%Y%m%d.%H%M%S", m_creationDateDate);
115 m_creationDateDate = Utils::parse_timestamp(value, "%Y%m%d.%H%M%S");
116
117#if defined(_DEBUG)
118
119 auto createdDate = Utils::make_timestamp(m_creationDateDate);
120 std::stringstream ss;
121 ss << "value: " << value << ", parsed createdDate: " << createdDate;
122 loginfo(ss.str());
123#endif // _DEBUG
124 }
125 else if (attribute == "save_date" ||
126 attribute == "SAVE_DATE")
127 {
129 //std::istringstream(value) >> std::chrono::parse("%Y%m%d.%H%M%S", m_saveDate);
130 m_saveDate = Utils::parse_timestamp(value, "%Y%m%d.%H%M%S");
131#if defined(_DEBUG)
132 auto saveDate = Utils::make_timestamp(m_saveDate);
133
134 std::stringstream ss;
135 ss << "value: " << value << ", parsed saveDate: " << saveDate;
136 loginfo(ss.str());
137#endif // _DEBUG
138 }
139 else if (attribute == "save_app" ||
140 attribute == "SAVE_APP")
141 {
142 m_saveApp = value;
143 }
144 else if (attribute == "save_user" ||
145 attribute == "SAVE_USER")
146 {
147 m_saveUser = value;
148 }
149 else if (attribute == "units" ||
150 attribute == "UNITS")
151 {
152 m_units = value;
153 }
154 else if (attribute == "max_uid" ||
155 attribute == "MAX_UID")
156 {
157 m_maxUniqueId = std::stoi(value);
158 }
159 else
160 {
161 // unknown attribute
162
163 // DO NOT fail parsing on unknown attributes- log instead
164 //return false;
165
166 parse_info pi(m_path, line, attribute, lineNumber);
167 logwarn(pi.toString("unrecognized line in misc/info file:"));
168 }
169 }
170 }
171 }
172
173 infoFile.close();
174 }
175 catch (invalid_odb_error& ioe)
176 {
177 parse_info pi(m_path, line, lineNumber);
178 const auto m = pi.toString();
179 logexception_msg(ioe, m);
180 // cleanup file
181 infoFile.close();
182 throw ioe;
183 }
184 catch (std::exception& e)
185 {
186 parse_info pi(m_path, line, lineNumber);
187 const auto m = pi.toString();
188 logexception_msg(e, m);
189 // cleanup file
190 infoFile.close();
191 throw e;
192 }
193
194 return true;
195 }
196
197 bool MiscInfoFile::Save(std::ostream& os)
198 {
199 os << PRODUCT_MODEL_NAME_KEY << "=" << m_productModelName << std::endl;
200 os << JOB_NAME_KEY << "=" << m_jobName << std::endl;
201 os << ODB_VERSION_MAJOR_KEY << "=" << m_odbVersionMajor << std::endl;
202 os << ODB_VERSION_MINOR_KEY << "=" << m_odbVersionMinor << std::endl;
203 os << ODB_SOURCE_KEY << "=" << m_odbSource << std::endl;
204 os << CREATION_DATE_KEY << "=" << Utils::make_timestamp(m_creationDateDate) << std::endl;
205 os << SAVE_DATE_KEY << "=" << Utils::make_timestamp(m_saveDate) << std::endl;
206 os << SAVE_APP_KEY << "=" << m_saveApp << std::endl;
207 os << SAVE_USER_KEY << "=" << m_saveUser << std::endl;
208 os << UNITS_KEY << "=" << m_units << std::endl;
209 os << MAX_UID_KEY << "=" << m_maxUniqueId << std::endl;
210
211 return true;
212 }
213
214 /*static*/ inline bool MiscInfoFile::attributeValueIsOptional(const std::string& attribute)
215 {
216 for (const auto& optionalAttribute : OPTIONAL_ATTRIBUTES)
217 {
218 if (attribute == optionalAttribute)
219 {
220 return true;
221 }
222 }
223 return false;
224 }
225
226 std::unique_ptr<Odb::Lib::Protobuf::MiscInfoFile> MiscInfoFile::to_protobuf() const
227 {
228 std::unique_ptr<Odb::Lib::Protobuf::MiscInfoFile> pMiscInfoFileMessage(new Odb::Lib::Protobuf::MiscInfoFile);
229 pMiscInfoFileMessage->set_jobname(Odb::Lib::Text::ToUtf8(m_jobName));
230 pMiscInfoFileMessage->set_productmodelname(Odb::Lib::Text::ToUtf8(m_productModelName));
231 pMiscInfoFileMessage->set_odbversionmajor(Odb::Lib::Text::ToUtf8(m_odbVersionMajor));
232 pMiscInfoFileMessage->set_odbversionminor(Odb::Lib::Text::ToUtf8(m_odbVersionMinor));
233 pMiscInfoFileMessage->set_odbsource(Odb::Lib::Text::ToUtf8(m_odbSource));
234 auto seconds = std::chrono::duration_cast<std::chrono::seconds>(m_creationDateDate.time_since_epoch()).count();
235 pMiscInfoFileMessage->mutable_creationdatedate()->set_seconds(seconds);
236 pMiscInfoFileMessage->mutable_creationdatedate()->set_nanos(0);
237 seconds = std::chrono::duration_cast<std::chrono::seconds>(m_saveDate.time_since_epoch()).count();
238 pMiscInfoFileMessage->mutable_savedate()->set_seconds(seconds);
239 pMiscInfoFileMessage->mutable_savedate()->set_nanos(0);
240 pMiscInfoFileMessage->set_saveapp(Odb::Lib::Text::ToUtf8(m_saveApp));
241 pMiscInfoFileMessage->set_saveuser(Odb::Lib::Text::ToUtf8(m_saveUser));
242 pMiscInfoFileMessage->set_units(Odb::Lib::Text::ToUtf8(m_units));
243 pMiscInfoFileMessage->set_maxuniqueid(m_maxUniqueId);
244 return pMiscInfoFileMessage;
245 }
246
247 void MiscInfoFile::from_protobuf(const Odb::Lib::Protobuf::MiscInfoFile& message)
248 {
249 m_jobName = message.jobname();
250 m_productModelName = message.productmodelname();
251 m_odbVersionMajor = message.odbversionmajor();
252 m_odbVersionMinor = message.odbversionminor();
253 m_odbSource = message.odbsource();
254 //m_creationDateDate = system_clock::from_time_t(message.creationdatedate().seconds());
255 m_creationDateDate = std::chrono::system_clock::time_point(std::chrono::seconds(message.creationdatedate().seconds()));
256 m_saveDate = std::chrono::system_clock::time_point(std::chrono::seconds(message.savedate().seconds()));
257 m_saveApp = message.saveapp();
258 m_saveUser = message.saveuser();
259 m_units = message.units();
260 m_maxUniqueId = message.maxuniqueid();
261 }
262
263 MiscInfoFile::MiscInfoFile()
264 : m_maxUniqueId((unsigned int)-1)
265 {
266 }
267
268 std::string MiscInfoFile::GetProductModelName() const
269 {
270 return m_productModelName;
271 }
272
273 std::string MiscInfoFile::GetJobName() const
274 {
275 return m_jobName;
276 }
277
278 std::string MiscInfoFile::GetOdbVersionMajor() const
279 {
280 return m_odbVersionMajor;
281 }
282
283 std::string MiscInfoFile::GetOdbVersionMinor() const
284 {
285 return m_odbVersionMinor;
286 }
287
288 std::string MiscInfoFile::GetOdbSource() const
289 {
290 return m_odbSource;
291 }
292
293 system_clock::time_point MiscInfoFile::GetCreationDate() const
294 {
295 return m_creationDateDate;
296 }
297
298 system_clock::time_point MiscInfoFile::GetSaveDate() const
299 {
300 return m_saveDate;
301 }
302
303 std::string MiscInfoFile::GetSaveApp() const
304 {
305 return m_saveApp;
306 }
307
308 std::string MiscInfoFile::GetSaveUser() const
309 {
310 return m_saveUser;
311 }
312
313 std::string MiscInfoFile::GetUnits() const
314 {
315 return m_units;
316 }
317
318 unsigned int MiscInfoFile::GetMaxUniqueId() const
319 {
320 return m_maxUniqueId;
321 }
322}