diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2021-08-25 06:49:53 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2021-08-25 06:49:53 -0700 |
commit | 98ec48bea40e4e80d25b26c99fbe44fc3e98459f (patch) | |
tree | 1a1761e44db628144c7cab6210a175952ebda74e | |
parent | a37665e615c504415d5425f71ce5af7b7175b3f2 (diff) | |
download | txr-98ec48bea40e4e80d25b26c99fbe44fc3e98459f.tar.gz txr-98ec48bea40e4e80d25b26c99fbe44fc3e98459f.tar.bz2 txr-98ec48bea40e4e80d25b26c99fbe44fc3e98459f.zip |
carray: allow displacement in carray-pun.
* ffi.c (carray_pun): Takes two new arguments to specify
displacement and size.
(ffi_init): Registration of carray-pun adjusted.
* ffi.h (carray_pun): Declaration updated.
* txr.1: Documented.
-rw-r--r-- | ffi.c | 26 | ||||
-rw-r--r-- | ffi.h | 2 | ||||
-rw-r--r-- | txr.1 | 47 |
3 files changed, 63 insertions, 12 deletions
@@ -5916,21 +5916,35 @@ val carray_putz(val carray, val seq) return carray; } -val carray_pun(val carray, val type) +val carray_pun(val carray, val type, val offset_in, val lim_in) { val self = lit("carray-pun"); struct carray *scry = carray_struct_checked(self, carray); struct txr_ffi_type *tft = ffi_type_struct_checked(self, type); - cnum len = scry->nelem; - cnum elsize = scry->eltft->size; - cnum size = (ucnum) len * (ucnum) elsize; + ucnum len = scry->nelem; + ucnum elsize = scry->eltft->size; + ucnum size = len * elsize; + ucnum off = if3(missingp(offset_in), 0, c_unum(offset_in, self)); + ucnum lim = if3(missingp(lim_in), size - off, c_unum(lim_in, self)); carray_elem_check(tft, self); if (len != 0 && size / elsize != len) uw_throwf(error_s, lit("~a: carray size overflow"), self, nao); - return make_carray(type, scry->data, size / tft->size, carray, 0); + if (off > size) + uw_throwf(error_s, lit("~a: ~s: offset ~a is out of bounds"), + self, carray, unum(off), nao); + + if (off + lim < off) + uw_throwf(error_s, lit("~a: ~s: limit ~a from offset ~a wraps around"), + self, carray, unum(lim), unum(off), nao); + + if (off + lim > size) + uw_throwf(error_s, lit("~a: ~s: limit ~a from offset ~a extends out of bounds"), + self, carray, unum(lim), unum(off), nao); + + return make_carray(type, scry->data + off, lim / tft->size, carray, 0); } val carray_uint(val num, val eltype_in) @@ -6750,7 +6764,7 @@ void ffi_init(void) 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)); - reg_fun(intern(lit("carray-pun"), user_package), func_n2(carray_pun)); + reg_fun(intern(lit("carray-pun"), user_package), func_n4o(carray_pun, 2)); { val ca_uint = func_n2o(carray_uint, 1); val ca_int = func_n2o(carray_int, 1); @@ -122,7 +122,7 @@ val carray_get(val carray); val carray_getz(val carray); val carray_put(val array, val seq); val carray_putz(val array, val seq); -val carray_pun(val carray, val type); +val carray_pun(val carray, val type, val offset_in, val lim_in); val carray_uint(val num, val type); val carray_int(val num, val type); val uint_carray(val carray); @@ -80428,7 +80428,7 @@ itself. .coNP Function @ carray-pun .synb -.mets (carray-pun < carray << type ) +.mets (carray-pun < carray < type >> [ offset <> [ size-limit ]]) .syne .desc The @@ -80444,13 +80444,37 @@ The .meta type argument specifies the element type used by the returned aliasing array. +If the +.meta offset +argument is specified, then the aliased view is displaced by that many +bytes from the start of the +.meta carray +object. The +.meta offset +argument must not be larger than the bytewise length of the array, +or an error exception is thrown. The bytewise length of the array +is the product of the number of elements and the element size. +The default value of +.meta offset +is zero: no displacement. + +If +.meta size-limit +is specified, it indicates the size, in bytes, of the aliased view. +This limit must not be such that the aliased view would extend beyond the +array, or an error exception is thrown. If omitted, +.meta size-limit +defaults to the entire remainder of the array, after the offset. +The number of elements of the returned array are then calculated from +.metn size-limit . + The .code carray-pun -function considers the byte size of the array, which is a product of -the original length and element size. It then calculates how many elements of +function calculates how many elements of .meta type -fit into this size. This value becomes the length of the aliasing array -which is returned. +fit into +.metn size-limit . +This value becomes the length of the aliasing array which is returned. Since the returned aliasing array and the original refer to the same storage, modifications performed in one view are reflected in the other. @@ -80464,6 +80488,19 @@ is invoked on the aliasing array. The meaning of the aliasing depends entirely on the bitwise representations of the types involved. +Note: +.code carray-pun +does not check whether +.meta offset +is a value that is suitably aligned for accessing elements of +.metn type ; +on some platforms that must be ensured. + +The +.code carray-pun +function may be invoked on an object that was itself returned by +.codn carray-pun . + .coNP Functions @ carray-uint and @ carray-int .synb .mets (carray-uint < number <> [ type ]) |