47 lines
1.3 KiB
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
|
|
}
|