File syn_stream.c¶
File List > src > syntropic > util > syn_stream.c
Go to the documentation of this file
#include "syn_stream.h"
#include "syn_ringbuf.h"
#include <string.h>
/* ── Internal: delimiter scan ──────────────────────────────────────────── */
static size_t stream_find_delimiter(const SYN_Stream *s)
{
const SYN_RingBuf *rb = &s->rb;
const size_t count = syn_ringbuf_count(rb);
size_t idx = rb->tail;
for (size_t i = 0; i < count; i++) {
if (rb->buf[idx] == s->delimiter) {
return i + 1; /* 1-based position (byte count including delim) */
}
idx++;
if (idx >= rb->size)
idx = 0;
}
return 0;
}
/* ── Init / config ─────────────────────────────────────────────────────── */
void syn_stream_init(SYN_Stream *s, uint8_t *buf, size_t size)
{
syn_ringbuf_init(&s->rb, buf, size);
s->threshold = 0;
s->delimiter = 0;
s->delim_en = false;
}
void syn_stream_set_threshold(SYN_Stream *s, size_t n)
{
s->threshold = n;
}
void syn_stream_set_delimiter(SYN_Stream *s, uint8_t delim)
{
s->delimiter = delim;
s->delim_en = true;
}
void syn_stream_clear_delimiter(SYN_Stream *s)
{
s->delim_en = false;
}
/* ── Producer ──────────────────────────────────────────────────────────── */
size_t syn_stream_write(SYN_Stream *s, const uint8_t *data, size_t len)
{
return syn_ringbuf_write(&s->rb, data, len);
}
bool syn_stream_put(SYN_Stream *s, uint8_t byte)
{
return syn_ringbuf_put(&s->rb, byte);
}
/* ── Consumer ──────────────────────────────────────────────────────────── */
bool syn_stream_readable(const SYN_Stream *s)
{
const size_t count = syn_ringbuf_count(&s->rb);
if (count == 0) {
return false;
}
/* Delimiter mode takes precedence */
if (s->delim_en) {
return stream_find_delimiter(s) > 0;
}
/* Threshold mode */
if (s->threshold > 0) {
return count >= s->threshold;
}
/* Default: any bytes */
return true;
}
size_t syn_stream_read(SYN_Stream *s, uint8_t *buf, size_t max_len)
{
return syn_ringbuf_read(&s->rb, buf, max_len);
}
size_t syn_stream_read_line(SYN_Stream *s, uint8_t *buf, size_t max_len)
{
if (!s->delim_en) {
/* No delimiter mode — behave like plain read */
return syn_ringbuf_read(&s->rb, buf, max_len);
}
/* Find delimiter position */
size_t delim_pos = stream_find_delimiter(s);
if (delim_pos == 0) {
return 0; /* No delimiter found — don't consume anything */
}
/* Read up to delimiter (inclusive), capped by max_len */
size_t to_read = (delim_pos < max_len) ? delim_pos : max_len;
return syn_ringbuf_read(&s->rb, buf, to_read);
}
size_t syn_stream_count(const SYN_Stream *s)
{
return syn_ringbuf_count(&s->rb);
}
size_t syn_stream_free(const SYN_Stream *s)
{
return syn_ringbuf_free(&s->rb);
}
void syn_stream_flush(SYN_Stream *s)
{
syn_ringbuf_reset(&s->rb);
}