StormByte C++ Library: Buffer module 1.2.0
StormByte-Buffer is the buffer module of the StormByte C++ suite.
Loading...
Searching...
No Matches
ring.hxx
Go to the documentation of this file.
1/*
2 * Copyright (C) 2024-2026 David C. Manuelda (StormBytePP)
3 *
4 * This file is part of StormByte-Buffer.
5 *
6 * StormByte-Buffer is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU Lesser General Public License version 3
8 * or later, as published by the Free Software Foundation.
9 *
10 * StormByte-Buffer is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public License
16 * along with StormByte-Buffer. If not, see
17 * <https://www.gnu.org/licenses/lgpl-3.0.html>.
18 */
19
20#pragma once
21
24#include <StormByte/string.hxx>
25
26#include <condition_variable>
27#include <deque>
28#include <shared_mutex>
29#include <span>
30#include <sstream>
31#include <string>
32#include <utility>
33
38namespace StormByte::Buffer {
63 public:
70 Ring() noexcept = default;
71
76 inline explicit Ring(const DataType& data) noexcept
77 : m_buffer(data.begin(), data.end()) {}
78
83 inline explicit Ring(DataType&& data) noexcept
84 : m_buffer(std::make_move_iterator(data.begin()),
85 std::make_move_iterator(data.end())) {}
86
92 template<Type::ByteInputRange R>
93 requires (!Type::SameAs<R, DataType>)
94 inline explicit Ring(const R& r) noexcept {
95 auto converted = DataConvert(r);
96 m_buffer.assign(converted.begin(), converted.end());
97 }
98
104 template<Type::ByteInputRange Rr>
105 inline explicit Ring(Rr&& r) noexcept {
106 auto converted = DataConvert(std::forward<Rr>(r));
107 m_buffer.assign(std::make_move_iterator(converted.begin()),
108 std::make_move_iterator(converted.end()));
109 }
110
115 inline explicit Ring(std::string_view sv) noexcept {
116 auto converted = DataConvert(sv);
117 m_buffer.assign(converted.begin(), converted.end());
118 }
119
124 inline explicit Ring(const char* s) noexcept
125 : Ring(s ? std::string_view(s) : std::string_view{}) {}
126
128 Ring(const Ring&) = delete;
129
134 Ring(Ring&& other) noexcept;
135
137 virtual ~Ring() noexcept;
138
140 Ring& operator=(const Ring&) = delete;
141
147 Ring& operator=(Ring&& other) noexcept;
148
161 bool operator==(const Ring& other) const noexcept;
162
168 inline bool operator!=(const Ring& other) const noexcept {
169 return !(*this == other);
170 }
171
183 std::size_t AvailableBytes() const noexcept override;
184
189 const DataType& Data() const noexcept override;
190
195 bool Empty() const noexcept override;
196
201 bool EoF() const noexcept override;
202
207 bool HasError() const noexcept;
208
213 bool IsReadable() const noexcept override;
214
219 bool IsWritable() const noexcept override;
220
225 std::size_t Size() const noexcept override;
226
237 void Clean() noexcept override;
238
243 void Clear() noexcept override;
244
250 void Close() noexcept override;
251
257 bool Drop(const std::size_t& count) noexcept override;
258
264 void Seek(const std::ptrdiff_t& offset, const Position& mode) const noexcept override;
265
270 void SetError() noexcept override;
271
285 std::string HexDump(const std::size_t& columns = 16,
286 const std::size_t& byte_limit = 0) const noexcept;
287
294 bool Peek(const std::size_t& count, DataType& outBuffer) const noexcept override;
295 bool Peek(const std::size_t& count, WriteOnly& outBuffer) const noexcept override;
302 bool Read(const std::size_t& count, DataType& outBuffer) const noexcept override;
303 bool Read(const std::size_t& count, WriteOnly& outBuffer) const noexcept override;
304 void ReadUntilEoF(DataType& outBuffer) const noexcept override;
305 void ReadUntilEoF(WriteOnly& outBuffer) const noexcept override;
312 bool Extract(const std::size_t& count, DataType& outBuffer) noexcept override;
313 bool Extract(const std::size_t& count, WriteOnly& outBuffer) noexcept override;
314 void ExtractUntilEoF(DataType& outBuffer) noexcept override;
315 void ExtractUntilEoF(WriteOnly& outBuffer) noexcept override;
322 bool Write(const std::size_t& count, const DataType& data) noexcept override;
323 bool Write(const std::size_t& count, DataType&& data) noexcept override;
324 bool Write(const std::size_t& count, const ReadOnly& data) noexcept override;
325 bool Write(const std::size_t& count, ReadOnly&& data) noexcept override;
326
328 using WriteOnly::Write;
331 protected:
335 enum class Operation {
336 Extract,
337 Read,
338 Peek
339 };
340
348 static std::string FormatHexLines(std::span<const std::byte> data,
349 std::size_t start_offset,
350 std::size_t columns) noexcept;
351
356 virtual std::ostringstream HexDumpHeader() const noexcept;
357
362 virtual bool ReadInternal(const std::size_t& count, DataType& outBuffer, Operation flag) noexcept;
363 virtual bool ReadInternal(const std::size_t& count, WriteOnly& outBuffer, Operation flag) noexcept;
364 virtual void ReadUntilEoFInternal(DataType& outBuffer, Operation flag) noexcept;
365 virtual void ReadUntilEoFInternal(WriteOnly& outBuffer, Operation flag) noexcept;
366
367 virtual bool WriteInternal(const std::size_t& count, const DataType& src) noexcept;
368 virtual bool WriteInternal(const std::size_t& count, DataType&& src) noexcept;
371 private:
372 std::deque<std::byte> m_buffer;
373 mutable std::size_t m_position_offset{0};
374 bool m_closed{false};
375 bool m_error{false};
376 std::string m_error_message;
377
378 mutable DataType m_data_cache;
379 mutable std::shared_mutex m_mutex;
380 mutable std::condition_variable_any m_cv;
381
387 void Wait(const std::size_t& n, std::unique_lock<std::shared_mutex>& lock) const;
388 };
389}
Pure interface for a buffer that can be read but not written.
Definition generic.hxx:164
Pure interface combining ReadOnly and WriteOnly.
Definition generic.hxx:762
High-performance, highly-concurrent thread-safe ring buffer.
Definition ring.hxx:62
Ring(const R &r) noexcept
Construct from an input range (copy / convert).
Definition ring.hxx:94
virtual ~Ring() noexcept
Virtual destructor.
virtual std::ostringstream HexDumpHeader() const noexcept
Build the hexdump header (size / position / status).
static std::string FormatHexLines(std::span< const std::byte > data, std::size_t start_offset, std::size_t columns) noexcept
Format hex/ASCII lines for a data span.
Ring(Ring &&other) noexcept
Move constructor.
Ring(const Ring &)=delete
Copy constructor (deleted – mutexes are not copyable).
std::size_t AvailableBytes() const noexcept override
Bytes available from the current read position.
Ring() noexcept=default
Default construct an empty Ring.
Ring(const char *s) noexcept
Construct from a null-terminated C string.
Definition ring.hxx:124
Ring(Rr &&r) noexcept
Construct from an rvalue range.
Definition ring.hxx:105
Ring(DataType &&data) noexcept
Construct with initial data (move elements from vector).
Definition ring.hxx:83
Ring(std::string_view sv) noexcept
Construct from a string view (no trailing NUL).
Definition ring.hxx:115
Operation
Kind of internal read operation.
Definition ring.hxx:335
Pure interface for a buffer that can be written but not read.
Definition generic.hxx:420
Buffer module of the StormByte suite.
std::vector< std::byte > DataType
Primary byte storage type used throughout the buffer API.
Definition typedefs.hxx:62
Position
Forward declaration of the WriteOnly interface.
Definition typedefs.hxx:50
#define STORMBYTE_BUFFER_PUBLIC
Definition visibility.h:28