WPILibC++ 2027.0.0-alpha-4
Loading...
Searching...
No Matches
Buffer.hpp
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#pragma once
6
7#include <cstring>
8#include <initializer_list>
9#include <span>
10#include <string_view>
11#include <utility>
12
13#include <uv.h>
14
15#include "wpi/util/SmallVector.hpp"
16
17namespace wpi::net::uv {
18
19/**
20 * Data buffer. Convenience wrapper around uv_buf_t.
21 */
22class Buffer : public uv_buf_t {
23 public:
25 base = nullptr;
26 len = 0;
27 }
28 /*implicit*/ Buffer(const uv_buf_t& oth) { // NOLINT
29 base = oth.base;
30 len = oth.len;
31 }
32 /*implicit*/ Buffer(std::string_view str) // NOLINT
33 : Buffer{str.data(), str.size()} {}
34 /*implicit*/ Buffer(std::span<const uint8_t> arr) // NOLINT
35 : Buffer{reinterpret_cast<const char*>(arr.data()), arr.size()} {}
36 Buffer(char* base_, size_t len_) {
37 base = base_;
38 len = static_cast<decltype(len)>(len_);
39 }
40 Buffer(const char* base_, size_t len_) {
41 base = const_cast<char*>(base_);
42 len = static_cast<decltype(len)>(len_);
43 }
44 Buffer(uint8_t* base_, size_t len_) {
45 base = reinterpret_cast<char*>(base_);
46 len = static_cast<decltype(len)>(len_);
47 }
48 Buffer(const uint8_t* base_, size_t len_) {
49 base = reinterpret_cast<char*>(const_cast<uint8_t*>(base_));
50 len = static_cast<decltype(len)>(len_);
51 }
52
53 std::span<const char> data() const { return {base, len}; }
54 std::span<char> data() { return {base, len}; }
55
56 std::span<const uint8_t> bytes() const {
57 return {reinterpret_cast<const uint8_t*>(base), len};
58 }
59 std::span<uint8_t> bytes() { return {reinterpret_cast<uint8_t*>(base), len}; }
60
61 operator std::span<const char>() const { return data(); } // NOLINT
62 operator std::span<char>() { return data(); } // NOLINT
63
64 static Buffer Allocate(size_t size) { return Buffer{new char[size], size}; }
65
66 static Buffer Dup(std::string_view in) {
67 Buffer buf = Allocate(in.size());
68 std::memcpy(buf.base, in.data(), in.size());
69 return buf;
70 }
71
72 static Buffer Dup(std::span<const uint8_t> in) {
73 Buffer buf = Allocate(in.size());
74 std::memcpy(buf.base, in.data(), in.size());
75 return buf;
76 }
77
78 Buffer Dup() const {
79 Buffer buf = Allocate(len);
80 std::memcpy(buf.base, base, len);
81 return buf;
82 }
83
84 void Deallocate() {
85 delete[] base;
86 base = nullptr;
87 len = 0;
88 }
89
91 Buffer buf = *this;
92 base = nullptr;
93 len = 0;
94 return buf;
95 }
96
97 friend void swap(Buffer& a, Buffer& b) {
98 using std::swap;
99 swap(a.base, b.base);
100 swap(a.len, b.len);
101 }
102};
103
104/**
105 * A simple pool allocator for Buffers.
106 * Buffers are allocated individually but are reused rather than returned
107 * to the heap.
108 * @tparam DEPTH depth of pool
109 */
110template <size_t DEPTH = 4>
112 public:
113 /**
114 * Constructor.
115 * @param size Size of each buffer to allocate.
116 */
117 explicit SimpleBufferPool(size_t size = 4096) : m_size{size} {}
119
120 SimpleBufferPool(const SimpleBufferPool& other) = delete;
122
123 /**
124 * Allocate a buffer.
125 */
127 if (m_pool.empty()) {
128 return Buffer::Allocate(m_size);
129 }
130 auto buf = m_pool.back();
131 m_pool.pop_back();
132 buf.len = m_size;
133 return buf;
134 }
135
136 /**
137 * Allocate a buffer.
138 */
139 Buffer operator()() { return Allocate(); }
140
141 /**
142 * Release allocated buffers back into the pool.
143 * This is NOT safe to use with arbitrary buffers unless they were
144 * allocated with the same size as the buffer pool allocation size.
145 */
146 void Release(std::span<Buffer> bufs) {
147 for (auto& buf : bufs) {
148 m_pool.emplace_back(buf.Move());
149 }
150 }
151
152 /**
153 * Clear the pool, releasing all buffers.
154 */
155 void Clear() {
156 for (auto& buf : m_pool) {
157 buf.Deallocate();
158 }
159 m_pool.clear();
160 }
161
162 /**
163 * Get number of buffers left in the pool before a new buffer will be
164 * allocated from the heap.
165 */
166 size_t Remaining() const { return m_pool.size(); }
167
168 private:
169 wpi::util::SmallVector<Buffer, DEPTH> m_pool;
170 size_t m_size; // NOLINT
171};
172
173} // namespace wpi::net::uv
Data buffer.
Definition Buffer.hpp:22
std::span< const char > data() const
Definition Buffer.hpp:53
Buffer(uint8_t *base_, size_t len_)
Definition Buffer.hpp:44
Buffer(const uint8_t *base_, size_t len_)
Definition Buffer.hpp:48
Buffer Move()
Definition Buffer.hpp:90
Buffer Dup() const
Definition Buffer.hpp:78
std::span< char > data()
Definition Buffer.hpp:54
std::span< uint8_t > bytes()
Definition Buffer.hpp:59
Buffer(const uv_buf_t &oth)
Definition Buffer.hpp:28
Buffer(const char *base_, size_t len_)
Definition Buffer.hpp:40
std::span< const uint8_t > bytes() const
Definition Buffer.hpp:56
static Buffer Dup(std::span< const uint8_t > in)
Definition Buffer.hpp:72
Buffer()
Definition Buffer.hpp:24
void Deallocate()
Definition Buffer.hpp:84
Buffer(char *base_, size_t len_)
Definition Buffer.hpp:36
Buffer(std::span< const uint8_t > arr)
Definition Buffer.hpp:34
static Buffer Allocate(size_t size)
Definition Buffer.hpp:64
static Buffer Dup(std::string_view in)
Definition Buffer.hpp:66
Buffer(std::string_view str)
Definition Buffer.hpp:32
friend void swap(Buffer &a, Buffer &b)
Definition Buffer.hpp:97
~SimpleBufferPool()
Definition Buffer.hpp:118
void Release(std::span< Buffer > bufs)
Release allocated buffers back into the pool.
Definition Buffer.hpp:146
Buffer operator()()
Allocate a buffer.
Definition Buffer.hpp:139
void Clear()
Clear the pool, releasing all buffers.
Definition Buffer.hpp:155
SimpleBufferPool(const SimpleBufferPool &other)=delete
SimpleBufferPool & operator=(const SimpleBufferPool &other)=delete
Buffer Allocate()
Allocate a buffer.
Definition Buffer.hpp:126
SimpleBufferPool(size_t size=4096)
Constructor.
Definition Buffer.hpp:117
size_t Remaining() const
Get number of buffers left in the pool before a new buffer will be allocated from the heap.
Definition Buffer.hpp:166
void swap(wpi::util::StringMap< T > &lhs, wpi::util::StringMap< T > &rhs)
Definition StringMap.hpp:775
Definition Prepare.hpp:14