streams.lisp 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. #+xcvb (module (:depends-on ("package")))
  2. (in-package :trivial-gray-streams)
  3. (defclass fundamental-stream (impl-specific-gray:fundamental-stream) ())
  4. (defclass fundamental-input-stream
  5. (fundamental-stream impl-specific-gray:fundamental-input-stream) ())
  6. (defclass fundamental-output-stream
  7. (fundamental-stream impl-specific-gray:fundamental-output-stream) ())
  8. (defclass fundamental-character-stream
  9. (fundamental-stream impl-specific-gray:fundamental-character-stream) ())
  10. (defclass fundamental-binary-stream
  11. (fundamental-stream impl-specific-gray:fundamental-binary-stream) ())
  12. (defclass fundamental-character-input-stream
  13. (fundamental-input-stream fundamental-character-stream
  14. impl-specific-gray:fundamental-character-input-stream) ())
  15. (defclass fundamental-character-output-stream
  16. (fundamental-output-stream fundamental-character-stream
  17. impl-specific-gray:fundamental-character-output-stream) ())
  18. (defclass fundamental-binary-input-stream
  19. (fundamental-input-stream fundamental-binary-stream
  20. impl-specific-gray:fundamental-binary-input-stream) ())
  21. (defclass fundamental-binary-output-stream
  22. (fundamental-output-stream fundamental-binary-stream
  23. impl-specific-gray:fundamental-binary-output-stream) ())
  24. (defgeneric stream-read-sequence
  25. (stream sequence start end &key &allow-other-keys))
  26. (defgeneric stream-write-sequence
  27. (stream sequence start end &key &allow-other-keys))
  28. (defgeneric stream-file-position (stream))
  29. (defgeneric (setf stream-file-position) (newval stream))
  30. ;;; Default methods for stream-read/write-sequence.
  31. ;;;
  32. ;;; It would be nice to implement default methods
  33. ;;; in trivial gray streams, maybe borrowing the code
  34. ;;; from some of CL implementations. But now, for
  35. ;;; simplicity we will fallback to default implementation
  36. ;;; of the implementation-specific analogue function which calls us.
  37. (defmethod stream-read-sequence ((stream fundamental-input-stream) seq start end &key)
  38. 'fallback)
  39. (defmethod stream-write-sequence ((stream fundamental-output-stream) seq start end &key)
  40. 'fallback)
  41. (defmacro or-fallback (&body body)
  42. `(let ((result ,@body))
  43. (if (eq result (quote fallback))
  44. (call-next-method)
  45. result)))
  46. ;; Implementations should provide this default method, I believe, but
  47. ;; at least sbcl and allegro don't.
  48. (defmethod stream-terpri ((stream fundamental-output-stream))
  49. (write-char #\newline stream))
  50. ;; stream-file-position could be specialized to
  51. ;; fundamental-stream, but to support backward
  52. ;; compatibility with flexi-streams, we specialize
  53. ;; it on T. The reason: flexi-streams calls stream-file-position
  54. ;; for non-gray stream:
  55. ;; https://github.com/edicl/flexi-streams/issues/4
  56. (defmethod stream-file-position ((stream t))
  57. nil)
  58. (defmethod (setf stream-file-position) (newval (stream t))
  59. (declare (ignore newval))
  60. nil)
  61. #+abcl
  62. (progn
  63. (defmethod gray-streams:stream-read-sequence
  64. ((s fundamental-input-stream) seq &optional start end)
  65. (or-fallback (stream-read-sequence s seq (or start 0) (or end (length seq)))))
  66. (defmethod gray-streams:stream-write-sequence
  67. ((s fundamental-output-stream) seq &optional start end)
  68. (or-fallback (stream-write-sequence s seq (or start 0) (or end (length seq)))))
  69. (defmethod gray-streams:stream-write-string
  70. ((stream xp::xp-structure) string &optional (start 0) (end (length string)))
  71. (xp::write-string+ string stream start end))
  72. #+#.(cl:if (cl:and (cl:find-package :gray-streams)
  73. (cl:find-symbol "STREAM-FILE-POSITION" :gray-streams))
  74. '(:and)
  75. '(:or))
  76. (defmethod gray-streams:stream-file-position
  77. ((s fundamental-stream) &optional position)
  78. (if position
  79. (setf (stream-file-position s) position)
  80. (stream-file-position s))))
  81. #+allegro
  82. (progn
  83. (defmethod excl:stream-read-sequence
  84. ((s fundamental-input-stream) seq &optional start end)
  85. (or-fallback (stream-read-sequence s seq (or start 0) (or end (length seq)))))
  86. (defmethod excl:stream-write-sequence
  87. ((s fundamental-output-stream) seq &optional start end)
  88. (or-fallback (stream-write-sequence s seq (or start 0) (or end (length seq)))))
  89. (defmethod excl::stream-file-position
  90. ((stream fundamental-stream) &optional position)
  91. (if position
  92. (setf (stream-file-position stream) position)
  93. (stream-file-position stream))))
  94. #+cmu
  95. (progn
  96. (defmethod ext:stream-read-sequence
  97. ((s fundamental-input-stream) seq &optional start end)
  98. (or-fallback (stream-read-sequence s seq (or start 0) (or end (length seq)))))
  99. (defmethod ext:stream-write-sequence
  100. ((s fundamental-output-stream) seq &optional start end)
  101. (or-fallback (stream-write-sequence s seq (or start 0) (or end (length seq))))))
  102. #+lispworks
  103. (progn
  104. (defmethod stream:stream-read-sequence
  105. ((s fundamental-input-stream) seq start end)
  106. (or-fallback (stream-read-sequence s seq start end)))
  107. (defmethod stream:stream-write-sequence
  108. ((s fundamental-output-stream) seq start end)
  109. (or-fallback (stream-write-sequence s seq start end)))
  110. (defmethod stream:stream-file-position ((stream fundamental-stream))
  111. (stream-file-position stream))
  112. (defmethod (setf stream:stream-file-position)
  113. (newval (stream fundamental-stream))
  114. (setf (stream-file-position stream) newval)))
  115. #+openmcl
  116. (progn
  117. (defmethod ccl:stream-read-vector
  118. ((s fundamental-input-stream) seq start end)
  119. (or-fallback (stream-read-sequence s seq start end)))
  120. (defmethod ccl:stream-write-vector
  121. ((s fundamental-output-stream) seq start end)
  122. (or-fallback (stream-write-sequence s seq start end)))
  123. (defmethod ccl:stream-read-list ((s fundamental-input-stream) list count)
  124. (or-fallback (stream-read-sequence s list 0 count)))
  125. (defmethod ccl:stream-write-list ((s fundamental-output-stream) list count)
  126. (or-fallback (stream-write-sequence s list 0 count)))
  127. (defmethod ccl::stream-position ((stream fundamental-stream) &optional new-position)
  128. (if new-position
  129. (setf (stream-file-position stream) new-position)
  130. (stream-file-position stream))))
  131. ;; up to version 2.43 there were no
  132. ;; stream-read-sequence, stream-write-sequence
  133. ;; functions in CLISP
  134. #+clisp
  135. (eval-when (:compile-toplevel :load-toplevel :execute)
  136. (when (find-symbol (string '#:stream-read-sequence) '#:gray)
  137. (pushnew :clisp-has-stream-read/write-sequence *features*)))
  138. #+clisp
  139. (progn
  140. #+clisp-has-stream-read/write-sequence
  141. (defmethod gray:stream-read-sequence
  142. (seq (s fundamental-input-stream) &key start end)
  143. (or-fallback (stream-read-sequence s seq (or start 0) (or end (length seq)))))
  144. #+clisp-has-stream-read/write-sequence
  145. (defmethod gray:stream-write-sequence
  146. (seq (s fundamental-output-stream) &key start end)
  147. (or-fallback (stream-write-sequence s seq (or start 0) (or end (length seq)))))
  148. ;;; for old CLISP
  149. (defmethod gray:stream-read-byte-sequence
  150. ((s fundamental-input-stream)
  151. seq
  152. &optional start end no-hang interactive)
  153. (when no-hang
  154. (error "this stream does not support the NO-HANG argument"))
  155. (when interactive
  156. (error "this stream does not support the INTERACTIVE argument"))
  157. (or-fallback (stream-read-sequence s seq start end)))
  158. (defmethod gray:stream-write-byte-sequence
  159. ((s fundamental-output-stream)
  160. seq
  161. &optional start end no-hang interactive)
  162. (when no-hang
  163. (error "this stream does not support the NO-HANG argument"))
  164. (when interactive
  165. (error "this stream does not support the INTERACTIVE argument"))
  166. (or-fallback (stream-write-sequence s seq start end)))
  167. (defmethod gray:stream-read-char-sequence
  168. ((s fundamental-input-stream) seq &optional start end)
  169. (or-fallback (stream-read-sequence s seq start end)))
  170. (defmethod gray:stream-write-char-sequence
  171. ((s fundamental-output-stream) seq &optional start end)
  172. (or-fallback (stream-write-sequence s seq start end)))
  173. ;;; end of old CLISP read/write-sequence support
  174. (defmethod gray:stream-position ((stream fundamental-stream) position)
  175. (if position
  176. (setf (stream-file-position stream) position)
  177. (stream-file-position stream))))
  178. #+sbcl
  179. (progn
  180. (defmethod sb-gray:stream-read-sequence
  181. ((s fundamental-input-stream) seq &optional start end)
  182. (or-fallback (stream-read-sequence s seq (or start 0) (or end (length seq)))))
  183. (defmethod sb-gray:stream-write-sequence
  184. ((s fundamental-output-stream) seq &optional start end)
  185. (or-fallback (stream-write-sequence s seq (or start 0) (or end (length seq)))))
  186. (defmethod sb-gray:stream-file-position
  187. ((stream fundamental-stream) &optional position)
  188. (if position
  189. (setf (stream-file-position stream) position)
  190. (stream-file-position stream)))
  191. ;; SBCL extension:
  192. (defmethod sb-gray:stream-line-length ((stream fundamental-stream))
  193. 80))
  194. #+ecl
  195. (progn
  196. (defmethod gray:stream-read-sequence
  197. ((s fundamental-input-stream) seq &optional start end)
  198. (or-fallback (stream-read-sequence s seq (or start 0) (or end (length seq)))))
  199. (defmethod gray:stream-write-sequence
  200. ((s fundamental-output-stream) seq &optional start end)
  201. (or-fallback (stream-write-sequence s seq (or start 0) (or end (length seq))))))
  202. #+mocl
  203. (progn
  204. (defmethod gray:stream-read-sequence
  205. ((s fundamental-input-stream) seq &optional start end)
  206. (or-fallback (stream-read-sequence s seq (or start 0) (or end (length seq)))))
  207. (defmethod gray:stream-write-sequence
  208. ((s fundamental-output-stream) seq &optional start end)
  209. (or-fallback (stream-write-sequence s seq (or start 0) (or end (length seq)))))
  210. (defmethod gray:stream-file-position
  211. ((stream fundamental-stream) &optional position)
  212. (if position
  213. (setf (stream-file-position stream) position)
  214. (stream-file-position stream))))
  215. ;; deprecated
  216. (defclass trivial-gray-stream-mixin () ())