summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2017-05-20 08:32:27 -0700
committerKaz Kylheku <kaz@kylheku.com>2017-05-20 08:32:27 -0700
commit945a99aafab2541253754d01dc903ccc6671155d (patch)
tree453efbabeb45de8b142da4b0453a9f14f2ea5050
parent6d8f4f8f500c8e8d36ff66a1160788042e219b61 (diff)
downloadtxr-945a99aafab2541253754d01dc903ccc6671155d.tar.gz
txr-945a99aafab2541253754d01dc903ccc6671155d.tar.bz2
txr-945a99aafab2541253754d01dc903ccc6671155d.zip
ffi: variable length zarray needs in operation.
* ffi.c (ffi_varray_null_term_in): New static function. (ffi_type_compile): Wire in new function as in operation of variable length zarray. * txr.1: Documented.
-rw-r--r--ffi.c34
-rw-r--r--txr.114
2 files changed, 47 insertions, 1 deletions
diff --git a/ffi.c b/ffi.c
index 5624b9dd..31666020 100644
--- a/ffi.c
+++ b/ffi.c
@@ -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;
diff --git a/txr.1 b/txr.1
index df361b52..c5fcee5c 100644
--- a/txr.1
+++ b/txr.1
@@ -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