Line data Source code
1 : /* Copyright (C) 2025 Robert Schiwon 2 : * 3 : * This file is part of libjdx. 4 : * 5 : * libjdx is free software: you can redistribute it and/or modify it under the 6 : * terms of the GNU Lesser General Public License as published by the Free 7 : * Software Foundation, either version 3 of the License, or (at your option) any 8 : * later version. 9 : * 10 : * libjdx is distributed in the hope that it will be useful, but WITHOUT ANY 11 : * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR 12 : * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 13 : * details. 14 : * 15 : * You should have received a copy of the GNU Lesser General Public License 16 : * along with libjdx. If not, see <https://www.gnu.org/licenses/>. 17 : */ 18 : #include "api/ConverterService.hpp" 19 : 20 : #include <stdexcept> 21 : #include <vector> 22 : 23 : #ifdef __EMSCRIPTEN__ 24 : #include <emscripten/bind.h> 25 : #endif 26 : 27 5 : libjdx::api::ConverterService::ConverterService( 28 5 : std::vector<std::shared_ptr<libjdx::api::Scanner>> scanners) 29 5 : : m_scanners{std::move(scanners)} 30 : { 31 5 : } 32 : 33 2 : bool libjdx::api::ConverterService::isRecognized(const std::string& path) 34 : { 35 : // for C++20 #include <algorithm> and do: 36 : // std::ranges::any_of(m_fileParsers, 37 : // [](auto const& scannerPtr) {scannerPtr->isRecognized(path)}); 38 : // for c++17, still do: 39 : // NOLINTNEXTLINE(readability-use-anyofallof) 40 4 : for (auto const& scannerPtr : m_scanners) 41 : { 42 3 : if (scannerPtr->isRecognized(path)) 43 : { 44 1 : return true; 45 : } 46 : } 47 1 : return false; 48 : } 49 : 50 : std::unique_ptr<libjdx::api::Converter> 51 3 : libjdx::api::ConverterService::getConverter(const std::string& path) 52 : { 53 6 : auto parseErrors = std::vector<std::string>{}; 54 : 55 8 : for (auto const& scannerPtr : m_scanners) 56 : { 57 6 : if (scannerPtr->isRecognized(path)) 58 : { 59 : try 60 : { 61 4 : auto converterPtr = scannerPtr->getConverter(path); 62 2 : return converterPtr; 63 : } 64 2 : catch (const std::exception& ex) 65 : { 66 2 : parseErrors.emplace_back(ex.what()); 67 : } 68 : } 69 : } 70 2 : if (parseErrors.empty()) 71 : { 72 : // no suitable converter was found 73 1 : throw std::runtime_error("No suitable converter found for: " + path); 74 : } 75 : // suitable converter(s) found but all threw exceptions while parsing 76 : // => collect exception messages and throw new umbrella exception 77 2 : std::string message{"Errors encountered while parsing: " + path + '\n'}; 78 1 : size_t i = 0; 79 3 : for (auto const& error : parseErrors) 80 : { 81 4 : message.append("Parser " + std::to_string(++i) + ": ") 82 2 : .append(error) 83 2 : .append("\n"); 84 : } 85 1 : throw std::runtime_error(message); 86 : } 87 : 88 : #ifdef __EMSCRIPTEN__ 89 : EMSCRIPTEN_BINDINGS(ConverterService) 90 : { 91 : using namespace libjdx::api; 92 : using namespace emscripten; 93 : class_<ConverterService, base<Scanner>>("ConverterService") 94 : .constructor<std::vector<std::shared_ptr<libjdx::api::Scanner>>>() 95 : .function("isRecognized", &ConverterService::isRecognized) 96 : .function("getConverter", &ConverterService::getConverter); 97 : register_vector<std::shared_ptr<libjdx::api::Scanner>>( 98 : "vector<std::shared_ptr<libjdx::api::Scanner>>"); 99 : } 100 : #endif