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
 | |
| }
 |