;;; ;;; <port.ss> ---- Port collection ;;; Time-stamp: <2008-03-17 21:38:16 noel> ;;; ;;; 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 "etc.ss") (lib "port.ss")) (provide port->list port->string port->bytes 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 (opt-lambda (reader [port (current-input-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 (opt-lambda ([port (current-input-port)]) (let ((output (open-output-string))) (copy-port port output) (get-output-string output)))) ;; port->bytes : port -> bytes ;; ;; Read all bytes from the port till eof and returns the accumulated bytes (define port->bytes (opt-lambda ([port (current-input-port)]) (let ((output (open-output-bytes))) (copy-port port output) (get-output-bytes output)))) ;;! ;; 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 (opt-lambda ([port (current-input-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 (opt-lambda ([port (current-input-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)))))) )