• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include "quiche/spdy/core/http2_header_storage.h"
2 
3 #include <cstring>
4 
5 #include "quiche/common/platform/api/quiche_logging.h"
6 
7 namespace spdy {
8 namespace {
9 
10 // Http2HeaderStorage allocates blocks of this size by default.
11 const size_t kDefaultStorageBlockSize = 2048;
12 
13 }  // namespace
14 
Http2HeaderStorage()15 Http2HeaderStorage::Http2HeaderStorage() : arena_(kDefaultStorageBlockSize) {}
16 
Write(const absl::string_view s)17 absl::string_view Http2HeaderStorage::Write(const absl::string_view s) {
18   return absl::string_view(arena_.Memdup(s.data(), s.size()), s.size());
19 }
20 
Rewind(const absl::string_view s)21 void Http2HeaderStorage::Rewind(const absl::string_view s) {
22   arena_.Free(const_cast<char*>(s.data()), s.size());
23 }
24 
WriteFragments(const std::vector<absl::string_view> & fragments,absl::string_view separator)25 absl::string_view Http2HeaderStorage::WriteFragments(
26     const std::vector<absl::string_view>& fragments,
27     absl::string_view separator) {
28   if (fragments.empty()) {
29     return absl::string_view();
30   }
31   size_t total_size = separator.size() * (fragments.size() - 1);
32   for (const absl::string_view& fragment : fragments) {
33     total_size += fragment.size();
34   }
35   char* dst = arena_.Alloc(total_size);
36   size_t written = Join(dst, fragments, separator);
37   QUICHE_DCHECK_EQ(written, total_size);
38   return absl::string_view(dst, total_size);
39 }
40 
Join(char * dst,const std::vector<absl::string_view> & fragments,absl::string_view separator)41 size_t Join(char* dst, const std::vector<absl::string_view>& fragments,
42             absl::string_view separator) {
43   if (fragments.empty()) {
44     return 0;
45   }
46   auto* original_dst = dst;
47   auto it = fragments.begin();
48   memcpy(dst, it->data(), it->size());
49   dst += it->size();
50   for (++it; it != fragments.end(); ++it) {
51     memcpy(dst, separator.data(), separator.size());
52     dst += separator.size();
53     memcpy(dst, it->data(), it->size());
54     dst += it->size();
55   }
56   return dst - original_dst;
57 }
58 
59 }  // namespace spdy
60