/* vim:set ts=2 sw=2 sts=2 et: */ /** * \author Marcus Holland-Moritz (github@mhxnet.de) * \copyright Copyright (c) Marcus Holland-Moritz * * This file is part of dwarfs. * * dwarfs is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * dwarfs is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with dwarfs. If not, see . */ #include #include #include #include #include #include #include namespace dwarfs::reader { namespace { constexpr std::array level_features{ /* 0 */ fsinfo_features(), /* 1 */ fsinfo_features( {fsinfo_feature::version, fsinfo_feature::metadata_summary}), /* 2 */ fsinfo_features({fsinfo_feature::frozen_analysis, fsinfo_feature::history}), /* 3 */ fsinfo_features( {fsinfo_feature::metadata_details, fsinfo_feature::section_details}), /* 4 */ fsinfo_features( {fsinfo_feature::directory_tree, fsinfo_feature::frozen_layout}), /* 5 */ fsinfo_features({fsinfo_feature::chunk_details}), /* 6 */ fsinfo_features({fsinfo_feature::metadata_full_dump}), }; constexpr std::array, static_cast(fsinfo_feature::num_fsinfo_feature_bits)> fsinfo_feature_names{{ #define FSINFO_FEATURE_PAIR_(f) {fsinfo_feature::f, #f} FSINFO_FEATURE_PAIR_(version), FSINFO_FEATURE_PAIR_(history), FSINFO_FEATURE_PAIR_(metadata_summary), FSINFO_FEATURE_PAIR_(metadata_details), FSINFO_FEATURE_PAIR_(metadata_full_dump), FSINFO_FEATURE_PAIR_(frozen_analysis), FSINFO_FEATURE_PAIR_(frozen_layout), FSINFO_FEATURE_PAIR_(directory_tree), FSINFO_FEATURE_PAIR_(section_details), FSINFO_FEATURE_PAIR_(chunk_details), #undef FSINFO_FEATURE_PAIR_ }}; constexpr bool fsinfo_feature_names_in_order() { for (size_t i = 0; i < fsinfo_feature_names.size(); ++i) { if (fsinfo_feature_names[i].first != static_cast(i)) { return false; } } return true; } static_assert(fsinfo_feature_names_in_order()); } // namespace int fsinfo_features::max_level() { return static_cast(level_features.size()) - 1; } fsinfo_features fsinfo_features::for_level(int level) { fsinfo_features features; level = std::min(level, level_features.size() - 1); for (int i = 0; i <= level; ++i) { features |= level_features[i]; } return features; } fsinfo_features fsinfo_features::parse(std::string_view features) { fsinfo_features result; for (auto const& f : split_view(features, ',')) { auto const it = std::find_if(fsinfo_feature_names.begin(), fsinfo_feature_names.end(), [&f](auto const& p) { return f == p.second; }); if (it == fsinfo_feature_names.end()) { DWARFS_THROW(runtime_error, fmt::format("invalid feature: \"{}\"", f)); } result |= it->first; } return result; } std::string fsinfo_features::to_string() const { std::string result; for (size_t bit = 0; bit < num_feature_bits; ++bit) { if (has(static_cast(bit))) { if (!result.empty()) { result += ','; } result += fsinfo_feature_names[bit].second; } } return result; } std::vector fsinfo_features::to_string_views() const { std::vector result; for (size_t bit = 0; bit < num_feature_bits; ++bit) { if (has(static_cast(bit))) { result.push_back(fsinfo_feature_names[bit].second); } } return result; } } // namespace dwarfs::reader