;;; Utility predicates (: pair-or-null? (* --> boolean)) (define (pair-or-null? x) (or (pair? x) (null? x))) (: u8? (* -> boolean)) (define (u8? obj) (and (exact-integer? obj) (<= 0 obj #xff))) (: char-ascii? (* -> boolean)) (define (char-ascii? obj) (and (char? obj) (char<=? obj #\delete))) ;;; Primitive bytestring comparison functions. (: %bytestring-prefix-length (u8vector u8vector -> fixnum)) (define (%bytestring-prefix-length bstring1 bstring2) (let ((end (min (bytevector-length bstring1) (bytevector-length bstring2)))) (if (eq? bstring1 bstring2) ; fast path end (let lp ((i 0)) (if (or (>= i end) (not (= (bytevector-u8-ref bstring1 i) (bytevector-u8-ref bstring2 i)))) i (lp (+ i 1))))))) (: %bytestring-compare (u8vector u8vector * * * -> *)) (define (%bytestring-compare bstring1 bstring2 res< res= res>) (let ((len1 (bytevector-length bstring1)) (len2 (bytevector-length bstring2))) (let ((match (%bytestring-prefix-length bstring1 bstring2))) (if (= match len1) (if (= match len2) res= res<) (if (= match len2) res> (if (< (bytevector-u8-ref bstring1 match) (bytevector-u8-ref bstring2 match)) res< res>)))))) ;; SRFI 160 shim (: u8vector-map (procedure u8vector -> u8vector)) (define (u8vector-map f bvec) (let* ((len (bytevector-length bvec)) (res (make-bytevector len))) (let loop ((i 0)) (if (= i len) res (begin (bytevector-u8-set! res i (f (bytevector-u8-ref bvec i))) (loop (+ i 1))))))) ;;; Index checks (: check-index (symbol u8vector fixnum -> undefined)) (define (check-index loc bstring i) (unless (<= 0 i (bytevector-length bstring)) (bounds-exception loc "index out of bounds" bstring i))) (: check-range (symbol u8vector fixnum fixnum -> undefined)) (define (check-range loc bstring start end) (unless (<= 0 start end (bytevector-length bstring)) (bounds-exception loc "invalid range" bstring start end)))