ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
ra8_io_stream.c File Reference

Byte-stream dispatcher + no-varargs formatted-output primitives. More...

#include "ra8_io_stream.h"
#include <stddef.h>
#include <stdint.h>
#include "ra8_attributes.h"
#include "ra8_check.h"
#include "ra8_err.h"
#include "ra8_io_stream_backend.h"
Include dependency graph for ra8_io_stream.c:

Go to the source code of this file.

Enumerations

enum  ra8_io_stream_const_t : uint32_t {
  k_ra8_io_dec_base = 10 ,
  k_ra8_io_hex_base = 16 ,
  k_ra8_io_u32_max_digits = 10 ,
  k_ra8_io_u64_max_digits = 20 ,
  k_ra8_io_hex_max_digits = 8 ,
  k_ra8_io_puts_max = 65535
}
 Rendering constants for the formatted-output helpers. More...

Functions

static ra8_err_t internal_validate (const ra8_io_stream_t *s)
 Reject a handle that is NULL or has no sink bound.
ra8_err_t ra8_io_stream_bind (ra8_io_stream_t *stream, const ra8_io_stream_iface_t *iface, void *context)
 Bind a backend vtable and caller-owned state into a stream handle.
ra8_err_t ra8_io_stream_write (ra8_io_stream_t *s, const uint8_t *buf, uint32_t len, uint32_t *out_written)
 Write len bytes to the bound sink.
ra8_err_t ra8_io_stream_flush (ra8_io_stream_t *s)
 Flush any sink-side buffering to its destination.
ra8_err_t ra8_io_stream_putc (ra8_io_stream_t *s, char c)
 Write a single byte to the bound sink.
ra8_err_t ra8_io_stream_puts (ra8_io_stream_t *s, const char *str)
 Write a NUL-terminated string (without the NUL) to the bound sink.
ra8_err_t ra8_io_stream_put_u32 (ra8_io_stream_t *s, uint32_t value)
 Write value as unsigned decimal ASCII (no leading zeros).
ra8_err_t ra8_io_stream_put_u64 (ra8_io_stream_t *s, uint64_t value)
 Write value as unsigned 64-bit decimal ASCII without leading zeros.
ra8_err_t ra8_io_stream_put_hex (ra8_io_stream_t *s, uint32_t value, uint8_t min_digits)
 Write value as lowercase hex ASCII, zero-padded to min_digits.

Variables

static const char *const s_tag = "ra8_io_stream"
 Module log tag.

Detailed Description

Byte-stream dispatcher + no-varargs formatted-output primitives.

Tag
[Ring 4 / PAL] {World: NS}

Validates the stream handle then forwards through the bound sink vtable. The formatted helpers (puts / put_u32 / put_hex) render into a small bounded stack buffer and call ra8_io_stream_write – no varargs, no allocation, so the _sbrk trap and the bounded-stack budget stay intact.

Definition in file ra8_io_stream.c.

Enumeration Type Documentation

◆ ra8_io_stream_const_t

enum ra8_io_stream_const_t : uint32_t

Rendering constants for the formatted-output helpers.

Since
0.1.0
Enumerator
k_ra8_io_dec_base 

Base for ra8_io_stream_put_u32.

k_ra8_io_hex_base 

Base for ra8_io_stream_put_hex.

k_ra8_io_u32_max_digits 

Decimal digits in UINT32_MAX.

k_ra8_io_u64_max_digits 

Decimal digits in UINT64_MAX.

k_ra8_io_hex_max_digits 

Hex digits in a 32-bit value.

k_ra8_io_puts_max 

Bounded scan limit for ra8_io_stream_puts.

Definition at line 37 of file ra8_io_stream.c.

Function Documentation

◆ internal_validate()

ra8_err_t internal_validate ( const ra8_io_stream_t * s)
static

Reject a handle that is NULL or has no sink bound.

Run on every entry point. Kept tiny so each public function stays under the NASA Power-of-10 Rule 4 sixty-line cap.

