f2af1d9

Bowmap · bowmap.git · Tickets

Branches > main > f2af1d9 > files / src / net / bowmap

Add functions to read and write frames with streams

Grahp, 2026-09-06

Commit: f2af1d98f50cc3785f129daa1454b56f72842fa9
Parent: 08c3a6c

3 changed files:

deps.edn modified (view file)

@@ -2,4 +2,5 @@  {:run {:exec-fn net.bowmap.core/-main         :extra-deps {nrepl/nrepl {:mvn/version "1.7.0"}}}}  :deps- {org.clojure/clojure {:mvn/version "1.13.0-alpha6"}}}+ {org.clojure/clojure {:mvn/version "1.13.0-alpha6"}+  io.netty/netty-buffer {:mvn/version "4.1.111.Final"}}}

src/net/bowmap/network/frame/types.clj added (view file)

@@ -0,0 +1,3 @@+(ns net.bowmap.network.frame.types)++(def max-varint-size 5)

src/net/bowmap/network/socket.clj added (view file)

@@ -0,0 +1,71 @@+(ns net.bowmap.network.socket+  "Functions for reading frames to and from java.net.Sockets."+  (:require+   [net.bowmap.network.frame.types :refer [max-varint-size]])+  (:import+   [io.netty.buffer ByteBuf Unpooled]+   [java.io+    EOFException+    IOException+    InputStream+    OutputStream]+   [java.net Socket]))++(defn read-byte!!+  "Blocks and reads an unsigned byte (int) from an InputStream.+   Throws if EOF is reached."+  [input-stream]+  (let [x (InputStream/.read input-stream)]+    (if (= x -1)+      (throw (EOFException. "EOF while reading from InputStream"))+      x)))++(defn read-varint!!+  "Blocks and reads a varint from an InputStream.+   Throws if EOF is reached, or if the encoded varint is invalid."+  [input-stream]+  (loop [num-read 0+         result 0]+    (if (>= num-read max-varint-size)+      (throw (IOException. "VarInt too long"))+      (let [b (read-byte!! input-stream)+            result' (bit-or result (bit-shift-left (bit-and b 0x7F) (* 7 num-read)))]+        (if (zero? (bit-and b 0x80))+          result'+          (recur (inc num-read) result'))))))++(defn read-frame!!+  "Blocks and reads a frame from an InputStream.+   Throws if EOF is reached, or if the encoded frame is invalid."+  [input-stream]+  (let [len (read-varint!! input-stream)+        arr (byte-array len)]+    (loop [offset 0]+      (when (< offset len)+        (let [r (InputStream/.read input-stream arr offset (- len offset))]+          (if (= r -1)+            (throw (EOFException. "EOF while reading frame"))+            (recur (+ offset r))))))+    (Unpooled/wrappedBuffer arr)))++(defn write-frame!!+  "Blocks and writes a frame to an OutputStream.+   Throws if the frame cannot be written."+  [frame output-stream]+  (let [len (ByteBuf/.readableBytes frame)+        arr (byte-array len)]+    (ByteBuf/.readBytes frame arr)+    (OutputStream/.write output-stream arr)+    (OutputStream/.flush output-stream)))++(defn receive-frame!!+  "Blocks and reads a frame from socket's InputStream.+   Throws if EOF is reached, or if the encoded frame is invalid."+  [socket]+  (read-frame!! (Socket/.getInputStream socket)))++(defn send-frame!!+  "Blocks and writes a frame to socket's OutputStream.+   Throws if the frame cannot be written."+  [frame socket]+  (write-frame!! frame (Socket/.getOutputStream socket)))