Skip to content

Commit a8d6172

Browse files
Avoid static std::string (#2103)
Replace static std::string objects with constexpr character arrays and use compile-time string length calculations.
1 parent 2f39723 commit a8d6172

File tree

1 file changed

+19
-17
lines changed

1 file changed

+19
-17
lines changed

httplib.h

+19-17
Original file line numberDiff line numberDiff line change
@@ -2050,6 +2050,10 @@ inline void duration_to_sec_and_usec(const T &duration, U callback) {
20502050
callback(static_cast<time_t>(sec), static_cast<time_t>(usec));
20512051
}
20522052

2053+
template <size_t N> inline constexpr size_t str_len(const char (&)[N]) {
2054+
return N - 1;
2055+
}
2056+
20532057
inline bool is_numeric(const std::string &str) {
20542058
return !str.empty() && std::all_of(str.begin(), str.end(), ::isdigit);
20552059
}
@@ -2209,9 +2213,9 @@ inline const char *status_message(int status) {
22092213

22102214
inline std::string get_bearer_token_auth(const Request &req) {
22112215
if (req.has_header("Authorization")) {
2212-
static std::string BearerHeaderPrefix = "Bearer ";
2216+
constexpr auto bearer_header_prefix_len = detail::str_len("Bearer ");
22132217
return req.get_header_value("Authorization")
2214-
.substr(BearerHeaderPrefix.length());
2218+
.substr(bearer_header_prefix_len);
22152219
}
22162220
return "";
22172221
}
@@ -4646,10 +4650,8 @@ write_content_chunked(Stream &strm, const ContentProvider &content_provider,
46464650
}
46474651
}
46484652

4649-
static const std::string done_marker("0\r\n");
4650-
if (!write_data(strm, done_marker.data(), done_marker.size())) {
4651-
ok = false;
4652-
}
4653+
constexpr const char done_marker[] = "0\r\n";
4654+
if (!write_data(strm, done_marker, str_len(done_marker))) { ok = false; }
46534655

46544656
// Trailer
46554657
if (trailer) {
@@ -4661,8 +4663,8 @@ write_content_chunked(Stream &strm, const ContentProvider &content_provider,
46614663
}
46624664
}
46634665

4664-
static const std::string crlf("\r\n");
4665-
if (!write_data(strm, crlf.data(), crlf.size())) { ok = false; }
4666+
constexpr const char crlf[] = "\r\n";
4667+
if (!write_data(strm, crlf, str_len(crlf))) { ok = false; }
46664668
};
46674669

46684670
data_sink.done = [&](void) { done_with_trailer(nullptr); };
@@ -4904,11 +4906,11 @@ class MultipartFormDataParser {
49044906
return false;
49054907
}
49064908

4907-
static const std::string header_content_type = "Content-Type:";
4909+
constexpr const char header_content_type[] = "Content-Type:";
49084910

49094911
if (start_with_case_ignore(header, header_content_type)) {
49104912
file_.content_type =
4911-
trim_copy(header.substr(header_content_type.size()));
4913+
trim_copy(header.substr(str_len(header_content_type)));
49124914
} else {
49134915
static const std::regex re_content_disposition(
49144916
R"~(^Content-Disposition:\s*form-data;\s*(.*)$)~",
@@ -5005,10 +5007,10 @@ class MultipartFormDataParser {
50055007
file_.content_type.clear();
50065008
}
50075009

5008-
bool start_with_case_ignore(const std::string &a,
5009-
const std::string &b) const {
5010-
if (a.size() < b.size()) { return false; }
5011-
for (size_t i = 0; i < b.size(); i++) {
5010+
bool start_with_case_ignore(const std::string &a, const char *b) const {
5011+
const auto b_len = strlen(b);
5012+
if (a.size() < b_len) { return false; }
5013+
for (size_t i = 0; i < b_len; i++) {
50125014
if (case_ignore::to_lower(a[i]) != case_ignore::to_lower(b[i])) {
50135015
return false;
50145016
}
@@ -5095,7 +5097,7 @@ class MultipartFormDataParser {
50955097
};
50965098

50975099
inline std::string random_string(size_t length) {
5098-
static const char data[] =
5100+
constexpr const char data[] =
50995101
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
51005102

51015103
// std::random_device might actually be deterministic on some
@@ -6094,7 +6096,7 @@ inline time_t BufferStream::duration() const { return 0; }
60946096
inline const std::string &BufferStream::get_buffer() const { return buffer; }
60956097

60966098
inline PathParamsMatcher::PathParamsMatcher(const std::string &pattern) {
6097-
static constexpr char marker[] = "/:";
6099+
constexpr const char marker[] = "/:";
60986100

60996101
// One past the last ending position of a path param substring
61006102
std::size_t last_param_end = 0;
@@ -6115,7 +6117,7 @@ inline PathParamsMatcher::PathParamsMatcher(const std::string &pattern) {
61156117
static_fragments_.push_back(
61166118
pattern.substr(last_param_end, marker_pos - last_param_end + 1));
61176119

6118-
const auto param_name_start = marker_pos + 2;
6120+
const auto param_name_start = marker_pos + str_len(marker);
61196121

61206122
auto sep_pos = pattern.find(separator, param_name_start);
61216123
if (sep_pos == std::string::npos) { sep_pos = pattern.length(); }

0 commit comments

Comments
 (0)