Changeset 29883 in project


Ignore:
Timestamp:
10/09/13 22:57:10 (8 years ago)
Author:
sjamaan
Message:

intarweb: Reduce CPU usage for read-string! on chunked ports. read-line is left for a better day... (ugh)

Location:
release/4/intarweb/trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • release/4/intarweb/trunk/intarweb.scm

    r29868 r29883  
    274274                                       (set! position #f))
    275275                                      (else (set! position 0))))))))))
    276     (make-input-port (lambda ()         ; read
     276    (make-input-port (lambda ()         ; read-char
    277277                       (check-position)
    278278                       (if position
    279279                           (let ((char (read-char port)))
    280                              (if (not (eof-object? char))
    281                                  (set! position (add1 position)))
     280                             (unless (eof-object? char)
     281                               (set! position (add1 position)))
    282282                             char)
    283283                           #!eof))
    284                      (lambda ()          ; ready?
     284                     (lambda ()         ; ready?
    285285                       (check-position)
    286                        (and position (char-ready? port)))
    287                      (lambda ()          ; close
     286                       (or (not position) (char-ready? port)))
     287                     (lambda ()         ; close
    288288                       (close-input-port port))
    289                      (lambda ()          ; peek
     289                     (lambda ()         ; peek-char
    290290                       (check-position)
    291291                       (if position
    292292                           (peek-char port)
    293                            #!eof)))))
     293                           #!eof))
     294                     (lambda (p bytes buf off) ; read-string!
     295                       (let lp ((todo bytes)
     296                                (total-bytes-read 0)
     297                                (off off))
     298                         (check-position)
     299                         (if (or (not position) (= todo 0))
     300                             total-bytes-read
     301                             (let* ((n (min todo (- chunk-length position)))
     302                                    (bytes-read (read-string! n buf port off)))
     303                               (set! position (+ position bytes-read))
     304                               (lp (- todo bytes-read)
     305                                   (+ total-bytes-read bytes-read)
     306                                   (+ off bytes-read)))))))))
     307;; TODO: Note that in the above, read-line is not currently
     308;; implemented.  It is *extremely* tricky to correctly maintain the
     309;; port position when all \r *AND/OR* \n characters get chopped off
     310;; the line-string.  It can be done by maintaining our own extra
     311;; buffer, but that complicates all the procedures here enormously,
     312;; including read-line itself.
    294313
    295314;; RFC2616, Section 4.3: "The presence of a message-body in a request
  • release/4/intarweb/trunk/tests/run.scm

    r29781 r29883  
    11521152                 (etag-matches?
    11531153                  '(strong . "xyz") `((strong . "blabla") *)))))
     1154
     1155
     1156;; We don't expose chunked-output-port/chunked-input-port.  Maybe we should?
     1157;; To work around this, prepend some stuff and parse some headers
     1158(define (chunked-inport string)
     1159  (let ((res (test-read-response
     1160              (string-append
     1161               "HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"
     1162               string))))
     1163    (response-port res)))
     1164
     1165(test-group "Chunked ports"
     1166  (let ((s "5\r\nab\ncd\r\n2\r\n\nx\r\n0\r\nDO NOT WANT"))
     1167    (test "read-lines" '("ab" "cd" "x") (read-lines (chunked-inport s)))
     1168    (let ((p (chunked-inport s)))
     1169      (test "read-char" #\a (read-char p))
     1170      (test "peek-char" #\b (peek-char p))
     1171      (test "partial read" "b\n" (read-string 2 p))
     1172      (test "short read" "c" (read-string 1 p))
     1173      (test "read across chunk boundaries" "d\nx" (read-string 3 p))
     1174      (test "read at eof" "" (read-string 1 p)))
     1175    (test "read beyond chunked port size"
     1176          "ab\ncd\nx" (read-string 10 (chunked-inport s)))))
     1177
    11541178(test-end)
    11551179
Note: See TracChangeset for help on using the changeset viewer.