journal/wire_proto.go

47 lines
1.3 KiB
Go

package journal
import (
"encoding/binary"
"io"
"net"
"slices"
)
var (
wireProtocolAttributeSeparator = []byte{'='}
wireProtocolAttributeTerminator = []byte{'\n'}
)
// WireWrite is the lowest-level routine. It writes a journal entry using the
// native wire protocol documented at https://systemd.io/JOURNAL_NATIVE_PROTOCOL/ .
// Invalid attributes are silently skipped. It appends to buf as needed.
//
// As long as w supports the net.buffersWriter interface, the write will be
// atomic, and this function is safe to use across goroutines. Otherwise,
// writes may be interleaved.
func WireWrite(buf *net.Buffers, w io.Writer, attrs []Attr) error {
*buf = slices.Grow(*buf, len(*buf)+len(attrs)*4)
for i := range attrs {
key := attrs[i].Key.key
if key == "" {
// silently discard invalid attributes
continue
}
*buf = append(*buf, []byte(key))
if attrs[i].UseTextProto() {
*buf = append(*buf, wireProtocolAttributeSeparator)
*buf = append(*buf, attrs[i].Value)
} else {
var valueSize [9]byte
valueSize[0] = '\n'
binary.LittleEndian.PutUint64(valueSize[1:], uint64(len(attrs[i].Value)))
*buf = append(*buf, valueSize[:])
*buf = append(*buf, attrs[i].Value)
}
*buf = append(*buf, wireProtocolAttributeTerminator)
}
_, err := buf.WriteTo(w)
return err
}