From a1ed5662ab1b0932a07549c39c8d435f0d2be0d7 Mon Sep 17 00:00:00 2001 From: Jo-Philipp Wich Date: Wed, 8 Jun 2022 12:22:23 +0200 Subject: struct: add optional offset argument to `unpack()` Extend the `unpack()` function to take an optional, second offset parameter which is useful to skip an initial portion of the input data without having to encode pad bytes into the format string. Signed-off-by: Jo-Philipp Wich --- lib/struct.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/lib/struct.c b/lib/struct.c index bd418b2..751127c 100644 --- a/lib/struct.c +++ b/lib/struct.c @@ -2307,6 +2307,7 @@ static uc_value_t * uc_unpack_common(uc_vm_t *vm, size_t nargs, formatstate_t *state, size_t argoff) { uc_value_t *bufval = uc_fn_arg(argoff); + uc_value_t *offset = uc_fn_arg(argoff + 1); const char *startfrom = NULL; ssize_t bufrem, size, n; uc_value_t *result; @@ -2322,6 +2323,27 @@ uc_unpack_common(uc_vm_t *vm, size_t nargs, formatstate_t *state, size_t argoff) startfrom = ucv_string_get(bufval); bufrem = ucv_string_length(bufval); + + if (offset) { + if (ucv_type(offset) != UC_INTEGER) { + uc_vm_raise_exception(vm, EXCEPTION_TYPE, + "Offset value not an integer"); + + return NULL; + } + + n = (ssize_t)ucv_int64_get(offset); + + if (n < 0) + n += bufrem; + + if (n < 0 || n >= bufrem) + return NULL; + + startfrom += n; + bufrem -= n; + } + result = ucv_array_new(vm); for (ncode = 0, code = &state->codes[0], off = 0; -- cgit v1.2.3