2007-10-25 16:27:34 -04:00
|
|
|
;;; Ikarus Scheme -- A compiler for R6RS Scheme.
|
|
|
|
;;; Copyright (C) 2006,2007 Abdulaziz Ghuloum
|
|
|
|
;;;
|
|
|
|
;;; This program is free software: you can redistribute it and/or modify
|
|
|
|
;;; it under the terms of the GNU General Public License version 3 as
|
|
|
|
;;; published by the Free Software Foundation.
|
|
|
|
;;;
|
|
|
|
;;; This program is distributed in the hope that it will be useful, but
|
|
|
|
;;; WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
;;; General Public License for more details.
|
|
|
|
;;;
|
|
|
|
;;; You should have received a copy of the GNU General Public License
|
|
|
|
;;; along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
2007-05-15 13:50:00 -04:00
|
|
|
|
|
|
|
(library (ikarus bytevectors)
|
2007-11-06 21:08:52 -05:00
|
|
|
(export
|
|
|
|
make-bytevector bytevector-length bytevector-s8-ref
|
|
|
|
bytevector-u8-ref bytevector-u8-set! bytevector-s8-set!
|
|
|
|
bytevector-copy! u8-list->bytevector bytevector->u8-list
|
|
|
|
bytevector-u16-native-ref bytevector-u16-native-set!
|
|
|
|
bytevector-u32-native-ref bytevector-u32-native-set!
|
|
|
|
bytevector-s32-native-ref bytevector-s32-native-set!
|
|
|
|
bytevector-u16-ref bytevector-u16-set!
|
|
|
|
bytevector-u32-ref bytevector-u32-set!
|
|
|
|
bytevector-s32-ref bytevector-s32-set!
|
|
|
|
bytevector-s16-native-ref bytevector-s16-native-set!
|
|
|
|
bytevector-s16-ref bytevector-s16-set!
|
|
|
|
bytevector-fill! bytevector-copy bytevector=?
|
|
|
|
bytevector-uint-ref bytevector-sint-ref
|
|
|
|
bytevector-uint-set! bytevector-sint-set!
|
|
|
|
bytevector->uint-list bytevector->sint-list
|
|
|
|
uint-list->bytevector sint-list->bytevector
|
|
|
|
bytevector-ieee-double-native-ref bytevector-ieee-double-native-set!
|
2007-11-07 01:26:38 -05:00
|
|
|
bytevector-ieee-double-ref bytevector-ieee-double-set!
|
2007-11-06 21:08:52 -05:00
|
|
|
native-endianness)
|
2007-05-15 13:50:00 -04:00
|
|
|
(import
|
|
|
|
(except (ikarus)
|
2007-11-06 21:08:52 -05:00
|
|
|
make-bytevector bytevector-length bytevector-s8-ref
|
|
|
|
bytevector-u8-ref bytevector-u8-set! bytevector-s8-set!
|
|
|
|
bytevector-copy! u8-list->bytevector bytevector->u8-list
|
|
|
|
bytevector-u16-native-ref bytevector-u16-native-set!
|
|
|
|
bytevector-u32-native-ref bytevector-u32-native-set!
|
|
|
|
bytevector-s32-native-ref bytevector-s32-native-set!
|
|
|
|
bytevector-u16-ref bytevector-u16-set!
|
|
|
|
bytevector-u32-ref bytevector-u32-set!
|
|
|
|
bytevector-s32-ref bytevector-s32-set!
|
|
|
|
bytevector-s16-native-ref bytevector-s16-native-set!
|
|
|
|
bytevector-s16-ref bytevector-s16-set!
|
|
|
|
bytevector-fill! bytevector-copy bytevector=?
|
|
|
|
bytevector-uint-ref bytevector-sint-ref
|
|
|
|
bytevector-uint-set! bytevector-sint-set!
|
|
|
|
bytevector->uint-list bytevector->sint-list
|
|
|
|
uint-list->bytevector sint-list->bytevector
|
|
|
|
bytevector-ieee-double-native-ref bytevector-ieee-double-native-set!
|
2007-11-07 01:26:38 -05:00
|
|
|
bytevector-ieee-double-ref bytevector-ieee-double-set!
|
2007-11-06 21:08:52 -05:00
|
|
|
native-endianness)
|
2007-05-15 13:50:00 -04:00
|
|
|
(ikarus system $fx)
|
2007-05-16 11:05:06 -04:00
|
|
|
(ikarus system $bignums)
|
2007-05-15 14:27:31 -04:00
|
|
|
(ikarus system $pairs)
|
2007-05-15 13:50:00 -04:00
|
|
|
(ikarus system $bytevectors))
|
|
|
|
|
2007-09-10 15:15:20 -04:00
|
|
|
(define (native-endianness) 'big) ;;; HARDCODED
|
|
|
|
|
|
|
|
|
2007-05-15 13:50:00 -04:00
|
|
|
(define ($bytevector-fill x i j fill)
|
|
|
|
(cond
|
|
|
|
[($fx= i j) x]
|
|
|
|
[else
|
|
|
|
($bytevector-set! x i fill)
|
|
|
|
($bytevector-fill x ($fxadd1 i) j fill)]))
|
|
|
|
|
|
|
|
(define make-bytevector
|
|
|
|
(case-lambda
|
|
|
|
[(k)
|
|
|
|
(if (and (fixnum? k) ($fx>= k 0))
|
|
|
|
($make-bytevector k)
|
2007-10-25 14:32:26 -04:00
|
|
|
(error 'make-bytevector "not a valid size" k))]
|
2007-05-15 13:50:00 -04:00
|
|
|
[(k fill)
|
|
|
|
(if (and (fixnum? fill) ($fx<= -128 fill) ($fx<= fill 255))
|
|
|
|
($bytevector-fill (make-bytevector k) 0 k fill)
|
2007-10-25 14:32:26 -04:00
|
|
|
(error 'make-bytevector "not a valid fill" fill))]))
|
2007-05-15 13:50:00 -04:00
|
|
|
|
2007-05-15 14:33:50 -04:00
|
|
|
(define bytevector-fill!
|
|
|
|
(lambda (x fill)
|
|
|
|
(unless (bytevector? x)
|
2007-10-25 14:32:26 -04:00
|
|
|
(error 'bytevector-fill! "not a bytevector" x))
|
2007-05-15 14:33:50 -04:00
|
|
|
(unless (and (fixnum? fill) ($fx<= -128 fill) ($fx<= fill 255))
|
2007-10-25 14:32:26 -04:00
|
|
|
(error 'bytevector-fill! "not a valid fill" fill))
|
2007-05-15 14:33:50 -04:00
|
|
|
($bytevector-fill x 0 ($bytevector-length x) fill)))
|
|
|
|
|
|
|
|
|
2007-05-15 13:50:00 -04:00
|
|
|
(define bytevector-length
|
|
|
|
(lambda (x)
|
|
|
|
(if (bytevector? x)
|
|
|
|
($bytevector-length x)
|
2007-10-25 14:32:26 -04:00
|
|
|
(error 'bytevector-length "not a bytevector" x))))
|
2007-05-15 13:50:00 -04:00
|
|
|
|
|
|
|
(define bytevector-s8-ref
|
|
|
|
(lambda (x i)
|
|
|
|
(if (bytevector? x)
|
|
|
|
(if (and (fixnum? i) ($fx<= 0 i) ($fx< i ($bytevector-length x)))
|
|
|
|
($bytevector-s8-ref x i)
|
2007-10-25 14:32:26 -04:00
|
|
|
(error 'bytevector-s8-ref "invalid index" i x))
|
|
|
|
(error 'bytevector-s8-ref "not a bytevector" x))))
|
2007-05-15 13:50:00 -04:00
|
|
|
|
|
|
|
(define bytevector-u8-ref
|
|
|
|
(lambda (x i)
|
|
|
|
(if (bytevector? x)
|
|
|
|
(if (and (fixnum? i) ($fx<= 0 i) ($fx< i ($bytevector-length x)))
|
|
|
|
($bytevector-u8-ref x i)
|
2007-10-25 14:32:26 -04:00
|
|
|
(error 'bytevector-u8-ref "invalid index" i x))
|
|
|
|
(error 'bytevector-u8-ref "not a bytevector" x))))
|
2007-05-15 13:50:00 -04:00
|
|
|
|
|
|
|
|
|
|
|
(define bytevector-s8-set!
|
|
|
|
(lambda (x i v)
|
|
|
|
(if (bytevector? x)
|
|
|
|
(if (and (fixnum? i) ($fx<= 0 i) ($fx< i ($bytevector-length x)))
|
|
|
|
(if (and (fixnum? v) ($fx<= -128 v) ($fx<= v 127))
|
|
|
|
($bytevector-set! x i v)
|
2007-10-25 14:32:26 -04:00
|
|
|
(error 'bytevector-s8-set! "not a byte" v))
|
|
|
|
(error 'bytevector-s8-set! "invalid index" i x))
|
|
|
|
(error 'bytevector-s8-set! "not a bytevector" x))))
|
2007-05-15 13:50:00 -04:00
|
|
|
|
|
|
|
(define bytevector-u8-set!
|
|
|
|
(lambda (x i v)
|
|
|
|
(if (bytevector? x)
|
|
|
|
(if (and (fixnum? i) ($fx<= 0 i) ($fx< i ($bytevector-length x)))
|
|
|
|
(if (and (fixnum? v) ($fx<= 0 v) ($fx<= v 255))
|
|
|
|
($bytevector-set! x i v)
|
2007-10-25 14:32:26 -04:00
|
|
|
(error 'bytevector-u8-set! "not an octet" v))
|
|
|
|
(error 'bytevector-u8-set! "invalid index" i x))
|
|
|
|
(error 'bytevector-u8-set! "not a bytevector" x))))
|
2007-09-10 14:10:37 -04:00
|
|
|
|
2007-09-10 15:15:20 -04:00
|
|
|
(define bytevector-u16-native-ref ;;; HARDCODED
|
2007-09-10 14:10:37 -04:00
|
|
|
(lambda (x i)
|
|
|
|
(if (bytevector? x)
|
|
|
|
(if (and (fixnum? i)
|
|
|
|
($fx<= 0 i)
|
|
|
|
($fx< i ($fxsub1 ($bytevector-length x)))
|
|
|
|
($fxzero? ($fxlogand i 1)))
|
2007-09-10 14:24:35 -04:00
|
|
|
($fxlogor
|
|
|
|
($fxsll ($bytevector-u8-ref x i) 8)
|
|
|
|
($bytevector-u8-ref x ($fxadd1 i)))
|
2007-10-25 14:32:26 -04:00
|
|
|
(error 'bytevector-u16-native-ref "invalid index" i))
|
|
|
|
(error 'bytevector-u16-native-ref "not a bytevector" x))))
|
2007-09-10 14:10:37 -04:00
|
|
|
|
2007-09-12 16:59:21 -04:00
|
|
|
|
2007-09-10 15:15:20 -04:00
|
|
|
(define bytevector-u16-native-set! ;;; HARDCODED
|
2007-09-10 14:47:29 -04:00
|
|
|
(lambda (x i n)
|
|
|
|
(if (bytevector? x)
|
|
|
|
(if (and (fixnum? n)
|
|
|
|
($fx<= 0 n)
|
2007-09-10 14:58:37 -04:00
|
|
|
($fx<= n #xFFFF))
|
2007-09-10 14:47:29 -04:00
|
|
|
(if (and (fixnum? i)
|
|
|
|
($fx<= 0 i)
|
|
|
|
($fx< i ($fxsub1 ($bytevector-length x)))
|
|
|
|
($fxzero? ($fxlogand i 1)))
|
|
|
|
(begin
|
|
|
|
($bytevector-set! x i ($fxsra n 8))
|
|
|
|
($bytevector-set! x ($fxadd1 i) n))
|
2007-10-25 14:32:26 -04:00
|
|
|
(error 'bytevector-u16-native-set! "invalid index" i))
|
|
|
|
(error 'bytevector-u16-native-set! "invalid value" n))
|
|
|
|
(error 'bytevector-u16-native-set! "not a bytevector" x))))
|
2007-09-10 14:24:35 -04:00
|
|
|
|
2007-09-10 15:15:20 -04:00
|
|
|
(define bytevector-s16-native-set! ;;; HARDCODED
|
2007-09-10 14:58:37 -04:00
|
|
|
(lambda (x i n)
|
|
|
|
(if (bytevector? x)
|
|
|
|
(if (and (fixnum? n)
|
|
|
|
($fx<= #x-8000 n)
|
|
|
|
($fx<= n #x7FFF))
|
|
|
|
(if (and (fixnum? i)
|
|
|
|
($fx<= 0 i)
|
|
|
|
($fx< i ($fxsub1 ($bytevector-length x)))
|
|
|
|
($fxzero? ($fxlogand i 1)))
|
|
|
|
(begin
|
|
|
|
($bytevector-set! x i ($fxsra n 8))
|
|
|
|
($bytevector-set! x ($fxadd1 i) n))
|
2007-10-25 14:32:26 -04:00
|
|
|
(error 'bytevector-s16-native-set! "invalid index" i))
|
|
|
|
(error 'bytevector-s16-native-set! "invalid value" n))
|
|
|
|
(error 'bytevector-s16-native-set! "not a bytevector" x))))
|
2007-09-10 14:58:37 -04:00
|
|
|
|
2007-09-10 15:15:20 -04:00
|
|
|
(define bytevector-s16-native-ref ;;; HARDCODED
|
2007-09-10 14:24:35 -04:00
|
|
|
(lambda (x i)
|
2007-09-10 14:10:37 -04:00
|
|
|
(if (bytevector? x)
|
|
|
|
(if (and (fixnum? i)
|
|
|
|
($fx<= 0 i)
|
|
|
|
($fx< i ($fxsub1 ($bytevector-length x)))
|
|
|
|
($fxzero? ($fxlogand i 1)))
|
2007-09-10 14:24:35 -04:00
|
|
|
($fxlogor
|
|
|
|
($fxsll ($bytevector-s8-ref x i) 8)
|
|
|
|
($bytevector-u8-ref x ($fxadd1 i)))
|
2007-10-25 14:32:26 -04:00
|
|
|
(error 'bytevector-s16-native-ref "invalid index" i))
|
|
|
|
(error 'bytevector-s16-native-ref "not a bytevector" x))))
|
2007-09-10 14:24:35 -04:00
|
|
|
|
|
|
|
(define bytevector-u16-ref
|
|
|
|
(lambda (x i end)
|
|
|
|
(if (bytevector? x)
|
|
|
|
(if (and (fixnum? i)
|
|
|
|
($fx<= 0 i)
|
|
|
|
($fx< i ($fxsub1 ($bytevector-length x))))
|
2007-09-10 14:10:37 -04:00
|
|
|
(case end
|
|
|
|
[(big)
|
2007-09-10 14:24:35 -04:00
|
|
|
($fxlogor
|
|
|
|
($fxsll ($bytevector-u8-ref x i) 8)
|
|
|
|
($bytevector-u8-ref x ($fxadd1 i)))]
|
2007-09-10 14:10:37 -04:00
|
|
|
[(little)
|
2007-09-10 14:24:35 -04:00
|
|
|
($fxlogor
|
|
|
|
($fxsll ($bytevector-u8-ref x (fxadd1 i)) 8)
|
|
|
|
($bytevector-u8-ref x i))]
|
2007-10-25 14:32:26 -04:00
|
|
|
[else (error 'bytevector-u16-ref "invalid endianness" end)])
|
|
|
|
(error 'bytevector-u16-ref "invalid index" i))
|
|
|
|
(error 'bytevector-u16-ref "not a bytevector" x))))
|
2007-09-10 14:47:29 -04:00
|
|
|
|
2007-09-12 16:59:21 -04:00
|
|
|
(define bytevector-u32-ref
|
|
|
|
(lambda (x i end)
|
|
|
|
(if (bytevector? x)
|
|
|
|
(if (and (fixnum? i)
|
|
|
|
($fx<= 0 i)
|
|
|
|
($fx< i ($fx- ($bytevector-length x) 3)))
|
|
|
|
(case end
|
|
|
|
[(big)
|
2007-09-13 01:44:10 -04:00
|
|
|
(+ (sll ($bytevector-u8-ref x i) 24)
|
2007-09-12 16:59:21 -04:00
|
|
|
($fxlogor
|
|
|
|
($fxsll ($bytevector-u8-ref x ($fx+ i 1)) 16)
|
|
|
|
($fxlogor
|
|
|
|
($fxsll ($bytevector-u8-ref x ($fx+ i 2)) 8)
|
|
|
|
($bytevector-u8-ref x ($fx+ i 3)))))]
|
|
|
|
[(little)
|
2007-09-13 01:44:10 -04:00
|
|
|
(+ (sll ($bytevector-u8-ref x ($fx+ i 3)) 24)
|
2007-09-12 16:59:21 -04:00
|
|
|
($fxlogor
|
|
|
|
($fxsll ($bytevector-u8-ref x ($fx+ i 2)) 16)
|
|
|
|
($fxlogor
|
|
|
|
($fxsll ($bytevector-u8-ref x ($fx+ i 1)) 8)
|
|
|
|
($bytevector-u8-ref x i))))]
|
2007-10-25 14:32:26 -04:00
|
|
|
[else (error 'bytevector-u32-ref "invalid endianness" end)])
|
|
|
|
(error 'bytevector-u32-ref "invalid index" i))
|
|
|
|
(error 'bytevector-u32-ref "not a bytevector" x))))
|
2007-09-12 16:59:21 -04:00
|
|
|
|
2007-09-13 01:57:36 -04:00
|
|
|
(define bytevector-u32-native-ref
|
|
|
|
(lambda (x i)
|
|
|
|
(if (bytevector? x)
|
|
|
|
(if (and (fixnum? i)
|
|
|
|
($fx<= 0 i)
|
|
|
|
($fx= 0 ($fxlogand i 3))
|
|
|
|
($fx< i ($fx- ($bytevector-length x) 3)))
|
|
|
|
(+ (sll ($bytevector-u8-ref x i) 24)
|
|
|
|
($fxlogor
|
|
|
|
($fxsll ($bytevector-u8-ref x ($fx+ i 1)) 16)
|
|
|
|
($fxlogor
|
|
|
|
($fxsll ($bytevector-u8-ref x ($fx+ i 2)) 8)
|
|
|
|
($bytevector-u8-ref x ($fx+ i 3)))))
|
2007-10-25 14:32:26 -04:00
|
|
|
(error 'bytevector-u32-native-ref "invalid index" i))
|
|
|
|
(error 'bytevector-u32-native-ref "not a bytevector" x))))
|
2007-09-13 01:44:10 -04:00
|
|
|
|
|
|
|
(define bytevector-s32-ref
|
|
|
|
(lambda (x i end)
|
|
|
|
(if (bytevector? x)
|
|
|
|
(if (and (fixnum? i)
|
|
|
|
($fx<= 0 i)
|
|
|
|
($fx< i ($fx- ($bytevector-length x) 3)))
|
|
|
|
(case end
|
|
|
|
[(big)
|
|
|
|
(+ (sll ($bytevector-s8-ref x i) 24)
|
|
|
|
($fxlogor
|
|
|
|
($fxsll ($bytevector-u8-ref x ($fx+ i 1)) 16)
|
|
|
|
($fxlogor
|
|
|
|
($fxsll ($bytevector-u8-ref x ($fx+ i 2)) 8)
|
|
|
|
($bytevector-u8-ref x ($fx+ i 3)))))]
|
|
|
|
[(little)
|
|
|
|
(+ (sll ($bytevector-s8-ref x ($fx+ i 3)) 24)
|
|
|
|
($fxlogor
|
|
|
|
($fxsll ($bytevector-u8-ref x ($fx+ i 2)) 16)
|
|
|
|
($fxlogor
|
|
|
|
($fxsll ($bytevector-u8-ref x ($fx+ i 1)) 8)
|
|
|
|
($bytevector-u8-ref x i))))]
|
2007-10-25 14:32:26 -04:00
|
|
|
[else (error 'bytevector-s32-ref "invalid endianness" end)])
|
|
|
|
(error 'bytevector-s32-ref "invalid index" i))
|
|
|
|
(error 'bytevector-s32-ref "not a bytevector" x))))
|
2007-09-13 01:44:10 -04:00
|
|
|
|
2007-09-13 01:57:36 -04:00
|
|
|
(define bytevector-s32-native-ref
|
|
|
|
(lambda (x i)
|
|
|
|
(if (bytevector? x)
|
|
|
|
(if (and (fixnum? i)
|
|
|
|
($fx<= 0 i)
|
|
|
|
($fx= 0 ($fxlogand i 3))
|
|
|
|
($fx< i ($fx- ($bytevector-length x) 3)))
|
|
|
|
(+ (sll ($bytevector-s8-ref x i) 24)
|
|
|
|
($fxlogor
|
|
|
|
($fxsll ($bytevector-u8-ref x ($fx+ i 1)) 16)
|
|
|
|
($fxlogor
|
|
|
|
($fxsll ($bytevector-u8-ref x ($fx+ i 2)) 8)
|
|
|
|
($bytevector-u8-ref x ($fx+ i 3)))))
|
2007-10-25 14:32:26 -04:00
|
|
|
(error 'bytevector-s32-native-ref "invalid index" i))
|
|
|
|
(error 'bytevector-s32-native-ref "not a bytevector" x))))
|
2007-09-13 01:57:36 -04:00
|
|
|
|
2007-09-10 14:47:29 -04:00
|
|
|
(define bytevector-u16-set!
|
|
|
|
(lambda (x i n end)
|
|
|
|
(if (bytevector? x)
|
|
|
|
(if (and (fixnum? n)
|
|
|
|
($fx<= 0 n)
|
|
|
|
($fx<= n #xFFFF))
|
|
|
|
(if (and (fixnum? i)
|
|
|
|
($fx<= 0 i)
|
|
|
|
($fx< i ($fxsub1 ($bytevector-length x))))
|
|
|
|
(case end
|
|
|
|
[(big)
|
|
|
|
($bytevector-set! x i ($fxsra n 8))
|
|
|
|
($bytevector-set! x ($fxadd1 i) n)]
|
|
|
|
[(little)
|
|
|
|
($bytevector-set! x i n)
|
|
|
|
($bytevector-set! x ($fxadd1 i) (fxsra n 8))]
|
2007-10-25 14:32:26 -04:00
|
|
|
[else (error 'bytevector-u16-ref "invalid endianness" end)])
|
|
|
|
(error 'bytevector-u16-set! "invalid index" i))
|
|
|
|
(error 'bytevector-u16-set! "invalid value" n))
|
|
|
|
(error 'bytevector-u16-set! "not a bytevector" x))))
|
2007-09-10 14:24:35 -04:00
|
|
|
|
2007-09-12 16:59:21 -04:00
|
|
|
|
|
|
|
(define bytevector-u32-set!
|
|
|
|
(lambda (x i n end)
|
|
|
|
(if (bytevector? x)
|
2007-09-13 01:44:10 -04:00
|
|
|
(if (if (fixnum? n)
|
|
|
|
($fx>= n 0)
|
|
|
|
(if (bignum? n)
|
|
|
|
(<= 0 n #xFFFFFFFF)
|
|
|
|
#f))
|
2007-09-12 16:59:21 -04:00
|
|
|
(if (and (fixnum? i)
|
|
|
|
($fx<= 0 i)
|
|
|
|
($fx< i ($fx- ($bytevector-length x) 3)))
|
|
|
|
(case end
|
|
|
|
[(big)
|
2007-09-13 01:44:10 -04:00
|
|
|
(let ([b (sra n 16)])
|
|
|
|
($bytevector-set! x i ($fxsra b 8))
|
|
|
|
($bytevector-set! x ($fx+ i 1) b))
|
|
|
|
(let ([b (logand n #xFFFF)])
|
|
|
|
($bytevector-set! x ($fx+ i 2) ($fxsra b 8))
|
|
|
|
($bytevector-set! x ($fx+ i 3) b))]
|
2007-09-12 16:59:21 -04:00
|
|
|
[(little)
|
2007-09-13 01:44:10 -04:00
|
|
|
(let ([b (sra n 16)])
|
|
|
|
($bytevector-set! x ($fx+ i 3) ($fxsra b 8))
|
|
|
|
($bytevector-set! x ($fx+ i 2) b))
|
|
|
|
(let ([b (logand n #xFFFF)])
|
|
|
|
($bytevector-set! x ($fx+ i 1) ($fxsra b 8))
|
|
|
|
($bytevector-set! x i b))]
|
2007-10-25 14:32:26 -04:00
|
|
|
[else (error 'bytevector-u32-ref "invalid endianness" end)])
|
|
|
|
(error 'bytevector-u32-set! "invalid index" i))
|
|
|
|
(error 'bytevector-u32-set! "invalid value" n))
|
|
|
|
(error 'bytevector-u32-set! "not a bytevector" x))))
|
2007-09-13 01:44:10 -04:00
|
|
|
|
2007-09-13 01:57:36 -04:00
|
|
|
(define bytevector-u32-native-set!
|
|
|
|
(lambda (x i n)
|
|
|
|
(if (bytevector? x)
|
|
|
|
(if (if (fixnum? n)
|
|
|
|
($fx>= n 0)
|
|
|
|
(if (bignum? n)
|
|
|
|
(<= 0 n #xFFFFFFFF)
|
|
|
|
#f))
|
|
|
|
(if (and (fixnum? i)
|
|
|
|
($fx<= 0 i)
|
|
|
|
($fx= 0 ($fxlogand i 3))
|
|
|
|
($fx< i ($fx- ($bytevector-length x) 3)))
|
|
|
|
(begin
|
|
|
|
(let ([b (sra n 16)])
|
|
|
|
($bytevector-set! x i ($fxsra b 8))
|
|
|
|
($bytevector-set! x ($fx+ i 1) b))
|
|
|
|
(let ([b (logand n #xFFFF)])
|
|
|
|
($bytevector-set! x ($fx+ i 2) ($fxsra b 8))
|
|
|
|
($bytevector-set! x ($fx+ i 3) b)))
|
2007-10-25 14:32:26 -04:00
|
|
|
(error 'bytevector-u32-native-set! "invalid index" i))
|
|
|
|
(error 'bytevector-u32-native-set! "invalid value" n))
|
|
|
|
(error 'bytevector-u32-native-set! "not a bytevector" x))))
|
2007-09-13 01:57:36 -04:00
|
|
|
|
|
|
|
|
|
|
|
(define bytevector-s32-native-set!
|
|
|
|
(lambda (x i n)
|
|
|
|
(if (bytevector? x)
|
|
|
|
(if (if (fixnum? n)
|
|
|
|
#t
|
|
|
|
(if (bignum? n)
|
|
|
|
(<= #x-80000000 n #x7FFFFFFF)
|
|
|
|
#f))
|
|
|
|
(if (and (fixnum? i)
|
|
|
|
($fx<= 0 i)
|
|
|
|
($fx= 0 ($fxlogand i 3))
|
|
|
|
($fx< i ($fx- ($bytevector-length x) 3)))
|
|
|
|
(begin
|
|
|
|
(let ([b (sra n 16)])
|
|
|
|
($bytevector-set! x i ($fxsra b 8))
|
|
|
|
($bytevector-set! x ($fx+ i 1) b))
|
|
|
|
(let ([b (logand n #xFFFF)])
|
|
|
|
($bytevector-set! x ($fx+ i 2) ($fxsra b 8))
|
|
|
|
($bytevector-set! x ($fx+ i 3) b)))
|
2007-10-25 14:32:26 -04:00
|
|
|
(error 'bytevector-s32-native-set! "invalid index" i))
|
|
|
|
(error 'bytevector-s32-native-set! "invalid value" n))
|
|
|
|
(error 'bytevector-s32-native-set! "not a bytevector" x))))
|
2007-09-13 01:44:10 -04:00
|
|
|
|
|
|
|
(define bytevector-s32-set!
|
|
|
|
(lambda (x i n end)
|
|
|
|
(if (bytevector? x)
|
|
|
|
(if (if (fixnum? n)
|
|
|
|
#t
|
|
|
|
(if (bignum? n)
|
|
|
|
(<= #x-80000000 n #x7FFFFFFF)
|
|
|
|
#f))
|
|
|
|
(if (and (fixnum? i)
|
|
|
|
($fx<= 0 i)
|
|
|
|
($fx< i ($fx- ($bytevector-length x) 3)))
|
|
|
|
(case end
|
|
|
|
[(big)
|
|
|
|
(let ([b (sra n 16)])
|
|
|
|
($bytevector-set! x i ($fxsra b 8))
|
|
|
|
($bytevector-set! x ($fx+ i 1) b))
|
|
|
|
(let ([b (logand n #xFFFF)])
|
|
|
|
($bytevector-set! x ($fx+ i 2) ($fxsra b 8))
|
|
|
|
($bytevector-set! x ($fx+ i 3) b))]
|
|
|
|
[(little)
|
|
|
|
(let ([b (sra n 16)])
|
|
|
|
($bytevector-set! x ($fx+ i 3) ($fxsra b 8))
|
|
|
|
($bytevector-set! x ($fx+ i 2) b))
|
|
|
|
(let ([b (logand n #xFFFF)])
|
|
|
|
($bytevector-set! x ($fx+ i 1) ($fxsra b 8))
|
|
|
|
($bytevector-set! x i b))]
|
2007-10-25 14:32:26 -04:00
|
|
|
[else (error 'bytevector-s32-ref "invalid endianness" end)])
|
|
|
|
(error 'bytevector-s32-set! "invalid index" i))
|
|
|
|
(error 'bytevector-s32-set! "invalid value" n))
|
|
|
|
(error 'bytevector-s32-set! "not a bytevector" x))))
|
2007-09-12 16:59:21 -04:00
|
|
|
|
2007-09-10 14:24:35 -04:00
|
|
|
(define bytevector-s16-ref
|
|
|
|
(lambda (x i end)
|
|
|
|
(if (bytevector? x)
|
|
|
|
(if (and (fixnum? i)
|
|
|
|
($fx<= 0 i)
|
|
|
|
($fx< i ($fxsub1 ($bytevector-length x))))
|
|
|
|
(case end
|
|
|
|
[(big)
|
|
|
|
($fxlogor
|
|
|
|
($fxsll ($bytevector-s8-ref x i) 8)
|
|
|
|
($bytevector-u8-ref x ($fxadd1 i)))]
|
|
|
|
[(little)
|
|
|
|
($fxlogor
|
|
|
|
($fxsll ($bytevector-s8-ref x (fxadd1 i)) 8)
|
|
|
|
($bytevector-u8-ref x i))]
|
2007-10-25 14:32:26 -04:00
|
|
|
[else (error 'bytevector-s16-ref "invalid endianness" end)])
|
|
|
|
(error 'bytevector-s16-ref "invalid index" i))
|
|
|
|
(error 'bytevector-s16-ref "not a bytevector" x))))
|
2007-09-10 14:24:35 -04:00
|
|
|
|
2007-09-10 14:58:37 -04:00
|
|
|
|
|
|
|
(define bytevector-s16-set!
|
|
|
|
(lambda (x i n end)
|
|
|
|
(if (bytevector? x)
|
|
|
|
(if (and (fixnum? n)
|
|
|
|
($fx<= #x-8000 n)
|
|
|
|
($fx<= n #x7FFF))
|
|
|
|
(if (and (fixnum? i)
|
|
|
|
($fx<= 0 i)
|
|
|
|
($fx< i ($fxsub1 ($bytevector-length x))))
|
|
|
|
(case end
|
|
|
|
[(big)
|
|
|
|
($bytevector-set! x i ($fxsra n 8))
|
|
|
|
($bytevector-set! x ($fxadd1 i) n)]
|
|
|
|
[(little)
|
|
|
|
($bytevector-set! x i n)
|
|
|
|
($bytevector-set! x ($fxadd1 i) (fxsra n 8))]
|
2007-10-25 14:32:26 -04:00
|
|
|
[else (error 'bytevector-s16-ref "invalid endianness" end)])
|
|
|
|
(error 'bytevector-s16-set! "invalid index" i))
|
|
|
|
(error 'bytevector-s16-set! "invalid value" n))
|
|
|
|
(error 'bytevector-s16-set! "not a bytevector" x))))
|
2007-09-10 14:58:37 -04:00
|
|
|
|
2007-09-12 16:59:21 -04:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2007-05-15 14:27:31 -04:00
|
|
|
(define bytevector->u8-list
|
|
|
|
(lambda (x)
|
|
|
|
(unless (bytevector? x)
|
2007-10-25 14:32:26 -04:00
|
|
|
(error 'bytevector->u8-list "not a bytevector" x))
|
2007-05-15 14:27:31 -04:00
|
|
|
(let f ([x x] [i ($bytevector-length x)] [ac '()])
|
|
|
|
(cond
|
|
|
|
[($fx= i 0) ac]
|
|
|
|
[else
|
|
|
|
(let ([i ($fxsub1 i)])
|
|
|
|
(f x i (cons ($bytevector-u8-ref x i) ac)))]))))
|
|
|
|
|
|
|
|
(define u8-list->bytevector
|
|
|
|
(letrec ([race
|
|
|
|
(lambda (h t ls n)
|
|
|
|
(if (pair? h)
|
|
|
|
(let ([h ($cdr h)])
|
|
|
|
(if (pair? h)
|
|
|
|
(if (not (eq? h t))
|
|
|
|
(race ($cdr h) ($cdr t) ls ($fx+ n 2))
|
2007-10-25 14:32:26 -04:00
|
|
|
(error 'u8-list->bytevector "circular list" ls))
|
2007-05-15 14:27:31 -04:00
|
|
|
(if (null? h)
|
|
|
|
($fx+ n 1)
|
2007-10-25 14:32:26 -04:00
|
|
|
(error 'u8-list->bytevector "not a proper list" ls))))
|
2007-05-15 14:27:31 -04:00
|
|
|
(if (null? h)
|
|
|
|
n
|
2007-10-25 14:32:26 -04:00
|
|
|
(error 'u8-list->bytevector "not a proper list" ls))))]
|
2007-05-15 14:27:31 -04:00
|
|
|
[fill
|
|
|
|
(lambda (s i ls)
|
|
|
|
(cond
|
|
|
|
[(null? ls) s]
|
|
|
|
[else
|
|
|
|
(let ([c ($car ls)])
|
|
|
|
(unless (and (fixnum? c) ($fx<= 0 c) ($fx<= c 255))
|
2007-10-25 14:32:26 -04:00
|
|
|
(error 'u8-list->bytevector "not an octet" c))
|
2007-05-15 14:27:31 -04:00
|
|
|
($bytevector-set! s i c)
|
|
|
|
(fill s ($fxadd1 i) (cdr ls)))]))])
|
|
|
|
(lambda (ls)
|
|
|
|
(let ([n (race ls ls ls 0)])
|
|
|
|
(let ([s ($make-bytevector n)])
|
|
|
|
(fill s 0 ls))))))
|
|
|
|
|
2007-05-15 14:33:50 -04:00
|
|
|
|
|
|
|
(define bytevector-copy
|
|
|
|
(lambda (src)
|
|
|
|
(unless (bytevector? src)
|
2007-10-25 14:32:26 -04:00
|
|
|
(error 'bytevector-copy "not a bytevector" src))
|
2007-05-15 14:33:50 -04:00
|
|
|
(let ([n ($bytevector-length src)])
|
|
|
|
(let f ([src src] [dst ($make-bytevector n)] [i 0] [n n])
|
|
|
|
(cond
|
|
|
|
[($fx= i n) dst]
|
|
|
|
[else
|
|
|
|
($bytevector-set! dst i ($bytevector-u8-ref src i))
|
|
|
|
(f src dst ($fxadd1 i) n)])))))
|
|
|
|
|
2007-05-15 14:37:04 -04:00
|
|
|
(define bytevector=?
|
|
|
|
(lambda (x y)
|
|
|
|
(unless (bytevector? x)
|
2007-10-25 14:32:26 -04:00
|
|
|
(error 'bytevector=? "not a bytevector" x))
|
2007-05-15 14:37:04 -04:00
|
|
|
(unless (bytevector? y)
|
2007-10-25 14:32:26 -04:00
|
|
|
(error 'bytevector=? "not a bytevector" y))
|
2007-05-15 14:37:04 -04:00
|
|
|
(let ([n ($bytevector-length x)])
|
|
|
|
(and ($fx= n ($bytevector-length y))
|
|
|
|
(let f ([x x] [y y] [i 0] [n n])
|
|
|
|
(or ($fx= i n)
|
|
|
|
(and ($fx= ($bytevector-u8-ref x i)
|
|
|
|
($bytevector-u8-ref y i))
|
|
|
|
(f x y ($fxadd1 i) n))))))))
|
2007-05-15 14:33:50 -04:00
|
|
|
|
2007-05-15 14:27:31 -04:00
|
|
|
(define bytevector-copy!
|
|
|
|
(lambda (src src-start dst dst-start k)
|
|
|
|
(cond
|
|
|
|
[(or (not (fixnum? src-start)) ($fx< src-start 0))
|
2007-10-25 14:32:26 -04:00
|
|
|
(error 'bytevector-copy! "not a valid starting index" src-start)]
|
2007-05-15 14:27:31 -04:00
|
|
|
[(or (not (fixnum? dst-start)) ($fx< dst-start 0))
|
2007-10-25 14:32:26 -04:00
|
|
|
(error 'bytevector-copy! "not a valid starting index" dst-start)]
|
2007-05-15 14:27:31 -04:00
|
|
|
[(or (not (fixnum? k)) ($fx< k 0))
|
2007-10-25 14:32:26 -04:00
|
|
|
(error 'bytevector-copy! "not a valid length" k)]
|
2007-05-15 14:27:31 -04:00
|
|
|
[(not (bytevector? src))
|
2007-10-25 14:32:26 -04:00
|
|
|
(error 'bytevector-copy! "not a bytevector" src)]
|
2007-05-15 14:27:31 -04:00
|
|
|
[(not (bytevector? dst))
|
2007-10-25 14:32:26 -04:00
|
|
|
(error 'bytevector-copy! "not a bytevector" dst)]
|
2007-05-15 14:27:31 -04:00
|
|
|
[(let ([n ($fx+ src-start k)])
|
|
|
|
(or ($fx< n 0) ($fx>= n ($bytevector-length src))))
|
2007-10-25 14:32:26 -04:00
|
|
|
(error 'bytevector-copy! "out of range" src-start k)]
|
2007-05-15 14:27:31 -04:00
|
|
|
[(let ([n ($fx+ dst-start k)])
|
|
|
|
(or ($fx< n 0) ($fx>= n ($bytevector-length dst))))
|
2007-10-25 14:32:26 -04:00
|
|
|
(error 'bytevector-copy! "out of range" dst-start k)]
|
2007-05-15 14:27:31 -04:00
|
|
|
[(eq? src dst)
|
|
|
|
(cond
|
|
|
|
[($fx< dst-start src-start)
|
|
|
|
(let f ([src src] [si src-start] [di dst-start] [sj ($fx+ src-start k)])
|
|
|
|
(unless ($fx= si sj)
|
|
|
|
($bytevector-set! src di ($bytevector-u8-ref src si))
|
|
|
|
(f src ($fxadd1 si) ($fxadd1 di) sj)))]
|
|
|
|
[($fx< src-start dst-start)
|
|
|
|
(let f ([src src] [si ($fx+ src-start k)] [di ($fx+ dst-start k)] [sj src-start])
|
|
|
|
(unless ($fx= si sj)
|
|
|
|
(let ([si ($fxsub1 si)] [di ($fxsub1 di)])
|
|
|
|
($bytevector-set! src di ($bytevector-u8-ref src si))
|
|
|
|
(f src si di sj))))]
|
|
|
|
[else (void)])]
|
|
|
|
[else
|
|
|
|
(let f ([src src] [si src-start] [dst dst] [di dst-start] [sj ($fx+ src-start k)])
|
|
|
|
(unless ($fx= si sj)
|
|
|
|
($bytevector-set! dst di ($bytevector-u8-ref src si))
|
|
|
|
(f src ($fxadd1 si) dst ($fxadd1 di) sj)))])))
|
|
|
|
|
2007-05-15 19:27:36 -04:00
|
|
|
(module (bytevector-uint-ref bytevector-sint-ref
|
|
|
|
bytevector->uint-list bytevector->sint-list)
|
|
|
|
(define (uref-big x ib il) ;; ib included, il excluded
|
|
|
|
(cond
|
|
|
|
[($fx= il ib) 0]
|
|
|
|
[else
|
|
|
|
(let ([b ($bytevector-u8-ref x ib)])
|
|
|
|
(cond
|
|
|
|
[($fx= b 0) (uref-big x ($fxadd1 ib) il)]
|
|
|
|
[else
|
|
|
|
(case ($fx- il ib)
|
|
|
|
[(1) b]
|
|
|
|
[(2) ($fx+ ($fxsll b 8)
|
|
|
|
($bytevector-u8-ref x ($fxsub1 il)))]
|
|
|
|
[(3)
|
|
|
|
($fx+ ($fxsll ($fx+ ($fxsll b 8)
|
|
|
|
($bytevector-u8-ref x ($fxadd1 ib)))
|
|
|
|
8)
|
|
|
|
($bytevector-u8-ref x ($fxsub1 il)))]
|
|
|
|
[else
|
|
|
|
(let ([im ($fxsra ($fx+ il ib) 1)])
|
|
|
|
(+ (uref-big x im il)
|
|
|
|
(* (uref-big x ib im)
|
|
|
|
(expt 256 ($fx- il im)))))])]))]))
|
|
|
|
(define (uref-little x il ib) ;; il included, ib excluded
|
|
|
|
(cond
|
|
|
|
[($fx= il ib) 0]
|
|
|
|
[else
|
|
|
|
(let ([ib^ ($fxsub1 ib)])
|
|
|
|
(let ([b ($bytevector-u8-ref x ib^)])
|
|
|
|
(cond
|
|
|
|
[($fx= b 0) (uref-little x il ib^)]
|
|
|
|
[else
|
|
|
|
(case ($fx- ib il)
|
|
|
|
[(1) b]
|
|
|
|
[(2) ($fx+ ($fxsll b 8) ($bytevector-u8-ref x il))]
|
|
|
|
[(3)
|
|
|
|
($fx+ ($fxsll ($fx+ ($fxsll b 8)
|
|
|
|
($bytevector-u8-ref x ($fxadd1 il)))
|
|
|
|
8)
|
|
|
|
($bytevector-u8-ref x il))]
|
|
|
|
[else
|
|
|
|
(let ([im ($fxsra ($fx+ il ib) 1)])
|
|
|
|
(+ (uref-little x il im)
|
|
|
|
(* (uref-little x im ib)
|
|
|
|
(expt 256 ($fx- im il)))))])])))]))
|
|
|
|
(define (sref-big x ib il) ;; ib included, il excluded
|
|
|
|
(cond
|
|
|
|
[($fx= il ib) -1]
|
|
|
|
[else
|
|
|
|
(let ([b ($bytevector-u8-ref x ib)])
|
|
|
|
(cond
|
|
|
|
[($fx= b 0) (uref-big x ($fxadd1 ib) il)]
|
|
|
|
[($fx= b 255) (sref-big-neg x ($fxadd1 ib) il)]
|
|
|
|
[($fx< b 128) (uref-big x ib il)]
|
|
|
|
[else (- (uref-big x ib il) (expt 256 ($fx- il ib)))]))]))
|
|
|
|
(define (sref-big-neg x ib il) ;; ib included, il excluded
|
|
|
|
(cond
|
|
|
|
[($fx= il ib) -1]
|
|
|
|
[else
|
|
|
|
(let ([b ($bytevector-u8-ref x ib)])
|
|
|
|
(cond
|
|
|
|
[($fx= b 255) (sref-big-neg x ($fxadd1 ib) il)]
|
|
|
|
[else (- (uref-big x ib il) (expt 256 ($fx- il ib)))]))]))
|
|
|
|
(define (sref-little x il ib) ;; il included, ib excluded
|
|
|
|
(cond
|
|
|
|
[($fx= il ib) -1]
|
|
|
|
[else
|
|
|
|
(let ([ib^ ($fxsub1 ib)])
|
|
|
|
(let ([b ($bytevector-u8-ref x ib^)])
|
|
|
|
(cond
|
|
|
|
[($fx= b 0) (uref-little x il ib^)]
|
|
|
|
[($fx= b 255) (sref-little-neg x il ib^)]
|
|
|
|
[($fx< b 128) (uref-little x il ib)]
|
|
|
|
[else (- (uref-little x il ib) (expt 256 ($fx- ib il)))])))]))
|
|
|
|
(define (sref-little-neg x il ib) ;; il included, ib excluded
|
|
|
|
(cond
|
|
|
|
[($fx= il ib) -1]
|
|
|
|
[else
|
|
|
|
(let ([ib^ ($fxsub1 ib)])
|
|
|
|
(let ([b ($bytevector-u8-ref x ib^)])
|
|
|
|
(cond
|
|
|
|
[($fx= b 255) (sref-little-neg x il ib^)]
|
|
|
|
[else (- (uref-little x il ib) (expt 256 ($fx- ib il)))])))]))
|
|
|
|
(define bytevector-sint-ref
|
|
|
|
(lambda (x k endianness size)
|
|
|
|
(define who 'bytevector-sint-ref)
|
2007-10-25 14:32:26 -04:00
|
|
|
(unless (bytevector? x) (error who "not a bytevector" x))
|
|
|
|
(unless (and (fixnum? k) ($fx>= k 0)) (error who "invalid index" k))
|
|
|
|
(unless (and (fixnum? size) ($fx>= size 1)) (error who "invalid size" size))
|
2007-05-15 19:27:36 -04:00
|
|
|
(let ([n ($bytevector-length x)])
|
2007-10-25 14:32:26 -04:00
|
|
|
(unless ($fx< k n) (error who "index is out of range" k))
|
2007-05-15 19:27:36 -04:00
|
|
|
(let ([end ($fx+ k size)])
|
|
|
|
(unless (and ($fx>= end 0) ($fx<= end n))
|
2007-10-25 14:32:26 -04:00
|
|
|
(error who "out of range" k size))
|
2007-05-15 19:27:36 -04:00
|
|
|
(case endianness
|
|
|
|
[(little) (sref-little x k end)]
|
|
|
|
[(big) (sref-big x k end)]
|
2007-10-25 14:32:26 -04:00
|
|
|
[else (error who "invalid endianness" endianness)])))))
|
2007-05-15 19:27:36 -04:00
|
|
|
(define bytevector-uint-ref
|
|
|
|
(lambda (x k endianness size)
|
|
|
|
(define who 'bytevector-uint-ref)
|
2007-10-25 14:32:26 -04:00
|
|
|
(unless (bytevector? x) (error who "not a bytevector" x))
|
|
|
|
(unless (and (fixnum? k) ($fx>= k 0)) (error who "invalid index" k))
|
|
|
|
(unless (and (fixnum? size) ($fx>= size 1)) (error who "invalid size" size))
|
2007-05-15 19:27:36 -04:00
|
|
|
(let ([n ($bytevector-length x)])
|
2007-10-25 14:32:26 -04:00
|
|
|
(unless ($fx< k n) (error who "index is out of range" k))
|
2007-05-15 19:27:36 -04:00
|
|
|
(let ([end ($fx+ k size)])
|
|
|
|
(unless (and ($fx>= end 0) ($fx<= end n))
|
2007-10-25 14:32:26 -04:00
|
|
|
(error who "out of range" k size))
|
2007-05-15 19:27:36 -04:00
|
|
|
(case endianness
|
|
|
|
[(little) (uref-little x k end)]
|
|
|
|
[(big) (uref-big x k end)]
|
2007-10-25 14:32:26 -04:00
|
|
|
[else (error who "invalid endianness" endianness)])))))
|
2007-05-15 19:27:36 -04:00
|
|
|
(define (bytevector->some-list x k n ls proc who)
|
|
|
|
(cond
|
|
|
|
[($fx= n 0) ls]
|
|
|
|
[else
|
|
|
|
(let ([i ($fx- n k)])
|
|
|
|
(cond
|
|
|
|
[($fx>= i 0)
|
|
|
|
(bytevector->some-list x k i (cons (proc x i n) ls) proc who)]
|
|
|
|
[else
|
2007-10-25 14:32:26 -04:00
|
|
|
(error who "invalid size" k)]))]))
|
2007-05-15 19:27:36 -04:00
|
|
|
(define bytevector->uint-list
|
|
|
|
(lambda (x endianness size)
|
|
|
|
(define who 'bytevector->uint-list)
|
2007-10-25 14:32:26 -04:00
|
|
|
(unless (bytevector? x) (error who "not a bytevector" x))
|
|
|
|
(unless (and (fixnum? size) ($fx>= size 1)) (error who "invalid size" size))
|
2007-05-15 19:27:36 -04:00
|
|
|
(case endianness
|
|
|
|
[(little) (bytevector->some-list x size ($bytevector-length x)
|
|
|
|
'() uref-little 'bytevector->uint-list)]
|
|
|
|
[(big) (bytevector->some-list x size ($bytevector-length x)
|
|
|
|
'() uref-big 'bytevector->uint-list)]
|
2007-10-25 14:32:26 -04:00
|
|
|
[else (error who "invalid endianness" endianness)])))
|
2007-05-15 19:27:36 -04:00
|
|
|
(define bytevector->sint-list
|
|
|
|
(lambda (x endianness size)
|
|
|
|
(define who 'bytevector->sint-list)
|
2007-10-25 14:32:26 -04:00
|
|
|
(unless (bytevector? x) (error who "not a bytevector" x))
|
|
|
|
(unless (and (fixnum? size) ($fx>= size 1)) (error who "invalid size" size))
|
2007-05-15 19:27:36 -04:00
|
|
|
(case endianness
|
|
|
|
[(little) (bytevector->some-list x size ($bytevector-length x)
|
|
|
|
'() sref-little 'bytevector->sint-list)]
|
|
|
|
[(big) (bytevector->some-list x size ($bytevector-length x)
|
|
|
|
'() sref-big 'bytevector->sint-list)]
|
2007-10-25 14:32:26 -04:00
|
|
|
[else (error who "invalid endianness" endianness)]))))
|
2007-05-15 20:19:24 -04:00
|
|
|
|
2007-05-16 11:05:06 -04:00
|
|
|
(module (bytevector-uint-set! bytevector-sint-set!)
|
|
|
|
(define (lufx-set! x k1 n k2 who no)
|
2007-05-15 20:19:24 -04:00
|
|
|
(cond
|
2007-05-16 11:05:06 -04:00
|
|
|
[($fx= k1 k2)
|
|
|
|
(unless ($fxzero? n)
|
2007-10-25 14:32:26 -04:00
|
|
|
(error who "number does not fit" no))]
|
2007-05-15 20:19:24 -04:00
|
|
|
[else
|
2007-05-16 11:05:06 -04:00
|
|
|
(lufx-set! x ($fxadd1 k1) ($fxsra n 8) k2 who no)
|
|
|
|
($bytevector-set! x k1 ($fxlogand n 255))]))
|
|
|
|
(define (lsfx-set! x k1 n k2 who no)
|
2007-05-15 20:19:24 -04:00
|
|
|
(cond
|
2007-05-16 11:05:06 -04:00
|
|
|
[($fx= k1 k2)
|
|
|
|
(unless ($fx= n -1) ;;; BUG: does not catch all errors
|
2007-10-25 14:32:26 -04:00
|
|
|
(error who "number does not fit" no))]
|
2007-05-15 20:19:24 -04:00
|
|
|
[else
|
2007-05-16 11:05:06 -04:00
|
|
|
(lsfx-set! x ($fxadd1 k1) ($fxsra n 8) k2 who no)
|
|
|
|
($bytevector-set! x k1 ($fxlogand n 255))]))
|
|
|
|
(define (bufx-set! x k1 n k2 who no)
|
|
|
|
(cond
|
|
|
|
[($fx= k1 k2)
|
|
|
|
(unless ($fxzero? n)
|
2007-10-25 14:32:26 -04:00
|
|
|
(error who "number does not fit" no))]
|
2007-05-16 11:05:06 -04:00
|
|
|
[else
|
|
|
|
(let ([k2 ($fxsub1 k2)])
|
|
|
|
(bufx-set! x k1 ($fxsra n 8) k2 who no)
|
|
|
|
($bytevector-set! x k2 ($fxlogand n 255)))]))
|
|
|
|
(define (bsfx-set! x k1 n k2 who no)
|
|
|
|
(cond
|
|
|
|
[($fx= k1 k2)
|
|
|
|
(unless ($fx= n -1)
|
2007-10-25 14:32:26 -04:00
|
|
|
(error who "number does not fit" no))]
|
2007-05-16 11:05:06 -04:00
|
|
|
[else
|
|
|
|
(let ([k2 ($fxsub1 k2)])
|
|
|
|
(bsfx-set! x k1 ($fxsra n 8) k2 who no)
|
|
|
|
($bytevector-set! x k2 ($fxlogand n 255)))]))
|
|
|
|
(define (lbn-copy! x k n i j)
|
|
|
|
(unless ($fx= i j)
|
|
|
|
($bytevector-set! x k ($bignum-byte-ref n i))
|
|
|
|
(lbn-copy! x ($fxadd1 k) n ($fxadd1 i) j)))
|
|
|
|
(define (bbn-copy! x k n i j)
|
|
|
|
(unless ($fx= i j)
|
|
|
|
(let ([k ($fxsub1 k)])
|
|
|
|
($bytevector-set! x k ($bignum-byte-ref n i))
|
|
|
|
(bbn-copy! x k n ($fxadd1 i) j))))
|
|
|
|
(define (bv-zero! x i j)
|
|
|
|
(unless ($fx= i j)
|
|
|
|
($bytevector-set! x i 0)
|
|
|
|
(bv-zero! x ($fxadd1 i) j)))
|
2007-05-17 03:36:28 -04:00
|
|
|
(define (make-lbn-neg-copy! who)
|
|
|
|
(define (lbn-neg-copy! x xi n ni xj nj c)
|
|
|
|
(cond
|
|
|
|
[($fx= ni nj)
|
|
|
|
(case ($fxsra c 7)
|
|
|
|
[(#x01) ;;; borrow is 0, last byte was negative
|
|
|
|
(bv-neg-zero! x xi xj)]
|
|
|
|
[(#x00) ;;; borrow is 0, last byte was positive
|
|
|
|
(if ($fx< xi xj)
|
|
|
|
(bv-neg-zero! x xi xj)
|
2007-10-25 14:32:26 -04:00
|
|
|
(error who "number does not fit" n))]
|
|
|
|
[else (error 'lbn-neg-copy! "BUG: not handled" c)])]
|
2007-05-17 03:36:28 -04:00
|
|
|
[else
|
|
|
|
(let ([c ($fx- ($fx+ 255 ($fxsra c 8)) ($bignum-byte-ref n ni))])
|
|
|
|
(lbn-neg-copy! x ($fxadd1 xi) n ($fxadd1 ni) xj nj c)
|
|
|
|
($bytevector-set! x xi ($fxlogand c 255)))]))
|
|
|
|
lbn-neg-copy!)
|
|
|
|
(define (make-bbn-neg-copy! who)
|
|
|
|
(define (bbn-neg-copy! x xi n ni xj nj c)
|
|
|
|
(cond
|
|
|
|
[($fx= ni nj)
|
|
|
|
(case ($fxsra c 7)
|
|
|
|
[(#x01) ;;; borrow is 0, last byte was negative
|
|
|
|
(bv-neg-zero! x xi xj)]
|
|
|
|
[(#x00) ;;; borrow is 0, last byte was positive
|
|
|
|
(if ($fx< xi xj)
|
|
|
|
(bv-neg-zero! x xi xj)
|
2007-10-25 14:32:26 -04:00
|
|
|
(error who "number does not fit" n))]
|
|
|
|
[else (error 'bbn-neg-copy! "BUG: not handled" c)])]
|
2007-05-17 03:36:28 -04:00
|
|
|
[else
|
|
|
|
(let ([c ($fx- ($fx+ 255 ($fxsra c 8)) ($bignum-byte-ref n ni))]
|
|
|
|
[xj ($fxsub1 xj)])
|
|
|
|
(bbn-neg-copy! x xi n ($fxadd1 ni) xj nj c)
|
|
|
|
($bytevector-set! x xj ($fxlogand c 255)))]))
|
|
|
|
bbn-neg-copy!)
|
|
|
|
(define (make-lbn-pos-copy! who)
|
|
|
|
(define (lbn-pos-copy! x xi n ni nj xj c)
|
|
|
|
(cond
|
|
|
|
[($fx= ni nj)
|
|
|
|
(cond
|
|
|
|
[(or ($fx<= c 127) ($fx< xi xj))
|
|
|
|
;;; last byte was positive
|
|
|
|
(bv-zero! x xi xj)]
|
|
|
|
[else
|
2007-10-25 14:32:26 -04:00
|
|
|
(error who "number does not fit" n)])]
|
2007-05-17 03:36:28 -04:00
|
|
|
[else
|
|
|
|
(let ([c ($bignum-byte-ref n ni)])
|
|
|
|
(lbn-pos-copy! x ($fxadd1 xi) n ($fxadd1 ni) nj xj c)
|
|
|
|
($bytevector-set! x xi ($fxlogand c 255)))]))
|
|
|
|
lbn-pos-copy!)
|
|
|
|
(define (make-bbn-pos-copy! who)
|
|
|
|
(define (bbn-pos-copy! x xi n ni nj xj c)
|
|
|
|
(cond
|
|
|
|
[($fx= ni nj)
|
|
|
|
(cond
|
|
|
|
[(or ($fx<= c 127) ($fx< xi xj))
|
|
|
|
;;; last byte was positive
|
|
|
|
(bv-zero! x xi xj)]
|
|
|
|
[else
|
2007-10-25 14:32:26 -04:00
|
|
|
(error who "number does not fit" n)])]
|
2007-05-17 03:36:28 -04:00
|
|
|
[else
|
|
|
|
(let ([c ($bignum-byte-ref n ni)]
|
|
|
|
[xj ($fxsub1 xj)])
|
|
|
|
(bbn-pos-copy! x xi n ($fxadd1 ni) nj xj c)
|
|
|
|
($bytevector-set! x xj ($fxlogand c 255)))]))
|
|
|
|
bbn-pos-copy!)
|
2007-05-16 11:05:06 -04:00
|
|
|
(define (bv-neg-zero! x i j)
|
|
|
|
(unless ($fx= i j)
|
|
|
|
($bytevector-set! x i 255)
|
|
|
|
(bv-neg-zero! x ($fxadd1 i) j)))
|
|
|
|
(define (bignum-bytes n)
|
|
|
|
(let ([i ($bignum-size n)])
|
|
|
|
(let ([i-1 ($fxsub1 i)])
|
|
|
|
(if ($fxzero? ($bignum-byte-ref n i-1))
|
|
|
|
(let ([i-2 ($fxsub1 i-1)])
|
|
|
|
(if ($fxzero? ($bignum-byte-ref n i-2))
|
|
|
|
(let ([i-3 ($fxsub1 i-2)])
|
|
|
|
(if ($fxzero? ($bignum-byte-ref n i-3))
|
|
|
|
(let ([i-4 ($fxsub1 i-3)])
|
|
|
|
(if ($fxzero? ($bignum-byte-ref n i-4))
|
|
|
|
(error 'bignum-bytes "BUG: malformed bignum")
|
|
|
|
i-3))
|
|
|
|
i-2))
|
|
|
|
i-1))
|
|
|
|
i))))
|
2007-05-17 03:36:28 -04:00
|
|
|
(define (make-bytevector-uint-set! who)
|
2007-05-15 20:19:24 -04:00
|
|
|
(lambda (x k n endianness size)
|
2007-10-25 14:32:26 -04:00
|
|
|
(unless (bytevector? x) (error who "not a bytevector" x))
|
|
|
|
(unless (and (fixnum? k) ($fx>= k 0)) (error who "invalid index" k))
|
|
|
|
(unless (and (fixnum? size) ($fx>= size 1)) (error who "invalid size" size))
|
2007-05-15 20:19:24 -04:00
|
|
|
(case endianness
|
2007-05-16 11:05:06 -04:00
|
|
|
[(little)
|
|
|
|
(cond
|
|
|
|
[(fixnum? n) (lufx-set! x k n ($fx+ k size) who n)]
|
|
|
|
[(bignum? n)
|
|
|
|
(if ($bignum-positive? n)
|
|
|
|
(let ([sz (bignum-bytes n)])
|
|
|
|
(cond
|
|
|
|
[($fx= sz size)
|
|
|
|
(lbn-copy! x k n 0 sz)]
|
|
|
|
[($fx< sz size)
|
|
|
|
(lbn-copy! x k n 0 sz)
|
|
|
|
(bv-zero! x ($fx+ k sz) ($fx+ k size))]
|
2007-10-25 14:32:26 -04:00
|
|
|
[else (error who "number does not fit" n)]))
|
|
|
|
(error who "value must be positive" n))]
|
|
|
|
[else (error who "invalid value argument" n)])]
|
2007-05-16 11:05:06 -04:00
|
|
|
[(big)
|
|
|
|
(cond
|
|
|
|
[(fixnum? n) (bufx-set! x k n ($fx+ k size) who n)]
|
|
|
|
[(bignum? n)
|
|
|
|
(if ($bignum-positive? n)
|
|
|
|
(let ([sz (bignum-bytes n)])
|
|
|
|
(cond
|
|
|
|
[($fx<= sz size)
|
|
|
|
(bbn-copy! x ($fx+ k size) n 0 sz)]
|
|
|
|
[($fx< sz size)
|
|
|
|
(bbn-copy! x ($fx+ k size) n 0 sz)
|
|
|
|
(bv-zero! x k ($fx+ k ($fx- size sz)))]
|
2007-10-25 14:32:26 -04:00
|
|
|
[else (error who "number does not fit" n)]))
|
|
|
|
(error who "value must be positive" n))]
|
|
|
|
[else (error who "invalid value argument" n)])]
|
|
|
|
[else (error who "invalid endianness" endianness)])))
|
2007-05-17 03:36:28 -04:00
|
|
|
(define bytevector-uint-set! (make-bytevector-uint-set! 'bytevector-uint-set!))
|
|
|
|
(define (make-bytevector-sint-set! who)
|
|
|
|
(define bbn-neg-copy! (make-bbn-neg-copy! who))
|
|
|
|
(define bbn-pos-copy! (make-bbn-pos-copy! who))
|
|
|
|
(define lbn-neg-copy! (make-lbn-neg-copy! who))
|
|
|
|
(define lbn-pos-copy! (make-lbn-pos-copy! who))
|
2007-05-16 11:05:06 -04:00
|
|
|
(lambda (x k n endianness size)
|
2007-10-25 14:32:26 -04:00
|
|
|
(unless (bytevector? x) (error who "not a bytevector" x))
|
|
|
|
(unless (and (fixnum? k) ($fx>= k 0)) (error who "invalid index" k))
|
|
|
|
(unless (and (fixnum? size) ($fx>= size 1)) (error who "invalid size" size))
|
2007-05-16 11:05:06 -04:00
|
|
|
(case endianness
|
|
|
|
[(little)
|
|
|
|
(cond
|
|
|
|
[(fixnum? n) (lsfx-set! x k n ($fx+ k size) who n)]
|
|
|
|
[(bignum? n)
|
|
|
|
(if ($bignum-positive? n)
|
|
|
|
(let ([sz (bignum-bytes n)])
|
|
|
|
(cond
|
|
|
|
[($fx<= sz size)
|
|
|
|
(lbn-pos-copy! x k n 0 size sz 255)]
|
2007-10-25 14:32:26 -04:00
|
|
|
[else (error who "number does not fit" n)]))
|
2007-05-16 11:05:06 -04:00
|
|
|
(let ([sz (bignum-bytes n)])
|
|
|
|
(cond
|
|
|
|
[($fx<= sz size)
|
|
|
|
(lbn-neg-copy! x k n 0 size sz 256)]
|
2007-10-25 14:32:26 -04:00
|
|
|
[else (error who "number does not fit" n)])))]
|
|
|
|
[else (error who "invalid value argument" n)])]
|
2007-05-16 11:05:06 -04:00
|
|
|
[(big)
|
|
|
|
(cond
|
|
|
|
[(fixnum? n) (bsfx-set! x k n ($fx+ k size) who n)]
|
2007-05-17 03:03:10 -04:00
|
|
|
[(bignum? n)
|
|
|
|
(if ($bignum-positive? n)
|
|
|
|
(let ([sz (bignum-bytes n)])
|
|
|
|
(cond
|
|
|
|
[($fx<= sz size)
|
|
|
|
(bbn-pos-copy! x k n 0 size sz 255)]
|
2007-10-25 14:32:26 -04:00
|
|
|
[else (error who "number does not fit" n)]))
|
2007-05-17 03:03:10 -04:00
|
|
|
(let ([sz (bignum-bytes n)])
|
|
|
|
(cond
|
|
|
|
[($fx<= sz size)
|
|
|
|
(bbn-neg-copy! x k n 0 size sz 256)]
|
2007-10-25 14:32:26 -04:00
|
|
|
[else (error who "number does not fit" n)])))]
|
|
|
|
[else (error who "invalid value argument" n)])]
|
|
|
|
[else (error who "invalid endianness" endianness)])))
|
2007-05-17 03:36:28 -04:00
|
|
|
(define bytevector-sint-set! (make-bytevector-sint-set! 'bytevector-sint-set!)))
|
|
|
|
|
|
|
|
(module (uint-list->bytevector sint-list->bytevector)
|
|
|
|
(define (make-xint-list->bytevector who bv-set!)
|
|
|
|
(define (race h t ls idx endianness size)
|
|
|
|
(if (pair? h)
|
|
|
|
(let ([h ($cdr h)] [a ($car h)])
|
|
|
|
(if (pair? h)
|
|
|
|
(if (not (eq? h t))
|
|
|
|
(let ([bv (race ($cdr h) ($cdr t) ls
|
|
|
|
($fx+ idx ($fx+ size size))
|
|
|
|
endianness size)])
|
|
|
|
(bv-set! bv idx a endianness size)
|
|
|
|
(bv-set! bv ($fx+ idx size) ($car h) endianness size)
|
|
|
|
bv)
|
2007-10-25 14:32:26 -04:00
|
|
|
(error who "circular list" ls))
|
2007-05-17 03:36:28 -04:00
|
|
|
(if (null? h)
|
|
|
|
(let ([bv (make-bytevector ($fx+ idx size))])
|
|
|
|
(bv-set! bv idx a endianness size)
|
|
|
|
bv)
|
2007-10-25 14:32:26 -04:00
|
|
|
(error who "not a proper list" ls))))
|
2007-05-17 03:36:28 -04:00
|
|
|
(if (null? h)
|
|
|
|
(make-bytevector idx)
|
2007-10-25 14:32:26 -04:00
|
|
|
(error who "not a proper list" ls))))
|
2007-05-17 03:36:28 -04:00
|
|
|
(lambda (ls endianness size)
|
|
|
|
(race ls ls ls 0 endianness size)))
|
|
|
|
(define uint-list->bytevector
|
|
|
|
(make-xint-list->bytevector
|
|
|
|
'uint-list->bytevector bytevector-uint-set!))
|
|
|
|
(define sint-list->bytevector
|
|
|
|
(make-xint-list->bytevector
|
|
|
|
'sint-list->bytevector bytevector-sint-set!)))
|
|
|
|
|
2007-11-06 21:08:52 -05:00
|
|
|
(define (bytevector-ieee-double-native-ref bv i)
|
|
|
|
(if (bytevector? bv)
|
|
|
|
(if (and (fixnum? i)
|
|
|
|
($fx>= i 0)
|
|
|
|
($fxzero? ($fxlogand i 3))
|
|
|
|
($fx< i ($bytevector-length bv)))
|
|
|
|
($bytevector-ieee-double-native-ref bv i)
|
|
|
|
(error 'bytevector-ieee-double-native-ref "invalid index" i))
|
|
|
|
(error 'bytevector-ieee-double-native-ref "not a bytevector" bv)))
|
|
|
|
|
|
|
|
|
|
|
|
(define (bytevector-ieee-double-native-set! bv i x)
|
|
|
|
(if (bytevector? bv)
|
|
|
|
(if (and (fixnum? i)
|
|
|
|
($fx>= i 0)
|
|
|
|
($fxzero? ($fxlogand i 3))
|
|
|
|
($fx< i ($bytevector-length bv)))
|
|
|
|
(if (flonum? x)
|
|
|
|
($bytevector-ieee-double-native-set! bv i x)
|
2007-11-07 01:26:38 -05:00
|
|
|
(error 'bytevector-ieee-double-native-set! "not a flonum" x))
|
|
|
|
(error 'bytevector-ieee-double-native-set! "invalid index" i))
|
|
|
|
(error 'bytevector-ieee-double-native-set! "not a bytevector" bv)))
|
|
|
|
|
|
|
|
(define (bytevector-ieee-double-ref bv i endianness)
|
|
|
|
(if (bytevector? bv)
|
|
|
|
(if (and (fixnum? i)
|
|
|
|
($fx>= i 0)
|
|
|
|
($fxzero? ($fxlogand i 3))
|
|
|
|
($fx< i ($bytevector-length bv)))
|
|
|
|
(case endianness
|
|
|
|
[(little) ($bytevector-ieee-double-native-ref bv i)]
|
|
|
|
[(big) ($bytevector-ieee-double-nonnative-ref bv i)]
|
|
|
|
[else (error 'bytevector-ieee-double-ref
|
|
|
|
"invalid endianness" endianness)])
|
|
|
|
(error 'bytevector-ieee-double-ref "invalid index" i))
|
|
|
|
(error 'bytevector-ieee-double-ref "not a bytevector" bv)))
|
|
|
|
|
|
|
|
(define (bytevector-ieee-double-set! bv i x endianness)
|
|
|
|
(if (bytevector? bv)
|
|
|
|
(if (and (fixnum? i)
|
|
|
|
($fx>= i 0)
|
|
|
|
($fxzero? ($fxlogand i 3))
|
|
|
|
($fx< i ($bytevector-length bv)))
|
|
|
|
(if (flonum? x)
|
|
|
|
(case endianness
|
|
|
|
[(little) ($bytevector-ieee-double-native-set! bv i x)]
|
|
|
|
[(big) (error 'bytevector-ieee-double-set! "no big")]
|
|
|
|
[else (error 'bytevector-ieee-double-set!
|
|
|
|
"invalid endianness" endianness)])
|
|
|
|
(error 'bytevector-ieee-double-set! "not a flonum" x))
|
|
|
|
(error 'bytevector-ieee-double-set! "invalid index" i))
|
|
|
|
(error 'bytevector-ieee-double-set! "not a bytevector" bv)))
|
2007-11-06 21:08:52 -05:00
|
|
|
|
2007-05-15 13:50:00 -04:00
|
|
|
)
|
|
|
|
|
|
|
|
|