From 5bb83cfab7aaac6f6401b62e25635a5e0d373e5e Mon Sep 17 00:00:00 2001 From: Aryadev Chavali Date: Fri, 6 Feb 2026 04:53:10 +0000 Subject: [PATCH] stream: stream_seek will do clamped movement if offset is invalid If a forward/backward offset is too big, we'll clamp to the edges of the file rather than failing completely. We return the number of bytes moved so callers can still validate, but the stream API can now deal with these situations a bit more effectively. --- include/alisp/stream.h | 6 +++--- src/stream.c | 27 ++++++++++++++++----------- 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/include/alisp/stream.h b/include/alisp/stream.h index 00d97cc..36fa09c 100644 --- a/include/alisp/stream.h +++ b/include/alisp/stream.h @@ -66,9 +66,9 @@ char stream_next(stream_t *); // Peek current character, do not push position char stream_peek(stream_t *); // Move forward or backward in the stream, return success of operation -bool stream_seek(stream_t *, i64); -bool stream_seek_forward(stream_t *, u64); -bool stream_seek_backward(stream_t *, u64); +u64 stream_seek(stream_t *, i64); +u64 stream_seek_forward(stream_t *, u64); +u64 stream_seek_backward(stream_t *, u64); // Return a relative substring of a given size sv_t stream_substr(stream_t *, u64); diff --git a/src/stream.c b/src/stream.c index 687fc67..ea40657 100644 --- a/src/stream.c +++ b/src/stream.c @@ -235,7 +235,7 @@ char stream_peek(stream_t *stream) } } -bool stream_seek(stream_t *stream, i64 offset) +u64 stream_seek(stream_t *stream, i64 offset) { if (offset < 0) return stream_seek_backward(stream, offset * -1); @@ -246,20 +246,20 @@ bool stream_seek(stream_t *stream, i64 offset) return true; } -bool stream_seek_forward(stream_t *stream, u64 offset) +u64 stream_seek_forward(stream_t *stream, u64 offset) { if (stream_eoc(stream)) - return false; + return 0; switch (stream->type) { case STREAM_TYPE_STRING: { if (stream->position + offset >= stream->string.size) - return false; + return 0; stream->position += offset; - return true; + return offset; } case STREAM_TYPE_PIPE: case STREAM_TYPE_FILE: @@ -270,7 +270,7 @@ bool stream_seek_forward(stream_t *stream, u64 offset) if (stream->position + offset < stream->pipe.cache.size) { stream->position += offset; - return true; + return offset; } // Try to read chunks in till we've reached it or we're at the end of the @@ -282,9 +282,11 @@ bool stream_seek_forward(stream_t *stream, u64 offset) // Same principle as the stream_eoc(stream) check. if (stream->position + offset > stream->pipe.cache.size) - return false; + { + offset = stream->pipe.cache.size - stream->position; + } stream->position += offset; - return true; + return offset; } default: FAIL("Unreachable"); @@ -292,13 +294,16 @@ bool stream_seek_forward(stream_t *stream, u64 offset) } } -bool stream_seek_backward(stream_t *stream, u64 offset) +u64 stream_seek_backward(stream_t *stream, u64 offset) { assert(stream); if (stream->position < offset) - return false; + { + offset = stream->position; + } + stream->position -= offset; - return true; + return offset; } sv_t stream_substr(stream_t *stream, u64 size)