Parameters
[in]sCandidate handle.
Returns
ra8_err_t Error code.
Return values
k_ra8_oks is non-NULL with a bound sink.
k_ra8_err_null_ptrs was NULL.
k_ra8_err_not_initializeds->iface was NULL (never bound).
Precondition
s may be null so callers can validate candidate handles directly.
A non-null s points to readable handle storage.
Postcondition
No state is mutated.
The return reflects only the binding state of s.
Note
Thread-safe.
Since
0.1.0

Definition at line 69 of file ra8_io_stream.c.

References ra8_io_stream_t::iface, k_ra8_err_not_initialized, k_ra8_err_null_ptr, k_ra8_ok, and RA8_INTERNAL.

Referenced by ra8_io_stream_flush(), ra8_io_stream_put_hex(), ra8_io_stream_put_u32(), ra8_io_stream_put_u64(), ra8_io_stream_putc(), ra8_io_stream_puts(), and ra8_io_stream_write().

◆ ra8_io_stream_bind()

ra8_err_t ra8_io_stream_bind ( ra8_io_stream_t * stream,
const ra8_io_stream_iface_t * iface,
void * context )
nodiscard

Bind a backend vtable and caller-owned state into a stream handle.

Parameters
[out]streamStream handle to initialize.
[in]ifaceImmutable backend operations.
[in,out]contextBackend-owned state retained by the handle.
Returns
Canonical binding status.
Return values
k_ra8_okThe handle is bound and ready.
k_ra8_err_null_ptrA required pointer is null.
k_ra8_err_invalid_argThe mandatory write operation is absent.
Precondition
iface and context outlive every operation through stream.
The caller exclusively owns stream while binding it.
Postcondition
Success replaces stream with the requested binding.
Failure leaves stream unchanged.
Note
Thread-safe across distinct handles and backend states.
Since
0.1.0

Definition at line 81 of file ra8_io_stream.c.

References k_ra8_err_invalid_arg, k_ra8_err_null_ptr, k_ra8_ok, and ra8_io_stream_iface::write.

Referenced by ra8_io_stream_blockdev_init(), ra8_io_stream_posix_init(), ra8_io_stream_ram_init(), ra8_io_stream_uart_init(), and ra8_io_stream_usbcdc_init().

◆ ra8_io_stream_flush()

ra8_err_t ra8_io_stream_flush ( ra8_io_stream_t * s)
nodiscard

Flush any sink-side buffering to its destination.

Parameters
[in]sBound stream handle.
Returns
ra8_err_t Error code.
Return values
k_ra8_okPending bytes committed (or none pending).
k_ra8_err_null_ptrs was NULL.
k_ra8_err_not_initializedNo sink is bound to s.
Precondition
A sink has been bound into s.
The stream is idle (no concurrent writer).
Postcondition
On success the destination reflects every prior successful write.
No handle state is mutated by a flush of an unbuffered sink.
Note
Not thread-safe with respect to the same stream.
Since
0.1.0

Definition at line 116 of file ra8_io_stream.c.

References ra8_io_stream_t::ctx, ra8_io_stream_iface::flush, ra8_io_stream_t::iface, internal_validate(), and k_ra8_ok.

Referenced by internal_solve_words(), main(), and priv_mdl_stream_flush().

◆ ra8_io_stream_put_hex()

ra8_err_t ra8_io_stream_put_hex ( ra8_io_stream_t * s,
uint32_t value,
uint8_t min_digits )
nodiscard

Write value as lowercase hex ASCII, zero-padded to min_digits.

Parameters
[in]sBound stream handle.
[in]valueValue to render.
[in]min_digitsMinimum digit count (1..8); pad with leading zeros.
Returns
ra8_err_t Error code.
Return values
k_ra8_okDigits written.
k_ra8_err_null_ptrs was NULL.
k_ra8_err_not_initializedNo sink is bound to s.
k_ra8_err_invalid_argmin_digits is zero or greater than eight.
k_ra8_err_no_memA bounded sink could not accept the digits.
Precondition
A sink has been bound into s.
min_digits is in 1..8.
Postcondition
On success the hex rendering of value was written (no 0x prefix).
At most eight ASCII digits are produced.
Note
Not thread-safe; uses a bounded stack buffer (no allocation).
Since
0.1.0

