Subject: [clisp-list] Problem with READ-BYTE-SEQUENCE on Windows

From: Edi Weitz <[email-masked]>
Date: Thu Jan 15 04:27:11 2004

The test code below works fine with binary downloads like, say,

  (foo "weitz.de" "/files/cl-interpol.tgz")

if I invoke it from Linux. But if I use it from Windows most of the
contents of the generated "out" file (towards the end) are nulls. Am I
doing something wrong or is this a bug? (Looks to me as if it acted
like the :NO-HANG argument were T.)

I had the same problem with the standard functions
READ-SEQUENCE/WRITE-SEQUENCE.

Both are CLISP 2.32. On Linux (SuSE 9.0) it was built from source, on
Windows (XP pro) I used the "clisp-2.32-win32.zip" binary from
Sourceforge.

Thanks,
Edi.

(defun foo (host url)
  (let ((stream (socket:socket-connect
                 80 host
                 :external-format
                 (ext:make-encoding :charset 'charset:iso-8859-1
                                    :line-terminator :unix))))
    (format stream "GET ~A HTTP/1.0~C~CHost: ~A~C~C~C~C"
            url #\Return #\Linefeed
            host #\Return #\Linefeed #\Return #\Linefeed)
    (force-output stream)
    (let (length)
      (loop for line = (read-line stream nil nil)
            until (or (null line)
                      (zerop (length line))
                      (eql (elt line 0) (code-char 13)))
            when (= (mismatch line "Content-length: "
                              :test #'char-equal)
                    16)
            do (setq length
                       (parse-integer line
                                      :start 15
                                      :junk-allowed t)))
      (unless length
        (error "No Content-Length header found"))
      (setf (stream-element-type stream) '(unsigned-byte 8))
      (with-open-file (out "out" :direction :output
                           :element-type '(unsigned-byte 8)
                           :if-exists :supersede)
        (let ((buf (make-array length
                               :element-type
                               (stream-element-type stream))))
          (ext:read-byte-sequence buf stream :no-hang nil)
          (ext:write-byte-sequence buf out)))
      (values))))

---

From: Edi Weitz <[email-masked]>
Date: Thu Jan 15 07:55:02 2004

Some more info: If I add two PRINT statements (see below) I get (on
Windows) something like

  147558
  6596

The second number is not always the same but it's always around 10000
or less.

Edi.

(defun foo (host url)
      (print length) ;; <---- HERE
          (print (ext:read-byte-sequence buf stream :no-hang nil)) ;; <---- HERE

---

From: Edi Weitz <[email-masked]>
Date: Fri Jan 16 06:32:08 2004

FWIW, this doesn't happen with the Cygwin version.

Cheers,
Edi.

---

From: Sam Steingold <[email-masked]>
Date: Fri Jan 16 11:25:03 2004

do you observe this bug when you try to read a file (as opposed to a socket)?
-- 
Sam Steingold (http://www.podval.org/~sds) running w2k
<http://www.camera.org> <http://www.iris.org.il> <http://www.memri.org/>
<http://www.mideasttruth.com/> <http://www.honestreporting.com>
There are 10 kinds of people: those who count in binary and those who do not.

---

From: Edi Weitz <[email-masked]>
Date: Fri Jan 16 14:36:03 2004

> do you observe this bug when you try to read a file (as opposed to a

No. I tried the code below which tries to mimick my original example
and it all went fine.

Edi.

(defun bar (name)
  (with-open-file (stream name)
    (let ((length (file-length stream)))
      (print length)
      (setf (stream-element-type stream) '(unsigned-byte 8))
      (with-open-file (out "out" :direction :output
                           :element-type '(unsigned-byte 8)
                           :if-exists :supersede)
        (let ((buf (make-array length
                               :element-type
                               (stream-element-type stream))))
          (print (ext:read-byte-sequence buf stream :no-hang nil))
          (ext:write-byte-sequence buf out)))
      (values))))