cs: fix integer->integer-bytes

Closes #2277
This commit is contained in:
Matthew Flatt 2018-10-04 19:20:34 -06:00
parent 4396b841c0
commit e94a519d44

View File

@ -81,42 +81,80 @@
(define/who integer->integer-bytes (define/who integer->integer-bytes
(case-lambda (case-lambda
[(num size signed? big-endian? bstr start) [(num size signed? big-endian? bstr start)
(check who bytes? bstr) (let ([check (lambda (n lo hi)
(case size (check who bytes? bstr)
[(2) (check who exact-nonnegative-integer? start)
(if signed? (let ([len (bytevector-length bstr)])
(bytevector-s16-set! bstr start num (if big-endian? (unless (>= len n)
(endianness big) (raise-arguments-error who
(endianness little))) "destination byte string is too small"
(bytevector-u16-set! bstr start num (if big-endian? "destination byte string length" len
(endianness big) "number of bytes to write" n))
(endianness little))))] (unless (<= start (- len n))
[(4) (raise-arguments-error who
(if signed? "starting position too large"
(bytevector-s32-set! bstr start num (if big-endian? "given starting position" start
(endianness big) "destination byte string length" len
(endianness little))) "number of bytes to write" n))
(bytevector-u32-set! bstr start num (if big-endian? (unless (<= lo num hi)
(endianness big) (raise-arguments-error who
(endianness little))))] "number is out of bounds for size in bytes"
[(8) "given number" num
(if signed? (if signed?
(bytevector-s64-set! bstr start num (if big-endian? "size in bytes for signed"
(endianness big) "size in bytes for unsigned")
(endianness little))) n))))])
(bytevector-u64-set! bstr start num (if big-endian? (case size
(endianness big) [(1)
(endianness little))))] (if signed?
[else (check 1 -128 127)
(raise-argument-error 'integer->integer-bytes (check 1 0 255))
"(or/c 2 4 8)" size)]) (if signed?
(bytevector-s8-set! bstr start num)
(bytevector-u8-set! bstr start num))]
[(2)
(if signed?
(check 2 -32768 32767)
(check 2 0 65535))
(if signed?
(bytevector-s16-set! bstr start num (if big-endian?
(endianness big)
(endianness little)))
(bytevector-u16-set! bstr start num (if big-endian?
(endianness big)
(endianness little))))]
[(4)
(if signed?
(check 4 -2147483648 2147483647)
(check 4 0 8589934591))
(if signed?
(bytevector-s32-set! bstr start num (if big-endian?
(endianness big)
(endianness little)))
(bytevector-u32-set! bstr start num (if big-endian?
(endianness big)
(endianness little))))]
[(8)
(if signed?
(check 8 -9223372036854775808 9223372036854775807)
(check 8 0 18446744073709551615))
(if signed?
(bytevector-s64-set! bstr start num (if big-endian?
(endianness big)
(endianness little)))
(bytevector-u64-set! bstr start num (if big-endian?
(endianness big)
(endianness little))))]
[else
(raise-argument-error 'integer->integer-bytes
"(or/c 1 2 4 8)" size)]))
bstr] bstr]
[(num size signed?) [(num size signed?)
(integer->integer-bytes num size signed? (system-big-endian?) (integer->integer-bytes num size signed? (system-big-endian?)
(and (exact-integer? size) (<= 2 size 8) (make-bytevector size)) 0)] (and (exact-integer? size) (<= 1 size 8) (make-bytevector size)) 0)]
[(num size signed? big-endian?) [(num size signed? big-endian?)
(integer->integer-bytes num size signed? big-endian? (integer->integer-bytes num size signed? big-endian?
(and (exact-integer? size) (<= 2 size 8) (make-bytevector size)) 0)] (and (exact-integer? size) (<= 1 size 8) (make-bytevector size)) 0)]
[(num size signed? big-endian? bstr) [(num size signed? big-endian? bstr)
(integer->integer-bytes num size signed? big-endian? bstr 0)])) (integer->integer-bytes num size signed? big-endian? bstr 0)]))