|
ProtoCore v0.0.1
Deterministic, zero-heap network stack for embedded targets
|
A byte region whose run length is bound in both directions. More...
#include <stddef.h>#include <stdint.h>Go to the source code of this file.
Classes | |
| struct | pc_span |
| A writable byte region: the storage, the capacity that belongs to it, and what has been produced into it. More... | |
| struct | pc_cspan |
| A read-only byte region. More... | |
Functions | |
| pc_span | pc_span_from (uint8_t *p, size_t cap) |
| Bind a span to memory whose extent is only known at run time. | |
| pc_cspan | pc_cspan_from (const uint8_t *p, size_t len) |
| Bind a read-only span to memory whose extent is only known at run time. | |
| bool | pc_span_ok (const pc_span &s) |
| True when the span refers to real storage and every write so far has fit. | |
| bool | pc_span_has_storage (const pc_span &s) |
| True when the span refers to real storage, whether or not a write has overflowed. | |
| bool | pc_cspan_ok (const pc_cspan &s) |
| True when the read-only span refers to real bytes and no read has run past the end. | |
| size_t | pc_span_len (const pc_span &s) |
| Bytes the payload needs - the backward direction. | |
| size_t | pc_span_room (const pc_span &s) |
| Writable bytes remaining (0 once the region is full or has overflowed). | |
| void | pc_span_reset (pc_span *s) |
| Rewind to empty, keeping the same storage and clearing the overflow flag. | |
| pc_span | pc_span_after (const pc_span &s, size_t off) |
The sub-span starting off bytes into s (a fresh, empty cursor over that tail). | |
| pc_span | pc_span_first (const pc_span &s, size_t n) |
The first n bytes of s as a fresh span, clamped to what s actually has. | |
| pc_cspan | pc_span_produced (const pc_span &s) |
A read-only view of what has been produced into s. | |
| pc_cspan | pc_span_read (const pc_span &s, size_t len) |
A read-only view of the first len bytes of s, clamped to its capacity. | |
A byte region whose run length is bound in both directions.
Every buffer in this library has a declared, compile-time run length - SSH_PKT_BUF_SIZE, PC_RSA_KEY_BYTES, and so on. The problem rule 19 exposes is not that the size is unknown; it is that once an array becomes a borrowed region, the size gets restated at each use and the restatements can disagree:
uint8_t *buf = (uint8_t *)scratch_alloc(SSH_PKT_BUF_SIZE, 16); handler(buf, &n, SSH_PKT_BUF_SIZE); // nothing forces these two constants to match
and sizeof(buf) silently becomes sizeof(uint8_t *) - 4 bytes on a 32-bit target - with no diagnostic, because -Wsizeof-pointer-memaccess only fires for the memcpy / strcpy family.
A span is stated once, from the constant that already names the size, and then carried. Nothing here re-derives a length the code already knows: there is no deduction and no sizeof on a borrow, only the one constant travelling with its storage.
Both directions, one object. A fixed-capacity region in this library is never one-way. The preempting queue is the reference: one depth constant sizes the lane, items go in at either end, and pc_pq_high_water_lane() reports the peak actually reached so the constant can be right-sized. A span carries the same pair:
cap - reserves the storage and bounds every writepos - what the payload actually needed, which keeps counting past cap on overflow, so an undersized run-length constant reports the size it should have been instead of merely failingThat retires the size_t *out_len out-parameter that used to ride beside the buffer: capacity in and produced length out are one object, and neither can be paired with the wrong buffer.
One byte-cursor API, not two. The field names here are exactly the write-cursor convention that shared_primitives/bytes.h already operates on ({uint8_t *buf; size_t cap; size_t pos; bool overflow;}), so pc_bw_put() / pc_bw_put_be() / pc_bw_len() / pc_bw_ok() apply to a pc_span unchanged. This type is the storage-binding half - where the region came from and how big it is; bytes.h is the writing half. There is no second byte-append API.
Fail-closed by construction. A failed allocation yields a null pointer with zero capacity, never a null pointer with a live capacity. A caller that forgets the check writes nothing into a zero-capacity region instead of dereferencing null, so an omitted check drops a message rather than crashing. Callers should still test pc_span_ok() and take their defined fail-closed path (drop the optional work, close the connection, answer 503).
Definition in file span.h.
|
inline |
Bind a span to memory whose extent is only known at run time.
Normalizes the empty case so a span with storage but no capacity - or capacity but no storage - cannot be constructed.
Definition at line 92 of file span.h.
References pc_span::buf, pc_span::cap, pc_span::overflow, and pc_span::pos.
Referenced by pc_scratch_span(), pc_secure_span(), pc_span_after(), pc_span_first(), ScratchBorrow::ScratchBorrow(), and SecureBorrow::SecureBorrow().
|
inline |
Bind a read-only span to memory whose extent is only known at run time.
Definition at line 103 of file span.h.
References pc_cspan::buf, pc_cspan::err, pc_cspan::len, and pc_cspan::pos.
Referenced by pc_aesgcm_seal(), pc_span_produced(), and pc_span_read().
|
inline |
True when the span refers to real storage and every write so far has fit.
Definition at line 114 of file span.h.
References pc_span::buf, and pc_span::overflow.
Referenced by bn_expmod_group14(), pc_aes256ctr_crypt(), pc_aes256ctr_get_length(), pc_chacha20_block_ietf(), pc_chacha20_xor(), pc_chachapoly_decrypt(), pc_chachapoly_encrypt(), pc_chachapoly_get_length(), pc_hmac_sha256(), pc_hmac_sha256_final(), pc_hmac_sha256_init(), pc_md_wants(), pc_poly1305(), pc_span_produced(), and pc_ssh_server_dispatch().
|
inline |
True when the span refers to real storage, whether or not a write has overflowed.
Definition at line 120 of file span.h.
References pc_span::buf.
Referenced by pc_span_after(), pc_span_first(), and pc_span_read().
|
inline |
True when the read-only span refers to real bytes and no read has run past the end.
Definition at line 126 of file span.h.
References pc_cspan::buf, and pc_cspan::err.
|
inline |
Bytes the payload needs - the backward direction.
Equals the bytes written while everything fit. After an overflow it keeps counting, so a value greater than pc_span::cap is exactly the capacity the run-length constant should have had.
Definition at line 137 of file span.h.
References pc_span::pos.
|
inline |
Writable bytes remaining (0 once the region is full or has overflowed).
Definition at line 143 of file span.h.
References pc_span::cap, and pc_span::pos.
|
inline |
Rewind to empty, keeping the same storage and clearing the overflow flag.
Definition at line 149 of file span.h.
References pc_span::overflow, and pc_span::pos.
The sub-span starting off bytes into s (a fresh, empty cursor over that tail).
Clamps rather than trapping: an off past the end yields an empty span, so a truncated frame produces a zero-capacity region that writes nothing instead of a pointer past the allocation.
Definition at line 161 of file span.h.
References pc_span::buf, pc_span::cap, pc_span_from(), and pc_span_has_storage().
The first n bytes of s as a fresh span, clamped to what s actually has.
Definition at line 171 of file span.h.
References pc_span::buf, pc_span::cap, pc_span_from(), and pc_span_has_storage().
A read-only view of what has been produced into s.
The natural handoff once a frame is built: the length comes from the span's own cursor, so a reader cannot be handed a length that disagrees with the bytes. Yields an empty view if the span overflowed - a partially written frame must not be transmitted as though it were whole.
Definition at line 187 of file span.h.
References pc_span::buf, pc_cspan_from(), pc_span_ok(), and pc_span::pos.
A read-only view of the first len bytes of s, clamped to its capacity.
Definition at line 197 of file span.h.
References pc_span::buf, pc_span::cap, pc_cspan_from(), and pc_span_has_storage().