diff options
| author | Dan Goodliffe <dan@randomdan.homeip.net> | 2025-06-13 23:12:32 +0100 | 
|---|---|---|
| committer | Dan Goodliffe <dan@randomdan.homeip.net> | 2025-06-13 23:12:32 +0100 | 
| commit | 1af14f1087fc38bba1f1110316aa58fcab35c1d9 (patch) | |
| tree | f4a4bc8548a50cf1eba6bbc98a4109d6984e6403 | |
| parent | Fix compilation with gcc-15 (diff) | |
| download | icespider-1af14f1087fc38bba1f1110316aa58fcab35c1d9.tar.bz2 icespider-1af14f1087fc38bba1f1110316aa58fcab35c1d9.tar.xz icespider-1af14f1087fc38bba1f1110316aa58fcab35c1d9.zip | |
Update to C++23 and fix lots of warnings
40 files changed, 1041 insertions, 999 deletions
| diff --git a/Jamroot.jam b/Jamroot.jam index 84c2b18..5a29d9a 100644 --- a/Jamroot.jam +++ b/Jamroot.jam @@ -9,7 +9,7 @@ variant coverage : debug ;  project icespider : requirements  			<define>ICE_CPP11_MAPPING -			<cxxstd>20 +			<cxxstd>23  			<visibility>hidden  			<linkflags>"-Wl,-z,defs,--warn-once,--gc-sections"  			<variant>release:<lto>on diff --git a/icespider/common/formatters.cpp b/icespider/common/formatters.cpp deleted file mode 100644 index 6bf31c0..0000000 --- a/icespider/common/formatters.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "formatters.h" diff --git a/icespider/common/maybeString.cpp b/icespider/common/maybeString.cpp deleted file mode 100644 index 8dab2cc..0000000 --- a/icespider/common/maybeString.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "maybeString.h" diff --git a/icespider/common/maybeString.h b/icespider/common/maybeString.h index 50928f5..b76da2f 100644 --- a/icespider/common/maybeString.h +++ b/icespider/common/maybeString.h @@ -1,10 +1,8 @@  #pragma once -#include <compare>  #include <iosfwd>  #include <string>  #include <string_view> -#include <type_traits>  #include <utility>  #include <variant> @@ -14,54 +12,54 @@ namespace IceSpider {  		MaybeString() = default;  		// cppcheck-suppress noExplicitConstructor; NOLINTNEXTLINE(hicpp-explicit-conversions) -		inline MaybeString(std::string s) : value_ {std::move(s)} { } +		MaybeString(std::string str) : valueContainer {std::move(str)} { }  		// cppcheck-suppress noExplicitConstructor; NOLINTNEXTLINE(hicpp-explicit-conversions) -		inline MaybeString(std::string_view s) : value_ {s} { } +		MaybeString(std::string_view str) : valueContainer {str} { }  		// NOLINTNEXTLINE(hicpp-explicit-conversions) -		[[nodiscard]] inline operator std::string_view() const +		[[nodiscard]] operator std::string_view() const  		{ -			if (value_.index() == 0) { -				return std::get<0>(value_); +			if (valueContainer.index() == 0) { +				return std::get<0>(valueContainer);  			} -			return std::get<1>(value_); +			return std::get<1>(valueContainer);  		} -		[[nodiscard]] inline std::string_view +		[[nodiscard]] std::string_view  		value() const  		{  			return *this;  		} -		[[nodiscard]] inline bool +		[[nodiscard]] bool  		isString() const  		{ -			return value_.index() > 0; +			return valueContainer.index() > 0;  		} -		[[nodiscard]] inline bool -		operator<(const MaybeString & o) const +		[[nodiscard]] bool +		operator<(const MaybeString & other) const  		{ -			return value() < o.value(); +			return value() < other.value();  		} -		[[nodiscard]] inline bool -		operator<(const std::string_view o) const +		[[nodiscard]] bool +		operator<(const std::string_view other) const  		{ -			return value() < o; +			return value() < other;  		}  	private: -		using value_type = std::variant<std::string_view, std::string>; -		value_type value_; +		using ValueType = std::variant<std::string_view, std::string>; +		ValueType valueContainer;  	};  };  namespace std {  	inline std::ostream & -	operator<<(std::ostream & s, const IceSpider::MaybeString & ms) +	operator<<(std::ostream & strm, const IceSpider::MaybeString & value)  	{ -		return s << ms.value(); +		return strm << value.value();  	}  } diff --git a/icespider/common/pathparts.cpp b/icespider/common/pathparts.cpp index cebfde0..feeab1c 100644 --- a/icespider/common/pathparts.cpp +++ b/icespider/common/pathparts.cpp @@ -2,26 +2,25 @@  #include <boost/algorithm/string/compare.hpp>  #include <boost/algorithm/string/find_iterator.hpp>  #include <boost/algorithm/string/finder.hpp> -#include <string>  namespace ba = boost::algorithm;  namespace IceSpider { -	const auto slash = ba::first_finder("/", ba::is_equal()); +	const auto SLASH = ba::first_finder("/", ba::is_equal()); -	Path::Path(const std::string_view p) : path(p) +	Path::Path(const std::string_view path) : path(path)  	{ -		auto relp = p.substr(1); +		auto relp = path.substr(1);  		if (relp.empty()) {  			return;  		} -		for (auto pi = ba::make_split_iterator(relp, slash); pi != decltype(pi)(); ++pi) { -			std::string_view pp {pi->begin(), pi->end()}; -			if (pp.front() == '{' && pp.back() == '}') { -				parts.push_back(std::make_unique<PathParameter>(pp)); +		for (auto pi = ba::make_split_iterator(relp, SLASH); pi != decltype(pi)(); ++pi) { +			std::string_view pathPart {pi->begin(), pi->end()}; +			if (pathPart.front() == '{' && pathPart.back() == '}') { +				parts.push_back(std::make_unique<PathParameter>(pathPart));  			}  			else { -				parts.push_back(std::make_unique<PathLiteral>(pp)); +				parts.push_back(std::make_unique<PathLiteral>(pathPart));  			}  		}  	} @@ -43,15 +42,15 @@ namespace IceSpider {  				== pathparts.end();  	} -	PathLiteral::PathLiteral(const std::string_view p) : value(p) { } +	PathLiteral::PathLiteral(const std::string_view value) : value(value) { }  	bool -	PathLiteral::matches(const std::string_view v) const +	PathLiteral::matches(const std::string_view candidate) const  	{ -		return value == v; +		return value == candidate;  	} -	PathParameter::PathParameter(const std::string_view s) : name(s.substr(1, s.length() - 2)) { } +	PathParameter::PathParameter(const std::string_view fmt) : name(fmt.substr(1, fmt.length() - 2)) { }  	bool  	PathParameter::matches(const std::string_view) const diff --git a/icespider/common/pathparts.h b/icespider/common/pathparts.h index e972a6f..76491a3 100644 --- a/icespider/common/pathparts.h +++ b/icespider/common/pathparts.h @@ -16,25 +16,25 @@ namespace IceSpider {  		virtual ~PathPart() = default;  		SPECIAL_MEMBERS_DEFAULT(PathPart); -		[[nodiscard]] virtual bool matches(const std::string_view) const = 0; +		[[nodiscard]] virtual bool matches(std::string_view) const = 0;  	};  	using PathPartPtr = std::unique_ptr<PathPart>;  	class DLL_PUBLIC PathLiteral : public PathPart {  	public: -		explicit PathLiteral(const std::string_view v); +		explicit PathLiteral(std::string_view value); -		[[nodiscard]] bool matches(const std::string_view) const override; +		[[nodiscard]] bool matches(std::string_view) const override;  		const std::string_view value;  	};  	class DLL_PUBLIC PathParameter : public PathPart {  	public: -		explicit PathParameter(const std::string_view); +		explicit PathParameter(std::string_view fmt); -		[[nodiscard]] bool matches(const std::string_view) const override; +		[[nodiscard]] bool matches(std::string_view) const override;  		const std::string_view name;  	}; @@ -43,7 +43,7 @@ namespace IceSpider {  	public:  		using PathParts = std::vector<PathPartPtr>; -		explicit Path(const std::string_view); +		explicit Path(std::string_view path);  		std::string_view path; diff --git a/icespider/compile/main.cpp b/icespider/compile/main.cpp index fa679f9..848c2a2 100644 --- a/icespider/compile/main.cpp +++ b/icespider/compile/main.cpp @@ -9,6 +9,7 @@  #include <cstdlib>  #include <filesystem>  #include <iostream> +#include <ranges>  #include <string>  #include <string_view>  #include <utility> @@ -21,14 +22,13 @@ namespace {  	std::string  	defaultPostProcessor()  	{ -		constexpr std::array<const std::pair<std::string_view, std::string_view>, 1> pps {{ +		constexpr std::array<const std::pair<std::string_view, std::string_view>, 1> POST_PROCESSORS {{  				{"clang-format", "-i"},  		}}; -		const std::string_view path {getenv("PATH") ?: "/usr/bin"}; -		const auto pathBegin = make_split_iterator(path, first_finder(":", boost::is_equal())); -		for (const auto & [cmd, opts] : pps) { -			for (auto p = pathBegin; p != decltype(pathBegin) {}; ++p) { -				if (std::filesystem::exists(std::filesystem::path(p->begin(), p->end()) / cmd)) { +		const std::string_view pathEnv {getenv("PATH") ?: "/usr/bin"}; +		for (const auto & [cmd, opts] : POST_PROCESSORS) { +			for (const auto & path : std::ranges::split_view(pathEnv, ':')) { +				if (std::filesystem::exists(std::filesystem::path(path.begin(), path.end()) / cmd)) {  					return "%? %?"_fmt(cmd, opts);  				}  			} @@ -38,10 +38,10 @@ namespace {  }  int -main(int c, char ** v) +main(int argc, char ** argv)  {  	bool showHelp = false; -	IceSpider::Compile::RouteCompiler rc; +	IceSpider::Compile::RouteCompiler routeCompiler;  	std::filesystem::path input, output;  	std::string post;  	po::options_description opts("IceSpider compile options"); @@ -49,26 +49,26 @@ main(int c, char ** v)  	opts.add_options()  		("input", po::value(&input), "Input .json file")  		("output", po::value(&output), "Output .cpp file") -		("include,I", po::value(&rc.searchPath)->composing(), "Search path") +		("include,I", po::value(&routeCompiler.searchPath)->composing(), "Search path")  		("post,p", po::value(&post)->default_value(defaultPostProcessor()), "Post-process command")  		("help,h", po::value(&showHelp)->default_value(false)->zero_tokens(), "Help")  		;  	// clang-format on  	po::positional_options_description pod;  	pod.add("input", 1).add("output", 2); -	po::variables_map vm; -	po::store(po::command_line_parser(c, v).options(opts).positional(pod).run(), vm); -	po::notify(vm); +	po::variables_map varMap; +	po::store(po::command_line_parser(argc, argv).options(opts).positional(pod).run(), varMap); +	po::notify(varMap);  	if (showHelp || input.empty() || output.empty()) {  		// LCOV_EXCL_START -		std::cout << opts << std::endl; +		std::cout << opts << '\n';  		return 1;  		// LCOV_EXCL_STOP  	} -	rc.searchPath.push_back(input.parent_path()); -	rc.compile(input, output); +	routeCompiler.searchPath.push_back(input.parent_path()); +	routeCompiler.compile(input, output);  	if (!post.empty()) {  		auto outputh = std::filesystem::path {output}.replace_extension(".h"); diff --git a/icespider/compile/routeCompiler.cpp b/icespider/compile/routeCompiler.cpp index cc8a960..564d067 100644 --- a/icespider/compile/routeCompiler.cpp +++ b/icespider/compile/routeCompiler.cpp @@ -15,7 +15,6 @@  #include <fprintbf.h>  #include <http.h>  #include <initializer_list> -#include <list>  #include <memory>  #include <pathparts.h>  #include <scopeExit.h> @@ -27,6 +26,15 @@  #include <utility>  namespace IceSpider::Compile { +	namespace { +		Ice::StringSeq +		operator+(Ice::StringSeq target, std::string value) +		{ +			target.emplace_back(std::move(value)); +			return target; +		} +	} +  	using namespace AdHoc::literals;  	RouteCompiler::RouteCompiler() @@ -35,35 +43,29 @@ namespace IceSpider::Compile {  	}  	RouteConfigurationPtr -	RouteCompiler::loadConfiguration(const std::filesystem::path & input) const +	RouteCompiler::loadConfiguration(const std::filesystem::path & input)  	{  		auto deserializer = Slicer::DeserializerPtr(  				Slicer::FileDeserializerFactory::createNew(input.extension().string(), input));  		return Slicer::DeserializeAnyWith<RouteConfigurationPtr>(deserializer);  	} -	Ice::StringSeq -	operator+(Ice::StringSeq ss, const std::string & s) -	{ -		ss.push_back(s); -		return ss; -	} -  	Slice::OperationPtr  	// NOLINTNEXTLINE(misc-no-recursion) -	RouteCompiler::findOperation(const std::string & on, const Slice::ContainerPtr & c, const Ice::StringSeq & ns) +	RouteCompiler::findOperation( +			const std::string & operationName, const Slice::ContainerPtr & container, const Ice::StringSeq & nameSpace)  	{ -		for (const auto & cls : c->classes()) { -			auto fqcn = ns + cls->name(); -			for (const auto & op : cls->allOperations()) { -				if (boost::algorithm::join(fqcn + op->name(), ".") == on) { -					return op; +		for (const auto & cls : container->classes()) { +			auto fqcn = nameSpace + cls->name(); +			for (const auto & operation : cls->allOperations()) { +				if (boost::algorithm::join(fqcn + operation->name(), ".") == operationName) { +					return operation;  				}  			}  		} -		for (const auto & m : c->modules()) { -			if (auto op = findOperation(on, m, ns + m->name())) { -				return op; +		for (const auto & module : container->modules()) { +			if (auto operation = findOperation(operationName, module, nameSpace + module->name())) { +				return operation;  			}  		}  		return nullptr; @@ -71,109 +73,116 @@ namespace IceSpider::Compile {  	Slice::OperationPtr  	// NOLINTNEXTLINE(misc-no-recursion) -	RouteCompiler::findOperation(const std::string & on, const Units & us) +	RouteCompiler::findOperation(const std::string & operationName, const Units & units)  	{ -		for (const auto & u : us) { -			if (auto op = findOperation(on, u.second)) { -				return op; +		for (const auto & unit : units) { +			if (auto operation = findOperation(operationName, unit.second)) { +				return operation;  			}  		} -		throw std::runtime_error("Find operation " + on + " failed."); +		throw std::runtime_error("Find operation " + operationName + " failed.");  	}  	std::optional<RouteCompiler::Type>  	// NOLINTNEXTLINE(misc-no-recursion) -	RouteCompiler::findType(const std::string & tn, const Slice::ContainerPtr & c, const Ice::StringSeq & ns) +	RouteCompiler::findType( +			const std::string & typeName, const Slice::ContainerPtr & container, const Ice::StringSeq & nameSpace)  	{ -		for (const auto & strct : c->structs()) { -			auto fqon = boost::algorithm::join(ns + strct->name(), "."); -			if (fqon == tn) { -				return {{Slice::typeToString(strct), {}, strct->dataMembers()}}; +		for (const auto & strct : container->structs()) { +			auto fqon = boost::algorithm::join(nameSpace + strct->name(), "."); +			if (fqon == typeName) { +				return {{.type = Slice::typeToString(strct), .scoped = {}, .members = strct->dataMembers()}};  			} -			auto t = findType(tn, strct, ns + strct->name()); -		} -		for (const auto & cls : c->classes()) { -			auto fqon = boost::algorithm::join(ns + cls->name(), "."); -			if (fqon == tn) { -				return {{Slice::typeToString(cls->declaration()), cls->scoped(), cls->dataMembers()}}; +			// auto t = findType(typeName, strct, nameSpace + strct->name()); +		} +		for (const auto & cls : container->classes()) { +			auto fqon = boost::algorithm::join(nameSpace + cls->name(), "."); +			if (fqon == typeName) { +				return {{.type = Slice::typeToString(cls->declaration()), +						.scoped = cls->scoped(), +						.members = cls->dataMembers()}};  			} -			if (auto t = findType(tn, cls, ns + cls->name())) { -				return t; +			if (auto type = findType(typeName, cls, nameSpace + cls->name())) { +				return type;  			}  		} -		for (const auto & m : c->modules()) { -			if (auto t = findType(tn, m, ns + m->name())) { -				return t; +		for (const auto & module : container->modules()) { +			if (auto type = findType(typeName, module, nameSpace + module->name())) { +				return type;  			}  		}  		return {};  	}  	RouteCompiler::Type -	RouteCompiler::findType(const std::string & tn, const Units & us) +	RouteCompiler::findType(const std::string & typeName, const Units & units)  	{ -		for (const auto & u : us) { -			if (auto t = findType(tn, u.second)) { -				return *t; +		for (const auto & unit : units) { +			if (auto type = findType(typeName, unit.second)) { +				return *type;  			}  		} -		throw std::runtime_error("Find type " + tn + " failed."); +		throw std::runtime_error("Find type " + typeName + " failed.");  	}  	RouteCompiler::ParameterMap -	RouteCompiler::findParameters(const RoutePtr & r, const Units & us) +	RouteCompiler::findParameters(const RoutePtr & route, const Units & units)  	{ -		RouteCompiler::ParameterMap pm; -		for (const auto & o : r->operations) { -			auto op = findOperation(o.second->operation, us); -			if (!op) { -				throw std::runtime_error("Find operator failed for " + r->path); -			} -			for (const auto & p : op->parameters()) { -				auto po = o.second->paramOverrides.find(p->name()); -				if (po != o.second->paramOverrides.end()) { -					pm[po->second] = p; +		RouteCompiler::ParameterMap parameters; +		for (const auto & operationName : route->operations) { +			auto operation = findOperation(operationName.second->operation, units); +			if (!operation) { +				throw std::runtime_error("Find operation failed for " + route->path); +			} +			for (const auto & parameter : operation->parameters()) { +				auto parameterOverride = operationName.second->paramOverrides.find(parameter->name()); +				if (parameterOverride != operationName.second->paramOverrides.end()) { +					parameters[parameterOverride->second] = parameter;  				}  				else { -					pm[p->name()] = p; +					parameters[parameter->name()] = parameter;  				}  			}  		} -		return pm; +		return parameters;  	}  	void -	RouteCompiler::applyDefaults(const RouteConfigurationPtr & c, const Units & u) const +	RouteCompiler::applyDefaults(const RouteConfigurationPtr & routeConfig, const Units & units)  	{ -		for (const auto & r : c->routes) { -			if (r.second->operation) { -				r.second->operations[std::string()] = std::make_shared<Operation>(*r.second->operation, StringMap()); -			} -			auto ps = findParameters(r.second, u); -			for (const auto & p : ps) { -				auto defined = r.second->params.find(p.first); -				if (defined != r.second->params.end()) { +		for (const auto & route : routeConfig->routes) { +			if (route.second->operation) { +				route.second->operations[std::string()] +						= std::make_shared<Operation>(*route.second->operation, StringMap()); +			} +			const auto parameters = findParameters(route.second, units); +			for (const auto & parameter : parameters) { +				auto defined = route.second->params.find(parameter.first); +				if (defined != route.second->params.end()) {  					if (!defined->second->key && defined->second->source != ParameterSource::Body) {  						defined->second->key = defined->first;  					}  				}  				else { -					defined = r.second->params -									  .insert({p.first, -											  std::make_shared<Parameter>(ParameterSource::URL, p.first, false, +					defined = route.second->params +									  .insert({parameter.first, +											  std::make_shared<Parameter>(ParameterSource::URL, parameter.first, false,  													  Ice::optional<std::string>(), Ice::optional<std::string>(),  													  false)})  									  .first;  				} -				auto d = defined->second; -				if (d->source == ParameterSource::URL) { -					Path path(r.second->path); -					d->hasUserSource = std::find_if(path.parts.begin(), path.parts.end(), [d](const auto & pp) { -						if (auto par = dynamic_cast<PathParameter *>(pp.get())) { -							return par->name == *d->key; -						} -						return false; -					}) != path.parts.end(); +				auto definition = defined->second; +				if (definition->source == ParameterSource::URL) { +					Path path(route.second->path); +					definition->hasUserSource +							= std::find_if(path.parts.begin(), path.parts.end(), +									  [definition](const auto & paramPtr) { +										  if (auto pathParam = dynamic_cast<PathParameter *>(paramPtr.get())) { +											  return pathParam->name == *definition->key; +										  } +										  return false; +									  }) +							!= path.parts.end();  				}  			}  		} @@ -193,8 +202,8 @@ namespace IceSpider::Compile {  		applyDefaults(configuration, units);  		AdHoc::ScopeExit uDestroy([&units]() { -			for (auto & u : units) { -				u.second->destroy(); +			for (auto & unit : units) { +				unit.second->destroy();  			}  		}); @@ -212,15 +221,15 @@ namespace IceSpider::Compile {  	}  	RouteCompiler::Units -	RouteCompiler::loadUnits(const RouteConfigurationPtr & c) const +	RouteCompiler::loadUnits(const RouteConfigurationPtr & routeConfig) const  	{  		RouteCompiler::Units units;  		AdHoc::ScopeExit uDestroy; -		for (const auto & slice : c->slices) { +		for (const auto & slice : routeConfig->slices) {  			std::filesystem::path realSlice; -			for (const auto & p : searchPath) { -				if (std::filesystem::exists(p / slice)) { -					realSlice = p / slice; +			for (const auto & path : searchPath) { +				if (std::filesystem::exists(path / slice)) { +					realSlice = path / slice;  					break;  				}  			} @@ -228,9 +237,9 @@ namespace IceSpider::Compile {  				throw std::runtime_error("Could not find slice file");  			}  			std::vector<std::string> cppArgs; -			for (const auto & p : searchPath) { +			for (const auto & path : searchPath) {  				cppArgs.emplace_back("-I"); -				cppArgs.emplace_back(p.string()); +				cppArgs.emplace_back(path.string());  			}  			Slice::PreprocessorPtr icecpp = Slice::Preprocessor::create("IceSpider", realSlice.string(), cppArgs);  			FILE * cppHandle = icecpp->preprocess(false); @@ -239,12 +248,12 @@ namespace IceSpider::Compile {  				throw std::runtime_error("Preprocess failed");  			} -			Slice::UnitPtr u = Slice::Unit::createUnit(false, false, false, false); -			uDestroy.onFailure.emplace_back([u]() { -				u->destroy(); +			Slice::UnitPtr unit = Slice::Unit::createUnit(false, false, false, false); +			uDestroy.onFailure.emplace_back([unit]() { +				unit->destroy();  			}); -			int parseStatus = u->parse(realSlice.string(), cppHandle, false); +			int parseStatus = unit->parse(realSlice.string(), cppHandle, false);  			if (!icecpp->close()) {  				throw std::runtime_error("Preprocess close failed"); @@ -254,57 +263,85 @@ namespace IceSpider::Compile {  				throw std::runtime_error("Unit parse failed");  			} -			units[slice] = u; +			units[slice] = unit;  		}  		return units;  	} -	template<typename... X> -	void -	fprintbf(unsigned int indent, FILE * output, const X &... x) -	{ -		for (; indent > 0; --indent) { -			fputc('\t', output); +	namespace { +		template<typename... Params> +		void +		fprintbf(unsigned int indent, FILE * output, Params &&... params) +		{ +			for (; indent > 0; --indent) { +				fputc('\t', output); +			} +			// NOLINTNEXTLINE(hicpp-no-array-decay) +			fprintbf(output, std::forward<Params>(params)...);  		} -		// NOLINTNEXTLINE(hicpp-no-array-decay) -		fprintbf(output, x...); -	} -	template<typename Enum> -	std::string -	getEnumString(Enum & e) -	{ -		return Slicer::ModelPartForEnum<Enum>::lookup(e); -	} +		template<typename Enum> +		std::string +		getEnumString(Enum & enumValue) +		{ +			return Slicer::ModelPartForEnum<Enum>::lookup(enumValue); +		} -	namespace {  		std::string -		outputSerializerClass(const IceSpider::OutputSerializers::value_type & os) +		outputSerializerClass(const IceSpider::OutputSerializers::value_type & outputSerializer)  		{ -			return boost::algorithm::replace_all_copy(os.second->serializer, ".", "::"); +			return boost::algorithm::replace_all_copy(outputSerializer.second->serializer, ".", "::");  		}  		AdHocFormatter(MimePair, R"C({ "%?", "%?" })C");  		std::string -		outputSerializerMime(const IceSpider::OutputSerializers::value_type & os) +		outputSerializerMime(const IceSpider::OutputSerializers::value_type & outputSerializer) +		{ +			auto slash = outputSerializer.first.find('/'); +			return MimePair::get(outputSerializer.first.substr(0, slash), outputSerializer.first.substr(slash + 1)); +		} + +		void +		processParameterSourceBody( +				FILE * output, const Parameters::value_type & param, bool & doneBody, std::string_view paramType)  		{ -			auto slash = os.first.find('/'); -			return MimePair::get(os.first.substr(0, slash), os.first.substr(slash + 1)); +			if (param.second->key) { +				if (!doneBody) { +					if (param.second->type) { +						fprintbf(4, output, "const auto _pbody(request->getBody<%s>());\n", *param.second->type); +					} +					else { +						fprintbf(4, output, "const auto _pbody(request->getBody<IceSpider::StringMap>());\n"); +					} +					doneBody = true; +				} +				if (param.second->type) { +					fprintbf(4, output, "const auto _p_%s(_pbody->%s", param.first, param.first); +				} +				else { +					fprintbf(4, output, "const auto _p_%s(request->getBodyParam<%s>(_pbody, _pn_%s)", param.first, +							paramType, param.first); +				} +			} +			else { +				fprintbf(4, output, "const auto _p_%s(request->getBody<%s>()", param.first, paramType); +			}  		}  	}  	void -	RouteCompiler::registerOutputSerializers(FILE * output, const RoutePtr & r) const +	RouteCompiler::registerOutputSerializers(FILE * output, const RoutePtr & route)  	{ -		for (const auto & os : r->outputSerializers) { -			fprintbf(4, output, "addRouteSerializer(%s,\n", outputSerializerMime(os)); -			fprintbf(6, output, "std::make_shared<%s::IceSpiderFactory>(", outputSerializerClass(os)); -			for (auto p = os.second->params.begin(); p != os.second->params.end(); ++p) { -				if (p != os.second->params.begin()) { +		for (const auto & outputSerializer : route->outputSerializers) { +			fprintbf(4, output, "addRouteSerializer(%s,\n", outputSerializerMime(outputSerializer)); +			fprintbf(6, output, "std::make_shared<%s::IceSpiderFactory>(", outputSerializerClass(outputSerializer)); +			for (auto parameter = outputSerializer.second->params.begin(); +					parameter != outputSerializer.second->params.end(); ++parameter) { +				if (parameter != outputSerializer.second->params.begin()) {  					fputs(", ", output);  				} -				fputs(p->c_str(), output); +				fputs(parameter->c_str(), output);  			}  			fputs("));\n", output);  		} @@ -312,22 +349,22 @@ namespace IceSpider::Compile {  	void  	RouteCompiler::processConfiguration(FILE * output, FILE * outputh, const std::string & name, -			const RouteConfigurationPtr & c, const Units & units) const +			const RouteConfigurationPtr & routeConfig, const Units & units)  	{  		fputs("// This source files was generated by IceSpider.\n", output); -		fprintbf(output, "// Configuration name: %s\n\n", c->name); +		fprintbf(output, "// Configuration name: %s\n\n", routeConfig->name);  		fputs("#pragma once\n", outputh);  		fputs("// This source files was generated by IceSpider.\n", outputh); -		fprintbf(outputh, "// Configuration name: %s\n\n", c->name); +		fprintbf(outputh, "// Configuration name: %s\n\n", routeConfig->name);  		fputs("// Configuration headers.\n", output);  		fprintbf(output, "#include \"%s.h\"\n", name);  		fputs("\n// Interface headers.\n", output);  		fputs("\n// Interface headers.\n", outputh); -		for (const auto & s : c->slices) { -			std::filesystem::path slicePath(s); +		for (const auto & slice : routeConfig->slices) { +			std::filesystem::path slicePath(slice);  			slicePath.replace_extension(".h");  			fprintbf(output, "#include <%s>\n", slicePath.string());  			fprintbf(outputh, "#include <%s>\n", slicePath.string()); @@ -359,246 +396,230 @@ namespace IceSpider::Compile {  			fprintbf(output, "#include <%s>\n", header);  		} -		if (!c->headers.empty()) { +		if (!routeConfig->headers.empty()) {  			fputs("\n// Extra headers.\n", output);  			fputs("\n// Extra headers.\n", outputh); -			for (const auto & h : c->headers) { -				fprintbf(output, "#include <%s> // IWYU pragma: keep\n", h); -				fprintbf(outputh, "#include <%s> // IWYU pragma: keep\n", h); +			for (const auto & header : routeConfig->headers) { +				fprintbf(output, "#include <%s> // IWYU pragma: keep\n", header); +				fprintbf(outputh, "#include <%s> // IWYU pragma: keep\n", header);  			}  		} -		processBases(output, outputh, c, units); -		processRoutes(output, c, units); +		processBases(output, outputh, routeConfig, units); +		processRoutes(output, routeConfig, units);  		fputs("\n// End generated code.\n", output);  	}  	void -	RouteCompiler::processBases(FILE * output, FILE * outputh, const RouteConfigurationPtr & c, const Units & u) const +	RouteCompiler::processBases( +			FILE * output, FILE * outputh, const RouteConfigurationPtr & routeConfig, const Units & units)  	{  		fputs("\n", outputh); -		fprintbf(outputh, "namespace %s {\n", c->name); +		fprintbf(outputh, "namespace %s {\n", routeConfig->name);  		fprintbf(1, outputh, "// Base classes.\n\n");  		fputs("\n", output); -		fprintbf(output, "namespace %s {\n", c->name); +		fprintbf(output, "namespace %s {\n", routeConfig->name);  		fprintbf(1, output, "// Base classes.\n\n"); -		for (const auto & r : c->routeBases) { -			processBase(output, outputh, r, u); +		for (const auto & route : routeConfig->routeBases) { +			processBase(output, outputh, route, units);  		} -		fprintbf(output, "} // namespace %s\n\n", c->name); -		fprintbf(outputh, "} // namespace %s\n\n", c->name); +		fprintbf(output, "} // namespace %s\n\n", routeConfig->name); +		fprintbf(outputh, "} // namespace %s\n\n", routeConfig->name);  	}  	void -	RouteCompiler::processBase(FILE * output, FILE * outputh, const RouteBases::value_type & b, const Units &) const +	RouteCompiler::processBase(FILE * output, FILE * outputh, const RouteBases::value_type & route, const Units &)  	{ -		fprintbf(1, outputh, "class %s {\n", b.first); +		fprintbf(1, outputh, "class %s {\n", route.first);  		fprintbf(2, outputh, "protected:\n"); -		fprintbf(3, outputh, "explicit %s(const IceSpider::Core * core);\n\n", b.first); -		for (const auto & f : b.second->functions) { -			fprintbf(3, outputh, "%s;\n", f); +		fprintbf(3, outputh, "explicit %s(const IceSpider::Core * core);\n\n", route.first); +		for (const auto & function : route.second->functions) { +			fprintbf(3, outputh, "%s;\n", function);  		} -		fprintbf(1, output, "%s::%s(const IceSpider::Core * core)", b.first, b.first); -		if (!b.second->proxies.empty()) { +		fprintbf(1, output, "%s::%s(const IceSpider::Core * core)", route.first, route.first); +		if (!route.second->proxies.empty()) {  			fputs(" :", output);  		}  		fputs("\n", output); -		unsigned int pn = 0; -		for (const auto & p : b.second->proxies) { -			fprintbf(3, outputh, "const %sPrxPtr prx%u;\n", boost::algorithm::replace_all_copy(p, ".", "::"), pn); -			fprintbf(3, output, "prx%u(core->getProxy<%s>())", pn, boost::algorithm::replace_all_copy(p, ".", "::")); -			if (++pn < b.second->proxies.size()) { +		unsigned int proxyNum = 0; +		for (const auto & proxy : route.second->proxies) { +			fprintbf(3, outputh, "const %sPrxPtr prx%u;\n", boost::algorithm::replace_all_copy(proxy, ".", "::"), +					proxyNum); +			fprintbf(3, output, "prx%u(core->getProxy<%s>())", proxyNum, +					boost::algorithm::replace_all_copy(proxy, ".", "::")); +			if (++proxyNum < route.second->proxies.size()) {  				fputs(",", output);  			}  			fputs("\n", output);  		} -		fprintbf(1, outputh, "}; // %s\n", b.first); +		fprintbf(1, outputh, "}; // %s\n", route.first);  		fprintbf(1, output, "{ }\n");  	}  	void -	RouteCompiler::processRoutes(FILE * output, const RouteConfigurationPtr & c, const Units & u) const +	RouteCompiler::processRoutes(FILE * output, const RouteConfigurationPtr & routeConfig, const Units & units)  	{  		fputs("\n", output); -		fprintbf(output, "namespace %s {\n", c->name); +		fprintbf(output, "namespace %s {\n", routeConfig->name);  		fprintbf(1, output, "// Implementation classes.\n\n"); -		for (const auto & r : c->routes) { -			processRoute(output, r, u); +		for (const auto & route : routeConfig->routes) { +			processRoute(output, route, units);  		} -		fprintbf(output, "} // namespace %s\n\n", c->name); +		fprintbf(output, "} // namespace %s\n\n", routeConfig->name);  		fputs("// Register route handlers.\n", output); -		for (const auto & r : c->routes) { -			fprintbf(output, "FACTORY(%s::%s, IceSpider::RouteHandlerFactory);\n", c->name, r.first); +		for (const auto & route : routeConfig->routes) { +			fprintbf(output, "FACTORY(%s::%s, IceSpider::RouteHandlerFactory);\n", routeConfig->name, route.first);  		}  	}  	void -	RouteCompiler::processRoute(FILE * output, const Routes::value_type & r, const Units & units) const +	RouteCompiler::processRoute(FILE * output, const Routes::value_type & route, const Units & units)  	{ -		std::string methodName = getEnumString(r.second->method); +		std::string methodName = getEnumString(route.second->method); -		fprintbf(1, output, "// Route name: %s\n", r.first); -		fprintbf(1, output, "//       path: %s\n", r.second->path); -		fprintbf(1, output, "class %s : public IceSpider::IRouteHandler", r.first); -		for (const auto & b : r.second->bases) { +		fprintbf(1, output, "// Route name: %s\n", route.first); +		fprintbf(1, output, "//       path: %s\n", route.second->path); +		fprintbf(1, output, "class %s : public IceSpider::IRouteHandler", route.first); +		for (const auto & base : route.second->bases) {  			fputs(",\n", output); -			fprintbf(3, output, "public %s", b); +			fprintbf(3, output, "public %s", base);  		}  		fputs(" {\n", output);  		fprintbf(2, output, "public:\n"); -		fprintbf(3, output, "explicit %s(const IceSpider::Core * core) :\n", r.first); -		fprintbf(4, output, "IceSpider::IRouteHandler(IceSpider::HttpMethod::%s, \"%s\")", methodName, r.second->path); -		for (const auto & b : r.second->bases) { +		fprintbf(3, output, "explicit %s(const IceSpider::Core * core) :\n", route.first); +		fprintbf(4, output, "IceSpider::IRouteHandler(IceSpider::HttpMethod::%s, \"%s\")", methodName, +				route.second->path); +		for (const auto & base : route.second->bases) {  			fputs(",\n", output); -			fprintbf(4, output, "%s(core)", b); +			fprintbf(4, output, "%s(core)", base);  		} -		auto proxies = initializeProxies(output, r.second); +		auto proxies = initializeProxies(output, route.second);  		fputs("\n", output);  		fprintbf(3, output, "{\n"); -		registerOutputSerializers(output, r.second); +		registerOutputSerializers(output, route.second);  		fprintbf(3, output, "}\n\n");  		fprintbf(3, output, "void execute(IceSpider::IHttpRequest * request) const override\n");  		fprintbf(3, output, "{\n"); -		auto ps = findParameters(r.second, units); +		auto parameters = findParameters(route.second, units);  		bool doneBody = false; -		for (const auto & p : r.second->params) { -			if (p.second->hasUserSource) { -				auto ip = ps.find(p.first)->second; -				const auto paramType = Slice::typeToString(ip->type(), false, "", ip->getMetaData()); -				// This shouldn't be needed... the warning is ignored elsewhere to no effect -				if (p.second->source == ParameterSource::Body) { -					if (p.second->key) { -						if (!doneBody) { -							if (p.second->type) { -								fprintbf(4, output, "const auto _pbody(request->getBody<%s>());\n", *p.second->type); -							} -							else { -								fprintbf(4, output, "const auto _pbody(request->getBody<IceSpider::StringMap>());\n"); -							} -							doneBody = true; -						} -						if (p.second->type) { -							fprintbf(4, output, "const auto _p_%s(_pbody->%s", p.first, p.first); -						} -						else { -							fprintbf(4, output, "const auto _p_%s(request->getBodyParam<%s>(_pbody, _pn_%s)", p.first, -									paramType, p.first); -						} -					} -					else { -						fprintbf(4, output, "const auto _p_%s(request->getBody<%s>()", p.first, paramType); -					} +		for (const auto & param : route.second->params) { +			if (param.second->hasUserSource) { +				auto iceParamDecl = parameters.find(param.first)->second; +				const auto paramType +						= Slice::typeToString(iceParamDecl->type(), false, "", iceParamDecl->getMetaData()); +				if (param.second->source == ParameterSource::Body) { +					processParameterSourceBody(output, param, doneBody, paramType);  				}  				else { -					fprintbf(4, output, "const auto _p_%s(request->get%sParam<%s>(_p%c_%s)", p.first, -							getEnumString(p.second->source), paramType, -							p.second->source == ParameterSource::URL ? 'i' : 'n', p.first); +					fprintbf(4, output, "const auto _p_%s(request->get%sParam<%s>(_p%c_%s)", param.first, +							getEnumString(param.second->source), paramType, +							param.second->source == ParameterSource::URL ? 'i' : 'n', param.first);  				} -				if (!p.second->isOptional && p.second->source != ParameterSource::URL) { +				if (!param.second->isOptional && param.second->source != ParameterSource::URL) {  					fprintbf(0, output, " /\n"); -					if (p.second->defaultExpr) { -						fprintbf(5, output, " [this]() { return _pd_%s; }", p.first); +					if (param.second->defaultExpr) { +						fprintbf(5, output, " [this]() { return _pd_%s; }", param.first);  					}  					else {  						fprintbf(5, output, " [this]() { return requiredParameterNotFound<%s>(\"%s\", _pn_%s); }", -								paramType, getEnumString(p.second->source), p.first); +								paramType, getEnumString(param.second->source), param.first);  					}  				}  				fprintbf(0, output, ");\n");  			}  		} -		if (r.second->operation) { -			addSingleOperation(output, r.second, findOperation(*r.second->operation, units)); +		if (route.second->operation) { +			addSingleOperation(output, route.second, findOperation(*route.second->operation, units));  		}  		else { -			addMashupOperations(output, r.second, proxies, units); +			addMashupOperations(output, route.second, proxies, units);  		}  		fprintbf(3, output, "}\n\n");  		fprintbf(2, output, "private:\n");  		declareProxies(output, proxies); -		for (const auto & p : r.second->params) { -			if (p.second->hasUserSource) { -				if (p.second->source == ParameterSource::URL) { -					Path path(r.second->path); +		for (const auto & param : route.second->params) { +			if (param.second->hasUserSource) { +				if (param.second->source == ParameterSource::URL) { +					Path path(route.second->path);  					long idx = -1; -					for (const auto & pp : path.parts) { -						if (auto par = dynamic_cast<PathParameter *>(pp.get())) { -							if (par->name == *p.second->key) { -								idx = &pp - &path.parts.front(); +					for (const auto & pathPart : path.parts) { +						if (auto par = dynamic_cast<PathParameter *>(pathPart.get())) { +							if (par->name == *param.second->key) { +								idx = &pathPart - &path.parts.front();  							}  						}  					} -					fprintbf(3, output, "static constexpr unsigned int _pi_%s{%ld};\n", p.first, idx); +					fprintbf(3, output, "static constexpr unsigned int _pi_%s{%ld};\n", param.first, idx);  				}  				else { -					fprintbf(3, output, "static constexpr std::string_view _pn_%s{", p.first); -					if (p.second->key) { -						fprintbf(output, "\"%s\"", *p.second->key); +					fprintbf(3, output, "static constexpr std::string_view _pn_%s{", param.first); +					if (param.second->key) { +						fprintbf(output, "\"%s\"", *param.second->key);  					}  					fputs("};\n", output);  				}  			} -			if (p.second->defaultExpr) { -				auto ip = ps.find(p.first)->second; -				fprintbf(3, output, "static const %s _pd_%s{%s};\n", Slice::typeToString(ip->type()), p.first, -						*p.second->defaultExpr); +			if (param.second->defaultExpr) { +				auto iceParamDecl = parameters.find(param.first)->second; +				fprintbf(3, output, "static const %s _pd_%s{%s};\n", Slice::typeToString(iceParamDecl->type()), +						param.first, *param.second->defaultExpr);  			}  		}  		fprintbf(1, output, "};\n\n");  	}  	RouteCompiler::Proxies -	RouteCompiler::initializeProxies(FILE * output, const RoutePtr & r) const +	RouteCompiler::initializeProxies(FILE * output, const RoutePtr & route)  	{  		Proxies proxies; -		int n = 0; -		for (const auto & o : r->operations) { -			auto proxyName = o.second->operation.substr(0, o.second->operation.find_last_of('.')); -			if (proxies.find(proxyName) == proxies.end()) { -				proxies[proxyName] = n; +		int proxyNum = 0; +		for (const auto & operation : route->operations) { +			auto proxyName = operation.second->operation.substr(0, operation.second->operation.find_last_of('.')); +			if (!proxies.contains(proxyName)) { +				proxies[proxyName] = proxyNum;  				fputs(",\n", output); -				fprintbf(4, output, "prx%d(core->getProxy<%s>())", n, +				fprintbf(4, output, "prx%d(core->getProxy<%s>())", proxyNum,  						boost::algorithm::replace_all_copy(proxyName, ".", "::")); -				n += 1; +				proxyNum += 1;  			}  		}  		return proxies;  	}  	void -	RouteCompiler::declareProxies(FILE * output, const Proxies & proxies) const +	RouteCompiler::declareProxies(FILE * output, const Proxies & proxies)  	{ -		for (const auto & p : proxies) { -			fprintbf(3, output, "const %sPrxPtr prx%d;\n", boost::algorithm::replace_all_copy(p.first, ".", "::"), -					p.second); +		for (const auto & proxy : proxies) { +			fprintbf(3, output, "const %sPrxPtr prx%d;\n", boost::algorithm::replace_all_copy(proxy.first, ".", "::"), +					proxy.second);  		}  	}  	void -	RouteCompiler::addSingleOperation(FILE * output, const RoutePtr & r, const Slice::OperationPtr & o) const +	RouteCompiler::addSingleOperation(FILE * output, const RoutePtr & route, const Slice::OperationPtr & operation)  	{ -		auto operation = r->operation->substr(r->operation->find_last_of('.') + 1); -		if (o->returnType()) { -			fprintbf(4, output, "auto _responseModel = prx0->%s(", operation); +		if (auto operationName = route->operation->substr(route->operation->find_last_of('.') + 1); +				operation->returnType()) { +			fprintbf(4, output, "auto _responseModel = prx0->%s(", operationName);  		}  		else { -			fprintbf(4, output, "prx0->%s(", operation); +			fprintbf(4, output, "prx0->%s(", operationName);  		} -		for (const auto & p : o->parameters()) { -			auto rp = *r->params.find(p->name()); -			if (rp.second->hasUserSource) { -				fprintbf(output, "_p_%s, ", p->name()); +		for (const auto & parameter : operation->parameters()) { +			auto routeParam = *route->params.find(parameter->name()); +			if (routeParam.second->hasUserSource) { +				fprintbf(output, "_p_%s, ", parameter->name());  			}  			else { -				fprintbf(output, "_pd_%s, ", p->name()); +				fprintbf(output, "_pd_%s, ", parameter->name());  			}  		}  		fprintbf(output, "request->getContext());\n"); -		for (const auto & mutator : r->mutators) { +		for (const auto & mutator : route->mutators) {  			fprintbf(4, output, "%s(request, _responseModel);\n", mutator);  		} -		if (o->returnType()) { +		if (operation->returnType()) {  			fprintbf(4, output, "request->response(this, _responseModel);\n");  		}  		else { @@ -608,49 +629,50 @@ namespace IceSpider::Compile {  	void  	RouteCompiler::addMashupOperations( -			FILE * output, const RoutePtr & r, const Proxies & proxies, const Units & us) const +			FILE * output, const RoutePtr & route, const Proxies & proxies, const Units & units)  	{ -		for (const auto & o : r->operations) { -			auto proxyName = o.second->operation.substr(0, o.second->operation.find_last_of('.')); -			auto operation = o.second->operation.substr(o.second->operation.find_last_of('.') + 1); -			fprintbf(4, output, "auto _ar_%s = prx%s->%sAsync(", o.first, proxies.find(proxyName)->second, operation); -			auto so = findOperation(o.second->operation, us); -			for (const auto & p : so->parameters()) { -				auto po = o.second->paramOverrides.find(p->name()); -				auto rp = *r->params.find(po != o.second->paramOverrides.end() ? po->second : p->name()); -				if (rp.second->hasUserSource) { -					fprintbf(output, "_p_%s, ", p->name()); +		for (const auto & operation : route->operations) { +			auto proxyName = operation.second->operation.substr(0, operation.second->operation.find_last_of('.')); +			auto operationName = operation.second->operation.substr(operation.second->operation.find_last_of('.') + 1); +			fprintbf(4, output, "auto _ar_%s = prx%s->%sAsync(", operation.first, proxies.find(proxyName)->second, +					operationName); +			for (const auto & parameter : findOperation(operation.second->operation, units)->parameters()) { +				auto parameterOverride = operation.second->paramOverrides.find(parameter->name()); +				if (route->params +								.find(parameterOverride != operation.second->paramOverrides.end() +												? parameterOverride->second +												: parameter->name()) +								->second->hasUserSource) { +					fprintbf(output, "_p_%s, ", parameter->name());  				}  				else { -					fprintbf(output, "_pd_%s, ", p->name()); +					fprintbf(output, "_pd_%s, ", parameter->name());  				}  			}  			fprintbf(output, "request->getContext());\n");  		} -		auto t = findType(r->type, us); -		fprintbf(4, output, "%s _responseModel", t.type); -		if (t.scoped) { -			fprintbf(4, output, " = std::make_shared<%s>()", *t.scoped); +		const auto type = findType(route->type, units); +		fprintbf(4, output, "%s _responseModel", type.type); +		if (type.scoped) { +			fprintbf(4, output, " = std::make_shared<%s>()", *type.scoped);  		}  		fprintbf(4, output, ";\n"); -		for (const auto & mi : t.members) { +		for (const auto & member : type.members) {  			bool isOp = false; -			fprintbf(4, output, "_responseModel%s%s = ", t.scoped ? "->" : ".", mi->name()); -			for (const auto & o : r->operations) { -				auto proxyName = o.second->operation.substr(0, o.second->operation.find_last_of('.')); -				auto operation = o.second->operation.substr(o.second->operation.find_last_of('.') + 1); -				if (mi->name() == o.first) { -					fprintbf(output, "_ar_%s.get()", o.first); +			fprintbf(4, output, "_responseModel%s%s = ", type.scoped ? "->" : ".", member->name()); +			for (const auto & operation : route->operations) { +				if (member->name() == operation.first) { +					fprintbf(output, "_ar_%s.get()", operation.first);  					isOp = true;  					break;  				}  			}  			if (!isOp) { -				fprintbf(output, "_p_%s", mi->name()); +				fprintbf(output, "_p_%s", member->name());  			}  			fputs(";\n", output);  		} -		for (const auto & mutator : r->mutators) { +		for (const auto & mutator : route->mutators) {  			fprintbf(4, output, "%s(request, _responseModel);\n", mutator);  		}  		fprintbf(4, output, "request->response(this, _responseModel);\n"); diff --git a/icespider/compile/routeCompiler.h b/icespider/compile/routeCompiler.h index 99da2ac..cc12bea 100644 --- a/icespider/compile/routeCompiler.h +++ b/icespider/compile/routeCompiler.h @@ -18,10 +18,10 @@ namespace IceSpider::Compile {  		RouteCompiler(); -		[[nodiscard]] RouteConfigurationPtr loadConfiguration(const std::filesystem::path &) const; +		[[nodiscard]] static RouteConfigurationPtr loadConfiguration(const std::filesystem::path &);  		[[nodiscard]] Units loadUnits(const RouteConfigurationPtr &) const; -		void applyDefaults(const RouteConfigurationPtr &, const Units & u) const; +		static void applyDefaults(const RouteConfigurationPtr &, const Units & units);  		void compile(const std::filesystem::path & input, const std::filesystem::path & output) const;  		std::vector<std::filesystem::path> searchPath; @@ -30,17 +30,17 @@ namespace IceSpider::Compile {  		using Proxies = std::map<std::string, int>;  #pragma GCC visibility push(hidden) -		void processConfiguration(FILE * output, FILE * outputh, const std::string & name, -				const RouteConfigurationPtr &, const Units &) const; -		void processBases(FILE * output, FILE * outputh, const RouteConfigurationPtr &, const Units &) const; -		void processBase(FILE * output, FILE * outputh, const RouteBases::value_type &, const Units &) const; -		void processRoutes(FILE * output, const RouteConfigurationPtr &, const Units &) const; -		void processRoute(FILE * output, const Routes::value_type &, const Units &) const; -		void registerOutputSerializers(FILE * output, const RoutePtr &) const; -		[[nodiscard]] Proxies initializeProxies(FILE * output, const RoutePtr &) const; -		void declareProxies(FILE * output, const Proxies &) const; -		void addSingleOperation(FILE * output, const RoutePtr &, const Slice::OperationPtr &) const; -		void addMashupOperations(FILE * output, const RoutePtr &, const Proxies &, const Units &) const; +		static void processConfiguration( +				FILE * output, FILE * outputh, const std::string & name, const RouteConfigurationPtr &, const Units &); +		static void processBases(FILE * output, FILE * outputh, const RouteConfigurationPtr &, const Units &); +		static void processBase(FILE * output, FILE * outputh, const RouteBases::value_type &, const Units &); +		static void processRoutes(FILE * output, const RouteConfigurationPtr &, const Units &); +		static void processRoute(FILE * output, const Routes::value_type &, const Units &); +		static void registerOutputSerializers(FILE * output, const RoutePtr &); +		[[nodiscard]] static Proxies initializeProxies(FILE * output, const RoutePtr &); +		static void declareProxies(FILE * output, const Proxies &); +		static void addSingleOperation(FILE * output, const RoutePtr &, const Slice::OperationPtr &); +		static void addMashupOperations(FILE * output, const RoutePtr &, const Proxies &, const Units &);  		using ParameterMap = std::map<std::string, Slice::ParamDeclPtr>;  		static ParameterMap findParameters(const RoutePtr &, const Units &);  		static Slice::OperationPtr findOperation(const std::string &, const Units &); diff --git a/icespider/core/core.cpp b/icespider/core/core.cpp index 4b4d087..09e1aa7 100644 --- a/icespider/core/core.cpp +++ b/icespider/core/core.cpp @@ -5,7 +5,6 @@  #include <Ice/ObjectAdapter.h>  #include <Ice/PropertiesF.h>  #include <algorithm> -#include <compare>  #include <compileTimeFormatter.h>  #include <cstdlib>  #include <cxxabi.h> @@ -22,33 +21,31 @@ INSTANTIATEFACTORY(IceSpider::Plugin, Ice::CommunicatorPtr, Ice::PropertiesPtr);  INSTANTIATEPLUGINOF(IceSpider::ErrorHandler);  namespace IceSpider { -	const std::filesystem::path Core::defaultConfig("config/ice.properties"); +	const std::filesystem::path Core::DEFAULT_CONFIG("config/ice.properties");  	Core::Core(const Ice::StringSeq & args)  	{ -		Ice::InitializationData id; -		id.properties = Ice::createProperties(); -		id.properties->parseCommandLineOptions("", args); -		auto config = id.properties->getPropertyWithDefault("IceSpider.Config", defaultConfig.string()); +		Ice::InitializationData initData; +		initData.properties = Ice::createProperties(); +		initData.properties->parseCommandLineOptions("", args); +		auto config = initData.properties->getPropertyWithDefault("IceSpider.Config", DEFAULT_CONFIG.string());  		if (std::filesystem::exists(config)) { -			id.properties->load(config); +			initData.properties->load(config);  		} -		communicator = Ice::initialize(id); +		communicator = Ice::initialize(initData);  		// Initialize routes -		for (const auto & rp : AdHoc::PluginManager::getDefault()->getAll<RouteHandlerFactory>()) { -			allRoutes.push_back(rp->implementation()->create(this)); +		for (const auto & routeHandleFactory : AdHoc::PluginManager::getDefault()->getAll<RouteHandlerFactory>()) { +			allRoutes.push_back(routeHandleFactory->implementation()->create(this));  		} -		std::sort(allRoutes.begin(), allRoutes.end(), [](const auto & a, const auto & b) { -			return a->path < b->path; -		}); +		std::ranges::sort(allRoutes, {}, &IRouteHandler::path);  		// Load plugins  		auto plugins = AdHoc::PluginManager::getDefault()->getAll<PluginFactory>();  		if (!plugins.empty()) {  			pluginAdapter = communicator->createObjectAdapterWithEndpoints("plugins", "default"); -			for (const auto & pf : plugins) { -				auto p = pf->implementation()->create(communicator, communicator->getProperties()); -				pluginAdapter->add(p, Ice::stringToIdentity(pf->name)); +			for (const auto & plugin : plugins) { +				pluginAdapter->add(plugin->implementation()->create(communicator, communicator->getProperties()), +						Ice::stringToIdentity(plugin->name));  			}  			pluginAdapter->activate();  		} @@ -59,8 +56,8 @@ namespace IceSpider {  		// Unload plugins  		auto plugins = AdHoc::PluginManager::getDefault()->getAll<PluginFactory>();  		if (!plugins.empty()) { -			for (const auto & pf : plugins) { -				pluginAdapter->remove(Ice::stringToIdentity(pf->name)); +			for (const auto & plugin : plugins) { +				pluginAdapter->remove(Ice::stringToIdentity(plugin->name));  			}  			pluginAdapter->deactivate();  			pluginAdapter->destroy(); @@ -85,7 +82,7 @@ namespace IceSpider {  			handleError(request, e);  		}  		catch (...) { -			request->response(Http500_InternalServerError::CODE, Http500_InternalServerError::MESSAGE); +			request->response(Http500InternalServerError::CODE, Http500InternalServerError::MESSAGE);  			request->dump(std::cerr);  		}  	} @@ -95,14 +92,14 @@ namespace IceSpider {  	Core::handleError(IHttpRequest * request, const std::exception & exception) const  	{  		auto errorHandlers = AdHoc::PluginManager::getDefault()->getAll<ErrorHandler>(); -		for (const auto & eh : errorHandlers) { +		for (const auto & errorHandler : errorHandlers) {  			try { -				switch (eh->implementation()->handleError(request, exception)) { -					case ErrorHandlerResult_Handled: +				switch (errorHandler->implementation()->handleError(request, exception)) { +					case ErrorHandlerResult::Handled:  						return; -					case ErrorHandlerResult_Unhandled: +					case ErrorHandlerResult::Unhandled:  						continue; -					case ErrorHandlerResult_Modified: +					case ErrorHandlerResult::Modified:  						process(request, nullptr);  						return;  				} @@ -112,7 +109,7 @@ namespace IceSpider {  				return;  			}  			catch (...) { -				std::cerr << "Error handler failed" << std::endl; +				std::cerr << "Error handler failed\n";  			}  		}  		defaultErrorReport(request, exception); @@ -130,11 +127,11 @@ namespace IceSpider {  	AdHocFormatter(LogExp, "Exception type: %?\nDetail: %?\n");  	void -	Core::defaultErrorReport(IHttpRequest * request, const std::exception & exception) const +	Core::defaultErrorReport(IHttpRequest * request, const std::exception & exception)  	{  		auto buf = demangle(typeid(exception).name());  		request->setHeader(H::CONTENT_TYPE, MIME::TEXT_PLAIN); -		request->response(Http500_InternalServerError::CODE, buf.get()); +		request->response(Http500InternalServerError::CODE, buf.get());  		LogExp::write(request->getOutputStream(), buf.get(), exception.what());  		request->dump(std::cerr);  		LogExp::write(std::cerr, buf.get(), exception.what()); @@ -148,12 +145,12 @@ namespace IceSpider {  	CoreWithDefaultRouter::CoreWithDefaultRouter(const Ice::StringSeq & opts) : Core(opts)  	{ -		for (const auto & r : allRoutes) { -			if (routes.size() <= r->pathElementCount()) { -				routes.resize(r->pathElementCount() + 1); +		for (const auto & route : allRoutes) { +			if (routes.size() <= route->pathElementCount()) { +				routes.resize(route->pathElementCount() + 1);  			} -			auto & lroutes = routes[r->pathElementCount()]; -			lroutes.push_back(r); +			auto & lroutes = routes[route->pathElementCount()]; +			lroutes.push_back(route);  		}  	} @@ -163,22 +160,22 @@ namespace IceSpider {  		const auto & pathparts = request->getRequestPath();  		const auto method = request->getRequestMethod();  		if (pathparts.size() >= routes.size()) { -			throw Http404_NotFound(); +			throw Http404NotFound();  		}  		const auto & routeSet = routes[pathparts.size()];  		bool match = false; -		for (const auto & r : routeSet) { -			if (r->matches(pathparts)) { -				if (r->method == method) { -					return r.get(); +		for (const auto & route : routeSet) { +			if (route->matches(pathparts)) { +				if (route->method == method) { +					return route.get();  				}  				match = true;  			}  		}  		if (!match) { -			throw Http404_NotFound(); +			throw Http404NotFound();  		} -		throw Http405_MethodNotAllowed(); +		throw Http405MethodNotAllowed();  	}  } diff --git a/icespider/core/core.h b/icespider/core/core.h index e4c5d0e..e24ca09 100644 --- a/icespider/core/core.h +++ b/icespider/core/core.h @@ -13,7 +13,6 @@  #include <exception>  #include <factory.h> // IWYU pragma: keep  #include <filesystem> -#include <memory>  #include <plugins.h> // IWYU pragma: keep  #include <string_view>  #include <vector> @@ -49,10 +48,10 @@ namespace IceSpider {  		Ice::CommunicatorPtr communicator;  		Ice::ObjectAdapterPtr pluginAdapter; -		static const std::filesystem::path defaultConfig; +		static const std::filesystem::path DEFAULT_CONFIG;  	private: -		void defaultErrorReport(IHttpRequest * request, const std::exception & ex) const; +		static void defaultErrorReport(IHttpRequest * request, const std::exception & exception);  	};  	class DLL_PUBLIC CoreWithDefaultRouter : public Core { @@ -71,15 +70,15 @@ namespace IceSpider {  	using PluginFactory = AdHoc::Factory<Plugin, Ice::CommunicatorPtr, Ice::PropertiesPtr>; -	enum ErrorHandlerResult { -		ErrorHandlerResult_Unhandled, -		ErrorHandlerResult_Handled, -		ErrorHandlerResult_Modified, +	enum class ErrorHandlerResult : uint8_t { +		Unhandled, +		Handled, +		Modified,  	};  	class DLL_PUBLIC ErrorHandler : public AdHoc::AbstractPluginImplementation {  	public: -		virtual ErrorHandlerResult handleError(IHttpRequest * IHttpRequest, const std::exception &) const = 0; +		virtual ErrorHandlerResult handleError(IHttpRequest * iHttpRequest, const std::exception &) const = 0;  	};  	using ErrorHandlerPlugin = AdHoc::PluginOf<ErrorHandler>; diff --git a/icespider/core/exceptions.cpp b/icespider/core/exceptions.cpp index b440c2a..19fc92c 100644 --- a/icespider/core/exceptions.cpp +++ b/icespider/core/exceptions.cpp @@ -1,4 +1,5 @@  #include "exceptions.h" +#include "http.h"  #define DefineHttpEx(Name, Code, Message) \  	Name::Name() : ::IceSpider::HttpException(__FILE__, __LINE__, CODE, MESSAGE) { } \ @@ -6,10 +7,10 @@  	const std::string Name::MESSAGE(Message);  namespace IceSpider { -	DefineHttpEx(Http400_BadRequest, 400, "Bad Request"); -	DefineHttpEx(Http404_NotFound, 404, "Not found"); -	DefineHttpEx(Http405_MethodNotAllowed, 405, "Method Not Allowed"); -	DefineHttpEx(Http406_NotAcceptable, 406, "Not Acceptable"); -	DefineHttpEx(Http415_UnsupportedMediaType, 415, "Unsupported Media Type"); -	DefineHttpEx(Http500_InternalServerError, 500, "Internal Server Error"); +	DefineHttpEx(Http400BadRequest, 400, "Bad Request"); +	DefineHttpEx(Http404NotFound, 404, "Not found"); +	DefineHttpEx(Http405MethodNotAllowed, 405, "Method Not Allowed"); +	DefineHttpEx(Http406NotAcceptable, 406, "Not Acceptable"); +	DefineHttpEx(Http415UnsupportedMediaType, 415, "Unsupported Media Type"); +	DefineHttpEx(Http500InternalServerError, 500, "Internal Server Error");  } diff --git a/icespider/core/exceptions.h b/icespider/core/exceptions.h index 0de3f70..ae97f5f 100644 --- a/icespider/core/exceptions.h +++ b/icespider/core/exceptions.h @@ -14,12 +14,12 @@  	}  namespace IceSpider { -	DeclareHttpEx(Http400_BadRequest); -	DeclareHttpEx(Http404_NotFound); -	DeclareHttpEx(Http405_MethodNotAllowed); -	DeclareHttpEx(Http406_NotAcceptable); -	DeclareHttpEx(Http415_UnsupportedMediaType); -	DeclareHttpEx(Http500_InternalServerError); +	DeclareHttpEx(Http400BadRequest); +	DeclareHttpEx(Http404NotFound); +	DeclareHttpEx(Http405MethodNotAllowed); +	DeclareHttpEx(Http406NotAcceptable); +	DeclareHttpEx(Http415UnsupportedMediaType); +	DeclareHttpEx(Http500InternalServerError);  }  #undef DeclareHttpEx diff --git a/icespider/core/flatMap.cpp b/icespider/core/flatMap.cpp deleted file mode 100644 index b6ad3a6..0000000 --- a/icespider/core/flatMap.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "flatMap.h" diff --git a/icespider/core/flatMap.h b/icespider/core/flatMap.h index a2506d9..4473a4e 100644 --- a/icespider/core/flatMap.h +++ b/icespider/core/flatMap.h @@ -3,14 +3,13 @@  #include <algorithm>  #include <cstddef>  #include <functional> -#include <iterator>  #include <stdexcept>  #include <string>  #include <utility>  #include <vector>  namespace IceSpider { -	template<typename K, typename M, typename Comp = std::less<>> class flatmap : std::vector<std::pair<K, M>> { +	template<typename K, typename M, typename Comp = std::less<>> class FlatMap : std::vector<std::pair<K, M>> {  	public:  		using V = std::pair<K, M>;  		using S = std::vector<V>; @@ -18,37 +17,44 @@ namespace IceSpider {  	private:  		template<typename N> struct KeyComp {  			bool -			operator()(const V & v, const N & n) const +			operator()(const V & value, const N & name) const  			{ -				return c(v.first, n); +				return comparator(value.first, name);  			}  			bool -			operator()(const N & n, const V & v) const +			operator()(const N & name, const V & value) const  			{ -				return c(n, v.first); +				return comparator(name, value.first);  			} -			Comp c; +			Comp comparator;  		};  	public: -		flatmap() = default; +		FlatMap() = default; -		explicit flatmap(std::size_t n) +		explicit FlatMap(std::size_t n)  		{  			reserve(n);  		}  		auto -		insert(V v) +		insert(V value)  		{ -			return S::insert(lower_bound(v.first), std::move(v)); +			return S::insert(lower_bound(value.first), std::move(value)); +		} + +		auto +		emplace(K key, M mapped) +		{ +			auto pos = lower_bound(key); +			return S::emplace(pos, std::move(key), std::move(mapped));  		}  		template<typename N>  		[[nodiscard]] auto -		lower_bound(const N & n) const +		lower_bound(const N & n) const // NOLINT(readability-identifier-naming) - STL like  		{  			return std::lower_bound(begin(), end(), n, KeyComp<N> {});  		} @@ -64,22 +70,22 @@ namespace IceSpider {  		[[nodiscard]] auto  		find(const N & n) const  		{ -			const auto lb = lower_bound(n); -			if (lb == end()) { -				return lb; +			const auto lower = lower_bound(n); +			if (lower == end()) { +				return lower;  			} -			if (Comp {}(n, lb->first)) { +			if (Comp {}(n, lower->first)) {  				return end();  			} -			return lb; +			return lower;  		}  		template<typename Ex = std::out_of_range, typename N>  		[[nodiscard]] const auto &  		at(const N & n) const  		{ -			if (const auto i = find(n); i != end()) { -				return i->second; +			if (const auto iter = find(n); iter != end()) { +				return iter->second;  			}  			if constexpr (std::is_constructible_v<Ex, N>) {  				// NOLINTNEXTLINE(hicpp-no-array-decay) @@ -107,7 +113,7 @@ namespace IceSpider {  		using S::empty;  		using S::reserve;  		using S::size; -		using iterator = typename S::iterator; -		using const_iterator = typename S::const_iterator; +		using iterator = typename S::iterator; // NOLINT(readability-identifier-naming) - STL like +		using const_iterator = typename S::const_iterator; // NOLINT(readability-identifier-naming) - STL like  	};  } diff --git a/icespider/core/ihttpRequest.cpp b/icespider/core/ihttpRequest.cpp index 205fa6e..75db2f1 100644 --- a/icespider/core/ihttpRequest.cpp +++ b/icespider/core/ihttpRequest.cpp @@ -9,7 +9,6 @@  #include <ctime>  #include <formatters.h>  #include <http.h> -#include <memory>  #include <plugins.h>  #include <slicer/modelParts.h>  #include <slicer/serializer.h> @@ -18,10 +17,10 @@  namespace IceSpider {  	using namespace AdHoc::literals; -	IHttpRequest::IHttpRequest(const Core * c) : core(c) { } +	IHttpRequest::IHttpRequest(const Core * core) : core(core) { }  	Ice::Context -	IHttpRequest::getContext() const +	IHttpRequest::getContext()  	{  		return {};  	} @@ -32,12 +31,12 @@ namespace IceSpider {  		try {  			return Slicer::StreamDeserializerFactory::createNew(  					getEnvStr(E::CONTENT_TYPE) / []() -> std::string_view { -						throw Http400_BadRequest(); +						throw Http400BadRequest();  					},  					getInputStream());  		}  		catch (const AdHoc::NoSuchPluginException &) { -			throw Http415_UnsupportedMediaType(); +			throw Http415UnsupportedMediaType();  		}  	} @@ -46,89 +45,82 @@ namespace IceSpider {  	{  		remove_leading(acceptHdr, ' ');  		if (acceptHdr.empty()) { -			throw Http400_BadRequest(); +			throw Http400BadRequest();  		}  		Accepted accepts;  		accepts.reserve(static_cast<std::size_t>(std::count(acceptHdr.begin(), acceptHdr.end(), ',') + 1)); -		auto upto = [](std::string_view & in, const std::string_view term, bool req) { -			remove_leading(in, ' '); -			const auto end = in.find_first_of(term); +		auto upto = [](std::string_view & input, const std::string_view term, bool req) { +			remove_leading(input, ' '); +			const auto end = input.find_first_of(term);  			if (req && end == std::string_view::npos) { -				throw Http400_BadRequest(); +				throw Http400BadRequest();  			} -			auto val = in.substr(0, end); +			auto val = input.substr(0, end);  			remove_trailing(val, ' ');  			if (val.empty()) { -				throw Http400_BadRequest(); +				throw Http400BadRequest();  			}  			if (end != std::string_view::npos) { -				const auto tc = in[end]; -				in.remove_prefix(end + 1); -				return std::make_pair(val, tc); -			} -			else { -				in.remove_prefix(in.length()); -				return std::make_pair(val, '\n'); +				const auto terminatorChar = input[end]; +				input.remove_prefix(end + 1); +				return std::make_pair(val, terminatorChar);  			} +			input.remove_prefix(input.length()); +			return std::make_pair(val, '\n');  		};  		while (!acceptHdr.empty()) {  			const auto group = upto(acceptHdr, "/", true).first; -			auto [type, tc] = upto(acceptHdr, ";,", false); -			Accept a; +			auto [type, terminatorChar] = upto(acceptHdr, ";,", false); +			Accept accept;  			if (type != "*") { -				a.type.emplace(type); +				accept.type.emplace(type);  			}  			if (group != "*") { -				a.group.emplace(group); +				accept.group.emplace(group);  			} -			else if (a.type) { -				throw Http400_BadRequest(); +			else if (accept.type) { +				throw Http400BadRequest();  			} -			while (tc == ';') { +			while (terminatorChar == ';') {  				const auto paramName = upto(acceptHdr, "=", true);  				const auto paramValue = upto(acceptHdr, ",;", false);  				if (paramName.first == "q") { -					if (convert(paramValue.first, a.q); a.q <= 0.0F || a.q > 1.0F) { -						throw Http400_BadRequest(); +					if (convert(paramValue.first, accept.q); accept.q <= 0.0F || accept.q > 1.0F) { +						throw Http400BadRequest();  					}  				} -				tc = paramValue.second; +				terminatorChar = paramValue.second;  			} -			accepts.emplace_back(a); +			accepts.emplace_back(accept);  		} -		std::stable_sort(accepts.begin(), accepts.end(), [](const auto & a, const auto & b) { -			return a.q > b.q; -		}); +		std::ranges::stable_sort(accepts, std::greater<float> {}, &Accept::q);  		return accepts;  	}  	ContentTypeSerializer  	IHttpRequest::getSerializer(const IRouteHandler * handler) const  	{ -		auto acceptHdr = getHeaderParamStr(H::ACCEPT); -		if (acceptHdr) { +		if (auto acceptHdr = getHeaderParamStr(H::ACCEPT)) {  			auto accepts = parseAccept(*acceptHdr);  			auto & strm = getOutputStream();  			if (accepts.empty()) { -				throw Http400_BadRequest(); +				throw Http400BadRequest();  			}  			if (!accepts.front().group && !accepts.front().type) {  				return handler->defaultSerializer(strm);  			} -			for (auto & a : accepts) { -				ContentTypeSerializer serializer = handler->getSerializer(a, strm); +			for (const auto & accept : accepts) { +				ContentTypeSerializer serializer = handler->getSerializer(accept, strm);  				if (serializer.second) {  					return serializer;  				}  			} -			throw Http406_NotAcceptable(); -		} -		else { -			return handler->defaultSerializer(getOutputStream()); +			throw Http406NotAcceptable();  		} +		return handler->defaultSerializer(getOutputStream());  	}  	std::string_view @@ -143,33 +135,35 @@ namespace IceSpider {  	// Set-Cookie: value[; expires=date][; domain=domain][; path=path][; secure]  	void -	IHttpRequest::setCookie(const std::string_view name, const std::string_view value, const OptionalString & d, -			const OptionalString & p, bool s, std::optional<time_t> e) +	IHttpRequest::setCookie(const std::string_view name, const std::string_view value, const OptionalString & domain, +			const OptionalString & path, bool secure, std::optional<time_t> expiry) const  	{ -		std::stringstream o; -		XWwwFormUrlEncoded::urlencodeto(o, name.begin(), name.end()); -		o << '='; -		XWwwFormUrlEncoded::urlencodeto(o, value.begin(), value.end()); -		if (e) { -			static constexpr auto dateLength = std::string_view {"Sat, 02 May 2009 23:38:25 GMT"}.length() + 1; -			std::array<char, dateLength> buf {}; -			tm tm {}; +		std::stringstream cookieString; +		XWwwFormUrlEncoded::urlencodeto(cookieString, name.begin(), name.end()); +		cookieString << '='; +		XWwwFormUrlEncoded::urlencodeto(cookieString, value.begin(), value.end()); +		if (expiry) { +			static constexpr auto DATE_LENGTH = sizeof("Sat, 02 May 2009 23:38:25 GMT"); +			tm timeParts {}; -			gmtime_r(&*e, &tm); -			const auto len = strftime(buf.data(), buf.size(), "%a, %d %b %Y %T %Z", &tm); -			o << "; expires=" << std::string_view {buf.data(), len}; +			gmtime_r(&*expiry, &timeParts); +			std::string buf; +			buf.resize_and_overwrite(DATE_LENGTH, [&timeParts](char * out, size_t len) { +				return strftime(out, len, "%a, %d %b %Y %T %Z", &timeParts); +			}); +			cookieString << "; expires=" << buf;  		} -		if (d) { -			"; domain=%?"_fmt(o, *d); +		if (domain) { +			"; domain=%?"_fmt(cookieString, *domain);  		} -		if (p) { -			"; path=%?"_fmt(o, *p); +		if (path) { +			"; path=%?"_fmt(cookieString, *path);  		} -		if (s) { -			"; secure"_fmt(o); +		if (secure) { +			"; secure"_fmt(cookieString);  		} -		"; samesite=strict"_fmt(o); -		setHeader(H::SET_COOKIE, o.str()); +		"; samesite=strict"_fmt(cookieString); +		setHeader(H::SET_COOKIE, std::move(cookieString).str());  	}  	void @@ -180,15 +174,15 @@ namespace IceSpider {  	}  	void -	IHttpRequest::modelPartResponse(const IRouteHandler * route, const Slicer::ModelPartForRootParam mp) const +	IHttpRequest::modelPartResponse(const IRouteHandler * route, const Slicer::ModelPartForRootParam modelPart) const  	{ -		auto s = getSerializer(route); -		setHeader(H::CONTENT_TYPE, MimeTypeFmt::get(s.first.group, s.first.type)); +		const auto serializer = getSerializer(route); +		setHeader(H::CONTENT_TYPE, MimeTypeFmt::get(serializer.first.group, serializer.first.type));  		response(200, S::OK); -		s.second->Serialize(mp); +		serializer.second->Serialize(modelPart);  	} -	static_assert(std::is_convertible<OptionalString::value_type, std::string_view>::value); -	static_assert(!std::is_convertible<OptionalString::value_type, std::string>::value); -	static_assert(std::is_constructible<OptionalString::value_type, std::string>::value); +	static_assert(std::is_convertible_v<OptionalString::value_type, std::string_view>); +	static_assert(!std::is_convertible_v<OptionalString::value_type, std::string>); +	static_assert(std::is_constructible_v<OptionalString::value_type, std::string>);  } diff --git a/icespider/core/ihttpRequest.h b/icespider/core/ihttpRequest.h index 9d95069..79bf6aa 100644 --- a/icespider/core/ihttpRequest.h +++ b/icespider/core/ihttpRequest.h @@ -1,11 +1,9 @@  #pragma once -#include "exceptions.h"  #include "util.h"  #include <Ice/Current.h>  #include <boost/lexical_cast.hpp>  #include <c++11Helpers.h> -#include <charconv>  #include <ctime>  #include <http.h>  #include <iosfwd> @@ -41,36 +39,34 @@ namespace IceSpider {  		virtual ~IHttpRequest() = default;  		SPECIAL_MEMBERS_DEFAULT_MOVE_NO_COPY(IHttpRequest); -		[[nodiscard]] Ice::Context getContext() const; +		[[nodiscard]] static Ice::Context getContext();  		[[nodiscard]] virtual const PathElements & getRequestPath() const = 0;  		[[nodiscard]] virtual PathElements & getRequestPath() = 0;  		[[nodiscard]] virtual HttpMethod getRequestMethod() const = 0; -		[[nodiscard]] std::string_view getURLParamStr(const unsigned int) const; -		[[nodiscard]] virtual OptionalString getQueryStringParamStr(const std::string_view) const = 0; -		[[nodiscard]] virtual OptionalString getHeaderParamStr(const std::string_view) const = 0; -		[[nodiscard]] virtual OptionalString getCookieParamStr(const std::string_view) const = 0; -		[[nodiscard]] virtual OptionalString getEnvStr(const std::string_view) const = 0; +		[[nodiscard]] std::string_view getURLParamStr(unsigned int) const; +		[[nodiscard]] virtual OptionalString getQueryStringParamStr(std::string_view) const = 0; +		[[nodiscard]] virtual OptionalString getHeaderParamStr(std::string_view) const = 0; +		[[nodiscard]] virtual OptionalString getCookieParamStr(std::string_view) const = 0; +		[[nodiscard]] virtual OptionalString getEnvStr(std::string_view) const = 0;  		[[nodiscard]] virtual bool isSecure() const = 0;  		[[nodiscard]] static Accepted parseAccept(std::string_view);  		[[nodiscard]] virtual Slicer::DeserializerPtr getDeserializer() const;  		[[nodiscard]] virtual ContentTypeSerializer getSerializer(const IRouteHandler *) const;  		[[nodiscard]] virtual std::istream & getInputStream() const = 0;  		[[nodiscard]] virtual std::ostream & getOutputStream() const = 0; -		virtual void setHeader(const std::string_view, const std::string_view) const = 0; +		virtual void setHeader(std::string_view, std::string_view) const = 0; -		virtual std::ostream & dump(std::ostream & s) const = 0; +		virtual std::ostream & dump(std::ostream & strm) const = 0;  		template<typename T, typename K> -		[[nodiscard]] inline std::optional<T> +		[[nodiscard]] std::optional<T>  		getFrom(const K key, OptionalString (IHttpRequest::*src)(const K) const) const  		{ -			if (auto v = (this->*src)(key)) { -				return convert<T>(*v); -			} -			else { -				return std::nullopt; +			if (auto value = (this->*src)(key)) { +				return convert<T>(*value);  			} +			return std::nullopt;  		}  		template<typename T> @@ -95,29 +91,30 @@ namespace IceSpider {  				return {};  			} -			if (const auto i = map->find(key); i != map->end()) { -				return convert<T>(i->second); +			if (const auto iter = map->find(key); iter != map->end()) { +				return convert<T>(iter->second);  			}  			return {};  		} -		void responseRedirect(const std::string_view url, const OptionalString & = {}) const; -		void setCookie(const std::string_view, const std::string_view, const OptionalString & = {}, -				const OptionalString & = {}, bool = false, std::optional<time_t> = {}); +		void responseRedirect(std::string_view url, const OptionalString & = {}) const; +		void setCookie(std::string_view, std::string_view, const OptionalString & = {}, const OptionalString & = {}, +				bool = false, std::optional<time_t> = {}) const;  		template<typename T> +			requires(!std::same_as<T, std::string_view>)  		void -		setCookie(const std::string_view n, const T & v, const OptionalString & d, const OptionalString & p, bool s, -				std::optional<time_t> e) +		setCookie(const std::string_view n, const T & value, const OptionalString & domain, const OptionalString & path, +				bool secure, std::optional<time_t> expiry)  		{  			if constexpr (std::is_constructible_v<std::string_view, T>) { -				setCookie(n, std::string_view(v), d, p, s, e); +				setCookie(n, std::string_view(value), domain, path, secure, expiry);  			} -			else if constexpr (requires { std::to_string(v); }) { -				setCookie(n, std::to_string(v), d, p, s, e); +			else if constexpr (requires { std::to_string(value); }) { +				setCookie(n, std::to_string(value), domain, path, secure, expiry);  			}  			else { -				setCookie(n, boost::lexical_cast<std::string>(v), d, p, s, e); +				setCookie(n, boost::lexical_cast<std::string>(value), domain, path, secure, expiry);  			}  		} @@ -142,18 +139,18 @@ namespace IceSpider {  			return getFrom<T, std::string_view>(key, &IHttpRequest::getCookieParamStr);  		} -		virtual void response(short, const std::string_view) const = 0; +		virtual void response(short, std::string_view) const = 0;  		template<typename T>  		void -		response(const IRouteHandler * route, const T & t) const +		response(const IRouteHandler * route, const T & value) const  		{ -			Slicer::ModelPart::OnRootFor(t, [this, route](Slicer::ModelPartForRootParam root) { +			Slicer::ModelPart::OnRootFor(value, [this, route](Slicer::ModelPartForRootParam root) {  				modelPartResponse(route, root);  			});  		} -		void modelPartResponse(const IRouteHandler * route, const Slicer::ModelPartForRootParam) const; +		void modelPartResponse(const IRouteHandler * route, Slicer::ModelPartForRootParam) const;  		const Core * core;  	}; diff --git a/icespider/core/irouteHandler.cpp b/icespider/core/irouteHandler.cpp index cb2f216..3f7617c 100644 --- a/icespider/core/irouteHandler.cpp +++ b/icespider/core/irouteHandler.cpp @@ -5,8 +5,6 @@  #include <formatters.h>  #include <optional>  #include <pathparts.h> -#include <set> -#include <sstream>  #include <string>  #include <utility> @@ -17,29 +15,34 @@ namespace IceSpider {  	static const std::string JSON = "json";  	static const std::string APPLICATION_JSON = MimeTypeFmt::get(APPLICATION, JSON); -	const RouteOptions IRouteHandler::defaultRouteOptions {}; +	const RouteOptions IRouteHandler::DEFAULT_ROUTE_OPTIONS {}; -	IRouteHandler::IRouteHandler(HttpMethod m, const std::string_view p) : -		IRouteHandler(m, p, defaultRouteOptions) { } +	IRouteHandler::IRouteHandler(HttpMethod method, const std::string_view path) : +		IRouteHandler(method, path, DEFAULT_ROUTE_OPTIONS) +	{ +	} -	IRouteHandler::IRouteHandler(HttpMethod m, const std::string_view p, const RouteOptions & ro) : Path(p), method(m) +	IRouteHandler::IRouteHandler(HttpMethod method, const std::string_view path, const RouteOptions & routeOpts) : +		Path(path), method(method)  	{ -		if (ro.addDefaultSerializers) { +		if (routeOpts.addDefaultSerializers) {  			auto globalSerializers = AdHoc::PluginManager::getDefault()->getAll<Slicer::StreamSerializerFactory>(); -			for (const auto & gs : globalSerializers) { -				auto slash = gs->name.find('/'); +			for (const auto & serializer : globalSerializers) { +				auto slash = serializer->name.find('/');  				routeSerializers.insert( -						{{gs->name.substr(0, slash), gs->name.substr(slash + 1)}, gs->implementation()}); +						{{.group = serializer->name.substr(0, slash), .type = serializer->name.substr(slash + 1)}, +								serializer->implementation()});  			}  		}  	}  	ContentTypeSerializer -	IRouteHandler::getSerializer(const Accept & a, std::ostream & strm) const +	IRouteHandler::getSerializer(const Accept & accept, std::ostream & strm) const  	{ -		for (const auto & rs : routeSerializers) { -			if ((!a.group || rs.first.group == a.group) && (!a.type || rs.first.type == a.type)) { -				return {rs.first, rs.second->create(strm)}; +		for (const auto & serializer : routeSerializers) { +			if ((!accept.group || serializer.first.group == accept.group) +					&& (!accept.type || serializer.first.type == accept.type)) { +				return {serializer.first, serializer.second->create(strm)};  			}  		}  		return {}; @@ -48,19 +51,20 @@ namespace IceSpider {  	ContentTypeSerializer  	IRouteHandler::defaultSerializer(std::ostream & strm) const  	{ -		return {{APPLICATION, JSON}, Slicer::StreamSerializerFactory::createNew(APPLICATION_JSON, strm)}; +		return {{.group = APPLICATION, .type = JSON}, +				Slicer::StreamSerializerFactory::createNew(APPLICATION_JSON, strm)};  	}  	void -	IRouteHandler::requiredParameterNotFound(const char *, const std::string_view) const +	IRouteHandler::requiredParameterNotFound(const char *, const std::string_view)  	{ -		throw Http400_BadRequest(); +		throw Http400BadRequest();  	}  	void -	IRouteHandler::addRouteSerializer(const MimeType & ct, const StreamSerializerFactoryPtr & ssfp) +	IRouteHandler::addRouteSerializer(const MimeType & contentType, const StreamSerializerFactoryPtr & ssfp)  	{ -		routeSerializers.erase(ct); -		routeSerializers.insert({ct, ssfp}); +		routeSerializers.erase(contentType); +		routeSerializers.emplace(contentType, ssfp);  	}  } diff --git a/icespider/core/irouteHandler.h b/icespider/core/irouteHandler.h index adea779..cd34053 100644 --- a/icespider/core/irouteHandler.h +++ b/icespider/core/irouteHandler.h @@ -22,10 +22,10 @@ namespace IceSpider {  	class DLL_PUBLIC IRouteHandler : public Path {  	public: -		const static RouteOptions defaultRouteOptions; +		const static RouteOptions DEFAULT_ROUTE_OPTIONS; -		IRouteHandler(HttpMethod, const std::string_view path); -		IRouteHandler(HttpMethod, const std::string_view path, const RouteOptions &); +		IRouteHandler(HttpMethod, std::string_view path); +		IRouteHandler(HttpMethod, std::string_view path, const RouteOptions &);  		SPECIAL_MEMBERS_MOVE_RO(IRouteHandler);  		virtual ~IRouteHandler() = default; @@ -40,13 +40,13 @@ namespace IceSpider {  		using RouteSerializers = std::map<MimeType, StreamSerializerFactoryPtr>;  		RouteSerializers routeSerializers; -		[[noreturn]] void requiredParameterNotFound(const char *, const std::string_view key) const; +		[[noreturn]] static void requiredParameterNotFound(const char *, std::string_view key);  		template<typename T, typename K> -		inline T -		requiredParameterNotFound(const char * s, const K & key) const +		static T +		requiredParameterNotFound(const char * source, const K & key)  		{ -			requiredParameterNotFound(s, key); +			requiredParameterNotFound(source, key);  		}  		void addRouteSerializer(const MimeType &, const StreamSerializerFactoryPtr &); diff --git a/icespider/core/util-test.cpp b/icespider/core/util-test.cpp index df79fb2..8966804 100644 --- a/icespider/core/util-test.cpp +++ b/icespider/core/util-test.cpp @@ -5,9 +5,9 @@ namespace foo ::bar {  	class really;  } -static_assert(type_names<int>::name() == "int"); -static_assert(type_names<int>::namespaces() == 0); +static_assert(TypeNames<int>::name() == "int"); +static_assert(TypeNames<int>::namespaces() == 0);  static_assert(TypeName<int>::str() == "int"); -static_assert(type_names<foo::bar::really>::name() == "foo::bar::really"); -static_assert(type_names<foo::bar::really>::namespaces() == 2); +static_assert(TypeNames<foo::bar::really>::name() == "foo::bar::really"); +static_assert(TypeNames<foo::bar::really>::namespaces() == 2);  static_assert(TypeName<foo::bar::really>::str() == "foo.bar.really"); diff --git a/icespider/core/util.cpp b/icespider/core/util.cpp index 5e51b8b..f808d6b 100644 --- a/icespider/core/util.cpp +++ b/icespider/core/util.cpp @@ -3,8 +3,8 @@  namespace IceSpider {  	void -	conversion_failure() +	conversionFailure()  	{ -		throw Http400_BadRequest(); +		throw Http400BadRequest();  	}  } diff --git a/icespider/core/util.h b/icespider/core/util.h index cbbd318..ae7316c 100644 --- a/icespider/core/util.h +++ b/icespider/core/util.h @@ -12,48 +12,48 @@  namespace std::experimental::Ice {  	template<typename T, typename TF>  	inline const T & -	operator/(const Ice::optional<T> & o, const TF & tf) +	operator/(const Ice::optional<T> & value, const TF & whenNullOpt)  	{ -		if (o) { -			return *o; +		if (value) { +			return *value;  		} -		return tf(); +		return whenNullOpt();  	}  	template<typename T, typename TF>  	inline T -	operator/(Ice::optional<T> && o, const TF & tf) +	operator/(Ice::optional<T> && value, const TF & whenNullOpt)  	{ -		if (o) { -			return std::move(*o); +		if (value) { +			return *std::move(value);  		} -		return tf(); +		return whenNullOpt();  	}  }  namespace std {  	template<typename T, typename TF>  	inline const T & -	operator/(const std::optional<T> & o, const TF & tf) +	operator/(const std::optional<T> & value, const TF & whenNullOpt)  	{ -		if (o) { -			return *o; +		if (value) { +			return *value;  		} -		return tf(); +		return whenNullOpt();  	}  	template<typename T, typename TF>  	inline T -	operator/(std::optional<T> && o, const TF & tf) +	operator/(std::optional<T> && value, const TF & whenNullOpt)  	{ -		if (o) { -			return std::move(*o); +		if (value) { +			return *std::move(value);  		} -		return tf(); +		return whenNullOpt();  	}  } -template<typename T> struct type_names { +template<typename T> struct TypeNames {  	static constexpr auto  	pf()  	{ @@ -63,46 +63,46 @@ template<typename T> struct type_names {  	static constexpr auto  	name()  	{ -		constexpr std::string_view with_T {"T = "}; -		constexpr auto start {pf().find(with_T) + with_T.length()}; -		constexpr auto end {pf().find(']', start)}; -		constexpr auto name {pf().substr(start, end - start)}; -		static_assert(name.find('<') == std::string_view::npos, "Templates not supported"); -		return name; +		constexpr std::string_view WITH_T {"T = "}; +		constexpr auto START {pf().find(WITH_T) + WITH_T.length()}; +		constexpr auto END {pf().find(']', START)}; +		constexpr auto NAME {pf().substr(START, END - START)}; +		static_assert(NAME.find('<') == std::string_view::npos, "Templates not supported"); +		return NAME;  	}  	static constexpr auto  	namespaces()  	{ -		return std::count(name().begin(), name().end(), ':') / 2; +		return std::ranges::count(name(), ':') / 2;  	} -	using char_type = typename decltype(name())::value_type; +	using CharType = typename decltype(name())::value_type;  }; -template<typename T> class TypeName : type_names<T> { +template<typename T> class TypeName : TypeNames<T> {  public: -	constexpr static inline auto +	constexpr static auto  	str()  	{ -		return std::string_view {buf.data(), buf.size() - 1}; +		return std::string_view {BUF.data(), BUF.size() - 1};  	} -	constexpr static inline auto -	c_str() +	constexpr static auto +	c_str() // NOLINT(readability-identifier-naming) - STL like  	{ -		return buf.data(); +		return BUF.data();  	}  private: -	using tn = type_names<T>; +	using Tn = TypeNames<T>; -	constexpr static auto buf {[]() { -		std::array<typename tn::char_type, tn::name().length() - tn::namespaces() + 1> buf {}; +	constexpr static auto BUF {[]() { +		std::array<typename Tn::CharType, Tn::name().length() - Tn::namespaces() + 1> buf {};  		auto out {buf.begin()};  		auto cln = false; -		for (const auto & in : tn::name()) { -			if (in == ':') { +		for (const auto & input : Tn::name()) { +			if (input == ':') {  				if (cln) {  					*out++ = '.';  				} @@ -111,7 +111,7 @@ private:  				}  			}  			else { -				*out++ = in; +				*out++ = input;  				cln = false;  			}  		} @@ -120,7 +120,7 @@ private:  };  namespace IceSpider { -	[[noreturn]] DLL_PUBLIC void conversion_failure(); +	[[noreturn]] DLL_PUBLIC void conversionFailure();  	static_assert(std::is_assignable_v<std::string, std::string_view>);  	static_assert(std::is_assignable_v<std::string_view, std::string_view>); @@ -128,20 +128,20 @@ namespace IceSpider {  	namespace {  		template<typename T>  		inline T -		from_chars(const std::string_view v, T && out) +		from_chars(const std::string_view chars, T && out) // NOLINT(readability-identifier-naming) - STL like  		{ -			if (std::from_chars(v.begin(), v.end(), out).ec != std::errc {}) { -				conversion_failure(); +			if (std::from_chars(chars.begin(), chars.end(), std::forward<T>(out)).ec != std::errc {}) { +				conversionFailure();  			}  			return out;  		}  		template<typename T>  		inline T -		lexical_cast(const std::string_view v, T && out) +		lexical_cast(const std::string_view value, T && out) // NOLINT(readability-identifier-naming) - Boost like  		{ -			if (!boost::conversion::try_lexical_convert(v, out)) { -				conversion_failure(); +			if (!boost::conversion::try_lexical_convert(value, std::forward<T>(out))) { +				conversionFailure();  			}  			return out;  		} @@ -149,32 +149,40 @@ namespace IceSpider {  	template<typename T>  	inline T -	convert(const std::string_view v, T && out = {}) +	convert(const std::string_view value, T && out)  	{  		if constexpr (std::is_assignable_v<T, std::string_view>) { -			return (out = v); +			return (out = value);  		} -		else if constexpr (requires { std::from_chars(v.begin(), v.end(), out); }) { -			return from_chars(v, out); +		else if constexpr (requires { std::from_chars(value.begin(), value.end(), out); }) { +			return from_chars(value, std::forward<T>(out));  		}  		else { -			return lexical_cast(v, out); +			return lexical_cast(value, std::forward<T>(out));  		}  	} +	template<typename T> +	inline T +	convert(const std::string_view value) +	{ +		T tmp; +		return convert(value, tmp); +	} +  	inline void -	remove_trailing(std::string_view & in, const char c) +	remove_trailing(std::string_view & input, const char chr) // NOLINT(readability-identifier-naming) - STL like  	{ -		if (const auto n = in.find_last_not_of(c); n != std::string_view::npos) { -			in.remove_suffix(in.length() - n - 1); +		if (const auto pos = input.find_last_not_of(chr); pos != std::string_view::npos) { +			input.remove_suffix(input.length() - pos - 1);  		}  	}  	inline void -	remove_leading(std::string_view & in, const char c) +	remove_leading(std::string_view & input, const char chr) // NOLINT(readability-identifier-naming) - STL like  	{ -		if (const auto n = in.find_first_not_of(c); n != std::string_view::npos) { -			in.remove_prefix(n); +		if (const auto pos = input.find_first_not_of(chr); pos != std::string_view::npos) { +			input.remove_prefix(pos);  		}  	}  } diff --git a/icespider/core/xwwwFormUrlEncoded.cpp b/icespider/core/xwwwFormUrlEncoded.cpp index 3cb0ece..40b42c6 100644 --- a/icespider/core/xwwwFormUrlEncoded.cpp +++ b/icespider/core/xwwwFormUrlEncoded.cpp @@ -13,7 +13,6 @@  #include <iterator>  #include <limits>  #include <maybeString.h> -#include <memory>  #include <optional>  #include <slicer/modelParts.h>  #include <slicer/serializer.h> @@ -22,100 +21,124 @@  namespace ba = boost::algorithm;  using namespace std::literals; -constexpr auto CHARMAX = std::numeric_limits<unsigned char>::max(); +namespace { +	constexpr auto CHARMAX = std::numeric_limits<unsigned char>::max(); -using HexPair = std::pair<char, char>; -using HexOut = std::array<HexPair, CHARMAX>; -constexpr auto hexout = []() { -	auto hexchar = [](auto c) { -		return static_cast<char>(c < 10 ? '0' + c : 'a' - 10 + c); -	}; -	HexOut out {}; -	for (unsigned int n = 0; n < CHARMAX; n++) { -		switch (n) { -			case ' ': -				out[n].first = '+'; -				break; -			case 'a' ... 'z': -			case 'A' ... 'Z': -			case '0' ... '9': -			case '-': -			case '.': -			case '_': -			case '~': -				// No special encoding -				break; -			default: -				out[n].first = hexchar(n >> 4U); -				out[n].second = hexchar(n & 0xfU); -				break; +	// NOLINTBEGIN(readability-magic-numbers) +	using HexPair = std::pair<char, char>; +	using HexOut = std::array<HexPair, CHARMAX>; +	constexpr auto HEXOUT = []() { +		auto hexchar = [](auto chr) { +			return static_cast<char>(chr < 10 ? '0' + chr : 'a' - 10 + chr); +		}; +		HexOut out {}; +		for (unsigned int chr = 0; chr < CHARMAX; chr++) { +			switch (chr) { +				case ' ': +					out[chr].first = '+'; +					break; +				case 'a' ... 'z': +				case 'A' ... 'Z': +				case '0' ... '9': +				case '-': +				case '.': +				case '_': +				case '~': +					// No special encoding +					break; +				default: +					out[chr].first = hexchar(chr >> 4U); +					out[chr].second = hexchar(chr & 0xfU); +					break; +			}  		} -	} -	return out; -}(); +		return out; +	}(); -static_assert(hexout['a'].first == 0); -static_assert(hexout['a'].second == 0); -static_assert(hexout['z'].first == 0); -static_assert(hexout['z'].second == 0); -static_assert(hexout['A'].first == 0); -static_assert(hexout['A'].second == 0); -static_assert(hexout['Z'].first == 0); -static_assert(hexout['Z'].second == 0); -static_assert(hexout['0'].first == 0); -static_assert(hexout['9'].second == 0); -static_assert(hexout['~'].first == 0); -static_assert(hexout['~'].second == 0); -static_assert(hexout[' '].first == '+'); -static_assert(hexout[' '].second == 0); -static_assert(hexout['?'].first == '3'); -static_assert(hexout['?'].second == 'f'); +	static_assert(HEXOUT['a'].first == 0); +	static_assert(HEXOUT['a'].second == 0); +	static_assert(HEXOUT['z'].first == 0); +	static_assert(HEXOUT['z'].second == 0); +	static_assert(HEXOUT['A'].first == 0); +	static_assert(HEXOUT['A'].second == 0); +	static_assert(HEXOUT['Z'].first == 0); +	static_assert(HEXOUT['Z'].second == 0); +	static_assert(HEXOUT['0'].first == 0); +	static_assert(HEXOUT['9'].second == 0); +	static_assert(HEXOUT['~'].first == 0); +	static_assert(HEXOUT['~'].second == 0); +	static_assert(HEXOUT[' '].first == '+'); +	static_assert(HEXOUT[' '].second == 0); +	static_assert(HEXOUT['?'].first == '3'); +	static_assert(HEXOUT['?'].second == 'f'); -constexpr std::array<std::optional<unsigned char>, CHARMAX> hextable = []() { -	std::array<std::optional<unsigned char>, CHARMAX> hextable {}; -	for (size_t n = '0'; n <= '9'; n++) { -		hextable[n] = {n - '0'}; -	} -	for (size_t n = 'a'; n <= 'f'; n++) { -		hextable[n] = hextable[n - 32] = {n - 'a' + 10}; -	} -	return hextable; -}(); +	constexpr std::array<std::optional<unsigned char>, CHARMAX> HEXTABLE = []() { +		std::array<std::optional<unsigned char>, CHARMAX> hextable {}; +		for (size_t chr = '0'; chr <= '9'; chr++) { +			hextable[chr] = {chr - '0'}; +		} +		for (size_t chr = 'a'; chr <= 'f'; chr++) { +			hextable[chr] = hextable[chr - 32] = {chr - 'a' + 10}; +		} +		return hextable; +	}(); -static_assert(!hextable['~'].has_value()); -static_assert(!hextable[' '].has_value()); -static_assert(hextable['0'] == 0); -static_assert(hextable['9'] == 9); -static_assert(hextable['a'] == 10); -static_assert(hextable['A'] == 10); -static_assert(hextable['f'] == 15); -static_assert(hextable['F'] == 15); -static_assert(!hextable['g'].has_value()); -static_assert(!hextable['G'].has_value()); +	static_assert(!HEXTABLE['~'].has_value()); +	static_assert(!HEXTABLE[' '].has_value()); +	static_assert(HEXTABLE['0'] == 0); +	static_assert(HEXTABLE['9'] == 9); +	static_assert(HEXTABLE['a'] == 10); +	static_assert(HEXTABLE['A'] == 10); +	static_assert(HEXTABLE['f'] == 15); +	static_assert(HEXTABLE['F'] == 15); +	static_assert(!HEXTABLE['g'].has_value()); +	static_assert(!HEXTABLE['G'].has_value()); +	// NOLINTEND(readability-magic-numbers) -using HexIn = std::array<std::array<char, CHARMAX>, CHARMAX>; -constexpr HexIn hexin = []() { -	HexIn hexin {}; -	size_t firstHex = std::min({'0', 'a', 'A'}); -	size_t lastHex = std::max({'9', 'f', 'F'}); -	for (auto first = firstHex; first <= lastHex; first++) { -		if (const auto & ch1 = hextable[first]) { -			for (auto second = firstHex; second <= lastHex; second++) { -				if (const auto & ch2 = hextable[second]) { -					hexin[first][second] = static_cast<char>((*ch1 << 4U) + *ch2); +	using HexIn = std::array<std::array<char, CHARMAX>, CHARMAX>; +	constexpr HexIn HEXIN = []() { +		HexIn hexin {}; +		size_t firstHex = std::min({'0', 'a', 'A'}); +		size_t lastHex = std::max({'9', 'f', 'F'}); +		for (auto first = firstHex; first <= lastHex; first++) { +			if (const auto & ch1 = HEXTABLE[first]) { +				for (auto second = firstHex; second <= lastHex; second++) { +					if (const auto & ch2 = HEXTABLE[second]) { +						hexin[first][second] = static_cast<char>((*ch1 << 4U) + *ch2); +					}  				}  			}  		} -	} -	hexin['+'][0] = ' '; -	return hexin; -}(); +		hexin['+'][0] = ' '; +		return hexin; +	}(); -static_assert(hexin[' '][' '] == 0); -static_assert(hexin['0']['a'] == '\n'); -static_assert(hexin['+'][0] == ' '); -static_assert(hexin['3']['f'] == '?'); -static_assert(hexin['3']['F'] == '?'); +	static_assert(HEXIN[' '][' '] == 0); +	static_assert(HEXIN['0']['a'] == '\n'); +	static_assert(HEXIN['+'][0] == ' '); +	static_assert(HEXIN['3']['f'] == '?'); +	static_assert(HEXIN['3']['F'] == '?'); + +	constexpr auto +	urlEncodeRange(auto && outIter, auto input, auto end) +	{ +		while (input != end) { +			const auto & out = HEXOUT[static_cast<uint8_t>(*input)]; +			if (out.second) { +				outIter = '%'; +				outIter = out.first; +				outIter = out.second; +			} +			else if (out.first) { +				outIter = (out.first); +			} +			else { +				outIter = (*input); +			} +			++input; +		} +	} +}  namespace IceSpider {  	static constexpr const std::string_view AMP = "&"; @@ -125,63 +148,63 @@ namespace IceSpider {  	static constexpr const std::string_view VALUE = "value";  	static constexpr const std::string_view URL_ESCAPES = "%+"; -	XWwwFormUrlEncoded::XWwwFormUrlEncoded(std::istream & in) : -		input(std::istreambuf_iterator<char>(in), std::istreambuf_iterator<char>()) +	XWwwFormUrlEncoded::XWwwFormUrlEncoded(std::istream & input) : +		input(std::istreambuf_iterator<char>(input), std::istreambuf_iterator<char>())  	{  	}  	void -	XWwwFormUrlEncoded::Deserialize(Slicer::ModelPartForRootParam mp) +	XWwwFormUrlEncoded::Deserialize(Slicer::ModelPartForRootParam modelPart)  	{ -		mp->Create(); -		mp->OnEachChild([this](auto, auto mp, auto) { -			switch (mp->GetType()) { +		modelPart->Create(); +		modelPart->OnEachChild([this](const auto &, auto child, auto) { +			switch (child->GetType()) {  				case Slicer::ModelPartType::Simple: -					this->DeserializeSimple(mp); +					this->deserializeSimple(child);  					break;  				case Slicer::ModelPartType::Complex: -					this->DeserializeComplex(mp); +					this->deserializeComplex(child);  					break;  				case Slicer::ModelPartType::Dictionary: -					this->DeserializeDictionary(mp); +					this->deserializeDictionary(child);  					break;  				default: -					throw IceSpider::Http400_BadRequest(); +					throw IceSpider::Http400BadRequest();  					break;  			}  		}); -		mp->Complete(); +		modelPart->Complete();  	}  	class SetFromString : public Slicer::ValueSource {  	public: -		explicit SetFromString(const MaybeString & v) : s(v) { } +		explicit SetFromString(const MaybeString & value) : s(value) { }  		void -		set(bool & t) const override +		set(bool & target) const override  		{  			if (s == TRUE) { -				t = true; +				target = true;  			}  			else if (s == FALSE) { -				t = false; +				target = false;  			}  			else { -				throw Http400_BadRequest(); +				throw Http400BadRequest();  			}  		}  		void -		set(std::string & t) const override +		set(std::string & target) const override  		{ -			t = s; +			target = s;  		}  #define SET(T) \  	/* NOLINTNEXTLINE(bugprone-macro-parentheses) */ \ -	void set(T & t) const override \ +	void set(T & target) const override \  	{ \ -		convert(s, t); \ +		convert(s, target); \  	}  		SET(Ice::Byte); @@ -196,149 +219,134 @@ namespace IceSpider {  	};  	std::string -	XWwwFormUrlEncoded::urlencode(const std::string_view s) +	XWwwFormUrlEncoded::urlencode(const std::string_view str)  	{ -		return urlencode(s.begin(), s.end()); +		return urlencode(str.begin(), str.end());  	} -	constexpr auto urlencoderange = [](auto && o, auto i, auto e) { -		while (i != e) { -			const auto & out = hexout[static_cast<uint8_t>(*i)]; -			if (out.second) { -				o = '%'; -				o = out.first; -				o = out.second; -			} -			else if (out.first) { -				o = (out.first); -			} -			else { -				o = (*i); -			} -			++i; -		} -	}; -  	std::string -	XWwwFormUrlEncoded::urlencode(std::string_view::const_iterator i, std::string_view::const_iterator e) +	XWwwFormUrlEncoded::urlencode(std::string_view::const_iterator input, std::string_view::const_iterator end)  	{ -		std::string o; -		o.reserve(static_cast<std::string::size_type>(std::distance(i, e))); -		urlencoderange(std::back_inserter(o), i, e); -		return o; +		std::string out; +		out.reserve(static_cast<std::string::size_type>(std::distance(input, end))); +		urlEncodeRange(std::back_inserter(out), input, end); +		return out;  	}  	void  	XWwwFormUrlEncoded::urlencodeto( -			std::ostream & o, std::string_view::const_iterator i, std::string_view::const_iterator e) +			std::ostream & outStrm, std::string_view::const_iterator input, std::string_view::const_iterator end)  	{ -		urlencoderange(std::ostream_iterator<decltype(*i)>(o), i, e); +		urlEncodeRange(std::ostream_iterator<decltype(*input)>(outStrm), input, end);  	}  	MaybeString -	XWwwFormUrlEncoded::urldecode(std::string_view::const_iterator i, std::string_view::const_iterator e) +	XWwwFormUrlEncoded::urlDecode(std::string_view::const_iterator input, std::string_view::const_iterator end)  	{ -		const auto getNext = [e, &i] { -			return std::find_first_of(i, e, URL_ESCAPES.begin(), URL_ESCAPES.end()); +		const auto getNext = [end, &input] { +			return std::find_first_of(input, end, URL_ESCAPES.begin(), URL_ESCAPES.end());  		};  		auto next = getNext(); -		if (next == e) { -			return std::string_view {i, e}; +		if (next == end) { +			return std::string_view {input, end};  		} -		std::string t; -		t.reserve(static_cast<std::string::size_type>(std::distance(i, e))); -		for (; i != e; next = getNext()) { -			if (next != i) { -				t.append(i, next); -				i = next; +		std::string target; +		target.reserve(static_cast<std::string::size_type>(std::distance(input, end))); +		for (; input != end; next = getNext()) { +			if (next != input) { +				target.append(input, next); +				input = next;  			}  			else { -				switch (*i) { +				switch (*input) {  					case '+': -						t += ' '; -						++i; +						target += ' '; +						++input;  						break;  					case '%': -						if (const auto ch = hexin[static_cast<uint8_t>(*(i + 1))][static_cast<uint8_t>(*(i + 2))]) { -							t += ch; +						if (const auto chr +								= HEXIN[static_cast<uint8_t>(*(input + 1))][static_cast<uint8_t>(*(input + 2))]) { +							target += chr;  						}  						else { -							throw Http400_BadRequest(); +							throw Http400BadRequest();  						} -						i += 3; +						input += 3;  						break; +					default: +						std::unreachable();  				}  			}  		} -		return t; +		return target;  	}  	void -	XWwwFormUrlEncoded::iterateVars(const KVh & h, ba::split_iterator<std::string_view::const_iterator> pi) +	XWwwFormUrlEncoded::iterateVars(const KVh & handler, ba::split_iterator<std::string_view::const_iterator> pi)  	{  		for (; pi != decltype(pi)(); ++pi) { -			auto eq = std::find(pi->begin(), pi->end(), '='); -			if (eq == pi->end()) { -				h(urldecode(pi->begin(), pi->end()), {}); +			auto equalPos = std::find(pi->begin(), pi->end(), '='); +			if (equalPos == pi->end()) { +				handler(urlDecode(pi->begin(), pi->end()), {});  			}  			else { -				h(urldecode(pi->begin(), eq), urldecode(eq + 1, pi->end())); +				handler(urlDecode(pi->begin(), equalPos), urlDecode(equalPos + 1, pi->end()));  			}  		}  	}  	void -	XWwwFormUrlEncoded::iterateVars(const std::string_view input, const KVh & h, const std::string_view split) +	XWwwFormUrlEncoded::iterateVars(const std::string_view input, const KVh & handler, const std::string_view split)  	{  		if (!input.empty()) { -			iterateVars(h, ba::make_split_iterator(input, ba::first_finder(split, ba::is_equal()))); +			iterateVars(handler, ba::make_split_iterator(input, ba::first_finder(split, ba::is_equal())));  		}  	}  	void -	XWwwFormUrlEncoded::iterateVars(const KVh & h) +	XWwwFormUrlEncoded::iterateVars(const KVh & handler)  	{ -		iterateVars(input, h, AMP); +		iterateVars(input, handler, AMP);  	}  	void -	XWwwFormUrlEncoded::DeserializeSimple(const Slicer::ModelPartParam mp) +	XWwwFormUrlEncoded::deserializeSimple(const Slicer::ModelPartParam modelPart)  	{ -		iterateVars([mp](auto &&, const auto && v) { -			mp->SetValue(SetFromString(std::forward<decltype(v)>(v))); +		iterateVars([modelPart](auto &&, const auto && value) { +			modelPart->SetValue(SetFromString(std::forward<decltype(value)>(value)));  		});  	}  	void -	XWwwFormUrlEncoded::DeserializeComplex(const Slicer::ModelPartParam mp) +	XWwwFormUrlEncoded::deserializeComplex(const Slicer::ModelPartParam modelPart)  	{ -		mp->Create(); -		iterateVars([mp](auto && k, const auto && v) { -			mp->OnChild( -					[&v](Slicer::ModelPartParam m, const Slicer::Metadata &) { -						m->SetValue(SetFromString(std::forward<decltype(v)>(v))); +		modelPart->Create(); +		iterateVars([modelPart](auto && key, const auto && value) { +			modelPart->OnChild( +					[&value](Slicer::ModelPartParam child, const Slicer::Metadata &) { +						child->SetValue(SetFromString(std::forward<decltype(value)>(value)));  					}, -					k); +					key);  		}); -		mp->Complete(); +		modelPart->Complete();  	}  	void -	XWwwFormUrlEncoded::DeserializeDictionary(const Slicer::ModelPartParam mp) +	XWwwFormUrlEncoded::deserializeDictionary(const Slicer::ModelPartParam modelPart)  	{ -		iterateVars([mp](auto && k, const auto && v) { -			mp->OnAnonChild([&k, &v](Slicer::ModelPartParam p, const Slicer::Metadata &) { -				p->OnChild( -						[&k](Slicer::ModelPartParam kp, const Slicer::Metadata &) { -							kp->SetValue(SetFromString(std::forward<decltype(k)>(k))); +		iterateVars([modelPart](auto && key, const auto && value) { +			modelPart->OnAnonChild([&key, &value](Slicer::ModelPartParam child, const Slicer::Metadata &) { +				child->OnChild( +						[&key](Slicer::ModelPartParam keyPart, const Slicer::Metadata &) { +							keyPart->SetValue(SetFromString(std::forward<decltype(key)>(key)));  						},  						KEY); -				p->OnChild( -						[&v](Slicer::ModelPartParam vp, const Slicer::Metadata &) { -							vp->SetValue(SetFromString(std::forward<decltype(v)>(v))); +				child->OnChild( +						[&value](Slicer::ModelPartParam valuePart, const Slicer::Metadata &) { +							valuePart->SetValue(SetFromString(std::forward<decltype(value)>(value)));  						},  						VALUE); -				p->Complete(); +				child->Complete();  			});  		});  	} diff --git a/icespider/core/xwwwFormUrlEncoded.h b/icespider/core/xwwwFormUrlEncoded.h index 89cf9bc..8182d19 100644 --- a/icespider/core/xwwwFormUrlEncoded.h +++ b/icespider/core/xwwwFormUrlEncoded.h @@ -17,16 +17,16 @@ namespace IceSpider {  	public:  		using KVh = std::function<void(MaybeString &&, MaybeString &&)>; -		explicit XWwwFormUrlEncoded(std::istream & in); +		explicit XWwwFormUrlEncoded(std::istream & input); -		void Deserialize(Slicer::ModelPartForRootParam mp) override; -		DLL_PUBLIC static void iterateVars(const std::string_view input, const KVh & h, const std::string_view split); +		void Deserialize(Slicer::ModelPartForRootParam modelPart) override; +		DLL_PUBLIC static void iterateVars(std::string_view input, const KVh & h, std::string_view split); -		DLL_PUBLIC static MaybeString urldecode(std::string_view::const_iterator s, std::string_view::const_iterator); -		DLL_PUBLIC static std::string urlencode(std::string_view::const_iterator s, std::string_view::const_iterator); +		DLL_PUBLIC static MaybeString urlDecode(std::string_view::const_iterator, std::string_view::const_iterator); +		DLL_PUBLIC static std::string urlencode(std::string_view::const_iterator, std::string_view::const_iterator);  		DLL_PUBLIC static void urlencodeto( -				std::ostream &, std::string_view::const_iterator s, std::string_view::const_iterator); -		DLL_PUBLIC static std::string urlencode(const std::string_view s); +				std::ostream &, std::string_view::const_iterator, std::string_view::const_iterator); +		DLL_PUBLIC static std::string urlencode(std::string_view);  	private:  		static inline void iterateVars( @@ -34,9 +34,9 @@ namespace IceSpider {  		void iterateVars(const KVh & h); -		void DeserializeSimple(const Slicer::ModelPartParam mp); -		void DeserializeComplex(const Slicer::ModelPartParam mp); -		void DeserializeDictionary(const Slicer::ModelPartParam mp); +		void deserializeSimple(Slicer::ModelPartParam modelPart); +		void deserializeComplex(Slicer::ModelPartParam modelPart); +		void deserializeDictionary(Slicer::ModelPartParam modelPart);  		const std::string input;  	}; diff --git a/icespider/fcgi/cgiRequest.cpp b/icespider/fcgi/cgiRequest.cpp index 2692d07..5079813 100644 --- a/icespider/fcgi/cgiRequest.cpp +++ b/icespider/fcgi/cgiRequest.cpp @@ -1,10 +1,9 @@  #include "cgiRequest.h"  #include <iostream> -#include <span>  namespace IceSpider { -	CgiRequest::CgiRequest(Core * c, int argc, char ** argv, char ** env) : -		CgiRequestBase(c, EnvNTL {env}, EnvArray {argv, static_cast<size_t>(argc)}) +	CgiRequest::CgiRequest(Core * core, int argc, char ** argv, char ** env) : +		CgiRequestBase(core, EnvNTL {env}, EnvArray {argv, static_cast<size_t>(argc)})  	{  	} diff --git a/icespider/fcgi/cgiRequest.h b/icespider/fcgi/cgiRequest.h index 2282334..8614254 100644 --- a/icespider/fcgi/cgiRequest.h +++ b/icespider/fcgi/cgiRequest.h @@ -8,7 +8,7 @@ namespace IceSpider {  	class CgiRequest : public CgiRequestBase {  	public: -		CgiRequest(Core * c, int argc, char ** argv, char ** env); +		CgiRequest(Core * core, int argc, char ** argv, char ** env);  		[[nodiscard]] std::istream & getInputStream() const override;  		[[nodiscard]] std::ostream & getOutputStream() const override; diff --git a/icespider/fcgi/cgiRequestBase.cpp b/icespider/fcgi/cgiRequestBase.cpp index 33fdd7b..5a07b92 100644 --- a/icespider/fcgi/cgiRequestBase.cpp +++ b/icespider/fcgi/cgiRequestBase.cpp @@ -14,7 +14,6 @@  #include <slicer/common.h>  #include <slicer/modelPartsTypes.h>  #include <utility> -#include <vector>  namespace ba = boost::algorithm;  using namespace std::literals; @@ -22,63 +21,75 @@ using namespace std::literals;  #define CGI_CONST(NAME) static constexpr std::string_view NAME(#NAME)  namespace IceSpider { -	static const auto slash_pred = boost::algorithm::is_any_of("/"); -	constexpr std::string_view amp("&"); -	constexpr std::string_view semi("; "); -	constexpr std::string_view HEADER_PREFIX("HTTP_"); -	CGI_CONST(HTTPS); -	CGI_CONST(REDIRECT_URL); -	CGI_CONST(SCRIPT_NAME); -	CGI_CONST(QUERY_STRING); -	CGI_CONST(HTTP_COOKIE); -	CGI_CONST(REQUEST_METHOD); - -	template<typename in, typename out> -	inline void -	mapVars(const std::string_view vn, const in & envmap, out & map, const std::string_view sp) -	{ -		auto qs = envmap.find(vn); -		if (qs != envmap.end()) { -			XWwwFormUrlEncoded::iterateVars( -					qs->second, -					[&map](auto && k, auto && v) { -						map.insert({std::forward<decltype(k)>(k), std::forward<decltype(v)>(v)}); -					}, -					sp); +	namespace { +		const auto SLASH_PRED = boost::algorithm::is_any_of("/"); +		constexpr std::string_view AMP("&"); +		constexpr std::string_view SEMI("; "); +		constexpr std::string_view HEADER_PREFIX("HTTP_"); +		CGI_CONST(HTTPS); +		CGI_CONST(REDIRECT_URL); +		CGI_CONST(SCRIPT_NAME); +		CGI_CONST(QUERY_STRING); +		CGI_CONST(HTTP_COOKIE); +		CGI_CONST(REQUEST_METHOD); + +		template<typename In, typename Out> +		inline void +		mapVars(const std::string_view key, const In & envmap, Out & map, const std::string_view separators) +		{ +			auto qs = envmap.find(key); +			if (qs != envmap.end()) { +				XWwwFormUrlEncoded::iterateVars( +						qs->second, +						[&map](auto && key, auto && value) { +							map.insert({std::forward<decltype(key)>(key), std::forward<decltype(value)>(value)}); +						}, +						separators); +			}  		} -	} -	template<typename Ex, typename Map, typename... Ks> -	const std::string_view -	findFirstOrElse(const Map & map, const std::string_view k, const Ks &... ks) -	{ -		if (const auto i = map.find(k); i != map.end()) { -			return i->second; +		template<typename Ex, typename Map, typename... Ks> +		std::string_view +		findFirstOrElse(const Map & map, const std::string_view key, const Ks &... ks) +		{ +			if (const auto iter = map.find(key); iter != map.end()) { +				return iter->second; +			} +			if constexpr (sizeof...(ks)) { +				return findFirstOrElse<Ex>(map, ks...); +			} +			throw Ex();  		} -		if constexpr (sizeof...(ks)) { -			return findFirstOrElse<Ex>(map, ks...); + +		template<typename Fmt, typename Map> +		void +		dumpMap(std::ostream & strm, const std::string_view name, const Map & map) +		{ +			strm << name << '\n'; +			for (const auto & [key, value] : map) { +				Fmt::write(strm, key, value); +			}  		} -		throw Ex();  	} -	CgiRequestBase::CgiRequestBase(Core * c, const EnvArray envs, const EnvArray extra) : IHttpRequest(c) +	CgiRequestBase::CgiRequestBase(Core * core, const EnvArray envs, const EnvArray extra) : IHttpRequest(core)  	{  		for (const auto & envdata : {envs, extra}) { -			for (const std::string_view e : envdata) { -				if (const auto eq = e.find('='); eq != std::string_view::npos) { -					envmap.insert({e.substr(0, eq), e.substr(eq + 1)}); +			for (const std::string_view env : envdata) { +				if (const auto equalPos = env.find('='); equalPos != std::string_view::npos) { +					envmap.emplace(env.substr(0, equalPos), env.substr(equalPos + 1));  				}  			}  		} -		if (auto path = findFirstOrElse<Http400_BadRequest>(envmap, REDIRECT_URL, SCRIPT_NAME).substr(1); +		if (auto path = findFirstOrElse<Http400BadRequest>(envmap, REDIRECT_URL, SCRIPT_NAME).substr(1);  				// NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks)  				!path.empty()) { -			ba::split(pathElements, path, slash_pred, ba::token_compress_off); +			ba::split(pathElements, path, SLASH_PRED, ba::token_compress_off);  		} -		mapVars(QUERY_STRING, envmap, qsmap, amp); -		mapVars(HTTP_COOKIE, envmap, cookiemap, semi); +		mapVars(QUERY_STRING, envmap, qsmap, AMP); +		mapVars(HTTP_COOKIE, envmap, cookiemap, SEMI);  		for (auto header = envmap.lower_bound(HEADER_PREFIX);  				header != envmap.end() && ba::starts_with(header->first, HEADER_PREFIX); header++) {  			hdrmap.insert({header->first.substr(HEADER_PREFIX.length()), header->second}); @@ -88,38 +99,28 @@ namespace IceSpider {  	AdHocFormatter(VarFmt, "\t%?: [%?]\n");  	AdHocFormatter(PathFmt, "\t[%?]\n"); -	template<typename Fmt, typename Map> -	void -	dumpMap(std::ostream & s, const std::string_view n, const Map & map) -	{ -		s << n << std::endl; -		for (const auto & p : map) { -			Fmt::write(s, p.first, p.second); -		} -	} -  	std::ostream & -	CgiRequestBase::dump(std::ostream & s) const +	CgiRequestBase::dump(std::ostream & strm) const  	{ -		dumpMap<VarFmt>(s, "Environment dump"sv, envmap); -		s << "Path dump" << std::endl; -		for (const auto & e : pathElements) { -			PathFmt::write(s, e); +		dumpMap<VarFmt>(strm, "Environment dump"sv, envmap); +		strm << "Path dump" << '\n'; +		for (const auto & element : pathElements) { +			PathFmt::write(strm, element);  		} -		dumpMap<VarFmt>(s, "Query string dump"sv, qsmap); -		dumpMap<VarFmt>(s, "Cookie dump"sv, cookiemap); -		return s; +		dumpMap<VarFmt>(strm, "Query string dump"sv, qsmap); +		dumpMap<VarFmt>(strm, "Cookie dump"sv, cookiemap); +		return strm;  	}  	template<typename MapType>  	OptionalString -	CgiRequestBase::optionalLookup(const std::string_view key, const MapType & vm) +	CgiRequestBase::optionalLookup(const std::string_view key, const MapType & map)  	{ -		auto i = vm.find(key); -		if (i == vm.end()) { +		auto iter = map.find(key); +		if (iter == map.end()) {  			return {};  		} -		return i->second; +		return iter->second;  	}  	const PathElements & @@ -138,14 +139,14 @@ namespace IceSpider {  	CgiRequestBase::getRequestMethod() const  	{  		try { -			auto i = envmap.find(REQUEST_METHOD); -			if (i == envmap.end()) { -				throw IceSpider::Http400_BadRequest(); +			auto iter = envmap.find(REQUEST_METHOD); +			if (iter == envmap.end()) { +				throw IceSpider::Http400BadRequest();  			} -			return Slicer::ModelPartForEnum<HttpMethod>::lookup(i->second); +			return Slicer::ModelPartForEnum<HttpMethod>::lookup(iter->second);  		}  		catch (const Slicer::InvalidEnumerationSymbol &) { -			throw IceSpider::Http405_MethodNotAllowed(); +			throw IceSpider::Http405MethodNotAllowed();  		}  	} diff --git a/icespider/fcgi/cgiRequestBase.h b/icespider/fcgi/cgiRequestBase.h index e5a0d32..75f0f90 100644 --- a/icespider/fcgi/cgiRequestBase.h +++ b/icespider/fcgi/cgiRequestBase.h @@ -20,29 +20,29 @@ namespace IceSpider {  		// Null terminated list, bsv will handle this and is convertible to span  		using EnvNTL = std::basic_string_view<const char * const>; -		CgiRequestBase(Core * c, const EnvArray envs, const EnvArray extra = {}); +		CgiRequestBase(Core * core, EnvArray envs, EnvArray extra = {});  	public: -		using VarMap = flatmap<std::string_view, std::string_view>; -		using HdrMap = flatmap<std::string_view, std::string_view, AdHoc::case_less>; -		using StrMap = flatmap<MaybeString, MaybeString>; +		using VarMap = FlatMap<std::string_view, std::string_view>; +		using HdrMap = FlatMap<std::string_view, std::string_view, AdHoc::case_less>; +		using StrMap = FlatMap<MaybeString, MaybeString>;  		[[nodiscard]] const PathElements & getRequestPath() const override;  		[[nodiscard]] PathElements & getRequestPath() override;  		[[nodiscard]] HttpMethod getRequestMethod() const override; -		[[nodiscard]] OptionalString getQueryStringParamStr(const std::string_view key) const override; -		[[nodiscard]] OptionalString getHeaderParamStr(const std::string_view key) const override; -		[[nodiscard]] OptionalString getCookieParamStr(const std::string_view key) const override; -		[[nodiscard]] OptionalString getEnvStr(const std::string_view key) const override; +		[[nodiscard]] OptionalString getQueryStringParamStr(std::string_view key) const override; +		[[nodiscard]] OptionalString getHeaderParamStr(std::string_view key) const override; +		[[nodiscard]] OptionalString getCookieParamStr(std::string_view key) const override; +		[[nodiscard]] OptionalString getEnvStr(std::string_view key) const override;  		[[nodiscard]] bool isSecure() const override; -		void response(short, const std::string_view) const override; -		void setHeader(const std::string_view, const std::string_view) const override; +		void response(short, std::string_view) const override; +		void setHeader(std::string_view, std::string_view) const override; -		std::ostream & dump(std::ostream & s) const override; +		std::ostream & dump(std::ostream & strm) const override;  	private: -		template<typename MapType> static OptionalString optionalLookup(const std::string_view key, const MapType &); +		template<typename MapType> static OptionalString optionalLookup(std::string_view key, const MapType &);  		VarMap envmap {40};  		StrMap qsmap; diff --git a/icespider/fcgi/fcgiRequest.cpp b/icespider/fcgi/fcgiRequest.cpp index fb56728..0c8af2d 100644 --- a/icespider/fcgi/fcgiRequest.cpp +++ b/icespider/fcgi/fcgiRequest.cpp @@ -1,8 +1,9 @@  #include "fcgiRequest.h"  namespace IceSpider { -	FcgiRequest::FcgiRequest(Core * c, FCGX_Request * r) : -		CgiRequestBase(c, EnvNTL {r->envp}), inputbuf(r->in), input(&inputbuf), outputbuf(r->out), output(&outputbuf) +	FcgiRequest::FcgiRequest(Core * core, FCGX_Request * req) : +		CgiRequestBase(core, EnvNTL {req->envp}), inputbuf(req->in), input(&inputbuf), outputbuf(req->out), +		output(&outputbuf)  	{  	} diff --git a/icespider/fcgi/fcgiRequest.h b/icespider/fcgi/fcgiRequest.h index a85d21f..cf9c9a5 100644 --- a/icespider/fcgi/fcgiRequest.h +++ b/icespider/fcgi/fcgiRequest.h @@ -10,11 +10,12 @@ namespace IceSpider {  	class FcgiRequest : public CgiRequestBase {  	public: -		FcgiRequest(Core * c, FCGX_Request * r); +		FcgiRequest(Core * core, FCGX_Request * req);  		std::istream & getInputStream() const override;  		std::ostream & getOutputStream() const override; +	private:  		fcgi_streambuf inputbuf;  		mutable std::istream input;  		fcgi_streambuf outputbuf; diff --git a/icespider/fcgi/main.cpp b/icespider/fcgi/main.cpp index b4b9052..4746f53 100644 --- a/icespider/fcgi/main.cpp +++ b/icespider/fcgi/main.cpp @@ -19,14 +19,14 @@ main(int argc, char ** argv, char ** env)  		FCGX_InitRequest(&request, 0, 0);  		while (FCGX_Accept_r(&request) == 0) { -			FcgiRequest r(&core, &request); -			core.process(&r); +			FcgiRequest req(&core, &request); +			core.process(&req);  			FCGX_Finish_r(&request);  		}  	}  	else { -		CgiRequest r(&core, argc, argv, env); -		core.process(&r); +		CgiRequest req(&core, argc, argv, env); +		core.process(&req);  	}  	return 0;  } diff --git a/icespider/fileSessions/fileSessions.cpp b/icespider/fileSessions/fileSessions.cpp index 9a23898..da9fdea 100644 --- a/icespider/fileSessions/fileSessions.cpp +++ b/icespider/fileSessions/fileSessions.cpp @@ -15,7 +15,6 @@  #include <exception>  #include <factory.impl.h>  #include <fileUtils.h> -#include <ios>  #include <memory>  #include <session.h>  #include <string> @@ -28,9 +27,10 @@  namespace IceSpider {  	class FileSessions : public Plugin, public SessionManager {  	public: -		FileSessions(Ice::CommunicatorPtr c, const Ice::PropertiesPtr & p) : -			ic(std::move(c)), root(p->getProperty("IceSpider.FileSessions.Path")), -			duration(static_cast<Ice::Short>(p->getPropertyAsIntWithDefault("IceSpider.FileSessions.Duration", 3600))) +		FileSessions(Ice::CommunicatorPtr com, const Ice::PropertiesPtr & props) : +			ic(std::move(com)), root(props->getProperty("IceSpider.FileSessions.Path")), +			duration(static_cast<Ice::Short>( +					props->getPropertyAsIntWithDefault("IceSpider.FileSessions.Duration", 3600)))  		{  			if (!root.empty() && !std::filesystem::exists(root)) {  				std::filesystem::create_directories(root); @@ -45,8 +45,7 @@ namespace IceSpider {  			try {  				removeExpired();  			} -			catch (...) { -				// Meh :) +			catch (...) { // NOLINT(bugprone-empty-catch) - Meh :)  			}  		} @@ -56,36 +55,36 @@ namespace IceSpider {  		SessionPtr  		createSession(const ::Ice::Current &) override  		{ -			auto s = std::make_shared<Session>(); +			auto session = std::make_shared<Session>();  			// NOLINTNEXTLINE(clang-analyzer-optin.cplusplus.VirtualCall) -			s->id = boost::lexical_cast<std::string>(boost::uuids::random_generator()()); -			s->duration = duration; -			save(s); -			return s; +			session->id = boost::lexical_cast<std::string>(boost::uuids::random_generator()()); +			session->duration = duration; +			save(session); +			return session;  		}  		SessionPtr -		getSession(const ::std::string id, const ::Ice::Current & current) override +		getSession(const ::std::string sessionId, const ::Ice::Current & current) override  		{ -			auto s = load(id); -			if (s && isExpired(s)) { -				destroySession(id, current); +			auto session = load(sessionId); +			if (session && isExpired(session)) { +				destroySession(sessionId, current);  				return nullptr;  			} -			return s; +			return session;  		}  		void -		updateSession(const SessionPtr s, const ::Ice::Current &) override +		updateSession(const SessionPtr session, const ::Ice::Current &) override  		{ -			save(s); +			save(session);  		}  		void -		destroySession(const ::std::string id, const ::Ice::Current &) override +		destroySession(const ::std::string sessionId, const ::Ice::Current &) override  		{  			try { -				std::filesystem::remove(root / id); +				std::filesystem::remove(root / sessionId);  			}  			catch (const std::exception & e) {  				throw SessionError(e.what()); @@ -94,36 +93,36 @@ namespace IceSpider {  	private:  		void -		save(const SessionPtr & s) +		save(const SessionPtr & session)  		{ -			s->lastUsed = time(nullptr); +			session->lastUsed = time(nullptr);  			Ice::OutputStream buf(ic); -			buf.write(s); +			buf.write(session);  			const auto range = buf.finished();  			// NOLINTNEXTLINE(hicpp-signed-bitwise) -			AdHoc::FileUtils::FileHandle f(root / s->id, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR); -			sysassert(flock(f.fh, LOCK_EX), -1); -			sysassert(pwrite(f.fh, range.first, static_cast<size_t>(range.second - range.first), 0), -1); -			sysassert(ftruncate(f.fh, range.second - range.first), -1); -			sysassert(flock(f.fh, LOCK_UN), -1); +			AdHoc::FileUtils::FileHandle sessionFile(root / session->id, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR); +			sysassert(flock(sessionFile.fh, LOCK_EX), -1); +			sysassert(pwrite(sessionFile.fh, range.first, static_cast<size_t>(range.second - range.first), 0), -1); +			sysassert(ftruncate(sessionFile.fh, range.second - range.first), -1); +			sysassert(flock(sessionFile.fh, LOCK_UN), -1);  		}  		SessionPtr -		load(const std::string & id) +		load(const std::string & sessionId)  		{ -			auto path = root / id; +			auto path = root / sessionId;  			if (!std::filesystem::exists(path)) {  				return nullptr;  			}  			try { -				AdHoc::FileUtils::MemMap f(path); -				sysassert(flock(f.fh, LOCK_SH), -1); -				auto fbuf = f.sv<Ice::Byte>(); +				AdHoc::FileUtils::MemMap sessionFile(path); +				sysassert(flock(sessionFile.fh, LOCK_SH), -1); +				auto fbuf = sessionFile.sv<Ice::Byte>();  				Ice::InputStream buf(ic, std::make_pair(fbuf.begin(), fbuf.end())); -				SessionPtr s; -				buf.read(s); -				sysassert(flock(f.fh, LOCK_UN), -1); -				return s; +				SessionPtr session; +				buf.read(session); +				sysassert(flock(sessionFile.fh, LOCK_UN), -1); +				return session;  			}  			catch (const AdHoc::SystemException & e) {  				if (e.errNo == ENOENT) { @@ -139,20 +138,21 @@ namespace IceSpider {  			if (root.empty() || !std::filesystem::exists(root)) {  				return;  			} -			std::filesystem::directory_iterator di(root); -			while (di != std::filesystem::directory_iterator()) { -				auto s = load(di->path()); -				if (s && isExpired(s)) { -					FileSessions::destroySession(s->id, Ice::Current()); +			std::filesystem::directory_iterator dirIter(root); +			while (dirIter != std::filesystem::directory_iterator()) { +				auto session = load(dirIter->path()); +				if (session && isExpired(session)) { +					FileSessions::destroySession(session->id, Ice::Current());  				} -				di++; +				dirIter++;  			}  		} -		bool -		isExpired(const SessionPtr & s) +		[[nodiscard]] +		static bool +		isExpired(const SessionPtr & session)  		{ -			return (s->lastUsed + s->duration < time(nullptr)); +			return (session->lastUsed + session->duration < time(nullptr));  		}  		template<typename R, typename ER> diff --git a/icespider/testing/testRequest.cpp b/icespider/testing/testRequest.cpp index 61c7d94..86e856b 100644 --- a/icespider/testing/testRequest.cpp +++ b/icespider/testing/testRequest.cpp @@ -1,5 +1,4 @@  #include "testRequest.h" -#include <array>  #include <boost/algorithm/string/classification.hpp>  #include <boost/algorithm/string/constants.hpp>  #include <boost/algorithm/string/find_iterator.hpp> @@ -12,16 +11,15 @@  #include <utility>  namespace IceSpider { -	constexpr std::string_view slash("/"); +	constexpr std::string_view SLASH("/"); -	TestRequest::TestRequest(const Core * c, HttpMethod m, const std::string_view p) : IHttpRequest(c), method(m) +	TestRequest::TestRequest(const Core * core, HttpMethod method, std::string_view path) : +		IHttpRequest(core), method(method)  	{  		namespace ba = boost::algorithm; -		auto path = p.substr(1); -		// NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) +		path.remove_prefix(1);  		if (!path.empty()) { -			// NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) -			ba::split(url, path, ba::is_any_of(slash), ba::token_compress_off); +			ba::split(url, path, ba::is_any_of(SLASH), ba::token_compress_off);  		}  	} @@ -74,13 +72,13 @@ namespace IceSpider {  	}  	OptionalString -	TestRequest::get(const std::string_view key, const MapVars & vars) const +	TestRequest::get(const std::string_view key, const MapVars & vars)  	{ -		auto i = vars.find(key); -		if (i == vars.end()) { +		auto iter = vars.find(key); +		if (iter == vars.end()) {  			return {};  		} -		return i->second; +		return iter->second;  	}  	void @@ -143,9 +141,9 @@ namespace IceSpider {  	}  	std::ostream & -	TestRequest::dump(std::ostream & s) const +	TestRequest::dump(std::ostream & strm) const  	{ -		return s; +		return strm;  	}  	const TestRequest::MapVars & @@ -153,13 +151,21 @@ namespace IceSpider {  	{  		if (responseHeaders.empty()) {  			while (true) { -				std::array<char, BUFSIZ> buf {}, n {}, v {}; -				output.getline(buf.data(), BUFSIZ); -				// NOLINTNEXTLINE(hicpp-vararg) -				if (sscanf(buf.data(), "%[^:]: %[^\r]", n.data(), v.data()) != 2) { +				std::string lineBuffer; +				lineBuffer.resize_and_overwrite(BUFSIZ, [this](char * buf, size_t len) { +					output.getline(buf, static_cast<std::streamsize>(len)); +					return static_cast<size_t>(output.gcount()); +				}); +				if (lineBuffer.empty()) {  					break;  				} -				responseHeaders[n.data()] = v.data(); +				auto colonPos = lineBuffer.find(':'); +				if (colonPos == std::string::npos) { +					break; +				} +				auto valStart = lineBuffer.find_first_not_of(' ', colonPos + 1); +				auto valEnd = lineBuffer.find_first_of("\r\n", valStart); +				responseHeaders.emplace(lineBuffer.substr(0, colonPos), lineBuffer.substr(valStart, valEnd - valStart));  			}  		}  		return responseHeaders; diff --git a/icespider/testing/testRequest.h b/icespider/testing/testRequest.h index 77efda2..6d87bb0 100644 --- a/icespider/testing/testRequest.h +++ b/icespider/testing/testRequest.h @@ -16,25 +16,25 @@ namespace IceSpider {  	public:  		using MapVars = std::map<std::string, std::string, std::less<>>; -		TestRequest(const Core * c, HttpMethod m, const std::string_view p); +		TestRequest(const Core * core, HttpMethod method, std::string_view path);  		const PathElements & getRequestPath() const override;  		PathElements & getRequestPath() override;  		HttpMethod getRequestMethod() const override; -		OptionalString getEnvStr(const std::string_view key) const override; -		OptionalString getQueryStringParamStr(const std::string_view key) const override; -		OptionalString getCookieParamStr(const std::string_view key) const override; -		OptionalString getHeaderParamStr(const std::string_view key) const override; +		OptionalString getEnvStr(std::string_view key) const override; +		OptionalString getQueryStringParamStr(std::string_view key) const override; +		OptionalString getCookieParamStr(std::string_view key) const override; +		OptionalString getHeaderParamStr(std::string_view key) const override;  		bool isSecure() const override; -		void setQueryStringParam(const std::string_view, const OptionalString &); -		void setHeaderParam(const std::string_view, const OptionalString &); -		void setCookieParam(const std::string_view, const OptionalString &); -		void setEnv(const std::string_view, const OptionalString &); +		void setQueryStringParam(std::string_view, const OptionalString &); +		void setHeaderParam(std::string_view, const OptionalString &); +		void setCookieParam(std::string_view, const OptionalString &); +		void setEnv(std::string_view, const OptionalString &);  		std::istream & getInputStream() const override;  		std::ostream & getOutputStream() const override; -		void response(short statusCode, const std::string_view statusMsg) const override; -		void setHeader(const std::string_view header, const std::string_view value) const override; -		std::ostream & dump(std::ostream & s) const override; +		void response(short statusCode, std::string_view statusMsg) const override; +		void setHeader(std::string_view header, std::string_view value) const override; +		std::ostream & dump(std::ostream & strm) const override;  		const MapVars & getResponseHeaders(); @@ -48,8 +48,8 @@ namespace IceSpider {  		const HttpMethod method;  	protected: -		OptionalString get(const std::string_view, const MapVars &) const; -		void set(const std::string_view, const OptionalString &, MapVars &); +		static OptionalString get(std::string_view, const MapVars &); +		static void set(std::string_view, const OptionalString &, MapVars &);  	private:  		MapVars responseHeaders; diff --git a/icespider/unittests/testAccept.cpp b/icespider/unittests/testAccept.cpp index 410147f..303cd7f 100644 --- a/icespider/unittests/testAccept.cpp +++ b/icespider/unittests/testAccept.cpp @@ -2,6 +2,7 @@  #include <boost/test/data/test_case.hpp>  #include <boost/test/unit_test.hpp> +#include <exceptions.h>  #include <ihttpRequest.h>  #include <optional>  #include <ostream> @@ -9,7 +10,7 @@  #include <vector>  namespace IceSpider { -	class Http400_BadRequest; +	class Http400BadRequest;  }  auto parse = IceSpider::IHttpRequest::parseAccept; @@ -42,7 +43,7 @@ BOOST_DATA_TEST_CASE(bad_requests,  		}),  		a)  { -	BOOST_CHECK_THROW(parse(a), IceSpider::Http400_BadRequest); +	BOOST_CHECK_THROW(parse(a), IceSpider::Http400BadRequest);  }  BOOST_DATA_TEST_CASE(texthtml, diff --git a/icespider/unittests/testApp.cpp b/icespider/unittests/testApp.cpp index c40ed95..de59cfd 100644 --- a/icespider/unittests/testApp.cpp +++ b/icespider/unittests/testApp.cpp @@ -104,13 +104,13 @@ BOOST_AUTO_TEST_CASE(testFindRoutes)  	BOOST_REQUIRE(findRoute(&requestGetIndex));  	TestRequest requestPostIndex(this, HttpMethod::POST, "/"); -	BOOST_REQUIRE_THROW(findRoute(&requestPostIndex), IceSpider::Http405_MethodNotAllowed); +	BOOST_REQUIRE_THROW(findRoute(&requestPostIndex), IceSpider::Http405MethodNotAllowed);  	TestRequest requestPostUpdate(this, HttpMethod::POST, "/something");  	BOOST_REQUIRE(findRoute(&requestPostUpdate));  	TestRequest requestGetUpdate(this, HttpMethod::GET, "/something"); -	BOOST_REQUIRE_THROW(findRoute(&requestGetUpdate), IceSpider::Http405_MethodNotAllowed); +	BOOST_REQUIRE_THROW(findRoute(&requestGetUpdate), IceSpider::Http405MethodNotAllowed);  	TestRequest requestGetItem(this, HttpMethod::GET, "/view/something/something");  	BOOST_REQUIRE(findRoute(&requestGetItem)); @@ -123,13 +123,13 @@ BOOST_AUTO_TEST_CASE(testFindRoutes)  	TestRequest requestGetItemLong(  			this, HttpMethod::GET, "/view/something/something/extra/many/things/longer/than/longest/route"); -	BOOST_REQUIRE_THROW(findRoute(&requestGetItemLong), IceSpider::Http404_NotFound); +	BOOST_REQUIRE_THROW(findRoute(&requestGetItemLong), IceSpider::Http404NotFound);  	TestRequest requestGetItemShort(this, HttpMethod::GET, "/view/missingSomething"); -	BOOST_REQUIRE_THROW(findRoute(&requestGetItemShort), IceSpider::Http404_NotFound); +	BOOST_REQUIRE_THROW(findRoute(&requestGetItemShort), IceSpider::Http404NotFound);  	TestRequest requestGetNothing(this, HttpMethod::GET, "/badview/something/something"); -	BOOST_REQUIRE_THROW(findRoute(&requestGetNothing), IceSpider::Http404_NotFound); +	BOOST_REQUIRE_THROW(findRoute(&requestGetNothing), IceSpider::Http404NotFound);  	TestRequest requestDeleteThing(this, HttpMethod::DELETE, "/something");  	BOOST_REQUIRE(findRoute(&requestDeleteThing)); @@ -540,18 +540,18 @@ public:  	{  		if (const auto * tex = dynamic_cast<const TestIceSpider::Ex *>(&ex)) {  			if (tex->message == "404") { -				throw IceSpider::Http404_NotFound(); +				throw IceSpider::Http404NotFound();  			}  			if (tex->message == "304") {  				request->getRequestPath().front() = "some value"; -				return IceSpider::ErrorHandlerResult_Modified; +				return IceSpider::ErrorHandlerResult::Modified;  			}  			if (tex->message == "400") {  				request->response(400, "Handled"); -				return IceSpider::ErrorHandlerResult_Handled; +				return IceSpider::ErrorHandlerResult::Handled;  			}  		} -		return IceSpider::ErrorHandlerResult_Unhandled; +		return IceSpider::ErrorHandlerResult::Unhandled;  	}  }; diff --git a/icespider/unittests/testFcgi.cpp b/icespider/unittests/testFcgi.cpp index b3ea6e2..67ab322 100644 --- a/icespider/unittests/testFcgi.cpp +++ b/icespider/unittests/testFcgi.cpp @@ -8,6 +8,7 @@  #include <cstdlib>  #include <cstring>  #include <ctime> +#include <exceptions.h>  #include <http.h>  #include <ihttpRequest.h>  #include <iostream> @@ -21,11 +22,11 @@  #include <vector>  namespace IceSpider { -	class Http400_BadRequest; +	class Http400BadRequest;  }  namespace IceSpider { -	class Http405_MethodNotAllowed; +	class Http405MethodNotAllowed;  }  using namespace std::literals; @@ -106,7 +107,7 @@ BOOST_FIXTURE_TEST_SUITE(CgiRequestBase, IceSpider::CoreWithDefaultRouter);  BOOST_AUTO_TEST_CASE(NoEnvironment)  { -	BOOST_REQUIRE_THROW({ TestRequest r(this, {}); }, IceSpider::Http400_BadRequest); +	BOOST_REQUIRE_THROW({ TestRequest r(this, {}); }, IceSpider::Http400BadRequest);  }  BOOST_AUTO_TEST_CASE(script_name_root) @@ -206,13 +207,13 @@ BOOST_AUTO_TEST_CASE(requestmethod_post)  BOOST_AUTO_TEST_CASE(requestmethod_bad)  {  	TestRequest r(this, {{"SCRIPT_NAME=/", "REQUEST_METHOD=No"}}); -	BOOST_REQUIRE_THROW((void)r.getRequestMethod(), IceSpider::Http405_MethodNotAllowed); +	BOOST_REQUIRE_THROW((void)r.getRequestMethod(), IceSpider::Http405MethodNotAllowed);  }  BOOST_AUTO_TEST_CASE(requestmethod_missing)  {  	TestRequest r {this, {{"SCRIPT_NAME=/"}}}; -	BOOST_REQUIRE_THROW((void)r.getRequestMethod(), IceSpider::Http400_BadRequest); +	BOOST_REQUIRE_THROW((void)r.getRequestMethod(), IceSpider::Http400BadRequest);  }  BOOST_AUTO_TEST_CASE(acceptheader) diff --git a/icespider/unittests/testFlatMap.cpp b/icespider/unittests/testFlatMap.cpp index ed19371..f673cdd 100644 --- a/icespider/unittests/testFlatMap.cpp +++ b/icespider/unittests/testFlatMap.cpp @@ -7,7 +7,7 @@  #include <utility>  #include <vector> -using TM = IceSpider::flatmap<std::string_view, int>; +using TM = IceSpider::FlatMap<std::string_view, int>;  BOOST_TEST_DONT_PRINT_LOG_VALUE(TM::const_iterator) @@ -68,7 +68,7 @@ BOOST_AUTO_TEST_CASE(several)  BOOST_AUTO_TEST_SUITE_END() -using TMI = IceSpider::flatmap<int, std::string_view>; +using TMI = IceSpider::FlatMap<int, std::string_view>;  BOOST_TEST_DONT_PRINT_LOG_VALUE(TMI::const_iterator) diff --git a/icespider/xslt/xsltStreamSerializer.cpp b/icespider/xslt/xsltStreamSerializer.cpp index c89e89c..4099317 100644 --- a/icespider/xslt/xsltStreamSerializer.cpp +++ b/icespider/xslt/xsltStreamSerializer.cpp @@ -1,5 +1,4 @@  #include "xsltStreamSerializer.h" -#include <chrono>  #include <filesystem>  #include <libxml++/document.h>  #include <libxml++/exceptions/exception.h> @@ -52,12 +51,15 @@ namespace IceSpider {  		return std::make_shared<XsltStreamSerializer>(strm, stylesheet.get());  	} -	XsltStreamSerializer::XsltStreamSerializer(std::ostream & os, xsltStylesheet * ss) : strm(os), stylesheet(ss) { } +	XsltStreamSerializer::XsltStreamSerializer(std::ostream & strm, xsltStylesheet * stylesheet) : +		strm(strm), stylesheet(stylesheet) +	{ +	}  	void -	XsltStreamSerializer::Serialize(Slicer::ModelPartForRootParam mp) +	XsltStreamSerializer::Serialize(Slicer::ModelPartForRootParam modelPart)  	{ -		Slicer::XmlDocumentSerializer::Serialize(mp); +		Slicer::XmlDocumentSerializer::Serialize(modelPart);  		const auto result = std::unique_ptr<xmlDoc, decltype(&xmlFreeDoc)> {  				xsltApplyStylesheet(stylesheet, doc.cobj(), nullptr), &xmlFreeDoc};  		if (!result) { diff --git a/icespider/xslt/xsltStreamSerializer.h b/icespider/xslt/xsltStreamSerializer.h index 3dda157..f64ed7e 100644 --- a/icespider/xslt/xsltStreamSerializer.h +++ b/icespider/xslt/xsltStreamSerializer.h @@ -27,7 +27,7 @@ namespace IceSpider {  		XsltStreamSerializer(std::ostream &, xsltStylesheet *); -		void Serialize(Slicer::ModelPartForRootParam mp) override; +		void Serialize(Slicer::ModelPartForRootParam modelPart) override;  	protected:  		std::ostream & strm; | 
