blob: 6bb1af900611b3ee64406120a0e5ffcb3a3f70b9 [file] [log] [blame]
Bence Békybac04052022-04-07 15:44:29 -04001// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef QUICHE_COMMON_QUICHE_BUFFER_ALLOCATOR_H_
6#define QUICHE_COMMON_QUICHE_BUFFER_ALLOCATOR_H_
7
8#include <stddef.h>
9
10#include <memory>
11
12#include "absl/strings/string_view.h"
13#include "quiche/common/platform/api/quiche_export.h"
14#include "quiche/common/platform/api/quiche_iovec.h"
15
16namespace quiche {
17
18// Abstract base class for classes which allocate and delete buffers.
19class QUICHE_EXPORT_PRIVATE QuicheBufferAllocator {
20 public:
21 virtual ~QuicheBufferAllocator() = default;
22
23 // Returns or allocates a new buffer of |size|. Never returns null.
24 virtual char* New(size_t size) = 0;
25
26 // Returns or allocates a new buffer of |size| if |flag_enable| is true.
27 // Otherwise, returns a buffer that is compatible with this class directly
28 // with operator new. Never returns null.
29 virtual char* New(size_t size, bool flag_enable) = 0;
30
31 // Releases a buffer.
32 virtual void Delete(char* buffer) = 0;
33
34 // Marks the allocator as being idle. Serves as a hint to notify the allocator
35 // that it should release any resources it's still holding on to.
36 virtual void MarkAllocatorIdle() {}
37};
38
39// A deleter that can be used to manage ownership of buffers allocated via
40// QuicheBufferAllocator through std::unique_ptr.
41class QUICHE_EXPORT_PRIVATE QuicheBufferDeleter {
42 public:
43 explicit QuicheBufferDeleter(QuicheBufferAllocator* allocator)
44 : allocator_(allocator) {}
45
46 QuicheBufferAllocator* allocator() { return allocator_; }
47 void operator()(char* buffer) { allocator_->Delete(buffer); }
48
49 private:
50 QuicheBufferAllocator* allocator_;
51};
52
53using QuicheUniqueBufferPtr = std::unique_ptr<char[], QuicheBufferDeleter>;
54
55inline QuicheUniqueBufferPtr MakeUniqueBuffer(QuicheBufferAllocator* allocator,
56 size_t size) {
57 return QuicheUniqueBufferPtr(allocator->New(size),
58 QuicheBufferDeleter(allocator));
59}
60
61// QuicheUniqueBufferPtr with a length attached to it. Similar to
62// QuicheMemSlice, except unlike QuicheMemSlice, QuicheBuffer is mutable and is
63// not platform-specific. Also unlike QuicheMemSlice, QuicheBuffer can be
64// empty.
65class QUICHE_EXPORT_PRIVATE QuicheBuffer {
66 public:
67 QuicheBuffer() : buffer_(nullptr, QuicheBufferDeleter(nullptr)), size_(0) {}
68 QuicheBuffer(QuicheBufferAllocator* allocator, size_t size)
69 : buffer_(MakeUniqueBuffer(allocator, size)), size_(size) {}
70
71 QuicheBuffer(QuicheUniqueBufferPtr buffer, size_t size)
72 : buffer_(std::move(buffer)), size_(size) {}
73
74 // Make sure the move constructor zeroes out the size field.
75 QuicheBuffer(QuicheBuffer&& other)
76 : buffer_(std::move(other.buffer_)), size_(other.size_) {
77 other.buffer_ = nullptr;
78 other.size_ = 0;
79 }
80 QuicheBuffer& operator=(QuicheBuffer&& other) {
81 buffer_ = std::move(other.buffer_);
82 size_ = other.size_;
83
84 other.buffer_ = nullptr;
85 other.size_ = 0;
86 return *this;
87 }
88
89 // Factory method to create a QuicheBuffer that holds a copy of `data`.
90 static QuicheBuffer Copy(QuicheBufferAllocator* allocator,
91 absl::string_view data) {
92 QuicheBuffer buffer(allocator, data.size());
93 memcpy(buffer.data(), data.data(), data.size());
94 return buffer;
95 }
96
97 // Factory method to create a QuicheBuffer of length `buffer_length` that
98 // holds a copy of `buffer_length` bytes from `iov` starting at offset
99 // `iov_offset`. `iov` must be at least `iov_offset + buffer_length` total
100 // length.
101 static QuicheBuffer CopyFromIovec(QuicheBufferAllocator* allocator,
102 const struct iovec* iov, int iov_count,
103 size_t iov_offset, size_t buffer_length);
104
105 const char* data() const { return buffer_.get(); }
106 char* data() { return buffer_.get(); }
107 size_t size() const { return size_; }
108 bool empty() const { return size_ == 0; }
109 absl::string_view AsStringView() const {
110 return absl::string_view(data(), size());
111 }
112
113 // Releases the ownership of the underlying buffer.
114 QuicheUniqueBufferPtr Release() {
115 size_ = 0;
116 return std::move(buffer_);
117 }
118
119 private:
120 QuicheUniqueBufferPtr buffer_;
121 size_t size_;
122};
123
124} // namespace quiche
125
126#endif // QUICHE_COMMON_QUICHE_BUFFER_ALLOCATOR_H_