1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
|
/* Copyright (C) Teemu Suutari */
#ifndef SUBBUFFER_HPP
#define SUBBUFFER_HPP
#include <cstddef>
#include <cstdint>
#include "Buffer.hpp"
#include "OverflowCheck.hpp"
namespace ancient::internal
{
// helpers to splice Buffer
template <typename T>
class GenericSubBuffer : public Buffer
{
public:
GenericSubBuffer(const GenericSubBuffer&)=delete;
GenericSubBuffer& operator=(const GenericSubBuffer&)=delete;
GenericSubBuffer(T &base,size_t start,size_t length) :
_base{base},
_start{start},
_length{length}
{
if (OverflowCheck::sum(start,length)>_base.size())
throw OutOfBoundsError();
}
~GenericSubBuffer() noexcept=default;
const uint8_t *data() const noexcept final
{
return _base.data()+_start;
}
uint8_t *data() final;
size_t size() const noexcept final
{
return _length;
}
bool isResizable() const noexcept final
{
return false;
}
// can only make the buffer smaller, can't run away from the current bounds
void adjust(size_t start,size_t length)
{
if (start<_start || OverflowCheck::sum(start,length)>_start+_length) throw OutOfBoundsError();
_start=start;
_length=length;
}
private:
T &_base;
size_t _start;
size_t _length;
};
typedef GenericSubBuffer<Buffer> SubBuffer;
typedef GenericSubBuffer<const Buffer> ConstSubBuffer;
}
#endif
|