/* 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 #include #include #include #include #include namespace dwarfs { block_compressor::block_compressor(const std::string& spec) { impl_ = compression_registry::instance().make_compressor(spec); } block_decompressor::block_decompressor(compression_type type, const uint8_t* data, size_t size, std::vector& target) { impl_ = compression_registry::instance().make_decompressor( type, std::span(data, size), target); } compression_registry& compression_registry::instance() { static compression_registry the_instance; return the_instance; } void compression_registry::register_factory( compression_type type, std::unique_ptr&& factory) { auto name = factory->name(); if (!factories_.emplace(type, std::move(factory)).second) { std::cerr << "compression factory type conflict (" << name << ", " << static_cast(type) << ")\n"; ::abort(); } if (!names_.emplace(name, type).second) { std::cerr << "compression factory name conflict (" << name << ", " << static_cast(type) << ")\n"; ::abort(); } } std::unique_ptr compression_registry::make_compressor(std::string_view spec) const { option_map om(spec); auto nit = names_.find(om.choice()); if (nit == names_.end()) { DWARFS_THROW(runtime_error, "unknown compression: " + om.choice()); } auto fit = factories_.find(nit->second); assert(fit != factories_.end()); auto obj = fit->second->make_compressor(om); om.report(); return obj; } std::unique_ptr compression_registry::make_decompressor(compression_type type, std::span data, std::vector& target) const { auto fit = factories_.find(type); if (fit == factories_.end()) { DWARFS_THROW(runtime_error, "unsupported compression type: " + get_compression_name(type)); } return fit->second->make_decompressor(data, target); } void compression_registry::for_each_algorithm( std::function const& fn) const { auto types = factories_ | ranges::views::keys | ranges::to; ranges::sort(types); for (auto type : types) { fn(type, *factories_.at(type)); } } compression_registry::compression_registry() { using namespace ::dwarfs::detail; using enum compression_type; compression_factory_registrar::reg(*this); #ifdef DWARFS_HAVE_LIBBROTLI compression_factory_registrar::reg(*this); #endif #ifdef DWARFS_HAVE_FLAC compression_factory_registrar::reg(*this); #endif #ifdef DWARFS_HAVE_LIBLZ4 compression_factory_registrar::reg(*this); compression_factory_registrar::reg(*this); #endif #ifdef DWARFS_HAVE_LIBLZMA compression_factory_registrar::reg(*this); #endif #ifdef DWARFS_HAVE_RICEPP compression_factory_registrar::reg(*this); #endif #ifdef DWARFS_HAVE_LIBZSTD compression_factory_registrar::reg(*this); #endif } compression_registry::~compression_registry() = default; } // namespace dwarfs