Rewrite concat_string_ref

This commit is contained in:
Tatsuhiro Tsujikawa 2016-03-20 17:55:17 +09:00
parent d2b55ad1a2
commit dc3119303a
5 changed files with 53 additions and 61 deletions

View File

@ -1187,17 +1187,10 @@ void prepare_redirect_response(Stream *stream, Http2Handler *hd,
authority = stream->header.host;
}
size_t len = scheme.size() + str_size("://") + authority.size() + path.size();
auto iov = make_byte_ref(stream->balloc, len + 1);
auto p = iov.base;
p = std::copy(std::begin(scheme), std::end(scheme), p);
p = util::copy_lit(p, "://");
p = std::copy(std::begin(authority), std::end(authority), p);
p = std::copy(std::begin(path), std::end(path), p);
*p = '\0';
auto location = concat_string_ref(
stream->balloc, scheme, StringRef::from_lit("://"), authority, path);
auto headers =
HeaderRefs{{StringRef::from_lit("location"), StringRef{iov.base, p}}};
auto headers = HeaderRefs{{StringRef::from_lit("location"), location}};
auto sessions = hd->get_sessions();
auto status_page = sessions->get_server()->get_status_page(status);

View File

@ -120,31 +120,43 @@ StringRef make_string_ref(BlockAllocator &alloc, const StringRef &src) {
return StringRef{dst, src.size()};
}
// Returns the string which is the concatenation of |a| and |b| in
// this order. The resulting string will be NULL-terminated.
template <typename BlockAllocator>
StringRef concat_string_ref(BlockAllocator &alloc, const StringRef &a,
const StringRef &b) {
auto len = a.size() + b.size();
auto dst = static_cast<uint8_t *>(alloc.alloc(len + 1));
auto p = dst;
p = std::copy(std::begin(a), std::end(a), p);
p = std::copy(std::begin(b), std::end(b), p);
*p = '\0';
return StringRef{dst, len};
// private function used in concat_string_ref. this is the base
// function of concat_string_ref_count().
inline size_t concat_string_ref_count(size_t acc) { return acc; }
// private function used in concat_string_ref. This function counts
// the sum of length of given arguments. The calculated length is
// accumulated, and passed to the next function.
template <typename... Args>
size_t concat_string_ref_count(size_t acc, const StringRef &value,
Args &&... args) {
return concat_string_ref_count(acc + value.size(),
std::forward<Args>(args)...);
}
// Returns the string which is the concatenation of |a|, |b| and |c|
// in this order. The resulting string will be NULL-terminated.
template <typename BlockAllocator>
StringRef concat_string_ref(BlockAllocator &alloc, const StringRef &a,
const StringRef &b, const StringRef &c) {
auto len = a.size() + b.size() + c.size();
// private function used in concat_string_ref. this is the base
// function of concat_string_ref_copy().
inline uint8_t *concat_string_ref_copy(uint8_t *p) { return p; }
// private function used in concat_string_ref. This function copies
// given strings into |p|. |p| is incremented by the copied length,
// and returned. In the end, return value points to the location one
// beyond the last byte written.
template <typename... Args>
uint8_t *concat_string_ref_copy(uint8_t *p, const StringRef &value,
Args &&... args) {
p = std::copy(std::begin(value), std::end(value), p);
return concat_string_ref_copy(p, std::forward<Args>(args)...);
}
// Returns the string which is the concatenation of |args| in the
// given order. The resulting string will be NULL-terminated.
template <typename BlockAllocator, typename... Args>
StringRef concat_string_ref(BlockAllocator &alloc, Args &&... args) {
size_t len = concat_string_ref_count(0, std::forward<Args>(args)...);
auto dst = static_cast<uint8_t *>(alloc.alloc(len + 1));
auto p = dst;
p = std::copy(std::begin(a), std::end(a), p);
p = std::copy(std::begin(b), std::end(b), p);
p = std::copy(std::begin(c), std::end(c), p);
p = concat_string_ref_copy(p, std::forward<Args>(args)...);
*p = '\0';
return StringRef{dst, len};
}

View File

@ -48,20 +48,11 @@ StringRef create_error_html(BlockAllocator &balloc, unsigned int http_status) {
auto status_string = http2::get_status_string(balloc, http_status);
const auto &server_name = httpconf.server_name;
size_t len = 256 + server_name.size() + status_string.size() * 2;
auto iov = make_byte_ref(balloc, len + 1);
auto p = iov.base;
p = util::copy_lit(p, R"(<!DOCTYPE html><html lang="en"><title>)");
p = std::copy(std::begin(status_string), std::end(status_string), p);
p = util::copy_lit(p, "</title><body><h1>");
p = std::copy(std::begin(status_string), std::end(status_string), p);
p = util::copy_lit(p, "</h1><footer>");
p = std::copy(std::begin(server_name), std::end(server_name), p);
p = util::copy_lit(p, "</footer></body></html>");
*p = '\0';
return StringRef{iov.base, p};
return concat_string_ref(
balloc, StringRef::from_lit(R"(<!DOCTYPE html><html lang="en"><title>)"),
status_string, StringRef::from_lit("</title><body><h1>"), status_string,
StringRef::from_lit("</h1><footer>"), server_name,
StringRef::from_lit("</footer></body></html>"));
}
StringRef create_forwarded(BlockAllocator &balloc, int params,

View File

@ -264,14 +264,8 @@ void rewrite_request_host_path_from_uri(BlockAllocator &balloc, Request &req,
auto q = util::get_uri_field(uri.c_str(), u, UF_QUERY);
path = StringRef{std::begin(path), std::end(q)};
} else {
auto iov = make_byte_ref(balloc, path.size() + 1 + fdata.len + 1);
auto p = iov.base;
p = std::copy(std::begin(path), std::end(path), p);
*p++ = '?';
p = std::copy_n(&uri[fdata.off], fdata.len, p);
*p = '\0';
path = StringRef{iov.base, p};
path = concat_string_ref(balloc, path, StringRef::from_lit("?"),
StringRef{&uri[fdata.off], fdata.len});
}
}

View File

@ -437,11 +437,11 @@ public:
return StringRef(s);
}
const_iterator begin() const { return base; };
const_iterator cbegin() const { return base; };
constexpr const_iterator begin() const { return base; };
constexpr const_iterator cbegin() const { return base; };
const_iterator end() const { return base + len; };
const_iterator cend() const { return base + len; };
constexpr const_iterator end() const { return base + len; };
constexpr const_iterator cend() const { return base + len; };
const_reverse_iterator rbegin() const {
return const_reverse_iterator{base + len};
@ -453,10 +453,12 @@ public:
const_reverse_iterator rend() const { return const_reverse_iterator{base}; }
const_reverse_iterator crend() const { return const_reverse_iterator{base}; }
const char *c_str() const { return base; }
size_type size() const { return len; }
bool empty() const { return len == 0; }
const_reference operator[](size_type pos) const { return *(base + pos); }
constexpr const char *c_str() const { return base; }
constexpr size_type size() const { return len; }
constexpr bool empty() const { return len == 0; }
constexpr const_reference operator[](size_type pos) const {
return *(base + pos);
}
std::string str() const { return std::string(base, len); }
const uint8_t *byte() const {