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), m_store_size(0), m_head_idx(0), m_allocated_size(0), m_high_water_mark(0) {}
23 
24 CircularBuffer ::CircularBuffer(U8* const buffer, const FwSizeType size)
25  : m_store(nullptr), m_store_size(0), m_head_idx(0), m_allocated_size(0), m_high_water_mark(0) {
26  setup(buffer, size);
27 }
28 
29 void CircularBuffer ::setup(U8* const buffer, const FwSizeType size) {
30  FW_ASSERT(size > 0);
31  FW_ASSERT(buffer != nullptr);
32  FW_ASSERT(m_store == nullptr && m_store_size == 0); // Not already setup
33 
34  // Initialize buffer data
35  m_store = buffer;
36  m_store_size = size;
37  m_head_idx = 0;
38  m_allocated_size = 0;
39  m_high_water_mark = 0;
40 }
41 
43  return m_allocated_size;
44 }
45 
47  FW_ASSERT(m_store != nullptr && m_store_size != 0); // setup method was called
48  FW_ASSERT(m_allocated_size <= m_store_size, static_cast<FwAssertArgType>(m_allocated_size));
49  return m_store_size - m_allocated_size;
50 }
51 
52 FwSizeType CircularBuffer ::advance_idx(FwSizeType idx, FwSizeType amount) const {
53  FW_ASSERT(idx < m_store_size, static_cast<FwAssertArgType>(idx));
54  return (idx + amount) % m_store_size;
55 }
56 
57 Fw::SerializeStatus CircularBuffer ::serialize(const U8* const buffer, const FwSizeType size) {
58  FW_ASSERT(m_store != nullptr && m_store_size != 0); // setup method was called
59  FW_ASSERT(buffer != nullptr);
60  // Check there is sufficient space
61  if (size > get_free_size()) {
63  }
64  // Copy in all the supplied data
65  FwSizeType idx = advance_idx(m_head_idx, m_allocated_size);
66  for (U32 i = 0; i < size; i++) {
67  FW_ASSERT(idx < m_store_size, static_cast<FwAssertArgType>(idx));
68  m_store[idx] = buffer[i];
69  idx = advance_idx(idx);
70  }
71  m_allocated_size += size;
72  FW_ASSERT(m_allocated_size <= this->get_capacity(), static_cast<FwAssertArgType>(m_allocated_size));
73  m_high_water_mark = (m_high_water_mark > m_allocated_size) ? m_high_water_mark : m_allocated_size;
74  return Fw::FW_SERIALIZE_OK;
75 }
76 
78  FW_ASSERT(m_store != nullptr && m_store_size != 0); // setup method was called
79  return peek(reinterpret_cast<U8&>(value), offset);
80 }
81 
83  FW_ASSERT(m_store != nullptr && m_store_size != 0); // setup method was called
84  // Check there is sufficient data
85  if ((sizeof(U8) + offset) > m_allocated_size) {
87  }
88  const FwSizeType idx = advance_idx(m_head_idx, offset);
89  FW_ASSERT(idx < m_store_size, static_cast<FwAssertArgType>(idx));
90  value = m_store[idx];
91  return Fw::FW_SERIALIZE_OK;
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(U32) + offset) > m_allocated_size) {
99  }
100  value = 0;
101  FwSizeType idx = advance_idx(m_head_idx, offset);
102 
103  // Deserialize all the bytes from network format
104  for (FwSizeType i = 0; i < sizeof(U32); i++) {
105  FW_ASSERT(idx < m_store_size, static_cast<FwAssertArgType>(idx));
106  value = (value << 8) | static_cast<U32>(m_store[idx]);
107  idx = advance_idx(idx);
108  }
109  return Fw::FW_SERIALIZE_OK;
110 }
111 
113  FW_ASSERT(m_store != nullptr && m_store_size != 0); // setup method was called
114  FW_ASSERT(buffer != nullptr);
115  // Check there is sufficient data
116  if ((size + offset) > m_allocated_size) {
118  }
119  FwSizeType idx = advance_idx(m_head_idx, offset);
120  // Deserialize all the bytes from network format
121  for (FwSizeType i = 0; i < size; i++) {
122  FW_ASSERT(idx < m_store_size, static_cast<FwAssertArgType>(idx));
123  buffer[i] = m_store[idx];
124  idx = advance_idx(idx);
125  }
126  return Fw::FW_SERIALIZE_OK;
127 }
128 
130  FW_ASSERT(m_store != nullptr && m_store_size != 0); // setup method was called
131  // Check there is sufficient data
132  if (amount > m_allocated_size) {
134  }
135  m_head_idx = advance_idx(m_head_idx, amount);
136  m_allocated_size -= amount;
137  return Fw::FW_SERIALIZE_OK;
138 }
139 
141  FW_ASSERT(m_store != nullptr && m_store_size != 0); // setup method was called
142  return m_store_size;
143 }
144 
146  return m_high_water_mark;
147 }
148 
150  m_high_water_mark = 0;
151 }
152 
153 } // 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:53
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