blob: 942318a1852971b13e85334600a8171c20c7ea7d [file] [log] [blame]
#ifndef QUICHE_COMMON_HTTP_HTTP_HEADER_STORAGE_H_
#define QUICHE_COMMON_HTTP_HTTP_HEADER_STORAGE_H_
#include "absl/container/inlined_vector.h"
#include "absl/strings/string_view.h"
#include "quiche/common/platform/api/quiche_export.h"
#include "quiche/common/quiche_simple_arena.h"
namespace quiche {
using Fragments = absl::InlinedVector<absl::string_view, 1>;
// This class provides a backing store for absl::string_views. It previously
// used custom allocation logic, but now uses an UnsafeArena instead. It has the
// property that absl::string_views that refer to data in HttpHeaderStorage are
// never invalidated until the HttpHeaderStorage is deleted or Clear() is
// called.
//
// Write operations always append to the last block. If there is not enough
// space to perform the write, a new block is allocated, and any unused space
// is wasted.
class QUICHE_EXPORT HttpHeaderStorage {
public:
HttpHeaderStorage();
HttpHeaderStorage(const HttpHeaderStorage&) = delete;
HttpHeaderStorage& operator=(const HttpHeaderStorage&) = delete;
HttpHeaderStorage(HttpHeaderStorage&& other) = default;
HttpHeaderStorage& operator=(HttpHeaderStorage&& other) = default;
absl::string_view Write(absl::string_view s);
// If |s| points to the most recent allocation from arena_, the arena will
// reclaim the memory. Otherwise, this method is a no-op.
void Rewind(absl::string_view s);
void Clear() { arena_.Reset(); }
// Given a list of fragments and a separator, writes the fragments joined by
// the separator to a contiguous region of memory. Returns a absl::string_view
// pointing to the region of memory.
absl::string_view WriteFragments(const Fragments& fragments,
absl::string_view separator);
size_t bytes_allocated() const { return arena_.status().bytes_allocated(); }
private:
QuicheSimpleArena arena_;
};
// Writes |fragments| to |dst|, joined by |separator|. |dst| must be large
// enough to hold the result. Returns the number of bytes written.
QUICHE_EXPORT size_t Join(char* dst, const Fragments& fragments,
absl::string_view separator);
} // namespace quiche
#endif // QUICHE_COMMON_HTTP_HTTP_HEADER_STORAGE_H_