Definition at line 197 of file ra8_io_stream.c.

References internal_validate(), k_ra8_err_invalid_arg, k_ra8_io_hex_base, k_ra8_io_hex_max_digits, k_ra8_ok, and ra8_io_stream_write().

Referenced by internal_put_hex(), and priv_mdl_stream_hex().

◆ ra8_io_stream_put_u32()

ra8_err_t ra8_io_stream_put_u32 ( ra8_io_stream_t * s,
uint32_t value )
nodiscard

Write value as unsigned decimal ASCII (no leading zeros).

Parameters
[in]sBound stream handle.
[in]valueValue to render.
Returns
ra8_err_t Error code.
Return values
k_ra8_okDigits written.
k_ra8_err_null_ptrs was NULL.
k_ra8_err_not_initializedNo sink is bound to s.
k_ra8_err_no_memA bounded sink could not accept the digits.
Precondition
A sink has been bound into s.
The stream is idle.
Postcondition
On success the decimal rendering of value was written.
At most ten ASCII digits are produced.
Note
Not thread-safe; uses a bounded stack buffer (no allocation).
Since
0.1.0

Definition at line 155 of file ra8_io_stream.c.

References internal_validate(), k_ra8_io_dec_base, k_ra8_io_u32_max_digits, k_ra8_ok, and ra8_io_stream_write().

Referenced by demo_report_map(), demo_report_wear(), internal_emit_match(), internal_put_u32(), internal_report_header(), internal_report_row(), internal_swap_run_one(), and main().

◆ ra8_io_stream_put_u64()

ra8_err_t ra8_io_stream_put_u64 ( ra8_io_stream_t * s,
uint64_t value )
nodiscard

Write value as unsigned 64-bit decimal ASCII without leading zeros.

Parameters
[in]sBound stream handle.
[in]valueValue to render.
Returns
Canonical stream status.
Return values
k_ra8_okDigits written.
k_ra8_err_null_ptrs was null.
k_ra8_err_not_initializedNo sink is bound to s.
k_ra8_err_no_memA bounded sink could not accept the digits.
Precondition
A sink has been bound into s and the stream is idle.
Postcondition
Success writes the exact base-10 identity of value.
At most twenty ASCII digits are produced.
Note
Not thread-safe for concurrent use of one stream.
Since
0.1.0

Definition at line 176 of file ra8_io_stream.c.

References internal_validate(), k_ra8_io_dec_base, k_ra8_io_u64_max_digits, k_ra8_ok, and ra8_io_stream_write().

Referenced by internal_cli_reject_limit(), internal_put_padded_u64(), internal_put_u64(), internal_report_header(), internal_run_report(), and priv_mdl_stream_u64().

◆ ra8_io_stream_putc()

ra8_err_t ra8_io_stream_putc ( ra8_io_stream_t * s,
char c )
nodiscard

Write a single byte to the bound sink.

Parameters
[in]sBound stream handle.
[in]cByte to write.
Returns
ra8_err_t Error code.
Return values
k_ra8_okByte written.
k_ra8_err_null_ptrs was NULL.
k_ra8_err_not_initializedNo sink is bound to s.
k_ra8_err_no_memA bounded sink was full.
Precondition
A sink has been bound into s.
The stream is idle.
Postcondition
On success one byte was appended to the sink.
No more than one byte is consumed.
Note
Not thread-safe with respect to the same stream.
Since
0.1.0

Definition at line 128 of file ra8_io_stream.c.

References internal_validate(), k_ra8_ok, and ra8_io_stream_write().

Referenced by internal_emit_match(), internal_log_byte(), internal_log_sink(), internal_put_padded_u64(), internal_report_row(), and priv_mdl_stream_repeat().

◆ ra8_io_stream_puts()

ra8_err_t ra8_io_stream_puts ( ra8_io_stream_t * s,
const char * str )
nodiscard

