summaryrefslogtreecommitdiffstatshomepage
path: root/src/lib/formats/fsmeta.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/formats/fsmeta.cpp')
-rw-r--r--src/lib/formats/fsmeta.cpp131
1 files changed, 131 insertions, 0 deletions
diff --git a/src/lib/formats/fsmeta.cpp b/src/lib/formats/fsmeta.cpp
new file mode 100644
index 00000000000..f3e91e706a0
--- /dev/null
+++ b/src/lib/formats/fsmeta.cpp
@@ -0,0 +1,131 @@
+// license:BSD-3-Clause
+// copyright-holders:Olivier Galibert
+
+// Filesystem metadata management
+
+#include "fsmeta.h"
+
+#include "strformat.h"
+
+#include <optional>
+
+namespace fs {
+
+const char *meta_data::entry_name(meta_name name)
+{
+ switch(name) {
+ case meta_name::basic: return "basic";
+ case meta_name::creation_date: return "creation_date";
+ case meta_name::length: return "length";
+ case meta_name::loading_address: return "loading_address";
+ case meta_name::locked: return "locked";
+ case meta_name::modification_date: return "modification_date";
+ case meta_name::name: return "name";
+ case meta_name::os_minimum_version: return "os_minimum_version";
+ case meta_name::os_version: return "os_version";
+ case meta_name::rsrc_length: return "rsrc_length";
+ case meta_name::sequential: return "sequential";
+ case meta_name::size_in_blocks: return "size_in_blocks";
+ case meta_name::file_type: return "file_type";
+ case meta_name::ascii_flag: return "ascii_flag";
+ case meta_name::owner_id: return "owner_id";
+ case meta_name::attributes: return "attributes";
+ case meta_name::oem_name: return "oem_name";
+ }
+ return "";
+}
+
+std::optional<meta_name> meta_data::from_entry_name(const char *name)
+{
+ for (int i = 0; i <= (int)meta_name::max; i++)
+ {
+ if (!strcmp(name, entry_name((meta_name)i)))
+ return (meta_name)i;
+ }
+ return {};
+}
+
+template <class... Ts> struct overloaded : Ts... { using Ts::operator()...; };
+template <class... Ts> overloaded(Ts...) -> overloaded<Ts...>;
+
+meta_type meta_value::type() const
+{
+ std::optional<meta_type> result;
+ std::visit(
+ overloaded{
+ [&result] (const std::string &) { result = meta_type::string; },
+ [&result] (std::uint64_t) { result = meta_type::number; },
+ [&result] (bool) { result = meta_type::flag; },
+ [&result] (const util::arbitrary_datetime &) { result = meta_type::date; } },
+ value);
+ return *result;
+}
+
+util::arbitrary_datetime meta_value::as_date() const
+{
+ util::arbitrary_datetime result = { 0, };
+
+ std::visit(
+ overloaded
+ {
+ [&result](const std::string &s)
+ {
+ sscanf(s.c_str(), "%d-%d-%d %d:%d:%d", &result.year, &result.month, &result.day_of_month, &result.hour, &result.minute, &result.second);
+ },
+ [&result](const util::arbitrary_datetime &dt) { result = dt; },
+ [](std::uint64_t) { /* nonsensical */ },
+ [](bool) { /* nonsensical */ }
+ }, value);
+
+ return result;
+}
+
+bool meta_value::as_flag() const
+{
+ bool result = false;
+
+ std::visit(
+ overloaded
+ {
+ [&result](const std::string &s) { result = !s.empty() && s != "f"; },
+ [&result](bool b) { result = b; },
+ [](std::uint64_t) { /* nonsensical */ },
+ [](const util::arbitrary_datetime &) { /* nonsensical */ }
+ }, value);
+ return result;
+}
+
+std::string meta_value::as_string() const
+{
+ std::string result;
+ std::visit(
+ overloaded{
+ [&result] (const std::string &val) { result = val; },
+ [&result] (std::uint64_t val) { result = util::string_format("0x%x", val); },
+ [&result] (bool val) { result = val ? "t" : "f"; },
+ [&result] (const util::arbitrary_datetime &val)
+ {
+ result = util::string_format("%04d-%02d-%02d %02d:%02d:%02d",
+ val.year, val.month, val.day_of_month,
+ val.hour, val.minute, val.second);
+ } },
+ value);
+ return result;
+}
+
+uint64_t meta_value::as_number() const
+{
+ uint64_t result = 0;
+
+ std::visit(overloaded
+ {
+ [&result](const std::string &s) { result = std::stoull(s); },
+ [&result](uint64_t i) { result = i; },
+ [](const util::arbitrary_datetime &) { /* nonsensical */ },
+ [](bool) { /* nonsensical */ }
+ }, value);
+ return result;
+}
+
+
+} // namespace fs