1
0
Fork 0
mirror of https://github.com/KingDuckZ/kamokan.git synced 2024-11-27 00:43:47 +00:00

Calculate string lengths at build time.

This commit is contained in:
King_DuckZ 2017-05-15 23:38:39 +01:00
parent 00f32d43d3
commit 8585e5baf5
3 changed files with 81 additions and 3 deletions

View file

@ -17,12 +17,17 @@
#include "cgi_environment_vars.hpp" #include "cgi_environment_vars.hpp"
#include "sanitized_utf8.hpp" #include "sanitized_utf8.hpp"
#include "string_lengths.hpp"
#include <utility> #include <utility>
#include <unordered_map> #include <unordered_map>
#include <boost/utility/string_ref.hpp> #include <boost/utility/string_ref.hpp>
#include <cassert> #include <cassert>
#include <cstring> #include <cstring>
#include <boost/functional/hash.hpp> #include <boost/functional/hash.hpp>
#include <cstddef>
#if !defined(NDEBUG)
# include <cstring>
#endif
namespace std { namespace std {
template<> template<>
@ -67,13 +72,19 @@ namespace tawashi {
retlist.reserve(CGIVars::_size()); retlist.reserve(CGIVars::_size());
auto unrefined_env_vars = get_unrefined_env_vars(parEnvList); auto unrefined_env_vars = get_unrefined_env_vars(parEnvList);
auto enum_str_lengths = string_lengths<CGIVars>();
std::size_t z = 0;
for (CGIVars var : CGIVars::_values()) { for (CGIVars var : CGIVars::_values()) {
auto it_found = unrefined_env_vars.find(var._to_string()); #if !defined(NDEBUG)
assert(std::strlen(var._to_string()) == enum_str_lengths[z]);
#endif
auto it_found = unrefined_env_vars.find(boost::string_ref(var._to_string(), enum_str_lengths[z]));
if (unrefined_env_vars.cend() != it_found) if (unrefined_env_vars.cend() != it_found)
retlist.push_back(sanitized_utf8(it_found->second)); retlist.push_back(sanitized_utf8(it_found->second));
else else
retlist.push_back(std::string()); retlist.push_back(std::string());
++z;
} }
return retlist; return retlist;
} }

View file

@ -18,10 +18,13 @@
#include "error_response.hpp" #include "error_response.hpp"
#include "error_reasons.hpp" #include "error_reasons.hpp"
#include "cgi_env.hpp" #include "cgi_env.hpp"
#include "sprout/array/array.hpp"
#include "string_lengths.hpp"
#include <boost/algorithm/string/replace.hpp> #include <boost/algorithm/string/replace.hpp>
#include <boost/lexical_cast.hpp> #include <boost/lexical_cast.hpp>
#include <ciso646> #include <ciso646>
#include <string> #include <string>
#include <cassert>
namespace tawashi { namespace tawashi {
ErrorResponse::ErrorResponse ( ErrorResponse::ErrorResponse (
@ -41,15 +44,23 @@ namespace tawashi {
if (reason_int >= 0 and reason_int < ErrorReasons::_size()) if (reason_int >= 0 and reason_int < ErrorReasons::_size())
reason_code = ErrorReasons::_from_integral(reason_int); reason_code = ErrorReasons::_from_integral(reason_int);
std::array<const char*, ErrorReasons::_size()> err_descs { constexpr const sprout::array<const char*, ErrorReasons::_size()> err_descs {
"Submitted pastie is either too short or too long and was rejected.", "Submitted pastie is either too short or too long and was rejected.",
"Submitted pastie couldn't be saved.", "Submitted pastie couldn't be saved.",
"The pastie was not saved because the client is submitting too many pasties too quickly. Please wait a bit longer and try again.", "The pastie was not saved because the client is submitting too many pasties too quickly. Please wait a bit longer and try again.",
"An unknown error was raised.", "An unknown error was raised.",
"Unable to connect to Redis." "Unable to connect to Redis."
}; };
constexpr const auto lengths = string_lengths(err_descs);
static_assert(err_descs.static_size == lengths.static_size, "Mismatching array sizes between strings and their lengths");
parContext["error_message"] = std::string(err_descs[reason_code]); #if !defined(NDEBUG)
for (std::size_t z = 0; z < err_descs.size(); ++z) {
assert(std::strlen(err_descs[z]) == lengths[z]);
}
#endif
parContext["error_message"] = std::string(err_descs[reason_code], lengths[reason_code]);
parContext["error_code"] = std::to_string(err_code); parContext["error_code"] = std::to_string(err_code);
parContext["error_id"] = std::to_string(reason_code); parContext["error_id"] = std::to_string(reason_code);
} }

View file

@ -0,0 +1,56 @@
/* Copyright 2017, Michele Santullo
* This file is part of "tawashi".
*
* "tawashi" is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* "tawashi" is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with "tawashi". If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "sprout/array/array.hpp"
#include "sprout/cstring/strlen.hpp"
#include "duckhandy/sequence_bt.hpp"
#include <cstddef>
namespace tawashi {
namespace implem {
template <std::size_t I, std::size_t S>
inline constexpr std::size_t string_length_at_index (const sprout::array<const char*, S>& parStrings) {
return sprout::strlen(parStrings[I]);
}
template <std::size_t... Indices>
inline constexpr sprout::array<std::size_t, sizeof...(Indices)> string_lengths (const sprout::array<const char*, sizeof...(Indices)>& parStrings, dhandy::bt::index_seq<Indices...>) {
return sprout::array<std::size_t, sizeof...(Indices)> {
string_length_at_index<Indices>(parStrings)...
};
}
template <typename Enum, std::size_t... Indices>
inline constexpr sprout::array<std::size_t, Enum::_size()> string_lengths (const typename Enum::_name_iterable& parEnumIterable, dhandy::bt::index_seq<Indices...>) {
return sprout::array<std::size_t, Enum::_size()> {
sprout::strlen(parEnumIterable[Indices])...
};
}
} //namespace implem
template <std::size_t S>
inline constexpr sprout::array<std::size_t, S> string_lengths (const sprout::array<const char*, S>& parStrings) {
return implem::string_lengths(parStrings, dhandy::bt::index_range<0, S>());
}
template <typename Enum>
inline constexpr sprout::array<std::size_t, Enum::_size()> string_lengths() {
return implem::string_lengths<Enum>(Enum::_names(), dhandy::bt::index_range<0, Enum::_size()>());
}
} //namespace tawashi