package internal import ( "bytes" "errors" "io" "log" "net" "sync" "go.cypherpunks.ru/netstring/v2" ) func ArgsEncode(datum ...[]byte) []byte { var buf bytes.Buffer w := netstring.NewWriter(&buf) for _, data := range datum { if _, err := w.WriteChunk(data); err != nil { log.Fatal(err) } } return buf.Bytes() } func ArgsDecode(buf []byte) (args [][]byte, err error) { r := netstring.NewReader(bytes.NewReader(buf)) var n uint64 for { n, err = r.Next() if err != nil { if errors.Is(err, io.EOF) { err = nil break } return } arg := make([]byte, int(n)) _, err = io.ReadFull(r, arg) if err != nil { return } args = append(args, arg) } return } type NSConn struct { Conn net.Conn Rx chan []byte Err error sync.Mutex } func NewNSConn(conn net.Conn) *NSConn { c := NSConn{Conn: conn, Rx: make(chan []byte)} go func() { r := netstring.NewReader(conn) var n uint64 for { n, c.Err = r.Next() if c.Err != nil { break } buf := make([]byte, int(n)) if _, c.Err = io.ReadFull(r, buf); c.Err != nil { break } c.Rx <- buf } close(c.Rx) }() return &c } func (ns *NSConn) Tx(data []byte) (err error) { ns.Lock() _, err = netstring.NewWriter(ns.Conn).WriteChunk(data) ns.Unlock() return }