ROSaic
Public Member Functions | Private Attributes
CircularBuffer Class Reference

Class for creating, writing to and reading from a circular buffer. More...

#include <circular_buffer.hpp>

Collaboration diagram for CircularBuffer:
Collaboration graph
[legend]

Public Member Functions

 CircularBuffer (std::size_t capacity)
 Constructor of CircularBuffer. More...
 
 ~CircularBuffer ()
 Destructor of CircularBuffer. More...
 
std::size_t size () const
 Returns size_. More...
 
std::size_t capacity () const
 Returns capacity_. More...
 
std::size_t write (const uint8_t *data, std::size_t bytes)
 Returns number of bytes written. More...
 
std::size_t read (uint8_t *data, std::size_t bytes)
 Returns number of bytes read. More...
 

Private Attributes

std::size_t head_
 Specifies where we start writing. More...
 
std::size_t tail_
 Specifies where we start reading. More...
 
std::size_t size_
 Number of bytes that have been written but not yet read. More...
 
std::size_t capacity_
 Capacity of the circular buffer. More...
 
uint8_t * data_
 Pointer that always points to the same memory address, hence could be const pointer. More...
 

Detailed Description

Class for creating, writing to and reading from a circular buffer.

Definition at line 51 of file circular_buffer.hpp.

Constructor & Destructor Documentation

◆ CircularBuffer()

CircularBuffer::CircularBuffer ( std::size_t  capacity)
explicit

Constructor of CircularBuffer.

Definition at line 39 of file circular_buffer.cpp.

References capacity(), and data_.

39  : head_(0), tail_(0), size_(0), capacity_(capacity)
40 {
41  data_ = new uint8_t[capacity];
42 }
std::size_t tail_
Specifies where we start reading.
uint8_t * data_
Pointer that always points to the same memory address, hence could be const pointer.
std::size_t size_
Number of bytes that have been written but not yet read.
std::size_t capacity_
Capacity of the circular buffer.
std::size_t head_
Specifies where we start writing.
std::size_t capacity() const
Returns capacity_.
Here is the call graph for this function:

◆ ~CircularBuffer()

CircularBuffer::~CircularBuffer ( )

Destructor of CircularBuffer.

The destructor frees memory (first line) and points the dangling pointer to NULL (second line).

Definition at line 45 of file circular_buffer.cpp.

References data_.

46 {
47  delete [] data_;
48  data_ = NULL;
49 }
uint8_t * data_
Pointer that always points to the same memory address, hence could be const pointer.

Member Function Documentation

◆ capacity()

std::size_t CircularBuffer::capacity ( ) const
inline

Returns capacity_.

Definition at line 61 of file circular_buffer.hpp.

References capacity_, read(), and write().

Referenced by CircularBuffer(), read(), and write().

61 { return capacity_; }
std::size_t capacity_
Capacity of the circular buffer.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ read()

std::size_t CircularBuffer::read ( uint8_t *  data,
std::size_t  bytes 
)

Returns number of bytes read.

Definition at line 86 of file circular_buffer.cpp.

References capacity(), capacity_, data_, size_, and tail_.

Referenced by capacity().

87 {
88  //ROS_DEBUG("Called CircularBuffer::read() method..");
89  if (bytes == 0) return 0;
90  std::size_t capacity = capacity_;
91  std::size_t bytes_to_read = std::min(bytes, size_);
92  //ROS_DEBUG("Number of bytes_to_read is %li.", bytes_to_read);
93  if (bytes_to_read != bytes)
94  {
95  ROS_ERROR("You are trying to read parts of the circular buffer that have not yet been written!");
96  }
97 
98  // Read in a single step
99  if (bytes_to_read <= capacity - tail_) // Note that it is not size_ - tail_:
100  // If write() hasn't written something into all of capacity yet (first round of writing), we would still read those unknown bytes..
101  {
102  memcpy(data, data_ + tail_, bytes_to_read);
103  tail_ += bytes_to_read;
104  if (tail_ == capacity) tail_ = 0; // Same here?
105  }
106 
107  // Read in two steps
108  else
109  {
110  std::size_t size_1 = capacity - tail_;
111  memcpy(data, data_ + tail_, size_1);
112  std::size_t size_2 = bytes_to_read - size_1;
113  memcpy(data + size_1, data_, size_2);
114  tail_ = size_2;
115  }
116 
117  size_ -= bytes_to_read;
118  //ROS_DEBUG("Leaving CircularBuffer::read() method..");
119  return bytes_to_read;
120 }
std::size_t tail_
Specifies where we start reading.
uint8_t * data_
Pointer that always points to the same memory address, hence could be const pointer.
std::size_t size_
Number of bytes that have been written but not yet read.
std::size_t capacity_
Capacity of the circular buffer.
std::size_t capacity() const
Returns capacity_.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ size()

