Roc Toolkit internal modules
Roc Toolkit: real-time audio streaming
Toggle main menu visibility
Loading...
Searching...
No Matches
slice.h
Go to the documentation of this file.
1
/*
2
* Copyright (c) 2015 Roc Streaming authors
3
*
4
* This Source Code Form is subject to the terms of the Mozilla Public
5
* License, v. 2.0. If a copy of the MPL was not distributed with this
6
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
7
*/
8
9
//! @file roc_core/slice.h
10
//! @brief Slice.
11
12
#ifndef ROC_CORE_SLICE_H_
13
#define ROC_CORE_SLICE_H_
14
15
#include "
roc_core/buffer.h
"
16
#include "
roc_core/print_memory.h
"
17
#include "
roc_core/shared_ptr.h
"
18
19
namespace
roc
{
20
namespace
core
{
21
22
//! Slice.
23
//!
24
//! Slice points to a subrange of data in pool-allocated Buffer.
25
//! Copying a slice produces a new slice referring the same data.
26
//!
27
//! Slice also acts as a kind of shared pointer to Buffer. A buffer won't be freed
28
//! (returned to pool) until there are slices referring it. Copying a slice
29
//! increments the buffer reference counter, and destroying a slice decrements it.
30
//!
31
//! While Buffer works with raw bytes, Slice<T> interprets it as array of elements
32
//! of type T, and works in terms of those elements.
33
//!
34
//! Slice has two important characteristics:
35
//! - size - the difference between the ending end beginning pointer
36
//! - capacity - the difference between the actual buffer end and the
37
//! slice beginning pointer
38
//!
39
//! Buffers are not resizable. They're allocated from pool and have fixed size,
40
//! defined by the pool parameters.
41
//!
42
//! Slices are reslicable, which means that their pointers to the buffer data
43
//! may be moved within the buffer.
44
//!
45
//! The beginning pointer may be moved only forward. Once moved, it's not allowed
46
//! to move it backward again. Moving it decreases the slice size and capacity.
47
//! Capacity is affected because it's relative to the beginning pointer.
48
//!
49
//! The ending pointer may be freely moved forward and backward within the slice
50
//! capacity. Moving it affects the slice size, but not capacity.
51
//!
52
//! In other words, slice capacity may be only decreased by moving beginning pointer,
53
//! and slice size may be freely changed within the slice capacity by moving both
54
//! beginning and ending pointers.
55
template
<
class
T>
class
Slice
{
56
public
:
57
//! Construct empty slice.
58
Slice
()
59
: buffer_()
60
, data_(NULL)
61
, size_(0) {
62
}
63
64
//! Construct slice pointing to the whole buffer.
65
Slice
(
const
BufferPtr
& buffer) {
66
buffer_ = buffer;
67
if
(buffer_) {
68
data_ = (T*)buffer->
data
();
69
size_ = buffer->
size
() /
sizeof
(T);
70
}
else
{
71
data_ = NULL;
72
size_ = 0;
73
}
74
}
75
76
//! Construct slice pointing to a part of a buffer.
77
Slice
(
Buffer
& buffer,
size_t
from,
size_t
to) {
78
if
(from > to) {
79
roc_panic
(
"slice: invalid range: [%lu,%lu)"
, (
unsigned
long
)from,
80
(
unsigned
long
)to);
81
}
82
if
(to > buffer.
size
() /
sizeof
(T)) {
83
roc_panic
(
"slice: out of bounds: available=[%lu,%lu) requested=[%lu,%lu)"
,
84
(
unsigned
long
)0, (
unsigned
long
)buffer.
size
() /
sizeof
(T),
85
(
unsigned
long
)from, (
unsigned
long
)to);
86
}
87
buffer_ = &buffer;
88
data_ = (T*)buffer.
data
() + from;
89
size_ = to - from;
90
}
91
92
//! Get slice data.
93
T*
data
()
const
{
94
if
(data_ == NULL) {
95
roc_panic
(
"slice: null slice"
);
96
}
97
return
data_;
98
}
99
100
//! Pointer to the next after the last element in slice.
101
T*
data_end
()
const
{
102
if
(data_ == NULL) {
103
roc_panic
(
"slice: null slice"
);
104
}
105
return
data_ + size_;
106
}
107
108
//! Get number of elements in slice.
109
size_t
size
()
const
{
110
return
size_;
111
}
112
113
//! Get maximum possible number of elements in slice.
114
size_t
capacity
()
const
{
115
if
(data_ == NULL) {
116
return
0;
117
}
else
{
118
return
buffer_->size() /
sizeof
(T) -
size_t
(data_ - (T*)buffer_->data());
119
}
120
}
121
122
//! Change slice beginning and ending inside the buffer.
123
//! @remarks
124
//! - @p from and @p to are relative to slice beginning.
125
//! - @p to value can be up to capacity().
126
void
reslice
(
size_t
from,
size_t
to) {
127
const
size_t
cap =
capacity
();
128
if
(from > to) {
129
roc_panic
(
"slice: invalid range: [%lu,%lu)"
, (
unsigned
long
)from,
130
(
unsigned
long
)to);
131
}
132
if
(to > cap) {
133
roc_panic
(
"slice: out of bounds: available=[%lu,%lu) requested=[%lu,%lu)"
,
134
(
unsigned
long
)0, (
unsigned
long
)cap, (
unsigned
long
)from,
135
(
unsigned
long
)to);
136
}
137
if
(data_) {
138
data_ = data_ + from;
139
size_ = to - from;
140
}
141
}
142
143
//! Increase size() by @p add_sz.
144
//! @returns
145
//! Pointer to the first element of extended range.
146
T*
extend
(
const
size_t
add_sz) {
147
if
(data_ == NULL) {
148
roc_panic
(
"slice: null slice"
);
149
}
150
if
(add_sz == 0) {
151
roc_panic
(
"slice: extend with zero size"
);
152
}
153
T* ret = data_ + size_;
154
reslice
(0,
size
() + add_sz);
155
return
ret;
156
}
157
158
//! Construct a slice pointing to a part of this slice.
159
//! @remarks
160
//! - @p from and @p to are relative to slice beginning.
161
//! - @p to value can be up to size().
162
Slice
subslice
(
size_t
from,
size_t
to)
const
{
163
if
(from > to) {
164
roc_panic
(
"slice: invalid range: [%lu,%lu)"
, (
unsigned
long
)from,
165
(
unsigned
long
)to);
166
}
167
if
(to > size_) {
168
roc_panic
(
"slice: out of bounds: available=[%lu,%lu) requested=[%lu,%lu)"
,
169
(
unsigned
long
)0, (
unsigned
long
)size_, (
unsigned
long
)from,
170
(
unsigned
long
)to);
171
}
172
Slice
ret;
173
ret.buffer_ = buffer_;
174
ret.data_ = data_ + from;
175
ret.size_ = to - from;
176
return
ret;
177
}
178
179
//! Print slice to stderr.
180
void
print
()
const
{
181
if
(buffer_) {
182
core::print_memory_slice
(data_, size_, (T*)buffer_->data(),
183
buffer_->size() /
sizeof
(T));
184
}
else
{
185
core::print_memory_slice
(data_, size_, NULL, 0);
186
}
187
}
188
189
//! Access to an element of the Slice with an array style.
190
T&
operator[]
(
const
size_t
i)
const
{
191
if
(data_ == NULL) {
192
roc_panic
(
"slice: null slice"
);
193
}
194
if
(i > size_) {
195
roc_panic
(
"slice: out of bounds: available=[%lu,%lu) requested=%lu"
,
196
(
unsigned
long
)0, (
unsigned
long
)size_, (
unsigned
long
)i);
197
}
198
return
data_[i];
199
}
200
201
//! Convert to bool.
202
//! @returns
203
//! true if the slice is attached to buffer, even if it has zero length.
204
operator
const
struct
unspecified_bool *()
const
{
205
return
(
const
unspecified_bool*)data_;
206
}
207
208
private
:
209
BufferPtr
buffer_;
210
T* data_;
211
size_t
size_;
212
};
213
214
}
// namespace core
215
}
// namespace roc
216
217
#endif
// ROC_CORE_SLICE_H_
buffer.h
Buffer.
roc::core::Buffer
Fixed-size dynamically-allocated byte buffer.
Definition
buffer.h:40
roc::core::Buffer::size
size_t size() const
Get buffer size in bytes.
Definition
buffer.h:46
roc::core::Buffer::data
uint8_t * data()
Get buffer data.
Definition
buffer.h:51
roc::core::Slice::subslice
Slice subslice(size_t from, size_t to) const
Construct a slice pointing to a part of this slice.
Definition
slice.h:162
roc::core::Slice::extend
T * extend(const size_t add_sz)
Increase size() by add_sz.
Definition
slice.h:146
roc::core::Slice::capacity
size_t capacity() const
Get maximum possible number of elements in slice.
Definition
slice.h:114
roc::core::Slice::Slice
Slice(Buffer &buffer, size_t from, size_t to)
Construct slice pointing to a part of a buffer.
Definition
slice.h:77
roc::core::Slice::data_end
T * data_end() const
Pointer to the next after the last element in slice.
Definition
slice.h:101
roc::core::Slice::operator[]
T & operator[](const size_t i) const
Access to an element of the Slice with an array style.
Definition
slice.h:190
roc::core::Slice::reslice
void reslice(size_t from, size_t to)
Change slice beginning and ending inside the buffer.
Definition
slice.h:126
roc::core::Slice::print
void print() const
Print slice to stderr.
Definition
slice.h:180
roc::core::Slice::Slice
Slice(const BufferPtr &buffer)
Construct slice pointing to the whole buffer.
Definition
slice.h:65
roc::core::Slice::data
T * data() const
Get slice data.
Definition
slice.h:93
roc::core::Slice::Slice
Slice()
Construct empty slice.
Definition
slice.h:58
roc::core::Slice::size
size_t size() const
Get number of elements in slice.
Definition
slice.h:109
roc::core
General-purpose building blocks and platform abstraction layer.
roc::core::BufferPtr
SharedPtr< Buffer > BufferPtr
Buffer smart pointer.
Definition
buffer.h:29
roc::core::print_memory_slice
void print_memory_slice(const uint8_t *inner, size_t inner_size, const uint8_t *outer, size_t outer_size)
Print memory slice.
roc
Root namespace.
roc_panic
#define roc_panic(...)
Print error message and terminate program gracefully.
Definition
panic.h:50
print_memory.h
Print memory to console.
shared_ptr.h
Shared ownership intrusive pointer.
roc_core
slice.h
Generated by
1.17.0