From 7c9edbf53d5c31ffcb3a6981848d24c09c064eef Mon Sep 17 00:00:00 2001 From: Peter Bex Date: Mon, 24 Aug 2026 09:36:34 +0200 Subject: Hack around to make read-bytevector work on custom (chunked) input port In CHICKEN 6.0.0, the signature was documented to be different, but we were using the actual signature. For later CHICKEN versions, the signature was updated to match the documentation so now we're kind of stuck having to support both signatures. Since we cannot cond-expand our way out of this because there are no features that differ between 6.0.0 and 6.0.1, we'll have to use case-lambda and convert the old signature to the new one. Oh well... --- intarweb.scm | 46 +++++++++++++++++++++++++++------------------- 1 file changed, 27 insertions(+), 19 deletions(-) (limited to 'intarweb.scm') diff --git a/intarweb.scm b/intarweb.scm index d2cca10..d2c899f 100644 --- a/intarweb.scm +++ b/intarweb.scm @@ -1,7 +1,7 @@ ;;; ;;; Intarweb is an improved HTTP library for Chicken ;;; -;; Copyright (c) 2008-2024, Peter Bex +;; Copyright (c) 2008-2026, Peter Bex ;; All rights reserved. ;; ;; Redistribution and use in source and binary forms, with or without @@ -100,7 +100,8 @@ basic-auth-param-subunparser digest-auth-param-subunparser ) -(import scheme (scheme base) (chicken base) (chicken foreign) (chicken irregex) +(import scheme (scheme base) (scheme case-lambda) (chicken base) + (chicken foreign) (chicken irregex) (chicken format) (chicken io) (chicken string) (chicken time posix) (chicken pathname) (chicken fixnum) (chicken condition) (chicken port) (chicken syntax) @@ -299,6 +300,25 @@ (safe-read-line port) (set! position #f)) (else (set! position 0)))))))))) + ;; NOTE: This is using case-lambda because the signature changed between CHICKEN 6.0.0 and later releases + ;; In 6.0.0 it receives the port and the the number of bytes to read so we have to convert that old + ;; signature to the newer signature. + (define read-chunked-bytevector (case-lambda + ((p bytes buf off) + (read-chunked-bytevector buf off (+ bytes off))) + ((buf start end) + (let lp ((todo (- end start)) + (total-bytes-read 0) + (start start)) + (check-position) + (if (or (not position) (= start end)) + total-bytes-read + (let* ((n (min todo (- chunk-length position))) + (bytes-read (read-bytevector! buf port start (+ start n)))) + (set! position (+ position bytes-read)) + (lp (- todo bytes-read) + (+ total-bytes-read bytes-read) + (+ start bytes-read)))))))) (make-input-port (lambda () ; read-char (check-position) (if position @@ -313,23 +333,11 @@ (lambda () ; close (close-input-port port)) peek-char: (lambda () - (check-position) - (if position - (peek-char port) - #!eof)) - read-bytevector: (lambda (p bytes buf off) - (let lp ((todo bytes) - (total-bytes-read 0) - (off off)) - (check-position) - (if (or (not position) (= todo 0)) - total-bytes-read - (let* ((n (min todo (- chunk-length position))) - (bytes-read (read-bytevector! buf port off (+ off n)))) - (set! position (+ position bytes-read)) - (lp (- todo bytes-read) - (+ total-bytes-read bytes-read) - (+ off bytes-read))))))))) + (check-position) + (if position + (peek-char port) + #!eof)) + read-bytevector: read-chunked-bytevector))) ;; TODO: Note that in the above, read-line is not currently ;; implemented. It is *extremely* tricky to correctly maintain the ;; port position when all \r *AND/OR* \n characters get chopped off -- cgit v1.2.3