/* * CircularBinaryRemoteBuffer.hh * * Created on: 24 апр. 2020 г. * Author: LeonidTitov */ #ifndef UMLIBRARY_DRIVER_CIRCULARBINARYREMOTEBUFFER_HH_ #define UMLIBRARY_DRIVER_CIRCULARBINARYREMOTEBUFFER_HH_ #include #include "../peripheral/IMemoryAccess.hh" #include #include namespace driver { class CircularBinaryRemoteBuffer { public: //!Отображает адрес и количество значений в кольцевом буфере class Index { friend class CircularBinaryRemoteBuffer; public: Index() : position( std::numeric_limits::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 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_ */