F´ Flight Software - C/C++ Documentation
A framework for building embedded system applications to NASA flight quality standards.
CircularBuffer.cpp
Go to the documentation of this file.
1 /*
2  * CircularBuffer.cpp:
3  *
4  * Buffer used to efficiently store data in ring data structure. Uses an externally supplied
5  * data store as the backing for this buffer. Thus it is dependent on receiving sole ownership
6  * of the supplied buffer.
7  *
8  * This implementation file contains the function definitions.
9  *
10  * Created on: Apr 4, 2019
11  * Author: lestarch
12  * Revised March 2022
13  * Author: bocchino
14  */
15 #include <Fw/FPrimeBasicTypes.hpp>
16 #include <Fw/Types/Assert.hpp>
18 
19 namespace Types {
20 
22  m_store(nullptr),
23  m_store_size(0),
24  m_head_idx(0),
25  m_allocated_size(0),
26  m_high_water_mark(0)
27 {
28 
29 }
30 
31 CircularBuffer :: CircularBuffer(U8* const buffer, const FwSizeType size) :
32  m_store(nullptr),
33  m_store_size(0),
34  m_head_idx(0),
35  m_allocated_size(0),
36  m_high_water_mark(0)
37 {
38  setup(buffer, size);
39 }
40 
41 void CircularBuffer :: setup(U8* const buffer, const FwSizeType size) {
42  FW_ASSERT(size > 0);
43  FW_ASSERT(buffer != nullptr);
44  FW_ASSERT(m_store == nullptr && m_store_size == 0); // Not already setup
45 
46  // Initialize buffer data
47  m_store = buffer;
48  m_store_size = size;
49  m_head_idx = 0;
50  m_allocated_size = 0;
51  m_high_water_mark = 0;
52 }
53 
55  return m_allocated_size;
56 }
57 
59  FW_ASSERT(m_store != nullptr && m_store_size != 0); // setup method was called
60  FW_ASSERT(m_allocated_size <= m_store_size, static_cast<FwAssertArgType>(m_allocated_size));
61  return m_store_size - m_allocated_size;
62 }
63 
64 FwSizeType CircularBuffer :: advance_idx(FwSizeType idx, FwSizeType amount) const {
65  FW_ASSERT(idx < m_store_size, static_cast<FwAssertArgType>(idx));
66  return (idx + amount) % m_store_size;
67 }
68 
70  FW_ASSERT(m_store != nullptr && m_store_size != 0); // setup method was called
71  FW_ASSERT(buffer != nullptr);
72  // Check there is sufficient space
73  if (size > get_free_size()) {
75  }
76  // Copy in all the supplied data
77  FwSizeType idx = advance_idx(m_head_idx, m_allocated_size);
78  for (U32 i = 0; i < size; i++) {
79  FW_ASSERT(idx < m_store_size, static_cast<FwAssertArgType>(idx));
80  m_store[idx] = buffer[i];
81  idx = advance_idx(idx);
82  }
83  m_allocated_size += size;
84  FW_ASSERT(m_allocated_size <= this->get_capacity(), static_cast<FwAssertArgType>(m_allocated_size));
85  m_high_water_mark = (m_high_water_mark > m_allocated_size) ? m_high_water_mark : m_allocated_size;
86  return Fw::FW_SERIALIZE_OK;
87 }
88 
90  FW_ASSERT(m_store != nullptr && m_store_size != 0); // setup method was called
91  return peek(reinterpret_cast<U8&>(value), offset);
92 }
93 
95  FW_ASSERT(m_store != nullptr && m_store_size != 0); // setup method was called
96  // Check there is sufficient data
97  if ((sizeof(U8) + offset) > m_allocated_size) {
99  }
100  const FwSizeType idx = advance_idx(m_head_idx, offset);
101  FW_ASSERT(idx < m_store_size, static_cast<FwAssertArgType>(idx));
102  value = m_store[idx];
103  return Fw::FW_SERIALIZE_OK;
104 }
105 
107  FW_ASSERT(m_store != nullptr && m_store_size != 0); // setup method was called
108  // Check there is sufficient data
109  if ((sizeof(U32) + offset) > m_allocated_size) {
111  }
112  value = 0;
113  FwSizeType idx = advance_idx(m_head_idx, offset);
114 
115  // Deserialize all the bytes from network format
116  for (FwSizeType i = 0; i < sizeof(U32); i++) {
117  FW_ASSERT(idx < m_store_size, static_cast<FwAssertArgType>(idx));
118  value = (value << 8) | static_cast<U32>(m_store[idx]);
119  idx = advance_idx(idx);
120  }
121  return Fw::FW_SERIALIZE_OK;
122 }
123 
125  FW_ASSERT(m_store != nullptr && m_store_size != 0); // setup method was called
126  FW_ASSERT(buffer != nullptr);
127  // Check there is sufficient data
128  if ((size + offset) > m_allocated_size) {
130  }
131  FwSizeType idx = advance_idx(m_head_idx, offset);
132  // Deserialize all the bytes from network format
133  for (FwSizeType i = 0; i < size; i++) {
134  FW_ASSERT(idx < m_store_size, static_cast<FwAssertArgType>(idx));
135  buffer[i] = m_store[idx];
136  idx = advance_idx(idx);
137  }
138  return Fw::FW_SERIALIZE_OK;
139 }
140 
142  FW_ASSERT(m_store != nullptr && m_store_size != 0); // setup method was called
143  // Check there is sufficient data
144  if (amount > m_allocated_size) {
146  }
147  m_head_idx = advance_idx(m_head_idx, amount);
148  m_allocated_size -= amount;
149  return Fw::FW_SERIALIZE_OK;
150 }
151 
153  FW_ASSERT(m_store != nullptr && m_store_size != 0); // setup method was called
154  return m_store_size;
155 }
156 
158  return m_high_water_mark;
159 }
160 
162  m_high_water_mark = 0;
163 }
164 
165 } //End Namespace Types
Serialization/Deserialization operation was successful.
Deserialization buffer was empty when trying to read more data.
PlatformSizeType FwSizeType
No room left in the buffer to serialize data.
SerializeStatus
forward declaration for string
FwSizeType get_high_water_mark() const
Fw::SerializeStatus serialize(const U8 *const buffer, const FwSizeType size)
Fw::SerializeStatus rotate(FwSizeType amount)
FwSizeType get_allocated_size() const
uint8_t U8
8-bit unsigned integer
Definition: BasicTypes.h:56
FwSizeType get_capacity() const
Fw::SerializeStatus peek(char &value, FwSizeType offset=0) const
void setup(U8 *const buffer, const FwSizeType size)
FwSizeType get_free_size() const
#define FW_ASSERT(...)
Definition: Assert.hpp:14