in source/io.c [620:672]
static int s_input_stream_seek(struct aws_input_stream *stream, int64_t offset, enum aws_stream_seek_basis basis) {
struct aws_napi_input_stream_impl *impl = stream->impl;
int result = AWS_OP_SUCCESS;
uint64_t final_offset = 0;
aws_mutex_lock(&impl->mutex);
uint64_t total_bytes = impl->bytes_read + impl->buffer.len;
switch (basis) {
case AWS_SSB_BEGIN:
/* Offset must be positive, must be greater than the bytes already read (because those
* bytes are gone from the buffer), and must not be greater than the sum of the bytes
* read so far and the size of the buffer
*/
if (offset < 0 || (uint64_t)offset > total_bytes || (uint64_t)offset < impl->bytes_read) {
result = aws_raise_error(AWS_IO_STREAM_INVALID_SEEK_POSITION);
goto failed;
}
final_offset = (uint64_t)offset - impl->bytes_read;
break;
case AWS_SSB_END:
/* Offset must be negative, and must not be trying to go further back than the
* current length of the buffer, because those bytes have been purged
*/
if (offset > 0 || offset == INT64_MIN || (uint64_t)(-offset) > impl->buffer.len) {
result = aws_raise_error(AWS_IO_STREAM_INVALID_SEEK_POSITION);
goto failed;
}
final_offset = (uint64_t)impl->buffer.len - (uint64_t)(-offset);
break;
default:
result = aws_raise_error(AWS_ERROR_INVALID_ARGUMENT);
goto failed;
}
AWS_ASSERT(final_offset <= SIZE_MAX);
size_t buf_offset = (size_t)final_offset;
AWS_ASSERT(buf_offset <= impl->buffer.len);
if (buf_offset == impl->buffer.len) {
impl->bytes_read += impl->buffer.len;
impl->buffer.len = 0;
} else if (buf_offset > 0) {
size_t new_len = impl->buffer.len - buf_offset;
memmove(impl->buffer.buffer, impl->buffer.buffer + buf_offset, new_len);
impl->buffer.len = new_len;
}
failed:
aws_mutex_unlock(&impl->mutex);
return result;
}