~ chicken-core (chicken-5) /srfi-4.scm
Trap1;;;; srfi-4.scm - Homogeneous numeric vectors2;3; Copyright (c) 2008-2022, The CHICKEN Team4; Copyright (c) 2000-2007, Felix L. Winkelmann5; All rights reserved.6;7; Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following8; conditions are met:9;10; Redistributions of source code must retain the above copyright notice, this list of conditions and the following11; disclaimer.12; Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following13; disclaimer in the documentation and/or other materials provided with the distribution.14; Neither the name of the author nor the names of its contributors may be used to endorse or promote15; products derived from this software without specific prior written permission.16;17; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS18; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY19; AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR20; CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR21; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR22; SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY23; THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR24; OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE25; POSSIBILITY OF SUCH DAMAGE.262728(declare29 (unit srfi-4)30 (uses expand extras)31 (disable-interrupts)32 (not inline ##sys#user-print-hook)33 (foreign-declare #<<EOF34#define C_copy_subvector(to, from, start_to, start_from, bytes) \35 (C_memcpy((C_char *)C_data_pointer(to) + C_unfix(start_to), (C_char *)C_data_pointer(from) + C_unfix(start_from), C_unfix(bytes)), \36 C_SCHEME_UNDEFINED)37EOF38) )3940(module srfi-441 (blob->f32vector blob->f32vector/shared42 blob->f64vector blob->f64vector/shared43 blob->s16vector blob->s16vector/shared44 blob->s32vector blob->s32vector/shared45 blob->s64vector blob->s64vector/shared46 blob->s8vector blob->s8vector/shared47 blob->u16vector blob->u16vector/shared48 blob->u32vector blob->u32vector/shared49 blob->u64vector blob->u64vector/shared50 blob->u8vector blob->u8vector/shared51 f32vector f32vector->blob f32vector->blob/shared f32vector->list52 f32vector-length f32vector-ref f32vector-set! f32vector?53 f64vector f64vector->blob f64vector->blob/shared f64vector->list54 f64vector-length f64vector-ref f64vector-set! f64vector?55 s8vector s8vector->blob s8vector->blob/shared s8vector->list56 s8vector-length s8vector-ref s8vector-set! s8vector?57 s16vector s16vector->blob s16vector->blob/shared s16vector->list58 s16vector-length s16vector-ref s16vector-set! s16vector?59 s32vector s32vector->blob s32vector->blob/shared s32vector->list60 s32vector-length s32vector-ref s32vector-set! s32vector?61 s64vector s64vector->blob s64vector->blob/shared s64vector->list62 s64vector-length s64vector-ref s64vector-set! s64vector?63 u8vector u8vector->blob u8vector->blob/shared u8vector->list64 u8vector-length u8vector-ref u8vector-set! u8vector?65 u16vector u16vector->blob u16vector->blob/shared u16vector->list66 u16vector-length u16vector-ref u16vector-set! u16vector?67 u32vector u32vector->blob u32vector->blob/shared u32vector->list68 u32vector-length u32vector-ref u32vector-set! u32vector?69 u64vector u64vector->blob u64vector->blob/shared u64vector->list70 u64vector-length u64vector-ref u64vector-set! u64vector?71 list->f32vector list->f64vector list->s16vector list->s32vector72 list->s64vector list->s8vector list->u16vector list->u32vector73 list->u8vector list->u64vector74 make-f32vector make-f64vector make-s16vector make-s32vector75 make-s64vector make-s8vector make-u16vector make-u32vector76 make-u64vector make-u8vector77 number-vector? read-u8vector read-u8vector! release-number-vector78 subf32vector subf64vector subs16vector subs32vector subs64vector79 subs8vector subu16vector subu8vector subu32vector subu64vector80 write-u8vector)8182(import scheme83 chicken.base84 chicken.bitwise85 chicken.fixnum86 chicken.foreign87 chicken.gc88 chicken.platform89 chicken.syntax)9091(include "common-declarations.scm")929394;;; Helper routines:9596(define-inline (check-int/flonum x loc)97 (unless (or (##core#inline "C_i_exact_integerp" x)98 (##core#inline "C_i_flonump" x))99 (##sys#error-hook (foreign-value "C_BAD_ARGUMENT_TYPE_NO_FLONUM_ERROR" int) loc x) ) )100101(define-inline (check-range i from to loc)102 (##sys#check-fixnum i loc)103 (unless (and (fx<= from i) (fx< i to))104 (##sys#error-hook105 (foreign-value "C_OUT_OF_RANGE_ERROR" int)106 loc i from to) ) )107108(define-inline (check-uint-length obj len loc)109 (##sys#check-exact-uinteger obj loc)110 (when (fx> (integer-length obj) len)111 (##sys#error-hook112 (foreign-value "C_OUT_OF_RANGE_ERROR" int) loc obj 0 (expt 2 len))))113114(define-inline (check-int-length obj len loc)115 (##sys#check-exact-integer obj loc)116 (when (fx> (integer-length obj) (fx- len 1))117 (##sys#error-hook118 (foreign-value "C_OUT_OF_RANGE_ERROR" int)119 loc obj (- (expt 2 len)) (sub1 (expt 2 len)))))120121;;; Get vector length:122123(define (u8vector-length x)124 (##core#inline "C_i_u8vector_length" x))125126(define (s8vector-length x)127 (##core#inline "C_i_s8vector_length" x))128129(define (u16vector-length x)130 (##core#inline "C_i_u16vector_length" x))131132(define (s16vector-length x)133 (##core#inline "C_i_s16vector_length" x))134135(define (u32vector-length x)136 (##core#inline "C_i_u32vector_length" x))137138(define (s32vector-length x)139 (##core#inline "C_i_s32vector_length" x))140141(define (u64vector-length x)142 (##core#inline "C_i_u64vector_length" x))143144(define (s64vector-length x)145 (##core#inline "C_i_s64vector_length" x))146147(define (f32vector-length x)148 (##core#inline "C_i_f32vector_length" x))149150(define (f64vector-length x)151 (##core#inline "C_i_f64vector_length" x))152153154;;; Safe accessors:155156(define (u8vector-set! x i y)157 (##core#inline "C_i_u8vector_set" x i y))158159(define (s8vector-set! x i y)160 (##core#inline "C_i_s8vector_set" x i y))161162(define (u16vector-set! x i y)163 (##core#inline "C_i_u16vector_set" x i y))164165(define (s16vector-set! x i y)166 (##core#inline "C_i_s16vector_set" x i y))167168(define (u32vector-set! x i y)169 (##core#inline "C_i_u32vector_set" x i y))170171(define (s32vector-set! x i y)172 (##core#inline "C_i_s32vector_set" x i y))173174(define (u64vector-set! x i y)175 (##core#inline "C_i_u64vector_set" x i y))176177(define (s64vector-set! x i y)178 (##core#inline "C_i_s64vector_set" x i y))179180(define (f32vector-set! x i y)181 (##core#inline "C_i_f32vector_set" x i y))182183(define (f64vector-set! x i y)184 (##core#inline "C_i_f64vector_set" x i y))185186(define u8vector-ref187 (getter-with-setter188 (lambda (x i) (##core#inline "C_i_u8vector_ref" x i))189 u8vector-set!190 "(chicken.srfi-4#u8vector-ref v i)"))191192(define s8vector-ref193 (getter-with-setter194 (lambda (x i) (##core#inline "C_i_s8vector_ref" x i))195 s8vector-set!196 "(chicken.srfi-4#s8vector-ref v i)"))197198(define u16vector-ref199 (getter-with-setter200 (lambda (x i) (##core#inline "C_i_u16vector_ref" x i))201 u16vector-set!202 "(chicken.srfi-4#u16vector-ref v i)"))203204(define s16vector-ref205 (getter-with-setter206 (lambda (x i) (##core#inline "C_i_s16vector_ref" x i))207 s16vector-set!208 "(chicken.srfi-4#s16vector-ref v i)"))209210(define u32vector-ref211 (getter-with-setter212 (lambda (x i) (##core#inline_allocate ("C_a_i_u32vector_ref" 5) x i))213 u32vector-set!214 "(chicken.srfi-4#u32vector-ref v i)"))215216(define s32vector-ref217 (getter-with-setter218 (lambda (x i) (##core#inline_allocate ("C_a_i_s32vector_ref" 5) x i))219 s32vector-set!220 "(chicken.srfi-4#s32vector-ref v i)"))221222(define u64vector-ref223 (getter-with-setter224 (lambda (x i) (##core#inline_allocate ("C_a_i_u64vector_ref" 7) x i))225 u64vector-set!226 "(chicken.srfi-4#u64vector-ref v i)"))227228(define s64vector-ref229 (getter-with-setter230 (lambda (x i) (##core#inline_allocate ("C_a_i_s64vector_ref" 7) x i))231 s64vector-set!232 "(chicken.srfi-4#s64vector-ref v i)"))233234(define f32vector-ref235 (getter-with-setter236 (lambda (x i) (##core#inline_allocate ("C_a_i_f32vector_ref" 4) x i))237 f32vector-set!238 "(chicken.srfi-4#f32vector-ref v i)"))239240(define f64vector-ref241 (getter-with-setter242 (lambda (x i) (##core#inline_allocate ("C_a_i_f64vector_ref" 4) x i))243 f64vector-set!244 "(chicken.srfi-4#f64vector-ref v i)"))245246247;;; Basic constructors:248249(define make-f32vector)250(define make-f64vector)251(define make-s16vector)252(define make-s32vector)253(define make-s64vector)254(define make-s8vector)255(define make-u8vector)256(define make-u16vector)257(define make-u32vector)258(define make-u64vector)259(define release-number-vector)260261(let* ((ext-alloc262 (foreign-lambda* scheme-object ((size_t bytes))263 "if (bytes > C_HEADER_SIZE_MASK) C_return(C_SCHEME_FALSE);"264 "C_word *buf = (C_word *)C_malloc(bytes + sizeof(C_header));"265 "if(buf == NULL) C_return(C_SCHEME_FALSE);"266 "C_block_header_init(buf, C_make_header(C_BYTEVECTOR_TYPE, bytes));"267 "C_return(buf);") )268 (ext-free269 (foreign-lambda* void ((scheme-object bv))270 "C_free((void *)C_block_item(bv, 1));") )271 (alloc272 (lambda (loc elem-size elems ext?)273 (##sys#check-fixnum elems loc)274 (when (fx< elems 0) (##sys#error loc "size is negative" elems))275 (let ((len (fx*? elems elem-size)))276 (unless len (##sys#error "overflow - cannot allocate the required number of elements" elems))277 (if ext?278 (let ((bv (ext-alloc len)))279 (or bv280 (##sys#error loc "not enough memory - cannot allocate external number vector" len)) )281 (let ((bv (##sys#allocate-vector len #t #f #t))) ; this could be made better...282 (##core#inline "C_string_to_bytevector" bv)283 bv) ) ) ) ))284285 (set! release-number-vector286 (lambda (v)287 (if (number-vector? v)288 (ext-free v)289 (##sys#error 'release-number-vector "bad argument type - not a number vector" v)) ) )290291 (set! make-u8vector292 (lambda (len #!optional (init #f) (ext? #f) (fin? #t))293 (let ((v (##sys#make-structure 'u8vector (alloc 'make-u8vector 1 len ext?))))294 (when (and ext? fin?) (set-finalizer! v ext-free))295 (if (not init)296 v297 (begin298 (check-uint-length init 8 'make-u8vector)299 (do ((i 0 (##core#inline "C_fixnum_plus" i 1)))300 ((##core#inline "C_fixnum_greater_or_equal_p" i len) v)301 (##core#inline "C_u_i_u8vector_set" v i init) ) ) ) ) ) )302303 (set! make-s8vector304 (lambda (len #!optional (init #f) (ext? #f) (fin? #t))305 (let ((v (##sys#make-structure 's8vector (alloc 'make-s8vector 1 len ext?))))306 (when (and ext? fin?) (set-finalizer! v ext-free))307 (if (not init)308 v309 (begin310 (check-uint-length init 8 'make-s8vector)311 (do ((i 0 (##core#inline "C_fixnum_plus" i 1)))312 ((##core#inline "C_fixnum_greater_or_equal_p" i len) v)313 (##core#inline "C_u_i_s8vector_set" v i init) ) ) ) ) ) )314315 (set! make-u16vector316 (lambda (len #!optional (init #f) (ext? #f) (fin? #t))317 (let ((v (##sys#make-structure 'u16vector (alloc 'make-u16vector 2 len ext?))))318 (when (and ext? fin?) (set-finalizer! v ext-free))319 (if (not init)320 v321 (begin322 (check-uint-length init 16 'make-u16vector)323 (do ((i 0 (##core#inline "C_fixnum_plus" i 1)))324 ((##core#inline "C_fixnum_greater_or_equal_p" i len) v)325 (##core#inline "C_u_i_u16vector_set" v i init) ) ) ) ) ) )326327 (set! make-s16vector328 (lambda (len #!optional (init #f) (ext? #f) (fin? #t))329 (let ((v (##sys#make-structure 's16vector (alloc 'make-s16vector 2 len ext?))))330 (when (and ext? fin?) (set-finalizer! v ext-free))331 (if (not init)332 v333 (begin334 (check-int-length init 16 'make-s16vector)335 (do ((i 0 (##core#inline "C_fixnum_plus" i 1)))336 ((##core#inline "C_fixnum_greater_or_equal_p" i len) v)337 (##core#inline "C_u_i_s16vector_set" v i init) ) ) ) ) ) )338339 (set! make-u32vector340 (lambda (len #!optional (init #f) (ext? #f) (fin? #t))341 (let ((v (##sys#make-structure 'u32vector (alloc 'make-u32vector 4 len ext?))))342 (when (and ext? fin?) (set-finalizer! v ext-free))343 (if (not init)344 v345 (begin346 (check-uint-length init 32 'make-u32vector)347 (do ((i 0 (##core#inline "C_fixnum_plus" i 1)))348 ((##core#inline "C_fixnum_greater_or_equal_p" i len) v)349 (##core#inline "C_u_i_u32vector_set" v i init) ) ) ) ) ) )350351 (set! make-u64vector352 (lambda (len #!optional (init #f) (ext? #f) (fin? #t))353 (let ((v (##sys#make-structure 'u64vector (alloc 'make-u64vector 8 len ext?))))354 (when (and ext? fin?) (set-finalizer! v ext-free))355 (if (not init)356 v357 (begin358 (check-uint-length init 64 'make-u64vector)359 (do ((i 0 (##core#inline "C_fixnum_plus" i 1)))360 ((##core#inline "C_fixnum_greater_or_equal_p" i len) v)361 (##core#inline "C_u_i_u64vector_set" v i init) ) ) ) ) ) )362363 (set! make-s32vector364 (lambda (len #!optional (init #f) (ext? #f) (fin? #t))365 (let ((v (##sys#make-structure 's32vector (alloc 'make-s32vector 4 len ext?))))366 (when (and ext? fin?) (set-finalizer! v ext-free))367 (if (not init)368 v369 (begin370 (check-int-length init 32 'make-s32vector)371 (do ((i 0 (##core#inline "C_fixnum_plus" i 1)))372 ((##core#inline "C_fixnum_greater_or_equal_p" i len) v)373 (##core#inline "C_u_i_s32vector_set" v i init) ) ) ) ) ) )374375 (set! make-s64vector376 (lambda (len #!optional (init #f) (ext? #f) (fin? #t))377 (let ((v (##sys#make-structure 's64vector (alloc 'make-s64vector 8 len ext?))))378 (when (and ext? fin?) (set-finalizer! v ext-free))379 (if (not init)380 v381 (begin382 (check-int-length init 64 'make-s64vector)383 (do ((i 0 (##core#inline "C_fixnum_plus" i 1)))384 ((##core#inline "C_fixnum_greater_or_equal_p" i len) v)385 (##core#inline "C_u_i_s64vector_set" v i init) ) ) ) ) ) )386387 (set! make-f32vector388 (lambda (len #!optional (init #f) (ext? #f) (fin? #t))389 (let ((v (##sys#make-structure 'f32vector (alloc 'make-f32vector 4 len ext?))))390 (when (and ext? fin?) (set-finalizer! v ext-free))391 (if (not init)392 v393 (begin394 (check-int/flonum init 'make-f32vector)395 (unless (##core#inline "C_i_flonump" init)396 (set! init (##core#inline_allocate ("C_a_u_i_int_to_flo" 4) init)))397 (do ((i 0 (##core#inline "C_fixnum_plus" i 1)))398 ((##core#inline "C_fixnum_greater_or_equal_p" i len) v)399 (##core#inline "C_u_i_f32vector_set" v i init) ) ) ) ) ) )400401 (set! make-f64vector402 (lambda (len #!optional (init #f) (ext? #f) (fin? #t))403 (let ((v (##sys#make-structure 'f64vector (alloc 'make-f64vector 8 len ext?))))404 (when (and ext? fin?) (set-finalizer! v ext-free))405 (if (not init)406 v407 (begin408 (check-int/flonum init 'make-f64vector)409 (unless (##core#inline "C_i_flonump" init)410 (set! init (##core#inline_allocate ("C_a_u_i_int_to_flo" 4) init)) )411 (do ((i 0 (##core#inline "C_fixnum_plus" i 1)))412 ((##core#inline "C_fixnum_greater_or_equal_p" i len) v)413 (##core#inline "C_u_i_f64vector_set" v i init) ) ) ) ) ) ) )414415416;;; Creating vectors from a list:417418(define-syntax list->NNNvector419 (er-macro-transformer420 (lambda (x r c)421 (let* ((tag (strip-syntax (cadr x)))422 (tagstr (symbol->string tag))423 (name (string->symbol (string-append "list->" tagstr)))424 (make (string->symbol (string-append "make-" tagstr)))425 (set (string->symbol (string-append tagstr "-set!"))))426 `(define ,name427 (let ((,make ,make))428 (lambda (lst)429 (##sys#check-list lst ',tag)430 (let* ((n (##core#inline "C_i_length" lst))431 (v (,make n)) )432 (do ((p lst (##core#inline "C_slot" p 1))433 (i 0 (##core#inline "C_fixnum_plus" i 1)) )434 ((##core#inline "C_eqp" p '()) v)435 (if (and (##core#inline "C_blockp" p) (##core#inline "C_pairp" p))436 (,set v i (##core#inline "C_slot" p 0))437 (##sys#error-not-a-proper-list lst ',name) ) ) ) )))))))438439(list->NNNvector u8vector)440(list->NNNvector s8vector)441(list->NNNvector u16vector)442(list->NNNvector s16vector)443(list->NNNvector u32vector)444(list->NNNvector s32vector)445(list->NNNvector u64vector)446(list->NNNvector s64vector)447(list->NNNvector f32vector)448(list->NNNvector f64vector)449450451;;; More constructors:452453(define u8vector454 (lambda xs (list->u8vector xs)) )455456(define s8vector457 (lambda xs (list->s8vector xs)) )458459(define u16vector460 (lambda xs (list->u16vector xs)) )461462(define s16vector463 (lambda xs (list->s16vector xs)) )464465(define u32vector466 (lambda xs (list->u32vector xs)) )467468(define s32vector469 (lambda xs (list->s32vector xs)) )470471(define u64vector472 (lambda xs (list->u64vector xs)) )473474(define s64vector475 (lambda xs (list->s64vector xs)) )476477(define f32vector478 (lambda xs (list->f32vector xs)) )479480(define f64vector481 (lambda xs (list->f64vector xs)) )482483484;;; Creating lists from a vector:485486(define-syntax NNNvector->list487 (er-macro-transformer488 (lambda (x r c)489 (let* ((tag (symbol->string (strip-syntax (cadr x))))490 (alloc (and (pair? (cddr x)) (caddr x)))491 (name (string->symbol (string-append tag "->list"))))492 `(define (,name v)493 (##sys#check-structure v ',(string->symbol tag) ',name)494 (let ((len (##core#inline ,(string-append "C_u_i_" tag "_length") v)))495 (let loop ((i 0))496 (if (fx>= i len)497 '()498 (cons499 ,(if alloc500 `(##core#inline_allocate (,(string-append "C_a_u_i_" tag "_ref") ,alloc) v i)501 `(##core#inline ,(string-append "C_u_i_" tag "_ref") v i))502 (loop (fx+ i 1)) ) ) ) ) ) ) )))503504(NNNvector->list u8vector)505(NNNvector->list s8vector)506(NNNvector->list u16vector)507(NNNvector->list s16vector)508;; The alloc amounts here are for 32-bit words; this over-allocates on 64-bits509(NNNvector->list u32vector 6)510(NNNvector->list s32vector 6)511(NNNvector->list u64vector 7)512(NNNvector->list s64vector 7)513(NNNvector->list f32vector 4)514(NNNvector->list f64vector 4)515516517;;; Predicates:518519(define (u8vector? x) (##core#inline "C_i_u8vectorp" x))520(define (s8vector? x) (##core#inline "C_i_s8vectorp" x))521(define (u16vector? x) (##core#inline "C_i_u16vectorp" x))522(define (s16vector? x) (##core#inline "C_i_s16vectorp" x))523(define (u32vector? x) (##core#inline "C_i_u32vectorp" x))524(define (s32vector? x) (##core#inline "C_i_s32vectorp" x))525(define (u64vector? x) (##core#inline "C_i_u64vectorp" x))526(define (s64vector? x) (##core#inline "C_i_s64vectorp" x))527(define (f32vector? x) (##core#inline "C_i_f32vectorp" x))528(define (f64vector? x) (##core#inline "C_i_f64vectorp" x))529530;; Catch-all predicate531(define number-vector? ##sys#srfi-4-vector?)532533;;; Accessing the packed bytevector:534535(define (pack tag loc)536 (lambda (v)537 (##sys#check-structure v tag loc)538 (##sys#slot v 1) ) )539540(define (pack-copy tag loc)541 (lambda (v)542 (##sys#check-structure v tag loc)543 (let* ((old (##sys#slot v 1))544 (new (##sys#make-blob (##sys#size old))))545 (##core#inline "C_copy_block" old new) ) ) )546547(define (unpack tag sz loc)548 (lambda (str)549 (##sys#check-byte-vector str loc)550 (let ([len (##sys#size str)])551 (if (or (eq? #t sz)552 (eq? 0 (##core#inline "C_fixnum_modulo" len sz)))553 (##sys#make-structure tag str)554 (##sys#error loc "blob does not have correct size for packing" tag len sz) ) ) ) )555556(define (unpack-copy tag sz loc)557 (lambda (str)558 (##sys#check-byte-vector str loc)559 (let* ((len (##sys#size str))560 (new (##sys#make-blob len)))561 (if (or (eq? #t sz)562 (eq? 0 (##core#inline "C_fixnum_modulo" len sz)))563 (##sys#make-structure564 tag565 (##core#inline "C_copy_block" str new) )566 (##sys#error loc "blob does not have correct size for packing" tag len sz) ) ) ) )567568(define u8vector->blob/shared (pack 'u8vector 'u8vector->blob/shared))569(define s8vector->blob/shared (pack 's8vector 's8vector->blob/shared))570(define u16vector->blob/shared (pack 'u16vector 'u16vector->blob/shared))571(define s16vector->blob/shared (pack 's16vector 's16vector->blob/shared))572(define u32vector->blob/shared (pack 'u32vector 'u32vector->blob/shared))573(define s32vector->blob/shared (pack 's32vector 's32vector->blob/shared))574(define u64vector->blob/shared (pack 'u64vector 'u64vector->blob/shared))575(define s64vector->blob/shared (pack 's64vector 's64vector->blob/shared))576(define f32vector->blob/shared (pack 'f32vector 'f32vector->blob/shared))577(define f64vector->blob/shared (pack 'f64vector 'f64vector->blob/shared))578579(define u8vector->blob (pack-copy 'u8vector 'u8vector->blob))580(define s8vector->blob (pack-copy 's8vector 's8vector->blob))581(define u16vector->blob (pack-copy 'u16vector 'u16vector->blob))582(define s16vector->blob (pack-copy 's16vector 's16vector->blob))583(define u32vector->blob (pack-copy 'u32vector 'u32vector->blob))584(define s32vector->blob (pack-copy 's32vector 's32vector->blob))585(define u64vector->blob (pack-copy 'u64vector 'u64vector->blob))586(define s64vector->blob (pack-copy 's64vector 's64vector->blob))587(define f32vector->blob (pack-copy 'f32vector 'f32vector->blob))588(define f64vector->blob (pack-copy 'f64vector 'f64vector->blob))589590(define blob->u8vector/shared (unpack 'u8vector #t 'blob->u8vector/shared))591(define blob->s8vector/shared (unpack 's8vector #t 'blob->s8vector/shared))592(define blob->u16vector/shared (unpack 'u16vector 2 'blob->u16vector/shared))593(define blob->s16vector/shared (unpack 's16vector 2 'blob->s16vector/shared))594(define blob->u32vector/shared (unpack 'u32vector 4 'blob->u32vector/shared))595(define blob->s32vector/shared (unpack 's32vector 4 'blob->s32vector/shared))596(define blob->u64vector/shared (unpack 'u64vector 4 'blob->u64vector/shared))597(define blob->s64vector/shared (unpack 's64vector 4 'blob->s64vector/shared))598(define blob->f32vector/shared (unpack 'f32vector 4 'blob->f32vector/shared))599(define blob->f64vector/shared (unpack 'f64vector 8 'blob->f64vector/shared))600601(define blob->u8vector (unpack-copy 'u8vector #t 'blob->u8vector))602(define blob->s8vector (unpack-copy 's8vector #t 'blob->s8vector))603(define blob->u16vector (unpack-copy 'u16vector 2 'blob->u16vector))604(define blob->s16vector (unpack-copy 's16vector 2 'blob->s16vector))605(define blob->u32vector (unpack-copy 'u32vector 4 'blob->u32vector))606(define blob->s32vector (unpack-copy 's32vector 4 'blob->s32vector))607(define blob->u64vector (unpack-copy 'u64vector 4 'blob->u64vector))608(define blob->s64vector (unpack-copy 's64vector 4 'blob->s64vector))609(define blob->f32vector (unpack-copy 'f32vector 4 'blob->f32vector))610(define blob->f64vector (unpack-copy 'f64vector 8 'blob->f64vector))611612613;;; Read syntax:614615;; This code is too complicated. We try to avoid mapping over616;; a potentially large list anc creating lots of garbage in the617;; process, therefore the final result list is constructed618;; via destructive updates and thus rather inelegant yet avoids619;; any re-consing unless elements are non-numeric.620(define (canonicalize-number-list! lst1)621 (let loop ((lst lst1) (prev #f))622 (if (and (##core#inline "C_blockp" lst)623 (##core#inline "C_pairp" lst))624 (let retry ((x (##sys#slot lst 0)))625 (cond ((char? x) (retry (##sys#char->utf8-string x)))626 ((string? x)627 (if (zero? (string-length x))628 (loop (##sys#slot lst 1) prev)629 (let loop2 ((ns (string->list x)) (prev prev))630 (let ((n (cons (char->integer (##sys#slot ns 0))631 (##sys#slot lst 1))))632 (if prev633 (##sys#setslot prev 1 n)634 (set! lst1 n))635 (let ((ns2 (##sys#slot ns 1)))636 (if (null? ns2)637 (loop (##sys#slot lst 1) n)638 (loop2 (##sys#slot ns 1) n)))))))639 (else (loop (##sys#slot lst 1) lst))))640 (cond (prev (##sys#setslot prev 1 '())641 lst1)642 (else '())))))643644(set! ##sys#user-read-hook645 (let ([old-hook ##sys#user-read-hook]646 [read read]647 [consers (list 'u8 list->u8vector648 's8 list->s8vector649 'u16 list->u16vector650 's16 list->s16vector651 'u32 list->u32vector652 's32 list->s32vector653 'u64 list->u64vector654 's64 list->s64vector655 'f32 list->f32vector656 'f64 list->f64vector) ] )657 (lambda (char port)658 (if (memq char '(#\u #\s #\f #\U #\S #\F))659 (let* ([x (read port)]660 [tag (and (symbol? x) x)] )661 (cond ((or (eq? tag 'f) (eq? tag 'F)) #f)662 ((memq tag consers) =>663 (lambda (c)664 (let ((val (read port)))665 (if (string? val)666 (set! val (map char->integer (string->list val)))667 (set! val (canonicalize-number-list! val)))668 ((##sys#slot (##sys#slot c 1) 0) val))))669 (else (##sys#read-error port "illegal bytevector syntax" tag)) ) )670 (old-hook char port) ) ) ) )671672673;;; Printing:674675(set! ##sys#user-print-hook676 (let ((old-hook ##sys#user-print-hook))677 (lambda (x readable port)678 (let ((tag (assq (##core#inline "C_slot" x 0)679 `((u8vector u8 ,u8vector->list)680 (s8vector s8 ,s8vector->list)681 (u16vector u16 ,u16vector->list)682 (s16vector s16 ,s16vector->list)683 (u32vector u32 ,u32vector->list)684 (s32vector s32 ,s32vector->list)685 (u64vector u64 ,u64vector->list)686 (s64vector s64 ,s64vector->list)687 (f32vector f32 ,f32vector->list)688 (f64vector f64 ,f64vector->list) ) ) ) )689 (cond (tag690 (##sys#print #\# #f port)691 (##sys#print (cadr tag) #f port)692 (##sys#print ((caddr tag) x) #t port) )693 (else (old-hook x readable port)) ) ) ) ) )694695696;;; Subvectors:697698(define (subnvector v t es from to loc)699 (##sys#check-structure v t loc)700 (let* ([bv (##sys#slot v 1)]701 [len (##sys#size bv)]702 [ilen (##core#inline "C_u_fixnum_divide" len es)] )703 (check-range from 0 (fx+ ilen 1) loc)704 (check-range to 0 (fx+ ilen 1) loc)705 (let* ([size2 (fx* es (fx- to from))]706 [bv2 (##sys#allocate-vector size2 #t #f #t)] )707 (##core#inline "C_string_to_bytevector" bv2)708 (let ([v (##sys#make-structure t bv2)])709 (##core#inline "C_copy_subvector" bv2 bv 0 (fx* from es) size2)710 v) ) ) )711712(define (subu8vector v from to) (subnvector v 'u8vector 1 from to 'subu8vector))713(define (subu16vector v from to) (subnvector v 'u16vector 2 from to 'subu16vector))714(define (subu32vector v from to) (subnvector v 'u32vector 4 from to 'subu32vector))715(define (subu64vector v from to) (subnvector v 'u64vector 8 from to 'subu64vector))716(define (subs8vector v from to) (subnvector v 's8vector 1 from to 'subs8vector))717(define (subs16vector v from to) (subnvector v 's16vector 2 from to 'subs16vector))718(define (subs32vector v from to) (subnvector v 's32vector 4 from to 'subs32vector))719(define (subs64vector v from to) (subnvector v 's64vector 8 from to 'subs64vector))720(define (subf32vector v from to) (subnvector v 'f32vector 4 from to 'subf32vector))721(define (subf64vector v from to) (subnvector v 'f64vector 8 from to 'subf64vector))722723(define (write-u8vector v #!optional (port ##sys#standard-output) (from 0) to)724 (##sys#check-structure v 'u8vector 'write-u8vector)725 (##sys#check-output-port port #t 'write-u8vector)726 (let ((len (##core#inline "C_u_i_8vector_length" v)))727 (check-range from 0 (fx+ (or to len) 1) 'write-u8vector)728 (when to (check-range to from (fx+ len 1) 'write-u8vector))729 ; using (write-string) since the "data" slot of a u8vector is730 ; represented the same as a string731 ((##sys#slot (##sys#slot port 2) 3) ; write-string732 port733 (if (and (fx= from 0) (or (not to) (fx= to len)))734 (##sys#slot v 1)735 (##sys#slot (subu8vector v from (or to len)) 1)))))736737(define (read-u8vector! n dest #!optional (port ##sys#standard-input) (start 0))738 (##sys#check-input-port port #t 'read-u8vector!)739 (##sys#check-fixnum start 'read-u8vector!)740 (##sys#check-structure dest 'u8vector 'read-u8vector!)741 (when n (##sys#check-fixnum n 'read-u8vector!))742 (let* ((dest (##sys#slot dest 1))743 (size (##sys#size dest)))744 (unless (and n (fx<= (fx+ start n) size))745 (set! n (fx- size start)))746 (chicken.io#read-string!/port n dest port start)))747748(define (read-u8vector #!optional n (p ##sys#standard-input))749 (##sys#check-input-port p #t 'read-u8vector)750 (when n (##sys#check-fixnum n 'read-u8vector))751 (let ((str (chicken.io#read-string/port n p)))752 (cond ((eof-object? str) str)753 (else754 (##core#inline "C_string_to_bytevector" str)755 (##sys#make-structure 'u8vector str)))))756757(register-feature! 'srfi-4))