123 lines
4.3 KiB
C++
123 lines
4.3 KiB
C++
/*
|
||
* CircularBinaryRemoteBuffer.hh
|
||
*
|
||
* Created on: 24 апр. 2020 г.
|
||
* Author: LeonidTitov
|
||
*/
|
||
|
||
#ifndef UMLIBRARY_DRIVER_CIRCULARBINARYREMOTEBUFFER_HH_
|
||
#define UMLIBRARY_DRIVER_CIRCULARBINARYREMOTEBUFFER_HH_
|
||
|
||
#include <utility>
|
||
|
||
#include "../peripheral/IMemoryAccess.hh"
|
||
|
||
#include <cstddef>
|
||
#include <limits>
|
||
|
||
namespace driver {
|
||
|
||
class CircularBinaryRemoteBuffer {
|
||
public:
|
||
|
||
//!Отображает адрес и количество значений в кольцевом буфере
|
||
class Index {
|
||
|
||
friend class CircularBinaryRemoteBuffer;
|
||
|
||
public:
|
||
Index() : position( std::numeric_limits<std::size_t>::max() ), size( 0 ) {}
|
||
Index( const Index & right ) : position(right.position), size(right.size) {}
|
||
Index & operator=( const Index & right ) {
|
||
position = right.position;
|
||
size = right.size;
|
||
|
||
return *this;
|
||
}
|
||
|
||
Index relative( std::size_t index ) {
|
||
std::size_t next = ( position + index ) < size ? position + index : position + index - size;
|
||
return Index( next, size );
|
||
}
|
||
|
||
protected:
|
||
Index( std::size_t p, std::size_t size ) : position(p), size(size) {}
|
||
|
||
std::size_t position; //!<Индекс кадра в кольцевом буфере
|
||
std::size_t size; //!<Количество кадров в кольцевом буфере
|
||
};
|
||
|
||
//!Получить размер фрейма.
|
||
std::size_t get_frame_size() const;
|
||
|
||
//!Добавить новую порцию данных - кадр.
|
||
bool put( const char * frame );
|
||
|
||
//!Очистить все привязки, сбросить кеш.
|
||
void clear();
|
||
|
||
//!Начать запись с индекса.
|
||
void restart( const Index & frame_index );
|
||
|
||
//!Зафиксировать индекс как базовый для запросов данных.
|
||
/*!
|
||
* \param[in] desired_pretrigger_frames желаемое количество кадров до фиксации.
|
||
* \return Индекс стартового кадра и общее количество кадров, фактически записанное количество кадров до фиксации.
|
||
*/
|
||
std::pair<Index, size_t> fixate( std::size_t desired_pretrigger_frames = 0 );
|
||
|
||
//!Общее количество доступных для чтения элементов.
|
||
std::size_t fixed( const Index & frame_index ) const;
|
||
|
||
//todo: Более адекватная работа с буффером:
|
||
//буфферизировать кадр в кэш, сбросить кэш,
|
||
|
||
//!Получить кадр по индексу.
|
||
const char * get( const Index & frame_index );
|
||
|
||
//!Емкость буфера.
|
||
std::size_t capacity() const;
|
||
|
||
CircularBinaryRemoteBuffer( peripheral::IMemoryAccess & memory, std::size_t frame_size,
|
||
char * put_cache, std::size_t put_cache_size,
|
||
char * get_cache, std::size_t get_cache_size );
|
||
|
||
CircularBinaryRemoteBuffer( const CircularBinaryRemoteBuffer & right ) = delete;
|
||
CircularBinaryRemoteBuffer & operator=( const CircularBinaryRemoteBuffer & right ) = delete;
|
||
~CircularBinaryRemoteBuffer() = default;
|
||
private:
|
||
const std::size_t useful_capacity; //!<Используемая емкость буфера памяти.
|
||
const std::size_t frame_size; //!<Размер карда.
|
||
const std::size_t number_of_frames; //!<Количество кадров.
|
||
|
||
peripheral::IMemoryAccess & memory;
|
||
|
||
std::size_t index_in_memory;
|
||
std::size_t position_in_memory; //!<Текущая позиция в памяти.
|
||
|
||
char * const put_cache_begin;
|
||
char * const put_cache_end;
|
||
|
||
char * put_cache_writed;
|
||
char * put_cache_stored;
|
||
|
||
char * const get_cache_begin;
|
||
const std::size_t get_cache_capacity;
|
||
std::size_t cached_index_begin;
|
||
std::size_t cached_index_end;
|
||
|
||
std::size_t index;
|
||
std::size_t loaded_frames;
|
||
|
||
std::size_t wrap_index( std::size_t next_index );
|
||
std::size_t wrap_position( std::size_t next_position );
|
||
std::size_t cut_part( std::size_t next_part );
|
||
std::size_t available_in_memory( const Index & frame_index );
|
||
};
|
||
|
||
}
|
||
|
||
|
||
|
||
#endif /* UMLIBRARY_DRIVER_CIRCULARBINARYREMOTEBUFFER_HH_ */
|