Write a NUL-terminated string (without the NUL) to the bound sink.

Scans up to a bounded maximum for the terminator (NASA Power-of-10 Rule 2), then writes that many bytes. An unterminated or overlong string is rejected; it is never silently truncated.

Parameters
[in]sBound stream handle.
[in]strNUL-terminated string.
Returns
ra8_err_t Error code.
Return values
k_ra8_okString written.
k_ra8_err_null_ptrs or str was NULL.
k_ra8_err_not_initializedNo sink is bound to s.
k_ra8_err_no_memA bounded sink could not accept all bytes.
k_ra8_err_invalid_sizeNo terminator appeared inside the scan bound.
Precondition
A sink has been bound into s.
str is NUL-terminated.
Postcondition
On success the sink consumed the string's bytes.
The terminating NUL is never written.
Note
Not thread-safe with respect to the same stream.
Since
0.1.0

Definition at line 138 of file ra8_io_stream.c.

References internal_validate(), k_ra8_err_invalid_size, k_ra8_io_puts_max, k_ra8_ok, RA8_CHECK_NULL_PTR, ra8_io_stream_write(), and s_tag.

Referenced by demo_print(), internal_cli_usage_network_options(), internal_demo_print(), internal_diagnostic(), internal_emit_match(), internal_prepare_args(), internal_prepare_credentials(), internal_put_text(), internal_report_header(), internal_report_row(), internal_run_report(), internal_swap_run_one(), internal_swap_uart_print(), internal_write_parts(), main(), priv_mdl_cli_put_parts(), priv_mdl_stream_text(), priv_viewer_output_capacity(), priv_viewer_output_error(), priv_viewer_output_index_error(), priv_viewer_output_open_error(), priv_viewer_output_opened(), priv_viewer_output_text(), priv_viewer_output_tile(), priv_viewer_output_usage(), and priv_viewer_output_wrote().

◆ ra8_io_stream_write()

ra8_err_t ra8_io_stream_write ( ra8_io_stream_t * s,
const uint8_t * buf,
uint32_t len,
uint32_t * out_written )
nodiscard

Write len bytes to the bound sink.

Forwards to the sink's write primitive. out_written (if non-NULL) receives the number of bytes the sink accepted, which may be less than len for a bounded sink (e.g. a full RAM buffer).

Parameters
[in]sBound stream handle.
[in]bufSource bytes.
[in]lenNumber of bytes to write.
[out]out_writtenBytes accepted by the sink, or NULL if not needed.
Returns
ra8_err_t Error code.
Return values
k_ra8_okAll len bytes accepted.
k_ra8_err_null_ptrs or buf was NULL.
k_ra8_err_not_initializedNo sink is bound to s.
k_ra8_err_no_memA bounded sink could not accept all bytes.
k_ra8_err_protocol_errorBackend reported an impossible count or success after a short write.
Precondition
A sink has been bound into s.
buf is readable for len bytes.
Postcondition
On success the sink has consumed all len bytes.
*out_written (when provided) holds the accepted byte count unless a backend published an impossible over-request count, in which case it is preserved and k_ra8_err_protocol_error is returned.
Note
Not thread-safe with respect to the same stream.
Since
0.1.0

Definition at line 94 of file ra8_io_stream.c.

References ra8_io_stream_t::ctx, ra8_io_stream_t::iface, internal_validate(), k_ra8_err_protocol_error, k_ra8_ok, RA8_CHECK_NULL_PTR, s_tag, and ra8_io_stream_iface::write.

Referenced by internal_io_log_byte(), internal_swap_replay_capture(), ra8_camera_codec_encode_to_stream(), ra8_io_stream_put_hex(), ra8_io_stream_put_u32(), ra8_io_stream_put_u64(), ra8_io_stream_putc(), and ra8_io_stream_puts().

Variable Documentation

◆ s_tag

const char* const s_tag = "ra8_io_stream"
static

Module log tag.

Definition at line 29 of file ra8_io_stream.c.