std::size_t CircularBuffer::size ( ) const
inline

Returns size_.

Definition at line 59 of file circular_buffer.hpp.

References size_.

59 { return size_; }
std::size_t size_
Number of bytes that have been written but not yet read.

◆ write()

std::size_t CircularBuffer::write ( const uint8_t *  data,
std::size_t  bytes 
)

Returns number of bytes written.

Definition at line 51 of file circular_buffer.cpp.

References capacity(), capacity_, data_, head_, and size_.

Referenced by io_comm_rx::AsyncManager< StreamT >::asyncReadSomeHandler(), and capacity().

52 {
53  //ROS_DEBUG("Called CircularBuffer::write() method..");
54  if (bytes == 0) return 0;
55 
56  std::size_t capacity = capacity_;
57  std::size_t bytes_to_write = std::min(bytes, capacity - size_);
58  //ROS_DEBUG("Number of bytes_to_write is %li.", bytes_to_write);
59  if (bytes_to_write != bytes)
60  {
61  ROS_ERROR("You are trying to overwrite parts of the circular buffer that have not yet been read!");
62  }
63 
64  // Writes in a single step
65  if (bytes_to_write <= capacity - head_)
66  {
67 
68  memcpy(data_ + head_, data, bytes_to_write);
69  head_ += bytes_to_write;
70  if (head_ == capacity) head_ = 0;
71  }
72  // Writes in two steps. Here the circular nature comes to the surface
73  else
74  {
75  std::size_t size_1 = capacity - head_;
76  memcpy(data_ + head_, data, size_1);
77  std::size_t size_2 = bytes_to_write - size_1;
78  memcpy(data_, data + size_1, size_2);
79  head_ = size_2; // Hence setting head_ = 0 three lines above was not necessary.
80  }
81  size_ += bytes_to_write;
82  //ROS_DEBUG("Leaving CircularBuffer::write() method..");
83  return bytes_to_write;
84 }
uint8_t * data_
Pointer that always points to the same memory address, hence could be const pointer.
std::size_t size_
Number of bytes that have been written but not yet read.
std::size_t capacity_
Capacity of the circular buffer.
std::size_t head_
Specifies where we start writing.
std::size_t capacity() const
Returns capacity_.
Here is the call graph for this function:
Here is the caller graph for this function:

Field Documentation

◆ capacity_

std::size_t CircularBuffer::capacity_
private

Capacity of the circular buffer.

Definition at line 75 of file circular_buffer.hpp.

Referenced by capacity(), read(), and write().

◆ data_

uint8_t* CircularBuffer::data_
private

Pointer that always points to the same memory address, hence could be const pointer.

Definition at line 77 of file circular_buffer.hpp.

Referenced by CircularBuffer(), read(), write(), and ~CircularBuffer().

◆ head_

std::size_t CircularBuffer::head_
private

Specifies where we start writing.

Definition at line 69 of file circular_buffer.hpp.

Referenced by write().

◆ size_

std::size_t CircularBuffer::size_
private

Number of bytes that have been written but not yet read.

Definition at line 73 of file circular_buffer.hpp.

Referenced by read(), size(), and write().

◆ tail_

std::size_t CircularBuffer::tail_
private

Specifies where we start reading.

Definition at line 71 of file circular_buffer.hpp.

Referenced by read().


The documentation for this class was generated from the following files: