3 ;;; Copyright 2007 Ludovic Courtès <ludovic.courtes@laas.fr>
6 ;;; This program is free software; you can redistribute it and/or modify
7 ;;; it under the terms of the GNU General Public License as published by
8 ;;; the Free Software Foundation; either version 2 of the License, or
9 ;;; (at your option) any later version.
11 ;;; This program is distributed in the hope that it will be useful,
12 ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
13 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 ;;; GNU General Public License for more details.
16 ;;; You should have received a copy of the GNU General Public License
17 ;;; along with this program; if not, write to the Free Software
18 ;;; Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 (define-module (test-i/o-ports)
21 :use-module (test-suite lib)
22 :use-module (srfi srfi-1)
23 :use-module (srfi srfi-11)
24 :use-module (r6rs i/o ports)
25 :use-module (r6rs bytevector))
27 ;;; All these tests assume Guile 1.8's port system, where characters are
28 ;;; treated as octets.
31 (with-test-prefix "7.2.5 End-of-File Object"
34 (and (eqv? (eof-object) (eof-object))
35 (eq? (eof-object) (eof-object)))))
38 (with-test-prefix "7.2.8 Binary Input"
41 (let ((port (open-input-string "A")))
42 (and (= (char->integer #\A) (get-u8 port))
43 (eof-object? (get-u8 port)))))
45 (pass-if "lookahead-u8"
46 (let ((port (open-input-string "A")))
47 (and (= (char->integer #\A) (lookahead-u8 port))
48 (not (eof-object? port))
49 (= (char->integer #\A) (get-u8 port))
50 (eof-object? (get-u8 port)))))
52 (pass-if "get-bytevector-n [short]"
53 (let* ((port (open-input-string "GNU Guile"))
54 (bv (get-bytevector-n port 4)))
56 (equal? (bytevector->u8-list bv)
57 (map char->integer (string->list "GNU "))))))
59 (pass-if "get-bytevector-n [long]"
60 (let* ((port (open-input-string "GNU Guile"))
61 (bv (get-bytevector-n port 256)))
63 (equal? (bytevector->u8-list bv)
64 (map char->integer (string->list "GNU Guile"))))))
66 (pass-if "get-bytevector-n! [short]"
67 (let* ((port (open-input-string "GNU Guile"))
68 (bv (make-bytevector 4))
69 (read (get-bytevector-n! port bv 0 4)))
71 (equal? (bytevector->u8-list bv)
72 (map char->integer (string->list "GNU "))))))
74 (pass-if "get-bytevector-n! [long]"
75 (let* ((str "GNU Guile")
76 (port (open-input-string str))
77 (bv (make-bytevector 256))
78 (read (get-bytevector-n! port bv 0 256)))
79 (and (equal? read (string-length str))
80 (equal? (map (lambda (i)
81 (bytevector-u8-ref bv i))
83 (map char->integer (string->list str))))))
85 (pass-if "get-bytevector-some [simple]"
86 (let* ((str "GNU Guile")
87 (port (open-input-string str))
88 (bv (get-bytevector-some port)))
90 (equal? (bytevector->u8-list bv)
91 (map char->integer (string->list str))))))
93 (pass-if "get-bytevector-some [only-some]"
94 (let* ((str "GNU Guile")
99 (if (>= index (string-length str))
101 (let ((c (string-ref str index)))
102 (set! index (+ index 1))
106 ;; Number of readily available octets: falls to
107 ;; zero after 4 octets have been read.
108 (- 4 (modulo index 5))))
110 (bv (get-bytevector-some port)))
111 (and (bytevector? bv)
113 (= (bytevector-length bv) index)
114 (equal? (bytevector->u8-list bv)
115 (map char->integer (string->list "GNU "))))))
117 (pass-if "get-bytevector-all"
118 (let* ((str "GNU Guile")
120 (port (make-soft-port
123 (if (>= index (string-length str))
125 (let ((c (string-ref str index)))
126 (set! index (+ index 1))
131 ;; Number of readily available octets: falls to
132 ;; zero after 4 octets have been read and then
135 (- (string-length str) index)
136 (- 4 (modulo index 5)))))
137 (if (= 0 a) (set! cont? #t))
140 (bv (get-bytevector-all port)))
141 (and (bytevector? bv)
142 (= index (string-length str))
143 (= (bytevector-length bv) (string-length str))
144 (equal? (bytevector->u8-list bv)
145 (map char->integer (string->list str)))))))
148 (define (make-soft-output-port)
149 (let* ((bv (make-bytevector 1024))
152 (write-char (lambda (chr)
153 (bytevector-u8-set! bv write-index
155 (set! write-index (+ 1 write-index)))))
158 (lambda (str) ;; write-string
159 (for-each write-char (string->list str)))
160 (lambda () #t) ;; flush-output
161 (lambda () ;; read-char
162 (if (>= read-index (bytevector-length bv))
164 (let ((c (bytevector-u8-ref bv read-index)))
165 (set! read-index (+ read-index 1))
167 (lambda () #t)) ;; close-port
170 (with-test-prefix "7.2.11 Binary Output"
173 (let ((port (make-soft-output-port)))
175 (equal? (get-u8 port) 77)))
177 (pass-if "put-bytevector [2 args]"
178 (let ((port (make-soft-output-port))
179 (bv (make-bytevector 256)))
180 (put-bytevector port bv)
181 (equal? (bytevector->u8-list bv)
183 (get-bytevector-n port (bytevector-length bv))))))
185 (pass-if "put-bytevector [3 args]"
186 (let ((port (make-soft-output-port))
187 (bv (make-bytevector 256))
189 (put-bytevector port bv start)
190 (equal? (drop (bytevector->u8-list bv) start)
192 (get-bytevector-n port (- (bytevector-length bv) start))))))
194 (pass-if "put-bytevector [4 args]"
195 (let ((port (make-soft-output-port))
196 (bv (make-bytevector 256))
199 (put-bytevector port bv start count)
200 (equal? (take (drop (bytevector->u8-list bv) start) count)
202 (get-bytevector-n port count)))))
204 (pass-if "open-bytevector-output-port"
205 (let-values (((port get-content)
206 (open-bytevector-output-port)))
207 (let ((source (make-bytevector 7777)))
208 (put-bytevector port source)
209 (and (bytevector=? (get-content) source)
210 (bytevector=? (get-content) (make-bytevector 0))))))
212 (pass-if "bytevector output port supports `port-position'"
213 (let-values (((port get-content)
214 (open-bytevector-output-port)))
215 (let ((source (make-bytevector 7777))
216 (overwrite (make-bytevector 33)))
217 (and (port-has-port-position? port)
218 (port-has-set-port-position!? port)
220 (put-bytevector port source)
221 (= (bytevector-length source)
222 (port-position port)))
224 (set-port-position! port 10)
225 (= 10 (port-position port)))
227 (put-bytevector port overwrite)
228 (bytevector-copy! overwrite 0 source 10
229 (bytevector-length overwrite))
230 (= (port-position port)
231 (+ 10 (bytevector-length overwrite))))
232 (bytevector=? (get-content) source)
233 (bytevector=? (get-content) (make-bytevector 0)))))))
236 (with-test-prefix "7.2.7 Input Ports"
238 ;; This section appears here so that it can use the binary input
241 (pass-if "open-bytevector-input-port [1 arg]"
242 (let* ((str "Hello Port!")
243 (bv (u8-list->bytevector (map char->integer
244 (string->list str))))
245 (port (open-bytevector-input-port bv))
248 (let loop ((chr (read-char port))
250 (if (eof-object? chr)
251 (apply string (reverse! result))
252 (loop (read-char port)
253 (cons chr result)))))))
255 (equal? (read-to-string port) str)))
257 (pass-if-exception "bytevector-input-port is read-only"
258 exception:wrong-type-arg
260 (let* ((str "Hello Port!")
261 (bv (u8-list->bytevector (map char->integer
262 (string->list str))))
263 (port (open-bytevector-input-port bv)))
265 (write "hello" port)))
267 (pass-if "bytevector input port supports seeking"
268 (let* ((str "Hello Port!")
269 (bv (u8-list->bytevector (map char->integer
270 (string->list str))))
271 (port (open-bytevector-input-port bv)))
273 (and (port-has-port-position? port)
274 (= 0 (port-position port))
275 (port-has-set-port-position!? port)
277 (set-port-position! port 6)
278 (= 6 (port-position port)))
279 (bytevector=? (get-bytevector-all port)
281 (map char->integer (string->list "Port!")))))))
283 (pass-if "make-custom-binary-input-port"
284 (let* ((source (make-bytevector 7777))
286 (len (bytevector-length source)))
287 (lambda (bv start count)
288 (let ((amount (min count (- len pos))))
290 (bytevector-copy! source pos
292 (set! pos (+ pos amount))
294 (port (make-custom-binary-input-port "the port" read!)))
296 (bytevector=? (get-bytevector-all port) source)))
298 (pass-if "custom binary input port does not support `port-position'"
299 (let* ((str "Hello Port!")
300 (source (open-bytevector-input-port
302 (map char->integer (string->list str)))))
303 (read! (lambda (bv start count)
304 (let ((r (get-bytevector-n! source bv start count)))
308 (port (make-custom-binary-input-port "the port" read!)))
309 (not (or (port-has-port-position? port)
310 (port-has-set-port-position!? port)))))
312 (pass-if "custom binary input port supports `port-position'"
313 (let* ((str "Hello Port!")
314 (source (open-bytevector-input-port
316 (map char->integer (string->list str)))))
317 (read! (lambda (bv start count)
318 (let ((r (get-bytevector-n! source bv start count)))
323 (port-position source)))
324 (set-pos! (lambda (pos)
325 (set-port-position! source pos)))
326 (port (make-custom-binary-input-port "the port" read!
329 (and (port-has-port-position? port)
330 (= 0 (port-position port))
331 (port-has-set-port-position!? port)
333 (set-port-position! port 6)
334 (= 6 (port-position port)))
335 (bytevector=? (get-bytevector-all port)
337 (map char->integer (string->list "Port!"))))))))
345 ;;; arch-tag: fc4f49fa-18a5-4a0c-bee8-ef7554f9cf1d