buffer.clj

Bowmap · bowmap.git · Tickets

Branches > main > c3bf28a > files / src / net / bowmap / server / protocol / buffer.clj

(ns net.bowmap.server.protocol.buffer
  (:require
   [clojure.spec.alpha :as s]
   [net.bowmap.server.protocol.frame :as frame])
  (:import
   [java.io ByteArrayOutputStream]))

(defprotocol WriteBuffer
  "A single-threaded transiently mutable growable buffer of bytes."
  (write-byte! [buf b] "Returns this buffer after adding one byte to the end.
                        Byte may be signed or unsigned.")
  (->frame [buf] "Returns a frame from this buf.
                  After this call, the buffer is not to be mutated."))

(s/def ::write-buffer #(satisfies? WriteBuffer %))

(defn write-buffer []
  (let [baos (ByteArrayOutputStream.)]
    ^{:type ::write-buffer}
    (reify WriteBuffer
      (write-byte! [buf b]
        (^[int] ByteArrayOutputStream/.write baos (bit-and 0xFF b))
        buf)
      (->frame [_]
        (frame/frame (ByteArrayOutputStream/.toByteArray baos))))))

(defmethod print-method ::write-buffer [buf writer]
  (frame/write! (->frame buf)
                (fn [array length]
                  (.write writer "#WriteBuffer ")
                  (.write writer (pr-str (subvec (vec array) 0 length))))))