export function bind_recvPacketStream(rstream, recv) :: return new Promise @ resolve => :: let on_data = binaryLenPrefixFeedBE @ shutdown, async pkt_lst => :: rstream.pause() for let p of pkt_lst.map(recv) :: await p rstream.resume() rstream.once @ 'error', shutdown rstream.once @ 'close', shutdown rstream.on @ 'data', on_data function shutdown(err) :: if null !== rstream :: rstream.off @ 'data', on_data rstream.end() rstream = null resolve() const lut_byLength = @! let len_u32be = buf => buf.readUInt32BE(1) let len_u16be = buf => buf.readUInt16BE(1) let len_u8 = (buf, b0) => b0 len_u8.width = 1 let lut = Array(256).fill(len_u8); lut[0] = lut[1] = lut[2] = lut[3] = null; (lut[254] = len_u16be).width = 3; (lut[255] = len_u32be).width = 5; return lut export function binaryLenPrefixFeedBE(shutdown, recv_dispatch) :: let tipLen=null, byteLen=0, q=[] return function(data) :: if 0 === data.byteLength :: return q.push(data) ; byteLen += data.byteLength let pktList = [] while 1 :: let buf = parseNext() if undefined !== buf :: pktList.push @ buf else break if 0 !== pktList.length :: recv_dispatch(pktList).catch(shutdown) return function parseNext() :: if null === tipLen :: if byteLen < 5 :: return let buf = Buffer.concat(q) let b0 = buf.readUInt8(0) let len_fn = lut_byLength[b0] if null === len_fn :: shutdown @ new Error @ 'Binary stream framing error' return let len_width = len_fn.width tipLen = len_fn @ buf, b0 q = @[] buf.slice @ len_width byteLen -= len_width if tipLen <= byteLen :: let buf_q = 1===q.length ? q[0] : Buffer.concat(q) let buf = buf_q.slice(0, tipLen) q = [buf_q.slice(tipLen)] byteLen -= tipLen tipLen = null return buf