3 ;;; **********************************************************************
4 ;;; This code was written by Paul Foley and has been placed in the public
8 ;;; Sbcl port by Rudi Schlatte.
10 (in-package "SB-SIMPLE-STREAMS")
13 ;;; **********************************************************************
15 ;;; Strategy functions for base simple-stream classes
19 (defun refill-buffer (stream blocking
)
20 (declare (type blocking blocking
))
21 (with-stream-class (simple-stream stream
)
22 (let* ((unread (sm last-char-read-size stream
))
23 (buffer (sm buffer stream
))
24 (bufptr (sm buffer-ptr stream
)))
25 (unless (or (zerop unread
) (zerop bufptr
))
26 (buffer-copy buffer
(- bufptr unread
) buffer
0 unread
))
27 (let ((bytes (device-read stream nil unread nil blocking
)))
28 (declare (type fixnum bytes
))
29 (setf (sm buffpos stream
) unread
30 (sm buffer-ptr stream
) (if (plusp bytes
)
35 (defun sc-set-dirty (stream)
36 (with-stream-class (single-channel-simple-stream stream
)
37 (setf (sm mode stream
)
38 (if (<= (sm buffpos stream
)
39 (sm buffer-ptr stream
))
44 (defun sc-set-clean (stream)
45 (with-stream-class (single-channel-simple-stream stream
)
46 (setf (sm mode stream
) 0)))
48 (defun sc-dirty-p (stream)
49 (with-stream-class (single-channel-simple-stream stream
)
50 (> (sm mode stream
) 0)))
52 (defun flush-buffer (stream blocking
)
53 (with-stream-class (single-channel-simple-stream stream
)
55 (bytes (sm buffpos stream
)))
56 (declare (type fixnum ptr bytes
))
57 (when (and (> (sm mode stream
) 0) (> (sm buffer-ptr stream
) 0))
58 ;; The data read in from the file could have been changed if
59 ;; the stream is opened in read-write mode -- write back
60 ;; everything in the buffer at the correct position just in
62 (setf (device-file-position stream
)
63 (- (device-file-position stream
) (sm buffer-ptr stream
))))
65 (when (>= ptr bytes
) (setf (sm buffpos stream
) 0) (setf (sm mode stream
) 0) (return 0))
66 (let ((bytes-written (device-write stream nil ptr nil blocking
)))
67 (declare (fixnum bytes-written
))
68 (when (minusp bytes-written
)
69 (error "DEVICE-WRITE error."))
70 (incf ptr bytes-written
))))))
72 (defun flush-out-buffer (stream blocking
)
73 (with-stream-class (dual-channel-simple-stream stream
)
75 (bytes (sm outpos stream
)))
76 (declare (type fixnum ptr bytes
))
78 (when (>= ptr bytes
) (setf (sm outpos stream
) 0) (return 0))
79 (let ((bytes-written (device-write stream nil ptr nil blocking
)))
80 (declare (fixnum bytes-written
))
81 (when (minusp bytes-written
)
82 (error "DEVICE-WRITE error."))
83 (incf ptr bytes-written
))))))
85 (defun read-byte-internal (stream eof-error-p eof-value blocking
)
86 (with-stream-class (simple-stream stream
)
87 (let ((ptr (sm buffpos stream
)))
88 (when (>= ptr
(sm buffer-ptr stream
))
89 (let ((bytes (device-read stream nil
0 nil blocking
)))
90 (declare (type fixnum bytes
))
92 (setf (sm buffer-ptr stream
) bytes
94 (return-from read-byte-internal
95 (sb-impl::eof-or-lose stream eof-error-p eof-value
)))))
96 (setf (sm buffpos stream
) (1+ ptr
))
97 (setf (sm last-char-read-size stream
) 0)
98 (setf (sm charpos stream
) nil
)
99 (bref (sm buffer stream
) ptr
))))
101 ;;;; Single-Channel-Simple-Stream strategy functions
104 (declaim (ftype j-listen-fn sc-listen-ef
))
105 (defun sc-listen-ef (stream)
106 (with-stream-class (simple-stream stream
)
107 (let ((lcrs (sm last-char-read-size stream
))
108 (buffer (sm buffer stream
))
109 (buffpos (sm buffpos stream
))
112 (declare (ignorable cnt
))
115 (when (>= buffpos
(sm buffer-ptr stream
))
116 (let ((bytes (refill-buffer stream nil
)))
118 (return-from sc-listen-ef nil
))
120 (return-from sc-listen-ef t
))
122 (setf buffpos
(sm buffpos stream
))))))
123 (incf (sm last-char-read-size stream
))
124 (prog1 (bref buffer buffpos
)
128 (setq char
(octets-to-char (sm external-format stream
)
130 cnt
#'input
#'unput
))
132 (setf (sm last-char-read-size stream
) lcrs
)))))
134 (declaim (ftype j-read-char-fn sc-read-char-ef
))
135 (defun sc-read-char-ef (stream eof-error-p eof-value blocking
)
136 #|
(declare (optimize (speed 3) (space 2) (safety 0) (debug 0)))|
#
137 (with-stream-class (simple-stream stream
)
138 (let* ((buffer (sm buffer stream
))
139 (buffpos (sm buffpos stream
))
140 (ctrl (sm control-in stream
))
141 (ef (sm external-format stream
))
142 (state (sm oc-state stream
)))
144 (when (>= buffpos
(sm buffer-ptr stream
))
145 (when (and (not (any-stream-instance-flags stream
:dual
:string
))
147 (flush-buffer stream t
))
148 (let ((bytes (refill-buffer stream blocking
)))
150 (return-from sc-read-char-ef nil
))
152 (return-from sc-read-char-ef
153 (sb-impl::eof-or-lose stream eof-error-p eof-value
)))
155 (setf buffpos
(sm buffpos stream
))))))
156 (incf (sm last-char-read-size stream
))
157 (prog1 (bref buffer buffpos
)
162 (char (octets-to-char ef state cnt
#'input
#'unput
))
163 (code (char-code char
)))
164 (setf (sm buffpos stream
) buffpos
165 (sm last-char-read-size stream
) cnt
166 (sm oc-state stream
) state
)
167 (when (and (< code
32) ctrl
(svref ctrl code
))
168 (setq char
(funcall (the (or symbol function
) (svref ctrl code
))
171 (sb-impl::eof-or-lose stream eof-error-p eof-value
)
175 (declaim (ftype j-read-char-fn sc-read-char-ef-mapped
))
176 (defun sc-read-char-ef-mapped (stream eof-error-p eof-value blocking
)
177 #|
(declare (optimize (speed 3) (space 2) (safety 0) (debug 0)))|
#
178 (declare (ignore blocking
))
179 (with-stream-class (simple-stream stream
)
180 (let* ((buffer (sm buffer stream
))
181 (buffpos (sm buffpos stream
))
182 (ctrl (sm control-in stream
))
183 (ef (sm external-format stream
))
184 (state (sm oc-state stream
)))
186 (when (>= buffpos
(sm buffer-ptr stream
))
187 (return-from sc-read-char-ef-mapped
188 (sb-impl::eof-or-lose stream eof-error-p eof-value
)))
189 (incf (sm last-char-read-size stream
))
190 (prog1 (bref buffer buffpos
)
195 (char (octets-to-char ef state cnt
#'input
#'unput
))
196 (code (char-code char
)))
197 (setf (sm buffpos stream
) buffpos
198 (sm last-char-read-size stream
) cnt
199 (sm oc-state stream
) state
)
200 (when (and (< code
32) ctrl
(svref ctrl code
))
201 (setq char
(funcall (the (or symbol function
) (svref ctrl code
))
204 (sb-impl::eof-or-lose stream eof-error-p eof-value
)
208 (declaim (ftype j-read-chars-fn sc-read-chars-ef
))
209 (defun sc-read-chars-ef (stream string search start end blocking
)
210 ;; string is filled from START to END, or until SEARCH is found
211 ;; Return two values: count of chars read and
212 ;; NIL if SEARCH was not found
213 ;; T if SEARCH was found
214 ;; :EOF if eof encountered before end
215 (declare (type simple-stream stream
)
217 (type (or null character
) search
)
218 (type fixnum start end
)
219 (type boolean blocking
)
220 #|
(optimize (speed 3) (space 2) (safety 0) (debug 0))|
#)
221 (with-stream-class (simple-stream stream
)
222 (when (and (not (any-stream-instance-flags stream
:dual
:string
))
224 (flush-buffer stream t
))
225 (do ((buffer (sm buffer stream
))
226 (buffpos (sm buffpos stream
))
227 (buffer-ptr (sm buffer-ptr stream
))
229 (ctrl (sm control-in stream
))
230 (ef (sm external-format stream
))
231 (state (sm oc-state stream
))
232 (posn start
(1+ posn
))
233 (count 0 (1+ count
)))
235 (setf (sm buffpos stream
) buffpos
236 (sm last-char-read-size stream
) lcrs
237 (sm oc-state stream
) state
)
239 (declare (type sb-int
:index buffpos buffer-ptr posn count
))
241 (when (>= buffpos buffer-ptr
)
242 (setf (sm last-char-read-size stream
) lcrs
)
243 (let ((bytes (refill-buffer stream blocking
)))
244 (declare (type fixnum bytes
))
245 (setf buffpos
(sm buffpos stream
)
246 buffer-ptr
(sm buffer-ptr stream
))
247 (unless (plusp bytes
)
248 (setf (sm buffpos stream
) buffpos
249 (sm last-char-read-size stream
) lcrs
250 (sm oc-state stream
) state
)
252 (return (values count nil
))
253 (return (values count
:eof
))))))
254 (prog1 (bref buffer buffpos
)
260 (char (octets-to-char ef state cnt
#'input
#'unput
))
261 (code (char-code char
)))
263 (when (and (< code
32) ctrl
(svref ctrl code
))
264 (setq char
(funcall (the (or symbol function
) (svref ctrl code
))
267 (setf (sm buffpos stream
) buffpos
268 (sm last-char-read-size stream
) lcrs
269 (sm oc-state stream
) state
)
270 (return (values count
:eof
)))
271 ((and search
(char= char search
))
272 (setf (sm buffpos stream
) buffpos
273 (sm last-char-read-size stream
) lcrs
274 (sm oc-state stream
) state
)
275 (return (values count t
)))
277 (setf (char string posn
) char
))))))))
280 (declaim (ftype j-read-chars-fn sc-read-chars-ef-mapped
))
281 (defun sc-read-chars-ef-mapped (stream string search start end blocking
)
282 ;; string is filled from START to END, or until SEARCH is found
283 ;; Return two values: count of chars read and
284 ;; NIL if SEARCH was not found
285 ;; T if SEARCH was found
286 ;; :EOF if eof encountered before end
287 (declare (type simple-stream stream
)
289 (type (or null character
) search
)
290 (type fixnum start end
)
291 (type boolean blocking
)
293 #|
(optimize (speed 3) (space 2) (safety 0) (debug 0))|
#)
294 (with-stream-class (simple-stream stream
)
295 ;; if stream is single-channel and mode == 3, flush buffer (if dirty)
296 (do ((buffer (sm buffer stream
))
297 (buffpos (sm buffpos stream
))
298 (buffer-ptr (sm buffer-ptr stream
))
300 (ctrl (sm control-in stream
))
301 (ef (sm external-format stream
))
302 (state (sm oc-state stream
))
303 (posn start
(1+ posn
))
304 (count 0 (1+ count
)))
306 (setf (sm buffpos stream
) buffpos
307 (sm last-char-read-size stream
) lcrs
308 (sm oc-state stream
) state
)
310 (declare (type sb-int
:index buffpos buffer-ptr posn count
))
312 (when (>= buffpos buffer-ptr
)
313 (return (values count
:eof
)))
314 (prog1 (bref buffer buffpos
)
320 (char (octets-to-char ef state cnt
#'input
#'unput
))
321 (code (char-code char
)))
323 (when (and (< code
32) ctrl
(svref ctrl code
))
324 (setq char
(funcall (the (or symbol function
) (svref ctrl code
))
327 (setf (sm buffpos stream
) buffpos
328 (sm last-char-read-size stream
) lcrs
329 (sm oc-state stream
) state
)
330 (return (values count
:eof
)))
331 ((and search
(char= char search
))
332 (setf (sm buffpos stream
) buffpos
333 (sm last-char-read-size stream
) lcrs
334 (sm oc-state stream
) state
)
335 (return (values count t
)))
337 (setf (char string posn
) char
))))))))
340 (declaim (ftype j-unread-char-fn sc-unread-char-ef
))
341 (defun sc-unread-char-ef (stream relaxed
)
342 (declare (ignore relaxed
))
343 (with-stream-class (simple-stream stream
)
344 (let ((unread (sm last-char-read-size stream
)))
345 (if (>= (sm buffpos stream
) unread
)
346 (decf (sm buffpos stream
) unread
)
347 (error "This shouldn't happen.")))))
349 (declaim (ftype j-write-char-fn sc-write-char-ef
))
350 (defun sc-write-char-ef (character stream
)
352 (with-stream-class (single-channel-simple-stream stream
)
353 (let ((buffer (sm buffer stream
))
354 (buffpos (sm buffpos stream
))
355 (buf-len (sm buf-len stream
))
356 (code (char-code character
))
357 (ctrl (sm control-out stream
)))
358 (when (and (< code
32) ctrl
(svref ctrl code
)
359 (funcall (the (or symbol function
) (svref ctrl code
))
361 (return-from sc-write-char-ef character
))
362 (flet ((output (byte)
363 (when (>= buffpos buf-len
)
364 (setf (sm buffpos stream
) buffpos
)
365 (setq buffpos
(flush-buffer stream t
)))
366 (setf (bref buffer buffpos
) byte
)
368 (char-to-octets (sm external-format stream
) character
369 (sm co-state stream
) #'output
))
370 (setf (sm buffpos stream
) buffpos
)
371 (sc-set-dirty stream
)
372 (if (sm charpos stream
) (incf (sm charpos stream
))))))
375 (declaim (ftype j-write-chars-fn sc-write-chars-ef
))
376 (defun sc-write-chars-ef (string stream start end
)
377 (with-stream-class (single-channel-simple-stream stream
)
378 (do ((buffer (sm buffer stream
))
379 (buffpos (sm buffpos stream
))
380 (buf-len (sm buf-len stream
))
381 (ef (sm external-format stream
))
382 (ctrl (sm control-out stream
))
383 (posn start
(1+ posn
))
384 (count 0 (1+ count
)))
385 ((>= posn end
) (setf (sm buffpos stream
) buffpos
) count
)
386 (declare (type fixnum buffpos buf-len posn count
))
387 (let* ((char (char string posn
))
388 (code (char-code char
)))
389 (unless (and (< code
32) ctrl
(svref ctrl code
)
390 (funcall (the (or symbol function
) (svref ctrl code
))
392 (flet ((output (byte)
393 (when (>= buffpos buf-len
)
394 (setf (sm buffpos stream
) buffpos
)
395 (setq buffpos
(flush-buffer stream t
)))
396 (setf (bref buffer buffpos
) byte
)
398 (char-to-octets ef char
(sm co-state stream
) #'output
))
399 (setf (sm buffpos stream
) buffpos
)
400 (if (sm charpos stream
) (incf (sm charpos stream
)))
401 (sc-set-dirty stream
))))))
404 ;;;; Dual-Channel-Simple-Stream strategy functions
406 ;; single-channel read-side functions work for dual-channel streams too
408 (declaim (ftype j-write-char-fn dc-write-char-ef
))
409 (defun dc-write-char-ef (character stream
)
411 (with-stream-class (dual-channel-simple-stream stream
)
412 (let ((out-buffer (sm out-buffer stream
))
413 (outpos (sm outpos stream
))
414 (max-out-pos (sm max-out-pos stream
))
415 (code (char-code character
))
416 (ctrl (sm control-out stream
)))
417 (when (and (< code
32) ctrl
(svref ctrl code
)
418 (funcall (the (or symbol function
) (svref ctrl code
))
420 (return-from dc-write-char-ef character
))
421 (flet ((output (byte)
422 (when (>= outpos max-out-pos
)
423 (setf (sm outpos stream
) outpos
)
424 (setq outpos
(flush-out-buffer stream t
)))
425 (setf (bref out-buffer outpos
) byte
)
427 (char-to-octets (sm external-format stream
) character
428 (sm co-state stream
) #'output
))
429 (setf (sm outpos stream
) outpos
)
430 (if (sm charpos stream
) (incf (sm charpos stream
))))))
434 (declaim (ftype j-write-chars-fn dc-write-chars-ef
))
435 (defun dc-write-chars-ef (string stream start end
)
436 (with-stream-class (dual-channel-simple-stream stream
)
437 (do ((buffer (sm out-buffer stream
))
438 (outpos (sm outpos stream
))
439 (max-out-pos (sm max-out-pos stream
))
440 (ef (sm external-format stream
))
441 (ctrl (sm control-out stream
))
442 (posn start
(1+ posn
))
443 (count 0 (1+ count
)))
444 ((>= posn end
) (setf (sm outpos stream
) outpos
) count
)
445 (declare (type fixnum outpos max-out-pos posn count
))
446 (let* ((char (char string posn
))
447 (code (char-code char
)))
448 (unless (and (< code
32) ctrl
(svref ctrl code
)
449 (funcall (the (or symbol function
) (svref ctrl code
))
451 (flet ((output (byte)
452 (when (>= outpos max-out-pos
)
453 (setf (sm outpos stream
) outpos
)
454 (setq outpos
(flush-out-buffer stream t
)))
455 (setf (bref buffer outpos
) byte
)
457 (char-to-octets ef char
(sm co-state stream
) #'output
))
458 (setf (sm outpos stream
) outpos
)
459 (if (sm charpos stream
) (incf (sm charpos stream
))))))))
461 ;;;; String-Simple-Stream strategy functions
463 (declaim (ftype j-read-char-fn str-read-char
))
464 (defun str-read-char (stream eof-error-p eof-value blocking
)
465 (declare (type string-input-simple-stream stream
) (ignore blocking
)
466 #|
(optimize (speed 3) (space 2) (safety 0) (debug 0))|
#
468 (with-stream-class (string-input-simple-stream stream
)
469 (when (any-stream-instance-flags stream
:eof
)
470 (sb-impl::eof-or-lose stream eof-error-p eof-value
))
471 (let* ((ptr (sm buffpos stream
))
472 (char (if (< ptr
(sm buffer-ptr stream
))
473 (schar (sm buffer stream
) ptr
)
476 (sb-impl::eof-or-lose stream eof-error-p eof-value
)
478 (setf (sm last-char-read-size stream
) 1)
479 ;; do string-streams do control-in processing?
480 #|
(let ((column (sm charpos stream
)))
481 (declare (type (or null fixnum
) column
))
483 (setf (sm charpos stream
) (1+ column
))))
487 (declaim (ftype j-listen-fn str-listen-e-crlf
))
488 (defun str-listen-e-crlf (stream)
489 (with-stream-class (composing-stream stream
)
490 ;; if this says there's a character available, it may be #\Return,
491 ;; in which case read-char will only return if there's a following
492 ;; #\Linefeed, so this really has to read the char...
493 ;; but without precluding the later unread-char of a character which
494 ;; has already been read.
495 (funcall-stm-handler j-listen
(sm melded-stream stream
))))
497 (declaim (ftype j-read-char-fn str-read-char-e-crlf
))
498 (defun str-read-char-e-crlf (stream eof-error-p eof-value blocking
)
499 (with-stream-class (composing-stream stream
)
500 (let* ((encap (sm melded-stream stream
))
501 (ctrl (sm control-in stream
))
502 (char (funcall-stm-handler j-read-char encap nil stream blocking
)))
503 ;; if CHAR is STREAM, we hit EOF; if NIL, blocking is NIL and no
504 ;; character was available...
505 (when (eql char
#\Return
)
506 (let ((next (funcall-stm-handler j-read-char encap nil stream blocking
)))
507 ;; if NEXT is STREAM, we hit EOF, so we should just return the
508 ;; #\Return (and mark the stream :EOF? At least unread if we
509 ;; got a soft EOF, from a terminal, etc.
510 ;; if NEXT is NIL, blocking is NIL and there's a CR but no
511 ;; LF available on the stream: have to unread the CR and
512 ;; return NIL, letting the CR be reread later.
514 ;; If we did get a linefeed, adjust the last-char-read-size
515 ;; so that an unread of the resulting newline will unread both
516 ;; the linefeed _and_ the carriage return.
517 (if (eql next
#\Linefeed
)
518 (setq char
#\Newline
)
519 (funcall-stm-handler j-unread-char encap nil
))))
520 (when (characterp char
)
521 (let ((code (char-code char
)))
522 (when (and (< code
32) ctrl
(svref ctrl code
))
523 (setq char
(funcall (the (or symbol function
) (svref ctrl code
))
526 (sb-impl::eof-or-lose stream eof-error-p eof-value
)
529 (declaim (ftype j-unread-char-fn str-unread-char-e-crlf
))
530 (defun str-unread-char-e-crlf (stream relaxed
)
531 (declare (ignore relaxed
))
532 (with-stream-class (composing-stream stream
)
533 (funcall-stm-handler j-unread-char
(sm melded-stream stream
) nil
)))
536 ;;; Functions to install the strategy functions in the appropriate slots
538 (defun melding-stream (stream)
539 (with-stream-class (simple-stream)
540 (do ((stm stream
(sm melded-stream stm
)))
541 ((eq (sm melded-stream stm
) stream
) stm
))))
543 (defun meld (stream encap
)
544 (with-stream-class (simple-stream)
545 (setf (sm melding-base encap
) (sm melding-base stream
))
546 (setf (sm melded-stream encap
) (sm melded-stream stream
))
547 (setf (sm melded-stream stream
) encap
)
548 (rotatef (sm j-listen encap
) (sm j-listen stream
))
549 (rotatef (sm j-read-char encap
) (sm j-read-char stream
))
550 (rotatef (sm j-read-chars encap
) (sm j-read-chars stream
))
551 (rotatef (sm j-unread-char encap
) (sm j-unread-char stream
))
552 (rotatef (sm j-write-char encap
) (sm j-write-char stream
))
553 (rotatef (sm j-write-chars encap
) (sm j-write-chars stream
))))
555 (defun unmeld (stream)
556 (with-stream-class (simple-stream)
557 (let ((encap (sm melded-stream stream
)))
558 (unless (eq encap
(sm melding-base stream
))
559 (setf (sm melding-base encap
) encap
)
560 (setf (sm melded-stream stream
) (sm melded-stream encap
))
561 (setf (sm melded-stream encap
) encap
)
562 (rotatef (sm j-listen stream
) (sm j-listen encap
))
563 (rotatef (sm j-read-char encap
) (sm j-read-char stream
))
564 (rotatef (sm j-read-chars stream
) (sm j-read-chars encap
))
565 (rotatef (sm j-unread-char stream
) (sm j-unread-char encap
))
566 (rotatef (sm j-write-char stream
) (sm j-write-char encap
))
567 (rotatef (sm j-write-chars stream
) (sm j-write-chars encap
))))))
569 ;;; In cmucl, this is done with define-function-name-syntax (lists as
570 ;;; function names), we make do with symbol frobbing.
571 (defun %sf
(kind name format
&optional access
)
572 (flet ((find-strategy-function (&rest args
)
574 (find-symbol (format nil
"~{~A~^-~}" (mapcar #'string args
))
576 (if (fboundp name
) (fdefinition name
) nil
))))
577 (or (find-strategy-function kind name format access
)
578 (find-strategy-function kind name format
)
579 (find-strategy-function kind name
:ef access
)
580 (find-strategy-function kind name
:ef
))))
583 (defun install-single-channel-character-strategy (stream external-format
585 (let ((format (find-external-format external-format
)))
586 ;; ACCESS is usually NIL
587 ;; May be "undocumented" values: stream::buffer, stream::mapped
588 ;; to install strategies suitable for direct buffer streams
589 ;; (i.e., ones that call DEVICE-EXTEND instead of DEVICE-READ)
590 ;; (Avoids checking "mode" flags by installing special strategy)
591 (with-stream-class (simple-stream stream
)
592 (setf (sm j-listen stream
)
593 (%sf
'sc
'listen
(ef-name format
) access
)
594 (sm j-read-char stream
)
595 (%sf
'sc
'read-char
(ef-name format
) access
)
596 (sm j-read-chars stream
)
597 (%sf
'sc
'read-chars
(ef-name format
) access
)
598 (sm j-unread-char stream
)
599 (%sf
'sc
'unread-char
(ef-name format
) access
)
600 (sm j-write-char stream
)
601 (%sf
'sc
'write-char
(ef-name format
) access
)
602 (sm j-write-chars stream
)
603 (%sf
'sc
'write-chars
(ef-name format
) access
))))
606 (defun install-dual-channel-character-strategy (stream external-format
)
607 (let ((format (find-external-format external-format
)))
608 (with-stream-class (simple-stream stream
)
609 (setf (sm j-listen stream
)
610 (%sf
'sc
'listen
(ef-name format
))
611 (sm j-read-char stream
)
612 (%sf
'sc
'read-char
(ef-name format
))
613 (sm j-read-chars stream
)
614 (%sf
'sc
'read-chars
(ef-name format
))
615 (sm j-unread-char stream
)
616 (%sf
'sc
'unread-char
(ef-name format
))
617 (sm j-write-char stream
)
618 (%sf
'dc
'write-char
(ef-name format
))
619 (sm j-write-chars stream
)
620 (%sf
'dc
'write-chars
(ef-name format
)))))
623 (defun install-string-character-strategy (stream)
624 (when (any-stream-instance-flags stream
:input
)
625 (install-string-input-character-strategy stream
))
626 (when (any-stream-instance-flags stream
:output
)
627 (install-string-output-character-strategy stream
))
630 (declaim (sb-ext:deprecated
631 :early
("SBCL" "1.2.15")
632 (function install-string-character-strategy
633 :replacement
(install-string-input-character-strategy
634 install-string-output-character-strategy
))))
636 (defun install-string-input-character-strategy (stream)
638 (with-stream-class (simple-stream stream
)
639 (setf (sm j-read-char stream
) #'str-read-char
))
642 (defun install-string-output-character-strategy (stream)
646 (defun install-composing-format-character-strategy (stream composing-format
)
647 (let ((format composing-format
))
648 (with-stream-class (simple-stream stream
)
650 (:e-crlf
(setf (sm j-read-char stream
) #'str-read-char-e-crlf
651 (sm j-unread-char stream
) #'str-unread-char-e-crlf
))))
655 (defun compose-encapsulating-streams (stream external-format
)
656 (when (consp external-format
)
657 (with-stream-class (simple-stream)
658 (let ((encap (if (eq (sm melded-stream stream
) stream
)
660 (sm melded-stream stream
))))
662 (setq encap
(make-instance 'composing-stream
))
664 (setf (stream-external-format encap
) (car (last external-format
)))
665 (setf (sm external-format stream
) external-format
)
666 (install-composing-format-character-strategy stream
667 (butlast external-format
))
670 (defmethod (setf stream-external-format
) (ef (stream simple-stream
))
671 (with-stream-class (simple-stream stream
)
672 (setf (sm external-format stream
) (find-external-format ef
)))