summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ffi.c79
-rw-r--r--ffi.h4
-rw-r--r--txr.162
3 files changed, 145 insertions, 0 deletions
diff --git a/ffi.c b/ffi.c
index a06a41a9..c0bc40ee 100644
--- a/ffi.c
+++ b/ffi.c
@@ -4244,6 +4244,7 @@ struct carray {
mem_t *data;
cnum nelem;
val ref;
+ val artype;
};
static struct carray *carray_struct(val carray)
@@ -4271,6 +4272,7 @@ static void carray_mark_op(val obj)
struct carray *scry = carray_struct(obj);
gc_mark(scry->eltype);
gc_mark(scry->ref);
+ gc_mark(scry->artype);
}
static void carray_destroy_op(val obj)
@@ -4304,6 +4306,7 @@ val make_carray(val type, mem_t *data, cnum nelem, val ref)
scry->data = data;
scry->nelem = nelem;
scry->ref = nil;
+ scry->artype = nil;
obj = cobj(coerce(mem_t *, scry), carray_s, &carray_borrowed_ops);
scry->eltype = type;
scry->ref = ref;
@@ -4538,6 +4541,78 @@ val carray_refset(val carray, val idx, val newval)
}
}
+static void carray_ensure_artype(val carray, struct carray *scry)
+{
+ if (!scry->artype) {
+ val dim = num(scry->nelem);
+ val syntax = list(carray_s, dim, scry->eltft->syntax, nao);
+ struct txr_ffi_type *etft = scry->eltft;
+ set(mkloc(scry->artype, carray), make_ffi_type_array(syntax, vec_s, dim, scry->eltype));
+
+ {
+ struct txr_ffi_type *atft = ffi_type_struct(scry->artype);
+ if (etft->syntax == char_s)
+ atft->char_conv = 1;
+ else if (etft->syntax == wchar_s)
+ atft->wchar_conv = 1;
+ else if (etft->syntax == bchar_s)
+ atft->bchar_conv = 1;
+ }
+ }
+}
+
+static val carray_get_common(val carray, val self, unsigned null_term)
+{
+ struct carray *scry = carray_struct_checked(carray);
+
+ carray_ensure_artype(carray, scry);
+
+ {
+ struct txr_ffi_type *atft = ffi_type_struct(scry->artype);
+ atft->null_term = null_term;
+ return atft->get(atft, scry->data, self);
+ }
+}
+
+static void carray_put_common(val carray, val seq, val self, unsigned null_term)
+{
+ struct carray *scry = carray_struct_checked(carray);
+
+ carray_ensure_artype(carray, scry);
+
+ {
+ struct txr_ffi_type *atft = ffi_type_struct(scry->artype);
+ atft->null_term = null_term;
+ return atft->put(atft, seq, scry->data, self);
+ }
+}
+
+val carray_get(val carray)
+{
+ val self = lit("carray-get");
+ return carray_get_common(carray, self, 0);
+}
+
+val carray_getz(val carray)
+{
+ val self = lit("carray-getz");
+ return carray_get_common(carray, self, 1);
+}
+
+val carray_put(val carray, val seq)
+{
+ val self = lit("carray-put");
+ carray_put_common(carray, seq, self, 0);
+ return carray;
+}
+
+val carray_putz(val carray, val seq)
+{
+ val self = lit("carray-putz");
+ carray_put_common(carray, seq, self, 1);
+ return carray;
+}
+
void ffi_init(void)
{
prot1(&ffi_typedef_hash);
@@ -4637,6 +4712,10 @@ void ffi_init(void)
reg_fun(intern(lit("list-carray"), user_package), func_n2o(list_carray, 1));
reg_fun(intern(lit("carray-ref"), user_package), func_n2(carray_ref));
reg_fun(intern(lit("carray-refset"), user_package), func_n3(carray_refset));
+ reg_fun(intern(lit("carray-get"), user_package), func_n1(carray_get));
+ reg_fun(intern(lit("carray-getz"), user_package), func_n1(carray_getz));
+ reg_fun(intern(lit("carray-put"), user_package), func_n2(carray_put));
+ reg_fun(intern(lit("carray-putz"), user_package), func_n2(carray_putz));
ffi_typedef_hash = make_hash(nil, nil, nil);
ffi_init_types();
ffi_init_extra_types();
diff --git a/ffi.h b/ffi.h
index bf46c8a6..88557b7b 100644
--- a/ffi.h
+++ b/ffi.h
@@ -103,4 +103,8 @@ val vec_carray(val carray, val null_term_p);
val list_carray(val carray, val null_term_p);
val carray_ref(val carray, val idx);
val carray_refset(val carray, val idx, val newval);
+val carray_get(val carray);
+val carray_getz(val carray);
+val carray_put(val array, val seq);
+val carray_putz(val array, val seq);
void ffi_init(void);
diff --git a/txr.1 b/txr.1
index 70a90197..18137aa2 100644
--- a/txr.1
+++ b/txr.1
@@ -56690,6 +56690,68 @@ Conversion of the foreign array to the vector or list is performed
by iterating over all of its elements, starting from element zero, up to the
element before the effective length,
+.coNP Functions @ carray-get and @ carray-getz
+.synb
+.mets (carray-get << carray )
+.mets (carray-getz << carray )
+.syne
+.desc
+The
+.code carray-get
+and
+.code carray-getz
+functions treat the contents of
+.meta carray
+as a FFI
+.code array
+and
+.code zarray
+type, respectively.
+
+They invoke the get semantics to convert the FFI array to a Lisp
+object, and return that object.
+
+If the element type is one of
+.codn char ,
+.code bchar
+or
+.codn wchar ,
+then the expected string conversion semantics applies.
+
+.coNP Functions @ carray-put and @ carray-putz
+.synb
+.mets (carray-put < carray << new-val )
+.mets (carray-putz < carray << new-val )
+.syne
+.desc
+The
+.code carray-put
+and
+.code carray-putz
+functions treat the contents of
+.meta carray
+as a FFI
+.code array
+and
+.code zarray
+type, respectively.
+
+They invoke the put semantics to convert the Lisp object
+.meta new-val
+array to the foreign array representation, which is placed into
+the array storage referenced by
+.metn carray .
+
+If the element type is one of
+.codn char ,
+.code bchar
+or
+.codn wchar ,
+then the expected string conversion semantics applies.
+
+Both of these functions return
+.metn carray .
+
.SH* INTERACTIVE LISTENER
.SS* Overview