;;; ;;; <port.ss> ---- Port collection ;;; Time-stamp: <05/12/05 14:56:01 nhw> ;;; ;;; Copyright (C) 2002-2004 by Noel Welsh. ;;; ;;; This file is part of Port collection. ;;; Port collection is free software; you can redistribute it and/or ;;; modify it under the terms of the GNU Lesser General Public ;;; License as published by the Free Software Foundation; either ;;; version 2.1 of the License, or (at your option) any later version. ;;; Port collection is distributed in the hope that it will be useful, ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ;;; Lesser General Public License for more details. ;;; You should have received a copy of the GNU Lesser General Public ;;; License along with Port collection; if not, write to the Free Software ;;; Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ;;; Author: Noel Welsh <noelwelsh@yahoo.com> ;; ;; ;; Commentary: (module port mzscheme (require (lib "port.ss")) (provide port->list port->string port->string-list port->sexp-list port-fold) ;;! ;; Contract: ((Port) -> Any) Port -> (listof Any) ;; (port->list reader port) -> list ;; ;; Apply reader to port, accumulating results till the eof-object is ;; reached. (define (port->list reader port) (let ((result (reader port))) (if (eof-object? result) '() (cons result (port->list reader port))))) ;;! ;; Contract : Port -> String ;; (port->string port) -> string ;; ;; Reads all characters from the port until eof and returns the ;; accumulated string (define (port->string port) (let ((output (open-output-string))) (let loop () (let ((char (read-char port))) (if (eof-object? char) (get-output-string output) (begin (display char output) (loop))))))) ;;! ;; Contract: Port -> (listof String) ;; (port->string-list port) -> list ;; ;; Repeatedly reads newline-terminated strings from the port unti eof, ;; then returns the accumulated list of strings. (define (port->string-list port) (port->list read-line port)) ;;! ;; Contract: Port -> (listof Any) ;; (port->sexp-list port) -> list ;; ;; Repeatedly reads data from the port until eof, then returns the ;; accumulated list of terms ;; ;; This elegant-yet-dirty hack to increase speed ;; contributed by Jacob Matthews. (define (port->sexp-list port) (let-values ([(pin pout) (make-pipe)]) (thread (lambda () (write-char #\( pout) (copy-port port pout) (write-char #\) pout))) (read pin))) ;;! ;; Contract: Port (Port -> 'a) ('a Any ... -> Any ...) Any ... ;; (port-fold port reader op . seeds) -> seeds (define (port-fold port reader op . seeds) (let ((result (reader port))) (if (eof-object? result) (apply values seeds) (call-with-values (lambda () (apply op result seeds)) (lambda values (apply port-fold port reader op values)))))) )