Module: streams-internals Synopsis: Implementation of abstract wrapper stream classes and defaults Author: Scott McKay, Marc Ferguson, Eliot Miranda Copyright: Original Code is Copyright (c) 1995-2004 Functional Objects, Inc. All rights reserved. License: Functional Objects Library Public License Version 1.0 Dual-license: GNU Lesser General Public License Warranty: Distributed WITHOUT WARRANTY OF ANY KIND /// Wrapper streams define open abstract primary class () slot %inner-stream :: , required-init-keyword: inner-stream:; end class ; define sealed class () end class ; define sealed inline method make (class == , #rest initargs, #key) => (stream :: ) apply(make, , initargs) end method make; define sealed domain make (singleton()); define sealed domain initialize (); define open generic inner-stream (wrapper-stream :: ) => (stream :: ); define method inner-stream (wrapper-stream :: ) => (stream :: ) wrapper-stream.%inner-stream; end method inner-stream; define open generic inner-stream-setter (stream :: , wrapper-stream :: ) => (stream :: ); define method inner-stream-setter (stream :: , wrapper-stream :: ) => (stream :: ) wrapper-stream.%inner-stream := stream; stream.outer-stream := wrapper-stream; stream end method inner-stream-setter; define method initialize (wrapper-stream :: , #key inner-stream: stream) => () next-method(); stream.outer-stream := wrapper-stream; unless (slot-initialized?(wrapper-stream, outer-stream)) wrapper-stream.outer-stream := wrapper-stream end end method initialize; /// The following methods define the core protocols that defer to their /// underlying stream. The following methods on non-wrapper-streams do /// _not_ defer to their outer-stream. /// Readable stream protocol define method read-element (stream :: , #rest keys, #key on-end-of-stream) => (element :: ) ignore(on-end-of-stream); apply(read-element, stream.inner-stream, keys) end method read-element; define method unread-element (stream :: , elt) => (element :: ) unread-element(stream.inner-stream, elt) end method unread-element; define method peek (stream :: , #rest keys, #key on-end-of-stream) => (element :: ) ignore(on-end-of-stream); apply(peek, stream.inner-stream, keys) end method peek; define method read (stream :: , n :: , #rest keys, #key on-end-of-stream) => (elements-or-eof :: ) ignore(on-end-of-stream); apply(read, stream.inner-stream, n, keys) end method read; define method read-into! (stream :: , n :: , seq :: , #rest keys, #key start, on-end-of-stream) => (n-read-or-eof :: ) ignore(start, on-end-of-stream); apply(read-into!, stream.inner-stream, n, seq, keys) end method read-into!; define method stream-input-available? (stream :: ) => (available? :: ) stream-input-available?(stream.inner-stream) end method stream-input-available?; define method discard-input (stream :: ) => () discard-input(stream.inner-stream) end method discard-input; /// Writable stream protocol define method write-element (stream :: , elt :: ) => () write-element(stream.inner-stream, elt) end method write-element; define method write (stream :: , elements :: , #rest keys, #key start: _start, end: _end) => () ignore(_start, _end); apply(write, stream.inner-stream, elements, keys) end method write; define method force-output (stream :: , #key synchronize?) => () force-output(stream.inner-stream, syncronize?: #t); end method force-output; define method synchronize-output (stream :: ) => () synchronize-output(stream.inner-stream) end method synchronize-output; define method discard-output (stream :: ) => () discard-output(stream.inner-stream) end method discard-output; /// Convenience functions define sealed method read-to (stream :: , elt, #rest keys, #key on-end-of-stream, test) => (sequence-or-eof :: , found? :: ) ignore(on-end-of-stream, test); apply(read-to, stream.inner-stream, elt, keys) end method read-to; define sealed method read-through (stream :: , elt, #rest keys, #key on-end-of-stream, test) => (sequence-or-eof :: , found? :: ) ignore(on-end-of-stream, test); apply(read-through, stream.inner-stream, elt, keys) end method read-through; define method read-to-end (stream :: ) => (elements :: ) read-to-end(stream.inner-stream) end method read-to-end; define method skip-through (stream :: , elt, #rest keys, #key test) => (found? :: ) ignore(test); apply(skip-through, stream.inner-stream, elt, keys) end method skip-through; /// Line-oriented functions define method read-line (stream :: , #rest keys, #key on-end-of-stream) => (string-or-eof :: , newline? :: ) ignore(on-end-of-stream); apply(read-line, stream.inner-stream, keys) end method read-line; define method read-line-into! (stream :: , string :: , #rest keys, #key start, on-end-of-stream, grow?) => (string-or-eof :: , newline? :: ) ignore(start, on-end-of-stream, grow?); apply(read-line-into!, stream.inner-stream, string, keys) end method read-line-into!; define method write-line (stream :: , string :: , #rest keys, #key start: _start, end: _end) => () ignore(_start, _end); apply(write-line, stream.inner-stream, string, keys) end method write-line; define method new-line (stream :: ) => () new-line(stream.inner-stream) end method new-line; /// Querying streams define method close (stream :: , #rest keys, #key wait?, synchronize?, abort?) => () ignore(wait?, synchronize?, abort?); apply(close, stream.inner-stream, keys); end method close; define method stream-open? (stream :: ) => (open? :: ) stream-open?(stream.inner-stream) end method stream-open?; define method stream-element-type (stream :: ) => (element-type :: ) stream-element-type(stream.inner-stream) end method stream-element-type; define method stream-at-end? (stream :: ) => (at-end? :: ) stream-at-end?(stream.inner-stream) end method stream-at-end?; define method stream-direction (stream :: ) => (at-end? :: ) stream-direction(stream.inner-stream) end method stream-direction; /// Positionable stream protocol define method stream-position (stream :: ) => (position :: ) stream-position(stream.inner-stream) end method stream-position; define method stream-position-setter (position :: , stream :: ) => (position :: ) stream-position-setter(position, stream.inner-stream) end method stream-position-setter; define method adjust-stream-position (stream :: , delta :: , #rest keys, #key from) => (position :: ) ignore(from); apply(adjust-stream-position, stream.inner-stream, delta, keys) end method adjust-stream-position; define method stream-size (stream :: ) => (size :: false-or()) stream-size(stream.inner-stream) end method stream-size; define method stream-contents (stream :: , #rest keys, #key clear-contents?) => (sequence :: ) ignore(clear-contents?); apply(stream-contents, stream.inner-stream, keys) end method stream-contents; define method stream-contents-as (type :: , stream :: , #rest keys, #key clear-contents?) => (sequence :: ) ignore(clear-contents?); apply(stream-contents-as, type, stream.inner-stream, keys) end method stream-contents-as; /// Locking define method stream-locked? (stream :: ) => (locked? :: ) stream-locked?(stream.inner-stream) end method stream-locked?; define method lock-stream (stream :: ) => () lock-stream(stream.inner-stream) end method lock-stream; define method unlock-stream (stream :: ) => () unlock-stream(stream.inner-stream) end method unlock-stream; /// Sequence streams define method stream-sequence-class (stream :: ) => (class :: subclass()) stream-sequence-class(stream.inner-stream) end method stream-sequence-class; /// File streams define method stream-limit (stream :: ) => (size :: false-or()) stream-limit(stream.inner-stream) end method stream-limit;