Common Lispの循環ストリームライブラリ「Circular-Streams」を公開しました
Clackではライブラリ内で使うユーティリティをsrc/util以下に置いているのですが、その1つであるreplay-input-streamを独立ライブラリの「Circular-Streams」として公開しました。
通常、ストリームは一度読み終わると再度読むことはできませんが、このライブラリを使うと何度もreadできる"循環ストリーム"を作ることができます。
;; 元のストリーム (defparameter *stream* (flex:make-in-memory-input-stream #(72 101 108 108 111))) ;; 循環ストリーム (defparameter *circular-stream* (make-circular-input-stream *stream*)) (read-char *circular-stream*) ;=> #\H (read-char *circular-stream*) ;=> #\e (read-char *circular-stream*) ;=> #\l (read-char *circular-stream*) ;=> #\l (read-char *circular-stream*) ;=> #\o (read-char *circular-stream* nil :eof) ;=> :eof (read-char *circular-stream*) ;=> #\H ← また読める!! (let ((buf (make-array 4 :adjustable t :fill-pointer 4))) (read-sequence buf *circular-stream*) (flex:octets-to-string buf)) ;=> "ello"
Octet stream (read-byteできるストリーム) しか扱えないので注意してください。
利用シーンがなかなか思い浮かばないかもしれないですが、たとえばClackではClack.RequestでのPOSTリクエストのパースに使っています。Clack.Requestではインスタンスを何回作っても同じbodyが返ってくることを期待しているので、何度もreadできるストリームは便利なわけです。
小さなリリースですが、興味があればお使いください。
追記: Quicklispに申請中です。2012年3月のアップデートで取り込まれる予定です。