WPILibC++ 2024.1.1-beta-4
Buffer.h
Go to the documentation of this file.
1// Copyright (c) FIRST and other WPILib contributors.
2// Open Source Software; you can modify and/or share it under the terms of
3// the WPILib BSD license file in the root directory of this project.
4
5#ifndef WPINET_UV_BUFFER_H_
6#define WPINET_UV_BUFFER_H_
7
8#include <uv.h>
9
10#include <cstring>
11#include <initializer_list>
12#include <span>
13#include <string_view>
14#include <utility>
15
16#include <wpi/SmallVector.h>
17
18namespace wpi::uv {
19
20/**
21 * Data buffer. Convenience wrapper around uv_buf_t.
22 */
23class Buffer : public uv_buf_t {
24 public:
26 base = nullptr;
27 len = 0;
28 }
29 /*implicit*/ Buffer(const uv_buf_t& oth) { // NOLINT
30 base = oth.base;
31 len = oth.len;
32 }
33 /*implicit*/ Buffer(std::string_view str) // NOLINT
34 : Buffer{str.data(), str.size()} {}
35 /*implicit*/ Buffer(std::span<const uint8_t> arr) // NOLINT
36 : Buffer{reinterpret_cast<const char*>(arr.data()), arr.size()} {}
37 Buffer(char* base_, size_t len_) {
38 base = base_;
39 len = static_cast<decltype(len)>(len_);
40 }
41 Buffer(const char* base_, size_t len_) {
42 base = const_cast<char*>(base_);
43 len = static_cast<decltype(len)>(len_);
44 }
45 Buffer(uint8_t* base_, size_t len_) {
46 base = reinterpret_cast<char*>(base_);
47 len = static_cast<decltype(len)>(len_);
48 }
49 Buffer(const uint8_t* base_, size_t len_) {
50 base = reinterpret_cast<char*>(const_cast<uint8_t*>(base_));
51 len = static_cast<decltype(len)>(len_);
52 }
53
54 std::span<const char> data() const { return {base, len}; }
55 std::span<char> data() { return {base, len}; }
56
57 std::span<const uint8_t> bytes() const {
58 return {reinterpret_cast<const uint8_t*>(base), len};
59 }
60 std::span<uint8_t> bytes() { return {reinterpret_cast<uint8_t*>(base), len}; }
61
62 operator std::span<const char>() const { return data(); } // NOLINT
63 operator std::span<char>() { return data(); } // NOLINT
64
65 static Buffer Allocate(size_t size) { return Buffer{new char[size], size}; }
66
68 Buffer buf = Allocate(in.size());
69 std::memcpy(buf.base, in.data(), in.size());
70 return buf;
71 }
72
73 static Buffer Dup(std::span<const uint8_t> in) {
74 Buffer buf = Allocate(in.size());
75 std::memcpy(buf.base, in.data(), in.size());
76 return buf;
77 }
78
79 Buffer Dup() const {
80 Buffer buf = Allocate(len);
81 std::memcpy(buf.base, base, len);
82 return buf;
83 }
84
85 void Deallocate() {
86 delete[] base;
87 base = nullptr;
88 len = 0;
89 }
90
92 Buffer buf = *this;
93 base = nullptr;
94 len = 0;
95 return buf;
96 }
97
98 friend void swap(Buffer& a, Buffer& b) {
99 using std::swap;
100 swap(a.base, b.base);
101 swap(a.len, b.len);
102 }
103};
104
105/**
106 * A simple pool allocator for Buffers.
107 * Buffers are allocated individually but are reused rather than returned
108 * to the heap.
109 * @tparam DEPTH depth of pool
110 */
111template <size_t DEPTH = 4>
113 public:
114 /**
115 * Constructor.
116 * @param size Size of each buffer to allocate.
117 */
118 explicit SimpleBufferPool(size_t size = 4096) : m_size{size} {}
120
121 SimpleBufferPool(const SimpleBufferPool& other) = delete;
123
124 /**
125 * Allocate a buffer.
126 */
128 if (m_pool.empty()) {
129 return Buffer::Allocate(m_size);
130 }
131 auto buf = m_pool.back();
132 m_pool.pop_back();
133 buf.len = m_size;
134 return buf;
135 }
136
137 /**
138 * Allocate a buffer.
139 */
140 Buffer operator()() { return Allocate(); }
141
142 /**
143 * Release allocated buffers back into the pool.
144 * This is NOT safe to use with arbitrary buffers unless they were
145 * allocated with the same size as the buffer pool allocation size.
146 */
147 void Release(std::span<Buffer> bufs) {
148 for (auto& buf : bufs) {
149 m_pool.emplace_back(buf.Move());
150 }
151 }
152
153 /**
154 * Clear the pool, releasing all buffers.
155 */
156 void Clear() {
157 for (auto& buf : m_pool) {
158 buf.Deallocate();
159 }
160 m_pool.clear();
161 }
162
163 /**
164 * Get number of buffers left in the pool before a new buffer will be
165 * allocated from the heap.
166 */
167 size_t Remaining() const { return m_pool.size(); }
168
169 private:
171 size_t m_size; // NOLINT
172};
173
174} // namespace wpi::uv
175
176#endif // WPINET_UV_BUFFER_H_
This file defines the SmallVector class.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1202
Data buffer.
Definition: Buffer.h:23
std::span< char > data()
Definition: Buffer.h:55
std::span< const char > data() const
Definition: Buffer.h:54
Buffer()
Definition: Buffer.h:25
Buffer(std::string_view str)
Definition: Buffer.h:33
void Deallocate()
Definition: Buffer.h:85
Buffer(const uv_buf_t &oth)
Definition: Buffer.h:29
Buffer Dup() const
Definition: Buffer.h:79
std::span< const uint8_t > bytes() const
Definition: Buffer.h:57
Buffer(const char *base_, size_t len_)
Definition: Buffer.h:41
Buffer(uint8_t *base_, size_t len_)
Definition: Buffer.h:45
static Buffer Allocate(size_t size)
Definition: Buffer.h:65
std::span< uint8_t > bytes()
Definition: Buffer.h:60
Buffer(const uint8_t *base_, size_t len_)
Definition: Buffer.h:49
Buffer(std::span< const uint8_t > arr)
Definition: Buffer.h:35
static Buffer Dup(std::string_view in)
Definition: Buffer.h:67
static Buffer Dup(std::span< const uint8_t > in)
Definition: Buffer.h:73
Buffer Move()
Definition: Buffer.h:91
Buffer(char *base_, size_t len_)
Definition: Buffer.h:37
friend void swap(Buffer &a, Buffer &b)
Definition: Buffer.h:98
A simple pool allocator for Buffers.
Definition: Buffer.h:112
Buffer operator()()
Allocate a buffer.
Definition: Buffer.h:140
SimpleBufferPool(size_t size=4096)
Constructor.
Definition: Buffer.h:118
SimpleBufferPool & operator=(const SimpleBufferPool &other)=delete
size_t Remaining() const
Get number of buffers left in the pool before a new buffer will be allocated from the heap.
Definition: Buffer.h:167
void Release(std::span< Buffer > bufs)
Release allocated buffers back into the pool.
Definition: Buffer.h:147
void Clear()
Clear the pool, releasing all buffers.
Definition: Buffer.h:156
SimpleBufferPool(const SimpleBufferPool &other)=delete
Buffer Allocate()
Allocate a buffer.
Definition: Buffer.h:127
~SimpleBufferPool()
Definition: Buffer.h:119
basic_string_view< char > string_view
Definition: core.h:501
constexpr auto in(type t, int set) -> bool
Definition: core.h:611
WPI_BASIC_JSON_TPL_DECLARATION void swap(wpi::WPI_BASIC_JSON_TPL &j1, wpi::WPI_BASIC_JSON_TPL &j2) noexcept(//NOLINT(readability-inconsistent-declaration-parameter-name) is_nothrow_move_constructible< wpi::WPI_BASIC_JSON_TPL >::value &&//NOLINT(misc-redundant-expression) is_nothrow_move_assignable< wpi::WPI_BASIC_JSON_TPL >::value)
exchanges the values of two JSON objects
Definition: json.h:5219
b
Definition: data.h:44
Definition: WebSocket.h:27
It should be possible to cast uv_buf_t[] to WSABUF[] see http://msdn.microsoft.com/en-us/library/ms74...
Definition: unix.h:112
size_t len
Definition: unix.h:114
char * base
Definition: unix.h:113