File: logattr.go

package info (click to toggle)
golang-github-cactus-mlog 1.0.10-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 272 kB
  • sloc: makefile: 2
file content (100 lines) | stat: -rw-r--r-- 1,755 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
// Copyright (c) 2012-2023 Eli Janssen
// Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file.

package mlog

import "fmt"

type Attr struct {
	Key   string
	Value interface{}
}

func A(key string, value interface{}) *Attr {
	return &Attr{key, value}
}

func (attr *Attr) writeBuf(w byteSliceWriter) {
	if attr == nil {
		return
	}

	// scratch buffer for intermediate writes
	buf := bufPool.Get()
	defer bufPool.Put(buf)

	w.WriteString(attr.Key)
	w.WriteString(`="`)
	fmt.Fprint(buf, attr.Value)

	// pull out byte slice from buff
	b := buf.Bytes()
	blen := buf.Len()
	p := 0
	for i := 0; i < blen; i++ {
		switch b[i] {
		case '"':
			w.Write(b[p:i])
			w.WriteString(`\"`)
			p = i + 1
		case '\t':
			w.Write(b[p:i])
			w.WriteString(`\t`)
			p = i + 1
		case '\r':
			w.Write(b[p:i])
			w.WriteString(`\r`)
			p = i + 1
		case '\n':
			w.Write(b[p:i])
			w.WriteString(`\n`)
			p = i + 1
		}
	}
	if p < blen {
		w.Write(b[p:blen])
	}

	w.WriteByte('"')
	// truncate intermediate buf so it is clean for next loop
	buf.Truncate(0)
}

func (attr *Attr) String() string {
	buf := bufPool.Get()
	defer bufPool.Put(buf)
	attr.writeBuf(buf)
	return buf.String()
}

func attrsWriteBuf(w byteSliceWriter, attrs []*Attr) {
	attrsLen := len(attrs)
	for i, attr := range filterAttrs(attrs) {
		attr.writeBuf(w)
		if i != attrsLen-1 {
			w.WriteByte(' ')
		}
	}
}

func filterAttrs(attrs []*Attr) []*Attr {
	hasNil := false
	for _, attr := range attrs {
		if attr == nil {
			hasNil = true
			break
		}
	}
	if !hasNil {
		return attrs
	}

	filteredAttrs := make([]*Attr, 0, len(attrs))
	for _, attr := range attrs {
		if attr != nil {
			filteredAttrs = append(filteredAttrs, attr)
		}
	}
	return filteredAttrs
}