mirror of
https://github.com/mhx/dwarfs.git
synced 2025-09-12 22:10:54 -04:00
Add safety check for multi-fragment sequential categorizers
This commit is contained in:
parent
33b2dfb95f
commit
a9bf89aa0c
@ -49,6 +49,7 @@ class categorizer {
|
|||||||
virtual ~categorizer() = default;
|
virtual ~categorizer() = default;
|
||||||
|
|
||||||
virtual std::span<std::string_view const> categories() const = 0;
|
virtual std::span<std::string_view const> categories() const = 0;
|
||||||
|
virtual bool is_single_fragment() const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class random_access_categorizer : public categorizer {
|
class random_access_categorizer : public categorizer {
|
||||||
@ -98,6 +99,10 @@ class categorizer_job {
|
|||||||
|
|
||||||
explicit operator bool() const { return impl_ != nullptr; }
|
explicit operator bool() const { return impl_ != nullptr; }
|
||||||
|
|
||||||
|
bool has_multi_fragment_sequential_categorizers() const {
|
||||||
|
return impl_->has_multi_fragment_sequential_categorizers();
|
||||||
|
}
|
||||||
|
|
||||||
class impl {
|
class impl {
|
||||||
public:
|
public:
|
||||||
virtual ~impl() = default;
|
virtual ~impl() = default;
|
||||||
@ -106,6 +111,7 @@ class categorizer_job {
|
|||||||
virtual void categorize_random_access(std::span<uint8_t const> data) = 0;
|
virtual void categorize_random_access(std::span<uint8_t const> data) = 0;
|
||||||
virtual void categorize_sequential(std::span<uint8_t const> data) = 0;
|
virtual void categorize_sequential(std::span<uint8_t const> data) = 0;
|
||||||
virtual inode_fragments result() = 0;
|
virtual inode_fragments result() = 0;
|
||||||
|
virtual bool has_multi_fragment_sequential_categorizers() const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -49,6 +49,7 @@ class categorizer_manager_private : public categorizer_manager::impl {
|
|||||||
categorizers() const = 0;
|
categorizers() const = 0;
|
||||||
virtual fragment_category::value_type
|
virtual fragment_category::value_type
|
||||||
category(std::string_view cat) const = 0;
|
category(std::string_view cat) const = 0;
|
||||||
|
virtual bool has_multi_fragment_sequential_categorizers() const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename LoggerPolicy>
|
template <typename LoggerPolicy>
|
||||||
@ -66,6 +67,7 @@ class categorizer_job_ final : public categorizer_job::impl {
|
|||||||
void categorize_random_access(std::span<uint8_t const> data) override;
|
void categorize_random_access(std::span<uint8_t const> data) override;
|
||||||
void categorize_sequential(std::span<uint8_t const> data) override;
|
void categorize_sequential(std::span<uint8_t const> data) override;
|
||||||
inode_fragments result() override;
|
inode_fragments result() override;
|
||||||
|
bool has_multi_fragment_sequential_categorizers() const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
LOG_PROXY_DECL(LoggerPolicy);
|
LOG_PROXY_DECL(LoggerPolicy);
|
||||||
@ -158,6 +160,12 @@ inode_fragments categorizer_job_<LoggerPolicy>::result() {
|
|||||||
return best_;
|
return best_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename LoggerPolicy>
|
||||||
|
bool categorizer_job_<
|
||||||
|
LoggerPolicy>::has_multi_fragment_sequential_categorizers() const {
|
||||||
|
return mgr_.has_multi_fragment_sequential_categorizers();
|
||||||
|
}
|
||||||
|
|
||||||
categorizer_job::categorizer_job() = default;
|
categorizer_job::categorizer_job() = default;
|
||||||
|
|
||||||
categorizer_job::categorizer_job(std::unique_ptr<impl> impl)
|
categorizer_job::categorizer_job(std::unique_ptr<impl> impl)
|
||||||
@ -188,6 +196,10 @@ class categorizer_manager_ final : public categorizer_manager_private {
|
|||||||
return it->second;
|
return it->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool has_multi_fragment_sequential_categorizers() const override {
|
||||||
|
return has_multi_fragment_sequential_categorizers_;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void add_category(std::string_view cat) {
|
void add_category(std::string_view cat) {
|
||||||
if (catmap_.emplace(cat, categories_.size()).second) {
|
if (catmap_.emplace(cat, categories_.size()).second) {
|
||||||
@ -202,6 +214,7 @@ class categorizer_manager_ final : public categorizer_manager_private {
|
|||||||
std::vector<std::shared_ptr<categorizer const>> categorizers_;
|
std::vector<std::shared_ptr<categorizer const>> categorizers_;
|
||||||
std::vector<std::string_view> categories_;
|
std::vector<std::string_view> categories_;
|
||||||
std::unordered_map<std::string_view, fragment_category::value_type> catmap_;
|
std::unordered_map<std::string_view, fragment_category::value_type> catmap_;
|
||||||
|
bool has_multi_fragment_sequential_categorizers_{false};
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename LoggerPolicy>
|
template <typename LoggerPolicy>
|
||||||
@ -211,6 +224,11 @@ void categorizer_manager_<LoggerPolicy>::add(
|
|||||||
add_category(c);
|
add_category(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!c->is_single_fragment() &&
|
||||||
|
dynamic_cast<sequential_categorizer const*>(c.get())) {
|
||||||
|
has_multi_fragment_sequential_categorizers_ = true;
|
||||||
|
}
|
||||||
|
|
||||||
categorizers_.emplace_back(std::move(c));
|
categorizers_.emplace_back(std::move(c));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,6 +62,8 @@ class binary_categorizer_ final : public binary_categorizer_base {
|
|||||||
categorize(std::filesystem::path const& path, std::span<uint8_t const> data,
|
categorize(std::filesystem::path const& path, std::span<uint8_t const> data,
|
||||||
category_mapper const& mapper) const override;
|
category_mapper const& mapper) const override;
|
||||||
|
|
||||||
|
bool is_single_fragment() const override { return false; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
LOG_PROXY_DECL(LoggerPolicy);
|
LOG_PROXY_DECL(LoggerPolicy);
|
||||||
};
|
};
|
||||||
|
@ -156,6 +156,7 @@ class incompressible_categorizer_ final : public sequential_categorizer {
|
|||||||
std::unique_ptr<sequential_categorizer_job>
|
std::unique_ptr<sequential_categorizer_job>
|
||||||
job(std::filesystem::path const& path, size_t total_size,
|
job(std::filesystem::path const& path, size_t total_size,
|
||||||
category_mapper const& mapper) const override;
|
category_mapper const& mapper) const override;
|
||||||
|
bool is_single_fragment() const override { return true; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
logger& lgr_;
|
logger& lgr_;
|
||||||
|
@ -147,6 +147,8 @@ class libmagic_categorizer_ final : public libmagic_categorizer_base {
|
|||||||
categorize(std::filesystem::path const& path, std::span<uint8_t const> data,
|
categorize(std::filesystem::path const& path, std::span<uint8_t const> data,
|
||||||
category_mapper const& mapper) const override;
|
category_mapper const& mapper) const override;
|
||||||
|
|
||||||
|
bool is_single_fragment() const override { return true; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
LOG_PROXY_DECL(LoggerPolicy);
|
LOG_PROXY_DECL(LoggerPolicy);
|
||||||
magic_wrapper m_;
|
magic_wrapper m_;
|
||||||
|
@ -155,6 +155,10 @@ class inode_ : public inode {
|
|||||||
|
|
||||||
if (mm) {
|
if (mm) {
|
||||||
if (catjob) {
|
if (catjob) {
|
||||||
|
DWARFS_CHECK(
|
||||||
|
!catjob.has_multi_fragment_sequential_categorizers(),
|
||||||
|
"multi-fragment sequential categorizers are not supported");
|
||||||
|
|
||||||
catjob.set_total_size(mm->size());
|
catjob.set_total_size(mm->size());
|
||||||
catjob.categorize_random_access(mm->span());
|
catjob.categorize_random_access(mm->span());
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user