proxygen
HPACKHeaderName.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015-present, Facebook, Inc.
3  * All rights reserved.
4  *
5  * This source code is licensed under the BSD-style license found in the
6  * LICENSE file in the root directory of this source tree. An additional grant
7  * of patent rights can be found in the PATENTS file in the same directory.
8  *
9  */
10 #pragma once
11 
12 #include <algorithm>
13 #include <cstdint>
14 #include <functional>
15 #include <string>
16 #include <iostream>
17 #include <boost/variant.hpp>
19 #include <folly/Range.h>
20 
21 namespace proxygen {
22 
23 /*
24  * HPACKHeaderName stores the header name of HPACKHeaders. If
25  * the header name is in HTTPCommonHeader, it will store a
26  * pointer to the common header, otherwise, it will store a
27  * pointer to a the dynamically allocated std::string
28  */
30  public:
32 
34  storeAddress(name);
35  }
36  HPACKHeaderName(const HPACKHeaderName& headerName) {
37  copyAddress(headerName);
38  }
40  moveAddress(goner);
41  }
43  resetAddress();
44  storeAddress(name);
45  return *this;
46  }
48  if (this != &headerName) {
49  resetAddress();
50  copyAddress(headerName);
51  }
52  return *this;
53  }
55  if (this != &goner) {
56  resetAddress();
57  moveAddress(goner);
58  }
59  return *this;
60  }
61 
63  resetAddress();
64  }
65 
66  /*
67  * Compare the strings stored in HPACKHeaderName
68  */
69  bool operator==(const HPACKHeaderName& headerName) const {
70  return address_ == headerName.address_ ||
71  *address_ == *(headerName.address_);
72  }
73  bool operator!=(const HPACKHeaderName& headerName) const {
74  // Utilize the == overloaded operator
75  return !(*this == headerName);
76  }
77  bool operator>(const HPACKHeaderName& headerName) const {
78  if (!isAllocated() && !headerName.isAllocated()) {
79  // Common header tables are aligned alphabetically (unit tested as well
80  // to ensure it isn't accidentally changed)
81  return address_ > headerName.address_;
82  } else {
83  return *address_ > *(headerName.address_);
84  }
85  }
86  bool operator<(const HPACKHeaderName& headerName) const {
87  if (!isAllocated() && !headerName.isAllocated()) {
88  // Common header tables are aligned alphabetically (unit tested as well
89  // to ensure it isn't accidentally changed)
90  return address_ < headerName.address_;
91  } else {
92  return *address_ < *(headerName.address_);
93  }
94  }
95  bool operator>=(const HPACKHeaderName& headerName) const {
96  // Utilize existing < overloaded operator
97  return !(*this < headerName);
98  }
99  bool operator<=(const HPACKHeaderName& headerName) const {
100  // Utilize existing > overload operator
101  return !(*this > headerName);
102  }
103 
104  /*
105  * Return std::string stored in HPACKHeaderName
106  */
107  const std::string& get() const {
108  return *address_;
109  }
110 
111  /*
112  * Returns the HTTPHeaderCode associated with the wrapped address_
113  */
117  }
118 
119  /*
120  * Returns whether the name pointed to by this instance is a common header
121  */
122  bool isCommonHeader() const {
124  }
125 
126  /*
127  * Exposing wrapped std::string member properties
128  */
129  uint32_t size() const {
130  return (uint32_t)(address_->size());
131  }
132  const char* c_str() const {
133  return address_->c_str();
134  }
135 
136  private:
137  /*
138  * Store a reference to either a common header or newly allocated string
139  */
142  name.data(), name.size());
143  if (headerCode == HTTPHeaderCode::HTTP_HEADER_NONE ||
144  headerCode == HTTPHeaderCode::HTTP_HEADER_OTHER) {
145  std::string* newAddress = new std::string(name.size(), 0);
146  std::transform(name.begin(), name.end(), newAddress->begin(), ::tolower);
147  address_ = newAddress;
148  } else {
150  headerCode, TABLE_LOWERCASE);
151  }
152  }
153 
154  /*
155  * Copy the address_ from another HPACKHeaderName
156  */
157  void copyAddress(const HPACKHeaderName& headerName) {
158  if (headerName.isAllocated()) {
159  address_ = new std::string(headerName.get());
160  } else {
161  address_ = headerName.address_;
162  }
163  }
164 
165  /*
166  * Move the address_ from another HPACKHeaderName
167  */
169  address_ = goner.address_;
170  goner.address_ = nullptr;
171  }
172 
173  /*
174  * Delete any allocated memory and reset address_ to nullptr
175  */
176  void resetAddress() {
177  if (isAllocated()) {
178  delete address_;
179  }
180  address_ = nullptr;
181  }
182 
183  /*
184  * Returns whether the underlying address_ points to a string that was
185  * allocated (memory) by this instance
186  */
187  bool isAllocated() const {
188  if (address_ == nullptr) {
189  return false;
190  } else {
193  }
194  }
195 
196  /*
197  * Address either stores a pointer to a header name in HTTPCommonHeaders,
198  * or stores a pointer to a dynamically allocated std::string
199  */
200  const std::string* address_ = nullptr;
201 };
202 
203 inline std::ostream& operator<<(std::ostream& os, const HPACKHeaderName& name) {
204  os << name.get();
205  return os;
206 }
207 
208 } // proxygen
209 
210 namespace std {
211 
212 template<>
213 struct hash<proxygen::HPACKHeaderName> {
214  size_t operator()(const proxygen::HPACKHeaderName& headerName) const {
215  return std::hash<std::string>()(headerName.get());
216  }
217 };
218 
219 } // std
bool operator==(const HPACKHeaderName &headerName) const
void storeAddress(folly::StringPiece name)
HPACKHeaderName & operator=(HPACKHeaderName &&goner) noexcept
void moveAddress(HPACKHeaderName &goner)
const char * c_str() const
HPACKHeaderName & operator=(folly::StringPiece name)
std::ostream & operator<<(std::ostream &os, const HeaderTable &table)
const std::string * address_
HTTPHeaderCode getHeaderCode() const
STL namespace.
constexpr size_type size() const
Definition: Range.h:431
bool operator!=(const HPACKHeaderName &headerName) const
static HTTPHeaderCode getHeaderCodeFromTableCommonHeaderName(const std::string *headerName, HTTPCommonHeaderTableType type)
requires E e noexcept(noexcept(s.error(std::move(e))))
PUSHMI_INLINE_VAR constexpr detail::transform_fn transform
Definition: transform.h:158
bool operator<=(const HPACKHeaderName &headerName) const
bool operator>=(const HPACKHeaderName &headerName) const
const char * name
Definition: http_parser.c:437
bool operator<(const HPACKHeaderName &headerName) const
static bool isHeaderNameFromTable(const std::string *headerName, HTTPCommonHeaderTableType type)
constexpr Iter data() const
Definition: Range.h:446
HPACKHeaderName(HPACKHeaderName &&goner) noexcept
static const std::string * getPointerToHeaderName(HTTPHeaderCode code, HTTPCommonHeaderTableType type=TABLE_CAMELCASE)
constexpr Iter end() const
Definition: Range.h:455
constexpr Iter begin() const
Definition: Range.h:452
bool operator>(const HPACKHeaderName &headerName) const
const char * string
Definition: Conv.cpp:212
HPACKHeaderName & operator=(const HPACKHeaderName &headerName)
static FB_EXPORT HTTPHeaderCode hash(const char *name, size_t len)
HPACKHeaderName(folly::StringPiece name)
size_t operator()(const proxygen::HPACKHeaderName &headerName) const
void copyAddress(const HPACKHeaderName &headerName)
HPACKHeaderName(const HPACKHeaderName &headerName)
const std::string & get() const