This implementation is much faster than using flexi-stream.

```Lisp
(defparameter *line-buffer-size* 10)
(defparameter *line-tmp-size* 3)

(defconstant +new-line+ 10)
(defconstant +max-bytes-in-ch+ 4)

(defclass character-input-stream (fundamental-character-input-stream)
((binary-input-stream :accessor binary-input-stream)
(pos :accessor pos :type integer)
(buf-pos :accessor buf-pos :type integer)
(buf :accessor buf)
(buf-len :accessor buf-len)))

(defun read-from-stream (s)
(setf (buf-len s)
(read-sequence (buf s)
(binary-input-stream s))))

(defun new-buf ()
(make-array *line-buffer-size* :fill-pointer t
:element-type '(unsigned-byte 8)))

(defun make-character-input-stream (binary-input-stream)
(let ((s (make-instance 'character-input-stream)))
(setf (binary-input-stream s) binary-input-stream)
(setf (pos s) 0)
(setf (buf-pos s) 0)
(setf (buf s) (new-buf))
(read-from-stream s)
s))

;; (defparameter *line-buffer-size* #x100000)
;; (defparameter *line-tmp-size* #x1000)

(defun new-line-tmp ()
(make-array *line-tmp-size* :fill-pointer 0
:element-type '(unsigned-byte 8)))

(defun end-of-stream? (s)
(eq 0 (buf-len s)))

(defun reset-buf-pos (s)
(setf (buf-pos s) 0))

(defun buf-is-consumed? (s)
(>= (buf-pos s) (buf-len s)))

(defun refill-buffer (s)
(when (buf-is-consumed? s)
(read-from-stream s)
(reset-buf-pos s)))

(defun make-ch-buf ()
(make-array +max-bytes-in-ch+
:fill-pointer 0 :element-type '(unsigned-byte 8)))

(defun read-byte-from-buf (s)
(let ((b (elt (buf s) (buf-pos s))))
(incf (buf-pos s))
(incf (pos s))
b))

(define-condition character-encoding-error (error)
((pos :initarg :pos :reader pos)))

(defun encode-char-1 (s ch-buf)
(declare (ignore s))
(let ((b0 (elt ch-buf 0)))
(when (eq 0 (mask-field (byte 1 7) b0))
(code-char b0))))

(defun encode-char-2 (s ch-buf)
(let ((b0 (elt ch-buf 0))
(b1 (elt ch-buf 1)))
(when (eq #b11000000 (mask-field (byte 3 5) b0))
(when (not (eq #b10000000 (mask-field (byte 2 6) b1)))
(error 'character-encoding-error :pos (pos s)))
(code-char (+ (ash (mask-field (byte 5 0) b0) 6)
(mask-field (byte 6 0) b1))))))

;; (encode-char-2 nil #(#xC2 #xA3))

(defun encode-char-3 (s ch-buf)
(let ((b0 (elt ch-buf 0))
(b1 (elt ch-buf 1))
(b2 (elt ch-buf 2)))
(when (eq #b11100000 (mask-field (byte 4 4) b0))
(when (or (not (eq #b10000000 (mask-field (byte 2 6) b1)))
(not (eq #b10000000 (mask-field (byte 2 6) b2))))
(error 'character-encoding-error :pos (pos s)))
(code-char (+ (mask-field (byte 6 0) b2)
(ash (mask-field (byte 6 0) b1) 6)
(ash (mask-field (byte 4 0) b0) 12))))))

;; (encode-char-3 nil #(224 184 129))

(defun encode-char-4 (s ch-buf)
(let ((b0 (elt ch-buf 0))
(b1 (elt ch-buf 1))
(b2 (elt ch-buf 2))
(b3 (elt ch-buf 3)))
(when (eq #b11110000 (mask-field (byte 5 3) b0))
(when (or (not (eq #b10000000 (mask-field (byte 2 6) b1)))
(not (eq #b10000000 (mask-field (byte 2 6) b2)))
(not (eq #b10000000 (mask-field (byte 2 6) b3))))
(error 'character-encoding-error :pos (pos s)))
(code-char (+ (mask-field (byte 6 0) b3)
(ash (mask-field (byte 6 0) b2) 6)
(ash (mask-field (byte 6 0) b1) 12)
(ash (mask-field (byte 4 0) b0) 18))))))

;; (encode-char-4 nil #(#xF0 #x90 #x8D #x88))

(defun encode-char (s ch-buf)
(let ((ch-buf-len (length ch-buf)))
(case ch-buf-len
(0 nil)
(1 (encode-char-1 s ch-buf))
(2 (encode-char-2 s ch-buf))
(3 (encode-char-3 s ch-buf))
(4 (encode-char-4 s ch-buf))
(otherwise (error 'character-encoding-error :pos (pos s))))))

(defun read-char-from-buf (s)
(let ((ch-buf (make-ch-buf)))
(loop do
(refill-buffer s)
(when (end-of-stream? s)
(return :EOF))
(vector-push (read-byte-from-buf s) ch-buf)
(let ((ch (encode-char s ch-buf)))
(when ch
(return ch))))))

(defmethod stream-read-char ((s character-input-stream))
(read-char-from-buf s))

(defun read-line-from-buf (s)
(let ((line-tmp (new-line-tmp)))
(loop do
(refill-buffer s)
(when (end-of-stream? s)
(return (values (babel:octets-to-string line-tmp :encoding :UTF-8) t)))
(let ((b (read-byte-from-buf s)))
(if (eq b +new-line+)
(return (values (babel:octets-to-string line-tmp :encoding :UTF-8) nil))
(vector-push b line-tmp))))))
```