F´ Flight Software - C/C++ Documentation  NASA-v1.5.0
A framework for building embedded system applications to NASA flight quality standards.
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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 <stdio.h>
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 = *(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 
150 #ifdef CIRCULAR_DEBUG
151 void CircularBuffer :: print() {
152  U8* pointer = m_head;
153  Os::Log::logMsg("Ring: ", 0, 0, 0, 0, 0, 0);
154  while (pointer != m_tail) {
155  Os::Log::logMsg("%c", *pointer, 0, 0, 0, 0, 0);
156  pointer = increment(pointer);
157  }
158  Os::Log::logMsg("\n", 0, 0, 0, 0, 0, 0);
159 }
160 #endif
161 } //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:9
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
BasicTypes.hpp
Declares ISF basic types.
ASSERT_CONSISTENT
#define ASSERT_CONSISTENT(store, size, X)
Definition: CircularBuffer.hpp:24
Log.hpp