output.lisp 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. (in-package :hurd-streams)
  2. (defclass hurd-output-stream (hurd-stream fundamental-binary-output-stream)
  3. ((cache :initform (%create-adjustable-array 0)
  4. :accessor cache)))
  5. (defmethod stream-write-byte ((stream hurd-output-stream) byte)
  6. (vector-push-extend byte (cache stream)))
  7. (defmethod stream-write-char ((stream hurd-output-stream) char)
  8. (stream-write-byte stream (char-code char)))
  9. (defun %hurd-stream-write-warn (stream err)
  10. (warn "Error writing to hurd-output-stream ~s: ~s"
  11. stream err))
  12. (defmethod %hurd-stream-inner-write ((stream hurd-output-stream))
  13. (with-accessors ((cache cache) (port port) (offset offset))
  14. stream
  15. (let ((total (fill-pointer cache)))
  16. (multiple-value-bind (total-written err)
  17. (io-write port cache :offset offset)
  18. (when err
  19. (%hurd-stream-write-warn stream err)
  20. (return-from %hurd-stream-inner-write nil))
  21. (incf offset total-written)
  22. (unless (= total-written total)
  23. (replace cache cache
  24. :start2 total-written)
  25. (setf (fill-pointer cache) total-written)
  26. (%hurd-stream-inner-write stream))))))
  27. (defun %hurd-stream-has-data-p (stream)
  28. (plusp (fill-pointer (cache stream))))
  29. (defmethod %hurd-stream-write ((stream hurd-output-stream))
  30. (with-accessors ((cache cache)) stream
  31. (cond
  32. ((%hurd-stream-has-data-p stream)
  33. (when (%hurd-stream-inner-write stream)
  34. (setf (fill-pointer cache) 0)
  35. t))
  36. (t t))))
  37. (defmethod stream-finish-output ((stream hurd-output-stream))
  38. (%hurd-stream-write stream))
  39. (defmethod stream-force-output ((stream hurd-output-stream))
  40. (%hurd-stream-write stream))
  41. (defmethod %hurd-stream-write-seq ((stream hurd-output-stream) seq)
  42. (with-accessors ((port port) (offset offset))
  43. stream
  44. (let ((total (length seq)))
  45. (multiple-value-bind (total-written err)
  46. (io-write port seq :offset offset)
  47. (when err
  48. (%hurd-stream-write-warn stream err)
  49. (return-from %hurd-stream-write-seq nil))
  50. (incf offset total-written)
  51. (unless (= total-written total)
  52. (%hurd-stream-write-seq
  53. stream
  54. (subseq seq total-written))))))
  55. t)
  56. (defmethod stream-write-sequence ((stream hurd-output-stream)
  57. sequence start end &key)
  58. (when (%hurd-stream-write stream)
  59. (%hurd-stream-write-seq stream
  60. (subseq sequence start end))))
  61. (defmethod stream-start-line-p ((stream hurd-output-stream))
  62. nil)
  63. (defmethod stream-line-column ((stream hurd-output-stream))
  64. nil)
  65. (defmethod make-hurd-output-stream ((file string) &optional (flags '(:write)))
  66. (make-hurd-output-stream
  67. (file-name-lookup file :flags flags)))
  68. (defmethod make-hurd-output-stream ((port number) &optional flags)
  69. (declare (ignore flags))
  70. (make-instance 'hurd-output-stream :port port))
  71. (defmacro with-hurd-output-stream ((stream-name file &optional (flags ''(:write))) &body body)
  72. `(with-stream (,stream-name (make-hurd-output-stream ,file ,flags))
  73. ,@body))