RAVENNAKIT
Loading...
Searching...
No Matches
buffer_view.hpp
Go to the documentation of this file.
1// SPDX-License-Identifier: AGPL-3.0-or-later
2/*
3 * Project: RAVENNAKIT (RAVENNA / AES67 / ST2110-30 SDK)
4 * Copyright (c) 2024-2025 Sound on Digital
5 *
6 * This file is part of RAVENNAKIT.
7 *
8 * RAVENNAKIT is dual-licensed:
9 * 1) Under the terms of the GNU Affero General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version (the "AGPL License"); and
12 * 2) Under a commercial license from Sound on Digital, for customers who
13 * cannot (or do not wish to) comply with the AGPL License terms.
14 *
15 * If you obtained this file under the AGPL License, you may redistribute it
16 * and/or modify it under the terms of the AGPL License. See the LICENSE
17 * file in the project root for details.
18 *
19 * For commercial licensing, support, and other inquiries, please visit:
20 *
21 * https://ravennakit.com
22 *
23 */
24
25#pragma once
26
29
30#include <cstddef>
31#include <array>
32#include <vector>
33
34namespace rav {
35
40template<class Type>
42 public:
43 BufferView() = default;
44
45 BufferView(const BufferView& other) = default;
46 BufferView& operator=(const BufferView& other) = default;
47
48 BufferView(BufferView&& other) noexcept = default;
49 BufferView& operator=(BufferView&& other) noexcept = default;
50
56 BufferView(Type* data, const size_t size) : data_(data), size_(size) {
57 if (data_ == nullptr) {
58 size_ = 0;
59 }
60 }
61
67 template<size_t S>
68 explicit BufferView(const std::array<Type, S>& array) : BufferView(array.data(), array.size()) {}
69
74 template<typename T = Type, std::enable_if_t<!std::is_const_v<T>, int> = 0> // Type must be non-const for vector.
75 explicit BufferView(const std::vector<Type>& vector) : BufferView(vector.data(), vector.size()) {}
76
81 template<typename T = Type, std::enable_if_t<!std::is_const_v<T>, int> = 0> // Type must be non-const for vector.
82 explicit BufferView(std::vector<Type>& vector) : BufferView(vector.data(), vector.size()) {}
83
88 Type& operator[](size_t index) const {
89 return data_[index];
90 }
91
95 [[nodiscard]] const Type* data() const {
96 return data_;
97 }
98
102 [[nodiscard]] Type* data() {
103 return data_;
104 }
105
109 [[nodiscard]] size_t size() const {
110 return size_;
111 }
112
116 [[nodiscard]] size_t size_bytes() const {
117 return size_ * sizeof(Type);
118 }
119
123 [[nodiscard]] bool empty() const {
124 return size_ == 0;
125 }
126
134 template<typename ValueType, std::enable_if_t<std::is_trivially_copyable_v<ValueType>, bool> = true>
135 ValueType read_ne(const size_t offset) const {
136 RAV_ASSERT(offset + sizeof(ValueType) <= size_bytes(), "Buffer view out of bounds");
137 return rav::read_ne<ValueType>(data_ + offset);
138 }
139
146 template<typename ValueType, std::enable_if_t<std::is_trivially_copyable_v<ValueType>, bool> = true>
147 ValueType read_be(const size_t offset) const {
148 return swap_if_le(read_ne<ValueType>(offset));
149 }
150
157 template<typename ValueType, std::enable_if_t<std::is_trivially_copyable_v<ValueType>, bool> = true>
158 ValueType read_le(const size_t offset) const {
159 return swap_if_be(read_ne<ValueType>(offset));
160 }
161
166 [[nodiscard]] BufferView subview(size_t offset) const {
167 offset = std::min(offset, size_);
168 return BufferView(data_ + offset, size_ - offset);
169 }
170
176 [[nodiscard]] BufferView subview(size_t offset, const size_t size) const {
177 offset = std::min(offset, size_);
178 return BufferView(data_ + offset, std::min(size_ - offset, size));
179 }
180
187
194 template<class NewType>
196 return BufferView<NewType>(reinterpret_cast<NewType*>(data_), size_ * sizeof(Type) / sizeof(NewType));
197 }
198
199 private:
200 Type* data_ {nullptr};
201 size_t size_ {0};
202};
203
204} // namespace rav
#define RAV_ASSERT(condition, message)
Asserts condition to be true, otherwise:
Definition assert.hpp:101
size_t size_bytes() const
ValueType read_ne(const size_t offset) const
Reads a value from the data in native byte order (not to be confused with network-endian).
BufferView< NewType > reinterpret() const
Returns a new buffer_view pointing to the same data, but reinterpreted as a different type.
BufferView & operator=(BufferView &&other) noexcept=default
BufferView< std::add_const_t< Type > > const_view() const
ValueType read_be(const size_t offset) const
Reads a big-endian value from the given data.
BufferView subview(size_t offset) const
BufferView(BufferView &&other) noexcept=default
BufferView(Type *data, const size_t size)
Construct a view pointing to given data.
BufferView(const std::vector< Type > &vector)
Construct a view from a std::vector.
Type & operator[](size_t index) const
BufferView(std::vector< Type > &vector)
Construct a view from a std::vector.
bool empty() const
BufferView(const std::array< Type, S > &array)
Construct a view from a std::array.
const Type * data() const
ValueType read_le(const size_t offset) const
Reads a little-endian value from the given data.
BufferView(const BufferView &other)=default
BufferView subview(size_t offset, const size_t size) const
BufferView()=default
size_t size() const
BufferView & operator=(const BufferView &other)=default
Type swap_if_le(const Type value)
Swaps the bytes of the given value if the system is little-endian.
Type read_ne(const uint8_t *data)
Reads a value from the given data in native byte order (not to be confused with network-endian).
Type swap_if_be(const Type value)
Swaps the bytes of the given value if the system is big-endian.