F´ Flight Software - C/C++ Documentation  NASA-v1.6.0
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  */
13 #include <Fw/Types/BasicTypes.hpp>
14 #include <Fw/Types/Assert.hpp>
16 
17 #ifdef CIRCULAR_DEBUG
18  #include <Os/Log.hpp>
19 #endif
20 
21 #include <cstdio>
22 
23 
24 namespace Types {
25 
27  m_store(buffer),
28  m_size(size),
29  m_head(m_store),
30  m_tail(m_store)
31 {}
32 
34  // Note: a byte is lost in order to prevent wrap-around confusion
35  const NATIVE_UINT_TYPE remaining = (m_tail >= m_head) ?
36  (m_size - 1 - (reinterpret_cast<POINTER_CAST>(m_tail) - reinterpret_cast<POINTER_CAST>(m_head))) :
37  (reinterpret_cast<POINTER_CAST>(m_head) - reinterpret_cast<POINTER_CAST>(m_tail) - 1);
38  FW_ASSERT(remaining != static_cast<NATIVE_UINT_TYPE>(-1));
39  return serialization ? remaining : m_size - 1 - remaining;
40 }
41 
42 U8* CircularBuffer :: increment(U8* const pointer, NATIVE_UINT_TYPE amount) {
43  U8* ret = pointer;
44  //TODO: need O(1) implementation here
45  for (NATIVE_UINT_TYPE i = 0; i < amount; i++) {
46  ret = ret + 1;
47  if (ret >= (m_store + m_size)) {
48  ret = m_store;
49  }
50  }
51  return ret;
52 }
53 
55  // Check that the head and tail pointers are consistent
56  ASSERT_CONSISTENT(m_store, m_size, m_head);
57  ASSERT_CONSISTENT(m_store, m_size, m_tail);
58  // Check there is sufficient space
59  if (size > get_remaining_size(true)) {
61  }
62  // Copy in all the supplied data
63  for (U32 i = 0; i < size; i++) {
64  *m_tail = buffer[i];
65  // Wrap-around increment of tail
66  m_tail = increment(m_tail);
67  FW_ASSERT(m_tail != m_head,
68  reinterpret_cast<POINTER_CAST>(m_tail),
69  reinterpret_cast<POINTER_CAST>(m_head));
70  }
71  ASSERT_CONSISTENT(m_store, m_size, m_head);
72  ASSERT_CONSISTENT(m_store, m_size, m_tail);
73  return Fw::FW_SERIALIZE_OK;
74 }
75 
77  return peek(reinterpret_cast<U8&>(value), offset);
78 }
79 
81  // Check that the head and tail pointers are consistent
82  ASSERT_CONSISTENT(m_store, m_size, m_head);
83  ASSERT_CONSISTENT(m_store, m_size, m_tail);
84  // Check there is sufficient data
85  if ((sizeof(U8) + offset) > get_remaining_size(false)) {
87  }
88  value = *increment(m_head, offset);
89  ASSERT_CONSISTENT(m_store, m_size, m_head);
90  ASSERT_CONSISTENT(m_store, m_size, m_tail);
91  return Fw::FW_SERIALIZE_OK;
92 }
93 
95  // Check that the head and tail pointers are consistent
96  ASSERT_CONSISTENT(m_store, m_size, m_head);
97  ASSERT_CONSISTENT(m_store, m_size, m_tail);
98  // Check there is sufficient data
99  if ((sizeof(U32) + offset) > get_remaining_size(false)) {
101  }
102  U8* peeker = m_head;
103  value = 0;
104  peeker = increment(peeker, offset);
105  // Deserialize all the bytes from network format
106  for (NATIVE_UINT_TYPE i = 0; i < sizeof(U32); i++) {
107  value = (value << 8) | static_cast<U32>(*peeker);
108  peeker = increment(peeker);
109  }
110  ASSERT_CONSISTENT(m_store, m_size, m_head);
111  ASSERT_CONSISTENT(m_store, m_size, m_tail);
112  return Fw::FW_SERIALIZE_OK;
113 }
114 
116  // Check that the head and tail pointers are consistent
117  ASSERT_CONSISTENT(m_store, m_size, m_head);
118  ASSERT_CONSISTENT(m_store, m_size, m_tail);
119  // Check there is sufficient data
120  if ((size + offset) > get_remaining_size(false)) {
122  }
123  U8* peeker = m_head;
124  peeker = increment(peeker, offset);
125  // Deserialize all the bytes from network format
126  for (NATIVE_UINT_TYPE i = 0; i < size; i++) {
127  *buffer = *peeker;
128  peeker = increment(peeker);
129  buffer = buffer + 1;
130  }
131  ASSERT_CONSISTENT(m_store, m_size, m_head);
132  ASSERT_CONSISTENT(m_store, m_size, m_tail);
133  return Fw::FW_SERIALIZE_OK;
134 }
135 
137  // Check that the head and tail pointers are consistent
138  ASSERT_CONSISTENT(m_store, m_size, m_head);
139  ASSERT_CONSISTENT(m_store, m_size, m_tail);
140  // Check there is sufficient data
141  if (amount > get_remaining_size(false)) {
143  }
144  m_head = increment(m_head, amount);
145  ASSERT_CONSISTENT(m_store, m_size, m_head);
146  ASSERT_CONSISTENT(m_store, m_size, m_tail);
147  return Fw::FW_SERIALIZE_OK;
148 }
149 
151  return m_size;
152 }
153 
154 #ifdef CIRCULAR_DEBUG
155 void CircularBuffer :: print() {
156  U8* pointer = m_head;
157  Os::Log::logMsg("Ring: ", 0, 0, 0, 0, 0, 0);
158  while (pointer != m_tail) {
159  Os::Log::logMsg("%c", *pointer, 0, 0, 0, 0, 0);
160  pointer = increment(pointer);
161  }
162  Os::Log::logMsg("\n", 0, 0, 0, 0, 0, 0);
163 }
164 #endif
165 } //End Namespace Types
Fw::FW_DESERIALIZE_BUFFER_EMPTY
@ FW_DESERIALIZE_BUFFER_EMPTY
Deserialization buffer was empty when trying to read more data.
Definition: Serializable.hpp:18
Types::CircularBuffer::serialize
Fw::SerializeStatus serialize(const U8 *const buffer, const NATIVE_UINT_TYPE size)
Definition: CircularBuffer.cpp:54
Fw::SerializeStatus
SerializeStatus
forward declaration for string
Definition: Serializable.hpp:14
U8
uint8_t U8
8-bit unsigned integer
Definition: BasicTypes.hpp:76
Assert.hpp
Fw::FW_SERIALIZE_OK
@ FW_SERIALIZE_OK
Serialization/Deserialization operation was successful.
Definition: Serializable.hpp:15
Types::CircularBuffer::get_remaining_size
NATIVE_UINT_TYPE get_remaining_size(bool serialization=false)
Definition: CircularBuffer.cpp:33
Fw::FW_SERIALIZE_NO_ROOM_LEFT
@ FW_SERIALIZE_NO_ROOM_LEFT
No room left in the buffer to serialize data.
Definition: Serializable.hpp:17
CircularBuffer.hpp
NATIVE_UINT_TYPE
unsigned int NATIVE_UINT_TYPE
native unsigned integer type declaration
Definition: BasicTypes.hpp:30
Types::CircularBuffer::rotate
Fw::SerializeStatus rotate(NATIVE_UINT_TYPE amount)
Definition: CircularBuffer.cpp:136
FW_ASSERT
#define FW_ASSERT(...)
Definition: Assert.hpp:8
Types::CircularBuffer::peek
Fw::SerializeStatus peek(char &value, NATIVE_UINT_TYPE offset=0)
Definition: CircularBuffer.cpp:76
Types
Definition: CircularBuffer.cpp:24
Fw::Logger::logMsg
static void logMsg(const char *fmt, POINTER_CAST a0=0, POINTER_CAST a1=0, POINTER_CAST a2=0, POINTER_CAST a3=0, POINTER_CAST a4=0, POINTER_CAST a5=0, POINTER_CAST a6=0, POINTER_CAST a7=0, POINTER_CAST a8=0, POINTER_CAST a9=0)
Definition: Logger.cpp:18
Types::CircularBuffer::CircularBuffer
CircularBuffer(U8 *const buffer, const NATIVE_UINT_TYPE size)
Definition: CircularBuffer.cpp:26
Types::CircularBuffer::get_capacity
NATIVE_UINT_TYPE get_capacity()
Definition: CircularBuffer.cpp:150
BasicTypes.hpp
Declares ISF basic types.
ASSERT_CONSISTENT
#define ASSERT_CONSISTENT(store, size, X)
Definition: CircularBuffer.hpp:24
Log.hpp