xref: /aosp_15_r20/external/cronet/net/third_party/quiche/src/quiche/common/http/http_header_storage.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 #include "quiche/common/http/http_header_storage.h"
2 
3 #include <cstring>
4 
5 #include "quiche/common/platform/api/quiche_logging.h"
6 
7 namespace quiche {
8 namespace {
9 
10 // HttpHeaderStorage allocates blocks of this size by default.
11 const size_t kDefaultStorageBlockSize = 2048;
12 
13 }  // namespace
14 
HttpHeaderStorage()15 HttpHeaderStorage::HttpHeaderStorage() : arena_(kDefaultStorageBlockSize) {}
16 
Write(const absl::string_view s)17 absl::string_view HttpHeaderStorage::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 HttpHeaderStorage::Rewind(const absl::string_view s) {
22   arena_.Free(const_cast<char*>(s.data()), s.size());
23 }
24 
WriteFragments(const Fragments & fragments,absl::string_view separator)25 absl::string_view HttpHeaderStorage::WriteFragments(
26     const Fragments& fragments, absl::string_view separator) {
27   if (fragments.empty()) {
28     return absl::string_view();
29   }
30   size_t total_size = separator.size() * (fragments.size() - 1);
31   for (const absl::string_view& fragment : fragments) {
32     total_size += fragment.size();
33   }
34   char* dst = arena_.Alloc(total_size);
35   size_t written = Join(dst, fragments, separator);
36   QUICHE_DCHECK_EQ(written, total_size);
37   return absl::string_view(dst, total_size);
38 }
39 
Join(char * dst,const Fragments & fragments,absl::string_view separator)40 size_t Join(char* dst, const Fragments& fragments,
41             absl::string_view separator) {
42   if (fragments.empty()) {
43     return 0;
44   }
45   auto* original_dst = dst;
46   auto it = fragments.begin();
47   memcpy(dst, it->data(), it->size());
48   dst += it->size();
49   for (++it; it != fragments.end(); ++it) {
50     memcpy(dst, separator.data(), separator.size());
51     dst += separator.size();
52     memcpy(dst, it->data(), it->size());
53     dst += it->size();
54   }
55   return dst - original_dst;
56 }
57 
58 }  // namespace quiche
59