SatCat5
io_readable.h
Go to the documentation of this file.
1 // Copyright 2023-2025 The Aerospace Corporation.
3 // This file is a part of SatCat5, licensed under CERN-OHL-W v2 or later.
12 
13 #pragma once
14 
15 #include <satcat5/polling.h>
16 #include <satcat5/types.h>
17 
18 namespace satcat5 {
19  namespace io {
23  enum class CopyMode {
27  STREAM,
31  PACKET,
35  ALWAYS,
36  };
37 
43  class EventListener {
44  public:
48  virtual void data_rcvd(satcat5::io::Readable* src) = 0;
49 
54  virtual void data_unlink(satcat5::io::Readable* src) {}
55 
56  protected:
57  ~EventListener() {}
58  };
59 
69  public:
73  virtual void set_callback(satcat5::io::EventListener* callback);
74 
78  virtual unsigned get_read_ready() const = 0;
79 
80  // Read various data types in big-endian format.
84  u8 read_u8();
86  // Triggers Doxygen warnings about missing docs, can we suppress?
87  u16 read_u16();
88  u32 read_u24();
89  u32 read_u32();
90  u64 read_u48();
91  u64 read_u64();
92  s8 read_s8();
93  s16 read_s16();
94  s32 read_s24();
95  s32 read_s32();
96  s64 read_s48();
97  s64 read_s64();
98  float read_f32();
99  double read_f64();
100 
101  // Read various data types in little-endian format.
102  u16 read_u16l();
103  u32 read_u24l();
104  u32 read_u32l();
105  u64 read_u48l();
106  u64 read_u64l();
107  s16 read_s16l();
108  s32 read_s24l();
109  s32 read_s32l();
110  s64 read_s48l();
111  s64 read_s64l();
112  float read_f32l();
113  double read_f64l();
115 
119  virtual bool read_bytes(unsigned nbytes, void* dst);
120 
124  virtual bool read_consume(unsigned nbytes);
125 
131  unsigned read_str(unsigned dst_size, char* dst);
132 
136  virtual void read_finalize();
137 
140  template <class T> inline bool read_obj(T& t)
141  {return t.read_from(this);}
142 
150  unsigned copy_to(satcat5::io::Writeable* dst);
151 
167  bool copy_and_finalize(
169  satcat5::io::CopyMode mode = CopyMode::PACKET);
170 
171  protected:
174 
176  explicit constexpr Readable(satcat5::io::EventListener* callback = 0)
177  : m_callback(callback) {}
178  ~Readable() SATCAT5_OPTIONAL_DTOR;
179 
182  virtual u8 read_next() = 0;
183 
187  void read_notify();
188 
191  virtual void read_underflow();
192 
193  private:
195  void poll_demand();
196 
199  satcat5::io::EventListener* m_callback;
200  };
201 
206  class ArrayRead : public satcat5::io::Readable {
207  public:
210  constexpr ArrayRead(const void* src, unsigned len)
211  : m_src((const u8*)src), m_len(len), m_rdidx(0) {}
212  constexpr ArrayRead(unsigned len, const void* src)
213  : m_src((const u8*)src), m_len(len), m_rdidx(0) {}
215 
218  constexpr ArrayRead()
219  : m_src(nullptr), m_len(0), m_rdidx(0) {}
220 
221  // Implement the public Readable API.
222  unsigned get_read_ready() const override;
223  void read_finalize() override;
224 
226  const u8* buffer() const
227  { return m_src; }
228 
231  void read_reset(unsigned len);
232 
233  private:
234  // Implement the private Readable API.
235  u8 read_next() override;
236  const u8* const m_src;
237 
238  // Internal state.
239  unsigned m_len; // Length of the backing array
240  unsigned m_rdidx; // Current read position
241  };
242 
256  public:
261  constexpr LimitedRead(satcat5::io::Readable* src, unsigned maxrd)
262  : m_src(src), m_rem(maxrd) {}
263  constexpr LimitedRead(unsigned maxrd, satcat5::io::Readable* src)
264  : m_src(src), m_rem(maxrd) {}
266 
268  explicit LimitedRead(satcat5::io::Readable* src);
269 
270  // Implement the public Readable API.
271  unsigned get_read_ready() const override;
272  bool read_bytes(unsigned nbytes, void* dst) override;
273  bool read_consume(unsigned nbytes) override;
274  void read_finalize() override;
275 
276  protected:
277  // Implement the private Readable API.
278  u8 read_next() override;
279 
281  inline void read_reset(unsigned rem) {m_rem = rem;}
282 
283  private:
284  satcat5::io::Readable* const m_src;
285  unsigned m_rem;
286  };
287 
300  public:
301  // Implement the public Readable API.
302  void set_callback(satcat5::io::EventListener* callback) override;
303  unsigned get_read_ready() const override;
304  bool read_bytes(unsigned nbytes, void* dst) override;
305  bool read_consume(unsigned nbytes) override;
306  void read_finalize() override;
307 
308  protected:
310  explicit constexpr ReadableRedirect(satcat5::io::Readable* src)
311  : m_src(src) {}
312  ~ReadableRedirect() {}
313 
314  // Implement the private Readable API.
315  u8 read_next() override;
316  void read_underflow() override;
317 
319  inline void read_src(satcat5::io::Readable* src) {m_src = src;}
320 
321  private:
322  satcat5::io::Readable* m_src;
323  };
324 
325 
328  public:
329  NullRead() {}
330  unsigned get_read_ready() const override;
331  private:
332  u8 read_next() override;
333  };
334 
337  void data_rcvd(satcat5::io::Readable* src) override;
338  };
339 
348  }
349 }
Ephemeral Readable interface for a simple array.
Definition: io_readable.h:206
const u8 * buffer() const
Read-only access to the working buffer.
Definition: io_readable.h:226
constexpr ArrayRead()
Create an empty ArrayRead object, empty constructor supports usage with util::optional.
Definition: io_readable.h:218
constexpr ArrayRead(unsigned len, const void *src)
For ease of use, constructor accepts src/length or length/src.
Definition: io_readable.h:212
constexpr ArrayRead(const void *src, unsigned len)
For ease of use, constructor accepts src/length or length/src.
Definition: io_readable.h:210
Event-handler interface for newly received data.
Definition: io_readable.h:43
virtual void data_unlink(satcat5::io::Readable *src)
Unlink this EventListener from the designated source, because the designated Readable object is being...
Definition: io_readable.h:54
virtual void data_rcvd(satcat5::io::Readable *src)=0
The data_rcvd() callback is polled whenever data is available.
Limited read of next N bytes.
Definition: io_readable.h:255
void read_reset(unsigned rem)
Children may reset the number of remaining bytes.
Definition: io_readable.h:281
constexpr LimitedRead(satcat5::io::Readable *src, unsigned maxrd)
Explicitly set maximum read length in bytes.
Definition: io_readable.h:261
constexpr LimitedRead(unsigned maxrd, satcat5::io::Readable *src)
Explicitly set maximum read length in bytes.
Definition: io_readable.h:263
Readable object that never produces any data.
Definition: io_readable.h:327
An EventListener object that immediately discards all received data.
Definition: io_readable.h:336
Abstract API for reading byte-streams and packets.
Definition: io_readable.h:68
constexpr Readable(satcat5::io::EventListener *callback=0)
Only children should create or destroy the base class.
Definition: io_readable.h:176
virtual void read_underflow()
Optional error handling for read underflow.
Definition: io_readable.cc:271
bool read_obj(T &t)
Templated wrapper for any object with the following method: bool read_from(satcat5::io::Readable* rd)...
Definition: io_readable.h:140
void poll_demand()
Event handler for on-demand polling.
Definition: io_readable.cc:261
unsigned read_str(unsigned dst_size, char *dst)
Safely read a null-terminated input string.
Definition: io_readable.cc:179
u8 read_u8()
One of many functions for reading integer/floating point values, see details.
Definition: io_readable.cc:44
virtual bool read_bytes(unsigned nbytes, void *dst)
Read 0 or more bytes into a buffer.
Definition: io_readable.cc:190
void read_notify()
Attempt notification by calling m_callback->data_rcvd().
Definition: io_readable.cc:254
virtual void read_finalize()
Consume any remaining bytes in this frame, if applicable.
Definition: io_readable.cc:270
virtual bool read_consume(unsigned nbytes)
Read and discard 0 or more bytes.
Definition: io_readable.cc:204
virtual u8 read_next()=0
Read the next byte from the underlying buffer or device.
bool copy_and_finalize(satcat5::io::Writeable *dst, satcat5::io::CopyMode mode=CopyMode::PACKET)
Copy data to a Writeable object, then finalize.
Definition: io_readable.cc:234
virtual void set_callback(satcat5::io::EventListener *callback)
Update registered callback for data_rcvd() events.
Definition: io_readable.cc:39
unsigned copy_to(satcat5::io::Writeable *dst)
Copy data to a Writeable object, without finalizing.
Definition: io_readable.cc:214
satcat5::io::EventListener * m_callback
Pointer to the callback object, or NULL.
Definition: io_readable.h:199
virtual unsigned get_read_ready() const =0
How many bytes can be read without blocking?
Wrapper class for forwarding reads to another object.
Definition: io_readable.h:299
constexpr ReadableRedirect(satcat5::io::Readable *src)
Constructor and destructor should only be called by the child.
Definition: io_readable.h:310
void read_src(satcat5::io::Readable *src)
Children may reset the source object as needed.
Definition: io_readable.h:319
Abstract API for writing byte-streams and packets.
Definition: io_writeable.h:24
An "OnDemand" object is polled only on request.
Definition: polling.h:131
CopyMode
Specify read and write behavior for Readable::copy_and_finalize().
Definition: io_readable.h:23
@ PACKET
PACKET mode (default) preserves packet boundaries.
@ STREAM
STREAM mode is used for non-packetized data.
@ ALWAYS
ALWAYS mode ensures write_finalize is always called.
satcat5::io::NullRead null_read
Global instances of the basic NullRead and NullSink objects.
Definition: io_readable.cc:29
satcat5::io::NullSink null_sink
Global instances of the basic NullRead and NullSink objects.
Definition: io_readable.cc:30
Core event-processing loop for SatCat5 software.
Basic type aliases and prototypes used throughout SatCat5.