diff options
-rw-r--r-- | ffi.c | 34 | ||||
-rw-r--r-- | txr.1 | 14 |
2 files changed, 47 insertions, 1 deletions
@@ -1345,6 +1345,39 @@ static val ffi_varray_in(struct txr_ffi_type *tft, int copy, mem_t *src, return ffi_array_in_common(tft, copy, src, vec, self, nelem); } +static val ffi_varray_null_term_in(struct txr_ffi_type *tft, int copy, mem_t *src, + val vec_in, val self) +{ + val vec = vector(zero, nil); + val eltype = tft->mtypes; + struct txr_ffi_type *etft = ffi_type_struct(eltype); + cnum elsize = etft->size; + cnum offs, i; + + for (i = 0, offs = 0; ; i++) { + mem_t *el = src + offs, *p; + + for (p = el; p < el + elsize; p++) + if (*p) + break; + + if (p == el + elsize) + break; + + if (etft->in != 0) { + val elval = ref(vec, num_fast(i)); + vec_push(vec, elval); + } else if (copy) { + val elval = etft->get(etft, src + offs, self); + vec_push(vec, elval); + } + + offs += elsize; + } + + return replace(vec_in, vec, 0, length_vec(vec)); +} + static val ffi_varray_null_term_get(struct txr_ffi_type *tft, mem_t *src, val self) { @@ -1623,6 +1656,7 @@ val ffi_type_compile(val syntax) if (sym == zarray_s) { tft->null_term = 1; tft->get = ffi_varray_null_term_get; + tft->in = ffi_varray_null_term_in; } tft->alloc = ffi_varray_alloc; tft->free = free; @@ -53719,7 +53719,19 @@ the .code zarray type supports the get operation, which extracts elements, accumulating them into a resulting vector, until it encounters an element consisting of all zero -bytes. +bytes. That element terminates the decoding, and isn't included in the +resulting array. + +The variable-length +.code zarray +also has a special in operation. Like the get operation, the in operation +extracts all elements until a terminating null, decoding them to a vector. +Then, a range of the original vector object is replaced with the decoded vector. +If the decoded vector is as long, or longer, than the original, all of the +elements of the original are replaced and its length is extended as necessary +to contain all of the new elements. If the decoded vector is shorter than the +decoded one, then it replaces a range of the original one corresponding to +its length. .meIP (ptr << type ) The |